Skip to content
Snippets Groups Projects
Commit a0df314b authored by Thomas Flori's avatar Thomas Flori
Browse files

alpha 1.0 implemented

parent 2587ef50
No related branches found
No related tags found
No related merge requests found
Pipeline #187 passed with stage
......@@ -16,14 +16,90 @@ namespace DependencyInjector;
* echo DependencyInjector:get('hello') . " " . DependencyInjector:.get('world') . "!\n";
*/
class DI {
protected static $_instances = [];
protected static $_dependencies = [];
/**
* Get a previously defined dependency identified by $name.
*
* @param string $name
* @throws Exception
* @return mixed
*/
public static function get($name) {
if (isset(self::$_instances[$name])) {
return self::$_instances[$name];
} elseif (isset(self::$_dependencies[$name])) {
if (self::$_dependencies[$name]['singleton']) {
self::$_instances[$name] = call_user_func(self::$_dependencies[$name]['getter']);
return self::$_instances[$name];
}
return call_user_func(self::$_dependencies[$name]['getter']);
} elseif (class_exists($name)) {
return $name;
}
throw new Exception("Unknown dependency '" . $name . "'");
}
/**
* Alias for DI::get($name). Example:
* DI::get('same') === DI::same()
*
* @param string $name
* @param array $arguments
* @return mixed
*/
public static function __callStatic($name, $arguments) {
return self::get($name);
}
/**
* Define a dependency.
*
* @param string $name
* @param mixed $getter
* @param bool $singleton
* @return void
*/
public static function set($name, $getter, $singleton = true) {
if (is_object($getter) && $getter instanceof \Closure && is_callable($getter)) {
if (isset(self::$_instances[$name])) {
unset(self::$_instances[$name]);
}
self::$_dependencies[$name] = [
'singleton' => $singleton,
'getter' => $getter
];
} else {
self::$_instances[$name] = $getter;
}
}
/**
* Resets the DependencyInjector
*
* @return void
*/
public static function reset() {
self::$_instances = [];
self::$_dependencies = [];
}
private function __construct() {}
}
......@@ -5,6 +5,11 @@ use DependencyInjector\DI;
class DependencyInjectorTest extends TestCase {
public function tearDown() {
DI::reset();
parent::tearDown();
}
/**
* Test that the setup works - the class should exist
*/
......@@ -12,6 +17,16 @@ class DependencyInjectorTest extends TestCase {
$this->assertTrue(class_exists('DependencyInjector\DI'));
}
/**
* Test that constructor is not callable
*/
public function testPrivateConstructor() {
$refDI = new ReflectionClass(DI::class);
$refConstruct = $refDI->getMethod('__construct');
$this->assertTrue($refConstruct->isPrivate());
}
/**
* Test that DI::get() throws a exception when the requested dependency is unknown.
*/
......@@ -21,4 +36,136 @@ class DependencyInjectorTest extends TestCase {
DI::get('unknown');
}
/**
* Test that DI::set() stores something.
*/
public function testSet_storesSomething() {
$something = [$this, __FUNCTION__];
DI::set('something', $something);
$this->assertEquals($something, DI::get('something'));
}
/**
* Test that DI::get() executes the given function and returns the return value.
*/
public function testGet_executesAnonymousFunctions() {
DI::set('anonymous', function() {
return 'fooBar';
});
$result = DI::get('anonymous');
$this->assertSame('fooBar', $result);
}
/**
* Test that the function got not executed before get.
*/
public function testSet_doesNotExecute() {
$calls = 0;
DI::set('dontCall', function() use(&$calls) {
$calls = $calls + 1;
});
$this->assertSame(0, $calls);
}
/**
* Test that the function got executed only once.
*/
public function testGet_executesOnce() {
$calls = 0;
DI::set('callOnce', function() use(&$calls) {
$calls = $calls + 1;
return new DateTime();
});
DI::get('callOnce');
DI::get('callOnce');
$this->assertSame(1, $calls);
}
/**
* Test that a non singleton got executed for each get.
*/
public function testGet_executesNonSingleton() {
$calls = 0;
DI::set('callTwice', function() use(&$calls) {
$calls = $calls + 1;
return new DateTime();
}, false);
DI::get('callTwice');
DI::get('callTwice');
$this->assertSame(2, $calls);
}
/**
* Test that DI::set() overrides created instances.
*/
public function testSet_overridesInstances() {
DI::set('microtime', function() {
return microtime(true);
});
$result1 = DI::get('microtime');
DI::set('microtime', function() {
return microtime(true);
});
$result2 = DI::get('microtime');
$this->assertNotSame($result1, $result2);
}
/**
* Test that you can get instances with magic method.
*/
public function testGet_callStatic() {
DI::set('magicCall', true);
/** @noinspection PhpUndefinedMethodInspection */
$result = DI::magicCall();
$this->assertTrue($result);
}
/**
* Test that undefined dependencies return the class name if it exists.
*/
public function testGet_returnsClassName() {
$result = DI::get(__CLASS__);
$this->assertSame(__CLASS__, $result);
}
/**
* Test that you can override class names.
*/
public function testGet_returnsStored() {
DI::set(__CLASS__, 'FooBar');
$result = DI::get(__CLASS__);
$this->assertSame('FooBar', $result);
}
/**
* Test that DI::reset() resets the DependencyInjector.
*/
public function testReset() {
DI::set(__CLASS__, function() {
return 'FooBar';
});
DI::get(__CLASS__);
DI::reset();
$this->assertSame(__CLASS__, DI::get(__CLASS__));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment