diff --git a/.travis/run-tests.sh b/.travis/run-tests.sh index 7e1baa3b..a84e0ba2 100755 --- a/.travis/run-tests.sh +++ b/.travis/run-tests.sh @@ -1,5 +1,5 @@ #!/bin/bash -travisdir=$(dirname $(readlink /proc/$$/fd/255)) +travisdir=$(dirname "$0") testdir="$travisdir/../tests" testedcomponents=(`cat "$travisdir/tested-components"`) result=0 diff --git a/.travis/skipped-components b/.travis/skipped-components index 31bcaa87..171dfe9d 100644 --- a/.travis/skipped-components +++ b/.travis/skipped-components @@ -1,5 +1,6 @@ Zend/Amf Zend/Date +Zend/Dojo Zend/Queue Zend/Service Zend/Test diff --git a/.travis/tested-components b/.travis/tested-components index b1f4a794..b0b94380 100644 --- a/.travis/tested-components +++ b/.travis/tested-components @@ -22,6 +22,7 @@ Zend/Form Zend/GData Zend/Http Zend/InfoCard +Zend/InputFilter Zend/Json Zend/Ldap Zend/Loader @@ -29,10 +30,11 @@ Zend/Locale Zend/Log Zend/Mail Zend/Markup +Zend/Math Zend/Measure Zend/Memory Zend/Mime -Zend/Module +Zend/ModuleManager Zend/Mvc Zend/Navigation Zend/OAuth diff --git a/src/Configuration.php b/src/Configuration.php index 7b275502..855bec97 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -48,10 +48,28 @@ public function configureDefinition(Di $di, $definition) foreach ($definition as $definitionType => $definitionData) { switch ($definitionType) { case 'compiler': - // @todo + foreach ($definitionData as $filename) { + if (is_readable($filename)) { + $di->definitions()->addDefinition(new \Zend\Di\Definition\ArrayDefinition(include $filename), false); + } + } break; case 'runtime': - // @todo + if (isset($definitionData['enabled']) && !$definitionData['enabled']) { + // Remove runtime from definition list if not enabled + $definitions = array(); + foreach ($di->definitions() as $definition) { + if (!$definition instanceof \Zend\Di\Definition\RuntimeDefinition) { + $definitions[] = $definition; + } + } + $definitions = new DefinitionList($definitions); + $di->setDefinitionList($definitions); + } elseif (isset($definitionData['use_annotations']) && $definitionData['use_annotations']) { + $di->definitions()->getDefinitionByType('\Zend\Di\Definition\RuntimeDefinition') + ->getIntrospectionStrategy() + ->setUseAnnotations(true); + } break; case 'class': foreach ($definitionData as $className => $classData) { diff --git a/src/Di.php b/src/Di.php index 7227a561..3c15ec94 100644 --- a/src/Di.php +++ b/src/Di.php @@ -208,7 +208,7 @@ public function newInstance($name, array $params = array(), $isShared = true) } } - $this->handleInjectDependencies($instance, $class, $injectionMethods, $supertypeInjectionMethods, $params, $alias); + $this->handleInjectDependencies($instance, $injectionMethods, $supertypeInjectionMethods, $params, $class, $alias, $name); array_pop($this->instanceContext); return $instance; @@ -236,13 +236,12 @@ public function injectDependencies($instance, array $params = array()) $superTypeInjectionMethods[$interface] = $definitions->getMethods($interface); } } - $this->handleInjectDependencies($instance, null, $injectionMethods, $superTypeInjectionMethods, $params, null); + $this->handleInjectDependencies($instance, $injectionMethods, $superTypeInjectionMethods, $params, $class, null, null); } - protected function handleInjectDependencies($instance, $name, $injectionMethods, $supertypeInjectionMethods, $params, $alias) + protected function handleInjectDependencies($instance, $injectionMethods, $supertypeInjectionMethods, $params, $instanceClass, $instanceAlias, $requestedName) { - $class = get_class($instance); // localize dependencies $definitions = $this->definitions; @@ -251,19 +250,19 @@ protected function handleInjectDependencies($instance, $name, $injectionMethods, if ($injectionMethods || $supertypeInjectionMethods) { foreach ($injectionMethods as $injectionMethod => $methodIsRequired) { if ($injectionMethod !== '__construct'){ - $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $alias, $methodIsRequired, $class); + $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $instanceAlias, $methodIsRequired, $instanceClass); } } foreach ($supertypeInjectionMethods as $supertype => $supertypeInjectionMethod) { foreach ($supertypeInjectionMethod as $injectionMethod => $methodIsRequired) { if ($injectionMethod !== '__construct') { - $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $alias, $methodIsRequired, $supertype); + $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $instanceAlias, $methodIsRequired, $supertype); } } } - if ($name) { - $instanceConfiguration = $instanceManager->getConfiguration($name); + if ($requestedName) { + $instanceConfiguration = $instanceManager->getConfiguration($requestedName); if ($instanceConfiguration['injections']) { $objectsToInject = $methodsToCall = array(); @@ -290,11 +289,11 @@ protected function handleInjectDependencies($instance, $name, $injectionMethods, if ($objectsToInject) { foreach ($objectsToInject as $objectToInject) { foreach ($injectionMethods as $injectionMethod => $methodIsRequired) { - $methodParams = $definitions->getMethodParameters($class, $injectionMethod); + $methodParams = $definitions->getMethodParameters($instanceClass, $injectionMethod); if ($methodParams) { foreach ($methodParams as $methodParam) { if (get_class($objectToInject) == $methodParam[1] || $this->isSubclassOf(get_class($objectToInject), $methodParam[1])) { - $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, array($methodParam[0] => $objectToInject), $alias, true, get_class($instance)); + $this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, array($methodParam[0] => $objectToInject), $instanceAlias, true, get_class($instance)); continue 3; } } @@ -304,7 +303,7 @@ protected function handleInjectDependencies($instance, $name, $injectionMethods, } if ($methodsToCall) { foreach ($methodsToCall as $methodInfo) { - $this->resolveAndCallInjectionMethodForInstance($instance, $methodInfo['method'], $methodInfo['args'], $alias, true, get_class($instance)); + $this->resolveAndCallInjectionMethodForInstance($instance, $methodInfo['method'], $methodInfo['args'], $instanceAlias, true, get_class($instance)); } } } diff --git a/src/ServiceLocator/Generator.php b/src/ServiceLocator/Generator.php index 3dd70883..44e88248 100644 --- a/src/ServiceLocator/Generator.php +++ b/src/ServiceLocator/Generator.php @@ -241,9 +241,9 @@ public function getCodeGenerator($filename = null) $container = new CodeGen\PhpClass(); $container->setName($this->containerClass) ->setExtendedClass('ServiceLocator') - ->setMethod($get) - ->setMethods($getters) - ->setMethods($aliasMethods); + ->addMethodFromGenerator($get) + ->addMethods($getters) + ->addMethods($aliasMethods); // Create PHP file code generation object $classFile = new CodeGen\PhpFile(); diff --git a/test/ConfigurationTest.php b/test/ConfigurationTest.php index 92557d56..e71ab172 100644 --- a/test/ConfigurationTest.php +++ b/test/ConfigurationTest.php @@ -72,7 +72,51 @@ public function testConfigurationCanConfigureBuilderDefinitionFromIni() ); } - - + public function testConfigurationCanConfigureRuntimeDefinitionDefaultFromIni() + { + $ini = ConfigFactory::fromFile(__DIR__ . '/_files/sample.ini', true)->get('section-c'); + $config = new Configuration($ini->di); + $di = new Di(); + $di->configure($config); + $definition = $di->definitions()->getDefinitionByType('Zend\Di\Definition\RuntimeDefinition'); + $this->assertInstanceOf('Zend\Di\Definition\RuntimeDefinition', $definition); + $this->assertFalse($definition->getIntrospectionStrategy()->getUseAnnotations()); + } + + public function testConfigurationCanConfigureRuntimeDefinitionDisabledFromIni() + { + $ini = ConfigFactory::fromFile(__DIR__ . '/_files/sample.ini', true)->get('section-d'); + $config = new Configuration($ini->di); + $di = new Di(); + $di->configure($config); + $definition = $di->definitions()->getDefinitionByType('Zend\Di\Definition\RuntimeDefinition'); + $this->assertFalse($definition); + } + + public function testConfigurationCanConfigureRuntimeDefinitionUseAnnotationFromIni() + { + $ini = ConfigFactory::fromFile(__DIR__ . '/_files/sample.ini', true)->get('section-e'); + $config = new Configuration($ini->di); + $di = new Di(); + $di->configure($config); + $definition = $di->definitions()->getDefinitionByType('Zend\Di\Definition\RuntimeDefinition'); + $this->assertTrue($definition->getIntrospectionStrategy()->getUseAnnotations()); + } + + public function testConfigurationCanConfigureCompiledDefinition() + { + $config = ConfigFactory::fromFile(__DIR__ . '/_files/sample.php', true); + $config = new Configuration($config->di); + $di = new Di(); + $di->configure($config); + $definition = $di->definitions()->getDefinitionByType('Zend\Di\Definition\ArrayDefinition'); + $this->assertInstanceOf('Zend\Di\Definition\ArrayDefinition', $definition); + $this->assertTrue($di->definitions()->hasClass('My\DbAdapter')); + $this->assertTrue($di->definitions()->hasClass('My\EntityA')); + $this->assertTrue($di->definitions()->hasClass('My\Mapper')); + $this->assertTrue($di->definitions()->hasClass('My\RepositoryA')); + $this->assertTrue($di->definitions()->hasClass('My\RepositoryB')); + $this->assertFalse($di->definitions()->hasClass('My\Foo')); + } } diff --git a/test/DiTest.php b/test/DiTest.php index 43763915..1210850f 100644 --- a/test/DiTest.php +++ b/test/DiTest.php @@ -43,18 +43,18 @@ public function testDiConstructorCanTakeDependencies() public function testPassingInvalidDefinitionRaisesException() { $di = new Di(); - + $this->setExpectedException('PHPUnit_Framework_Error'); $di->setDefinitionList(array('foo')); } - + public function testGetRetrievesObjectWithMatchingClassDefinition() { $di = new Di(); $obj = $di->get('ZendTest\Di\TestAsset\BasicClass'); $this->assertInstanceOf('ZendTest\Di\TestAsset\BasicClass', $obj); } - + public function testGetRetrievesSameInstanceOnSubsequentCalls() { $di = new Di(); @@ -64,23 +64,23 @@ public function testGetRetrievesSameInstanceOnSubsequentCalls() $this->assertInstanceOf('ZendTest\Di\TestAsset\BasicClass', $obj2); $this->assertSame($obj1, $obj2); } - + public function testGetThrowsExceptionWhenUnknownClassIsUsed() { $di = new Di(); - + $this->setExpectedException('Zend\Di\Exception\ClassNotFoundException', 'could not be located in'); $obj1 = $di->get('ZendTest\Di\TestAsset\NonExistentClass'); } - + public function testGetThrowsExceptionWhenMissingParametersAreEncountered() { $di = new Di(); - + $this->setExpectedException('Zend\Di\Exception\MissingPropertyException', 'Missing instance/object for '); $obj1 = $di->get('ZendTest\Di\TestAsset\BasicClassWithParam'); } - + public function testNewInstanceReturnsDifferentInstances() { $di = new Di(); @@ -90,7 +90,7 @@ public function testNewInstanceReturnsDifferentInstances() $this->assertInstanceOf('ZendTest\Di\TestAsset\BasicClass', $obj2); $this->assertNotSame($obj1, $obj2); } - + public function testNewInstanceReturnsInstanceThatIsSharedWithGet() { $di = new Di(); @@ -100,7 +100,7 @@ public function testNewInstanceReturnsInstanceThatIsSharedWithGet() $this->assertInstanceOf('ZendTest\Di\TestAsset\BasicClass', $obj2); $this->assertSame($obj1, $obj2); } - + public function testNewInstanceReturnsInstanceThatIsNotSharedWithGet() { $di = new Di(); @@ -204,7 +204,7 @@ public function testGetWillResolveConstructorInjectionDependencies() $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\A', $b->a); } - + /** * @group ConstructorInjection */ @@ -214,15 +214,15 @@ public function testGetWillResolveConstructorInjectionDependenciesAndInstanceAre $b = $di->get('ZendTest\Di\TestAsset\ConstructorInjection\B'); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\A', $b->a); - + $b2 = $di->get('ZendTest\Di\TestAsset\ConstructorInjection\B'); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\B', $b2); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\A', $b2->a); - + $this->assertSame($b, $b2); $this->assertSame($b->a, $b2->a); } - + /** * @group ConstructorInjection */ @@ -233,48 +233,48 @@ public function testNewInstanceWillResolveConstructorInjectionDependencies() $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\A', $b->a); } - + /** * @group ConstructorInjection */ public function testNewInstanceWillResolveConstructorInjectionDependenciesWithProperties() { $di = new Di(); - + $im = $di->instanceManager(); $im->setParameters('ZendTest\Di\TestAsset\ConstructorInjection\X', array('one' => 1, 'two' => 2)); - + $y = $di->newInstance('ZendTest\Di\TestAsset\ConstructorInjection\Y'); $this->assertEquals(1, $y->x->one); $this->assertEquals(2, $y->x->two); } - + /** * @group ConstructorInjection */ public function testNewInstanceWillThrowExceptionOnConstructorInjectionDependencyWithMissingParameter() { $di = new Di(); - + $this->setExpectedException('Zend\Di\Exception\MissingPropertyException', 'Missing instance/object for parameter'); $b = $di->newInstance('ZendTest\Di\TestAsset\ConstructorInjection\X'); } - + /** * @group ConstructorInjection */ public function testNewInstanceWillResolveConstructorInjectionDependenciesWithMoreThan2Dependencies() { $di = new Di(); - + $im = $di->instanceManager(); $im->setParameters('ZendTest\Di\TestAsset\ConstructorInjection\X', array('one' => 1, 'two' => 2)); - + $z = $di->newInstance('ZendTest\Di\TestAsset\ConstructorInjection\Z'); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\Y', $z->y); $this->assertInstanceOf('ZendTest\Di\TestAsset\ConstructorInjection\X', $z->y->x); } - + /** * @group SetterInjection */ @@ -290,7 +290,7 @@ public function testGetWillResolveSetterInjectionDependencies() $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a); } - + /** * @group SetterInjection */ @@ -306,16 +306,16 @@ public function testGetWillResolveSetterInjectionDependenciesAndInstanceAreTheSa $b = $di->get('ZendTest\Di\TestAsset\SetterInjection\B'); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a); - + $b2 = $di->get('ZendTest\Di\TestAsset\SetterInjection\B'); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\B', $b2); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b2->a); - + $this->assertSame($b, $b2); $this->assertSame($b->a, $a); $this->assertSame($b2->a, $a); } - + /** * @group SetterInjection */ @@ -332,7 +332,7 @@ public function testNewInstanceWillResolveSetterInjectionDependencies() $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\B', $b); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a); } - + /** * @todo Setter Injections is not automatic, find a way to test this logically * @@ -341,7 +341,7 @@ public function testNewInstanceWillResolveSetterInjectionDependencies() public function testNewInstanceWillResolveSetterInjectionDependenciesWithProperties() { $di = new Di(); - + $im = $di->instanceManager(); $im->setParameters('ZendTest\Di\TestAsset\SetterInjection\X', array('one' => 1, 'two' => 2)); @@ -351,10 +351,10 @@ public function testNewInstanceWillResolveSetterInjectionDependenciesWithPropert $this->assertEquals(1, $y->x->one); $this->assertEquals(2, $y->x->two); } - + /** * Test for Circular Dependencies (case 1) - * + * * A->B, B->A * @group CircularDependencyCheck */ @@ -365,10 +365,10 @@ public function testNewInstanceThrowsExceptionOnBasicCircularDependency() $this->setExpectedException('Zend\Di\Exception\CircularDependencyException'); $di->newInstance('ZendTest\Di\TestAsset\CircularClasses\A'); } - + /** * Test for Circular Dependencies (case 2) - * + * * C->D, D->E, E->C * @group CircularDependencyCheck */ @@ -382,10 +382,10 @@ public function testNewInstanceThrowsExceptionOnThreeLevelCircularDependency() ); $di->newInstance('ZendTest\Di\TestAsset\CircularClasses\C'); } - + /** * Test for Circular Dependencies (case 2) - * + * * C->D, D->E, E->C * @group CircularDependencyCheck */ @@ -399,10 +399,10 @@ public function testNewInstanceThrowsExceptionWhenEnteringInMiddleOfCircularDepe ); $di->newInstance('ZendTest\Di\TestAsset\CircularClasses\D'); } - + /** * Fix for PHP bug in is_subclass_of - * + * * @see https://bugs.php.net/bug.php?id=53727 */ public function testNewInstanceWillUsePreferredClassForInterfaceHints() @@ -412,7 +412,7 @@ public function testNewInstanceWillUsePreferredClassForInterfaceHints() 'ZendTest\Di\TestAsset\PreferredImplClasses\A', 'ZendTest\Di\TestAsset\PreferredImplClasses\BofA' ); - + $c = $di->get('ZendTest\Di\TestAsset\PreferredImplClasses\C'); $a = $c->a; $this->assertInstanceOf('ZendTest\Di\TestAsset\PreferredImplClasses\BofA', $a); @@ -590,7 +590,7 @@ public function testInjectionForSetterInjectionWillConsultSupertypeDefinitionInC $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\C', $c); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $c->a); } - + /** * @group SharedInstance */ @@ -624,4 +624,20 @@ public function testDiWillInjectDependenciesForInstance() $di->injectDependencies($b); $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a); } + + public function testDiWillInjectDependenciesForAlias() + { + $di = new Di; + + // for setter injection, the dependency is not required, thus it must be forced + $classDef = new Definition\ClassDefinition('ZendTest\Di\TestAsset\SetterInjection\B'); + $classDef->addMethod('setA', false); + $classDef->addMethodParameter('setA', 'a', array('type' => 'ZendTest\Di\TestAsset\SetterInjection\A', 'required' => false)); + $di->definitions()->addDefinition($classDef, false); + $di->instanceManager()->addAlias('b_alias', 'ZendTest\Di\TestAsset\SetterInjection\B'); + $di->instanceManager()->setInjections('b_alias', array('ZendTest\Di\TestAsset\SetterInjection\A')); + + $b = $di->get('b_alias'); + $this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a); + } } diff --git a/test/_files/sample.ini b/test/_files/sample.ini index cb4d23ce..b1f49824 100644 --- a/test/_files/sample.ini +++ b/test/_files/sample.ini @@ -19,4 +19,16 @@ di.definitions.1.class = Zend\Di\Definition\BuilderDefinition di.definitions.1.My\DbAdapter.methods.__construct.username = NULL di.definitions.1.My\DbAdapter.methods.__construct.password = NULL di.definitions.1.My\Mapper.methods.__construct.dbAdapter = My\DbAdapter -di.definitions.1.My\Repository.methods.__construct.mapper = My\Mapper \ No newline at end of file +di.definitions.1.My\Repository.methods.__construct.mapper = My\Mapper + +[section-c] + +di.definition.runtime.xxx = zzz + +[section-d] + +di.definition.runtime.enabled = 0 + +[section-e] + +di.definition.runtime.use_annotations = 1 \ No newline at end of file diff --git a/test/_files/sample.php b/test/_files/sample.php new file mode 100644 index 00000000..5f6e79e6 --- /dev/null +++ b/test/_files/sample.php @@ -0,0 +1,10 @@ + array( + 'definition' => array( + 'compiler' => array( + __DIR__ . '/definition-array.php', + ), + ), + ), +); \ No newline at end of file