diff --git a/.gitignore b/.gitignore index b2395aa..4395d07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock composer.phar /vendor/ +/build/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 6e5d8b9..3b68382 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: php php: - 5.5 + - 5.6 + - 7.0 before_script: - wget http://getcomposer.org/composer.phar diff --git a/README.md b/README.md index 654ad2c..a8b8760 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # YACO - Yet another compiler YACO (Yet Another COmpiler) is a PHP tool that generates a PHP container based on entry definitions. -Entry definitions must be compatible with interfaces defined in [*compiler-interop*](https://github.com/container-interop/compiler-interop/) +It is fully compatible with entry definitions from [*definition-interop*](https://github.com/container-interop/definition-interop/). ## Installation @@ -25,7 +25,7 @@ between minor versions. ## Usage This package contains a `Compiler` class. The goal of this class is to take a number of "entry definitions" -(as defined in [*compiler-interop*](https://github.com/container-interop/compiler-interop/)) and to transform those +(as defined in [*definition-interop*](https://github.com/container-interop/definition-interop/)) and to transform those into a PHP class that implements the [`ContainerInterface`](https://github.com/container-interop/container-interop/) ```php @@ -36,10 +36,25 @@ $compiler = new Compiler(); // ... foreach ($definitions as $definition) { - /* @var $definition TheCodingMachine\Yaco\Definition\DumpableInterface */ + /* @var $definition Interop\Container\Definition\DefinitionInterface */ $compiler->addDefinition($definition); } // Let's dump the code of the My\Container class. file_put_contents("Container.php", $compiler->compile("My\\Container")); ``` + +You can also directly register a **definition provider** using the *register* method: + +```php +use TheCodingMachine\Yaco\Compiler; + +$compiler = new Compiler(); + +// ... + +$compiler->register($definitionProvider); + +// Let's dump the code of the My\Container class. +file_put_contents("Container.php", $compiler->compile("My\\Container")); +``` diff --git a/composer.json b/composer.json index fd0653b..457252c 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,4 @@ { - "repositories": [ - { - "type": "vcs", - "url": "git@github.com:container-interop/definition-interop.git" - } - ], "name": "thecodingmachine/yaco", "type": "library", "description": "YACO (Yet Another COmpiler) is a PHP tool that generates a PHP container based on entry definitions.", @@ -20,14 +14,16 @@ } }, "require": { - "container-interop/definition-interop": "dev-master", + "container-interop/definition-interop": "~0.1.0", "container-interop/container-interop": "^1.0", "jeremeamia/superclosure": "^2.0", "mouf/picotainer": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~5.0", - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "~4.5", + "mnapoli/assembly": "~0.1.0", + "satooshi/php-coveralls": "dev-master", + "container-interop/definition-interop-compiler-test-suite": "~0.1.0" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/src/Compiler.php b/src/Compiler.php index 38ce17f..89ba1e6 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -1,5 +1,9 @@ converter = $converter; + } /** - * @param DumpableInterface $definition + * Adds a definition to the list of definitions managed by this compiler. + * + * @param DefinitionInterface $definition */ - public function addDefinition(DumpableInterface $definition) { + public function addDefinition(DefinitionInterface $definition) + { $this->definitions[$definition->getIdentifier()] = $definition; + unset($this->dumpableDefinitions[$definition->getIdentifier()]); + } + + /** + * Registers a new definition provider. + * + * @param DefinitionProviderInterface $definitionProvider + */ + public function register(DefinitionProviderInterface $definitionProvider) { + foreach ($definitionProvider->getDefinitions() as $definition) { + $this->addDefinition($definition); + } + } + + /** + * Adds a dumpable definition to the list of definitions managed by this compiler. + * Note: a "dumpable" definition is a definition represented in Yaco internal format. + * + * @param DumpableInterface $dumpableDefinition + */ + public function addDumpableDefinition(DumpableInterface $dumpableDefinition) + { + $this->dumpableDefinitions[$dumpableDefinition->getIdentifier()] = $dumpableDefinition; + unset($this->definitions[$dumpableDefinition->getIdentifier()]); } /** * @param string $className + * * @return string */ - public function compile($className) { - + public function compile($className) + { $classCode = <<splitFQCN($className); - $closuresCode = ""; - $parametersCode = ""; + $closuresCode = ''; + $parametersCode = ''; + + // Let's merge dumpable definitions with standard definitions. + $convertedDefinitions = array_map([$this->converter, 'convert'], $this->definitions); + $allDefinitions = $convertedDefinitions + $this->dumpableDefinitions; - foreach ($this->definitions as $identifier => $definition) { + foreach ($allDefinitions as $identifier => $definition) { $inlineEntry = $definition->toPhpCode('$container', ['$container']); if ($inlineEntry->isLazilyEvaluated()) { - $closuresCode .= " ".var_export($identifier, true)." => ".$this->getClosureCode($inlineEntry).",\n"; + $closuresCode .= ' '.var_export($identifier, true).' => '.$this->getClosureCode($inlineEntry).",\n"; } else { - $parametersCode .= " ".var_export($identifier, true)." => ".$this->getParametersCode($inlineEntry).",\n"; + $parametersCode .= ' '.var_export($identifier, true).' => '.$this->getParametersCode($inlineEntry).",\n"; } } return sprintf($classCode, $namespaceLine, $shortClassName, $closuresCode, $parametersCode); } - private function splitFQCN($className) { + private function splitFQCN($className) + { $pos = strrpos($className, '\\'); if ($pos !== false) { - $shortClassName = substr($className, $pos+1); - $namespaceLine = "namespace ".substr($className, 0, $pos).";"; + $shortClassName = substr($className, $pos + 1); + $namespaceLine = 'namespace '.substr($className, 0, $pos).';'; } else { $shortClassName = $className; - $namespaceLine = ""; + $namespaceLine = ''; } + return [ $shortClassName, - $namespaceLine + $namespaceLine, ]; } - private function getParametersCode(InlineEntryInterface $inlineEntry) { + private function getParametersCode(InlineEntryInterface $inlineEntry) + { if (!empty($inlineEntry->getStatements())) { throw new CompilerException('An entry that contains parameters (not lazily loaded) cannot return statements.'); } + return $inlineEntry->getExpression(); } - private function getClosureCode(InlineEntryInterface $inlineEntry) { + private function getClosureCode(InlineEntryInterface $inlineEntry) + { $code = $inlineEntry->getStatements(); - $code .= "return ".$inlineEntry->getExpression().";\n"; + $code .= 'return '.$inlineEntry->getExpression().";\n"; + return sprintf("function(\$container) {\n%s}", $code); } } diff --git a/src/CompilerException.php b/src/CompilerException.php index f751dce..75fa3a6 100644 --- a/src/CompilerException.php +++ b/src/CompilerException.php @@ -1,10 +1,7 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()) diff --git a/src/Definition/ClosureDefinition.php b/src/Definition/ClosureDefinition.php index cbcbcef..2c5bd20 100644 --- a/src/Definition/ClosureDefinition.php +++ b/src/Definition/ClosureDefinition.php @@ -1,4 +1,5 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface + * * @throws DefinitionException */ public function toPhpCode($containerVariable, array $usedVariables = array()) @@ -78,7 +82,8 @@ public function toPhpCode($containerVariable, array $usedVariables = array()) $code = $analysis['code']; $variableName = VariableUtils::getNextAvailableVariableName("\$closure", $usedVariables); $usedVariables[] = $variableName; - $assignClosure = sprintf("%s = %s;", $variableName, $code); + $assignClosure = sprintf('%s = %s;', $variableName, $code); + return new InlineEntry($variableName.'('.$containerVariable.')', $assignClosure, $usedVariables); } } diff --git a/src/Definition/ConstParameterDefinition.php b/src/Definition/ConstParameterDefinition.php index 31ee34e..d714ac2 100644 --- a/src/Definition/ConstParameterDefinition.php +++ b/src/Definition/ConstParameterDefinition.php @@ -1,13 +1,12 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()) diff --git a/src/Definition/DefinitionException.php b/src/Definition/DefinitionException.php index 480d1be..afccdaa 100644 --- a/src/Definition/DefinitionException.php +++ b/src/Definition/DefinitionException.php @@ -1,8 +1,7 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()); diff --git a/src/Definition/FactoryCallDefinition.php b/src/Definition/FactoryCallDefinition.php new file mode 100644 index 0000000..bb4de51 --- /dev/null +++ b/src/Definition/FactoryCallDefinition.php @@ -0,0 +1,126 @@ +identifier = $identifier; + $this->factory = $factory; + $this->methodName = $methodName; + $this->methodArguments = $methodArguments; + } + + /** + * Returns the identifier of the instance. + * + * @return string + */ + public function getIdentifier() + { + return $this->identifier; + } + + /** + * Returns a pointer to the service that the factory method will be called upon, or a fully qualified class name. + * + * @return ReferenceInterface|string + */ + public function getFactory() + { + return $this->factory; + } + + /** + * Returns the name of the factory method. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns the parameters of the factory method. + * + * @return array + */ + public function getMethodArguments() + { + return $this->methodArguments; + } + + /** + * Adds an argument to the method. + * + * @param mixed $argument + */ + public function addMethodArgument($argument) + { + $this->methodArguments[] = $argument; + } + + /** + * Returns an InlineEntryInterface object representing the PHP code necessary to generate + * the container entry. + * + * @param string $containerVariable The name of the variable that allows access to the container instance. For instance: "$container", or "$this->container" + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * + * @return InlineEntryInterface + */ + public function toPhpCode($containerVariable, array $usedVariables = array()) + { + $dumpedArguments = ValueUtils::dumpArguments($this->methodArguments, $containerVariable, $usedVariables); + $prependedCode = $dumpedArguments->getStatements(); + if ($this->factory instanceof ReferenceInterface) { + $code = sprintf("%s->get(%s)->%s(%s);\n", $containerVariable, var_export($this->factory->getTarget(), true), $this->methodName, $dumpedArguments->getExpression()); + } else { + $code = sprintf("%s::%s(%s);\n", $this->factory, $this->methodName, $dumpedArguments->getExpression()); + } + + return new InlineEntry($code, $prependedCode, $usedVariables); + } +} diff --git a/src/Definition/InlineEntry.php b/src/Definition/InlineEntry.php index 72e1893..1f317d1 100644 --- a/src/Definition/InlineEntry.php +++ b/src/Definition/InlineEntry.php @@ -1,4 +1,5 @@ lazyEvaluation = $lazyEvaluation; } - /** * Returns a list of PHP statements (ending with a ;) that are necessary to * build the entry. - * For instance, these are valid PHP statements: + * For instance, these are valid PHP statements:. * * "$service = new MyService($container->get('my_dependency')); * $service->setStuff('foo');" @@ -62,7 +61,7 @@ public function getStatements() /** * Returns the PHP expression representing the entry. * This must be a string representing a valid PHP expression, - * with no ending ; + * with no ending ;. * * For instance, "$service" is a valid PHP expression. * @@ -77,6 +76,7 @@ public function getExpression() * Returns the list of variables used in the process of creating this * entry definition. These variables should not be used by other * definitions in the same scope. + * * @return array */ public function getUsedVariables() @@ -91,7 +91,8 @@ public function getUsedVariables() * * @return bool */ - public function isLazilyEvaluated() { + public function isLazilyEvaluated() + { return $this->lazyEvaluation; } } diff --git a/src/Definition/InlineEntryInterface.php b/src/Definition/InlineEntryInterface.php index bfee4b4..ffee005 100644 --- a/src/Definition/InlineEntryInterface.php +++ b/src/Definition/InlineEntryInterface.php @@ -1,4 +1,5 @@ get('my_dependency')); * $service->setStuff('foo');" @@ -23,7 +24,7 @@ public function getStatements(); /** * Returns the PHP expression representing the entry. * This must be a string representing a valid PHP expression, - * with no ending ; + * with no ending ;. * * For instance, "$service" is a valid PHP expression. * @@ -35,6 +36,7 @@ public function getExpression(); * Returns the list of variables used in the process of creating this * entry definition. These variables should not be used by other * definitions in the same scope. + * * @return array */ public function getUsedVariables(); diff --git a/src/Definition/MethodCall.php b/src/Definition/MethodCall.php index 7237fb5..748d5d3 100644 --- a/src/Definition/MethodCall.php +++ b/src/Definition/MethodCall.php @@ -1,4 +1,5 @@ arguments[] = $argument; + return $this; } - /** * Generates PHP code for the line. + * * @param string $variableName * @param string $containerVariable - * @param array $usedVariables + * @param array $usedVariables + * * @return InlineEntryInterface */ - public function toPhpCode($variableName, $containerVariable, array $usedVariables) { + public function toPhpCode($variableName, $containerVariable, array $usedVariables) + { $dumpedArguments = ValueUtils::dumpArguments($this->arguments, $containerVariable, $usedVariables); - $codeLine = sprintf("%s->%s(%s);", $variableName, $this->methodName, $dumpedArguments->getExpression()); + $codeLine = sprintf('%s->%s(%s);', $variableName, $this->methodName, $dumpedArguments->getExpression()); - return new InlineEntry("", $dumpedArguments->getStatements().$codeLine, $dumpedArguments->getUsedVariables()); + return new InlineEntry('', $dumpedArguments->getStatements().$codeLine, $dumpedArguments->getUsedVariables()); } } diff --git a/src/Definition/InstanceDefinition.php b/src/Definition/ObjectDefinition.php similarity index 80% rename from src/Definition/InstanceDefinition.php rename to src/Definition/ObjectDefinition.php index f12ef82..1b826e8 100644 --- a/src/Definition/InstanceDefinition.php +++ b/src/Definition/ObjectDefinition.php @@ -1,13 +1,13 @@ identifier = $identifier; - $this->className = $className; + $this->className = '\\'.ltrim($className, '\\'); $this->constructorArguments = $constructorArguments; } /** * Returns the identifier of the instance. + * * @return string */ public function getIdentifier() @@ -77,11 +78,15 @@ public function getConstructorParameters() /** * Adds an argument to the list of arguments to be passed to the constructor. + * * @param mixed $argument + * * @return self */ - public function addConstructorArgument($argument) { + public function addConstructorArgument($argument) + { $this->constructorArguments[] = $argument; + return $this; } @@ -89,11 +94,14 @@ public function addConstructorArgument($argument) { * Adds a method call. * * @param string $methodName - * @param array $arguments + * @param array $arguments + * * @return MethodCall */ - public function addMethodCall($methodName, array $arguments = array()) { + public function addMethodCall($methodName, array $arguments = array()) + { $this->actions[] = $methodCall = new MethodCall($methodName, $arguments); + return $methodCall; } @@ -101,11 +109,14 @@ public function addMethodCall($methodName, array $arguments = array()) { * Adds a method call. * * @param string $propertyName - * @param mixed $value + * @param mixed $value + * * @return self */ - public function setProperty($propertyName, $value) { + public function setProperty($propertyName, $value) + { $this->actions[] = new PropertyAssignment($propertyName, $value); + return $this; } @@ -114,7 +125,8 @@ public function setProperty($propertyName, $value) { * the container entry. * * @param string $containerVariable The name of the variable that allows access to the container instance. For instance: "$container", or "$this->container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()) @@ -135,6 +147,7 @@ public function toPhpCode($containerVariable, array $usedVariables = array()) $code .= $inlineCode->getStatements()."\n"; $usedVariables = $inlineCode->getUsedVariables(); } + return new InlineEntry($variableName, $prependedCode.$code, $usedVariables); } } diff --git a/src/Definition/ParameterDefinition.php b/src/Definition/ParameterDefinition.php index 849f01b..73ea3ac 100644 --- a/src/Definition/ParameterDefinition.php +++ b/src/Definition/ParameterDefinition.php @@ -1,4 +1,5 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()) diff --git a/src/Definition/PropertyAssignment.php b/src/Definition/PropertyAssignment.php index b2994f5..e28b67e 100644 --- a/src/Definition/PropertyAssignment.php +++ b/src/Definition/PropertyAssignment.php @@ -1,13 +1,14 @@ value, $containerVariable, $usedVariables); - $codeLine = sprintf("%s->%s = %s;", $variableName, $this->propertyName, $inlineEntry->getExpression()); - return new InlineEntry("", $inlineEntry->getStatements().$codeLine, $inlineEntry->getUsedVariables()); + $codeLine = sprintf('%s->%s = %s;', $variableName, $this->propertyName, $inlineEntry->getExpression()); + + return new InlineEntry('', $inlineEntry->getStatements().$codeLine, $inlineEntry->getUsedVariables()); } } diff --git a/src/Definition/Reference.php b/src/Definition/Reference.php new file mode 100644 index 0000000..8231b92 --- /dev/null +++ b/src/Definition/Reference.php @@ -0,0 +1,48 @@ +target = $target; + } + + /** + * Returns the identifier for the object in the container. + * + * @return string + */ + public function getTarget() + { + return $this->target; + } + + /** + * Returns an InlineEntryInterface object representing the PHP code necessary to generate + * the container entry. + * + * @param string $containerVariable The name of the variable that allows access to the container instance. For instance: "$container", or "$this->container" + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * + * @return InlineEntryInterface + */ + public function toPhpCode($containerVariable, array $usedVariables = array()) + { + return new InlineEntry(sprintf('%s->get(%s)', $containerVariable, var_export($this->getTarget(), true)), null, $usedVariables); + } +} diff --git a/src/Definition/ReferenceInterface.php b/src/Definition/ReferenceInterface.php new file mode 100644 index 0000000..dfda3f0 --- /dev/null +++ b/src/Definition/ReferenceInterface.php @@ -0,0 +1,20 @@ +container" + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * + * @return InlineEntryInterface + */ + public function toPhpCode($containerVariable, array $usedVariables = array()); +} diff --git a/src/Definition/ValueUtils.php b/src/Definition/ValueUtils.php index 9694dd4..a8d85aa 100644 --- a/src/Definition/ValueUtils.php +++ b/src/Definition/ValueUtils.php @@ -1,21 +1,24 @@ getUsedVariables(); $arguments[] = $inlineEntry->getExpression(); if (!empty($inlineEntry->getStatements())) { @@ -38,10 +42,12 @@ public static function dumpArguments($argumentsValues, $containerVariable, array } $argumentsCode = implode(', ', $arguments); $prependedCodeString = implode("\n", $prependedCode); + return new InlineEntry($argumentsCode, $prependedCodeString, $usedVariables); } - private static function dumpArray(array $value, $containerVariable, array $usedVariables) { + private static function dumpArray(array $value, $containerVariable, array $usedVariables) + { $code = array(); $prependCode = array(); foreach ($value as $k => $v) { @@ -58,12 +64,18 @@ private static function dumpArray(array $value, $containerVariable, array $usedV return new InlineEntry(sprintf('array(%s)', implode(', ', $code)), implode("\n", $prependCode), $usedVariables); } - private static function dumpDefinition(DumpableInterface $definition, $containerVariable, array $usedVariables) { + private static function dumpDefinition(DumpableInterface $definition, $containerVariable, array $usedVariables) + { // If the identifier is null, we must inline the definition. if ($definition->getIdentifier() === null) { return $definition->toPhpCode($containerVariable, $usedVariables); } else { - return new InlineEntry(sprintf("%s->get(%s)", $containerVariable, var_export($definition->getIdentifier(), true)), null, $usedVariables); + return self::dumpReference(new Reference($definition->getIdentifier()), $containerVariable, $usedVariables); } } + + private static function dumpReference(ReferenceInterface $reference, $containerVariable, array $usedVariables) + { + return $reference->toPhpCode($containerVariable, $usedVariables); + } } diff --git a/src/Definition/VariableUtils.php b/src/Definition/VariableUtils.php index 7f14f49..dfd38ec 100644 --- a/src/Definition/VariableUtils.php +++ b/src/Definition/VariableUtils.php @@ -1,14 +1,15 @@ = '0' && $lastCharacter <= '9') { $numbers = $lastCharacter.$numbers; - $variable = substr($variable, 0, strlen($variable)-1); + $variable = substr($variable, 0, strlen($variable) - 1); } else { break; } @@ -36,10 +37,11 @@ public static function getNextAvailableVariableName($variable, array $usedVariab } else { $numbers = (int) $numbers; } - $numbers++; + ++$numbers; $variable = $variable.$numbers; } + return $variable; } @@ -51,13 +53,16 @@ public static function getNextAvailableVariableName($variable, array $usedVariab * - fo$o => $foo * * @param string $name + * * @return string */ - private static function toVariableName($name) { - $variableName = preg_replace("/[^A-Za-z0-9]/", '', $name); + private static function toVariableName($name) + { + $variableName = preg_replace('/[^A-Za-z0-9]/', '', $name); if ($variableName{0} >= '0' && $variableName{0} <= '9') { $variableName = 'a'.$variableName; } + return '$'.$variableName; } } diff --git a/src/DefinitionConverter.php b/src/DefinitionConverter.php new file mode 100644 index 0000000..6b04211 --- /dev/null +++ b/src/DefinitionConverter.php @@ -0,0 +1,104 @@ +getIdentifier(), + $definition->getClassName(), + $this->convertArguments($definition->getConstructorArguments())); + + foreach ($definition->getPropertyAssignments() as $assignment) { + $yacoObjectDefinition->setProperty($assignment->getPropertyName(), $this->convertValue($assignment->getValue())); + } + + foreach ($definition->getMethodCalls() as $methodCall) { + $yacoObjectDefinition->addMethodCall($methodCall->getMethodName(), $this->convertArguments($methodCall->getArguments())); + } + + return $yacoObjectDefinition; + } elseif ($definition instanceof FactoryCallDefinitionInterface) { + return new FactoryCallDefinition($definition->getIdentifier(), + $this->convertValue($definition->getFactory()), + $definition->getMethodName(), + $this->convertArguments($definition->getArguments())); + } elseif ($definition instanceof ParameterDefinitionInterface) { + return new ParameterDefinition($definition->getIdentifier(), $definition->getValue()); + } elseif ($definition instanceof AliasDefinitionInterface) { + return new AliasDefinition($definition->getIdentifier(), $definition->getTarget()); + } else { + throw new \RuntimeException(sprintf('Cannot convert object of type "%s"', get_class($definition))); + } + } + + /** + * @param array $arguments + * + * @return array + */ + private function convertArguments(array $arguments) + { + $yacoArguments = []; + foreach ($arguments as $argument) { + $yacoArguments[] = $this->convertValue($argument); + } + + return $yacoArguments; + } + + private function convertValue($value) + { + if (is_array($value)) { + return $this->convertArray($value); + } elseif ($value instanceof DefinitionInterface) { + return $this->convert($value); + } elseif ($value instanceof ReferenceInterface) { + return $this->convertReference($value); + } elseif (is_object($value) || is_resource($value)) { + throw new \RuntimeException('Unable to convert a definition. Parameters cannot be an object or a resource.'); + } else { + return $value; + } + } + + private function convertArray(array $values) + { + $result = []; + + foreach ($values as $k => $v) { + $result[$k] = $this->convertValue($v); + } + + return $result; + } + + private function convertReference(ReferenceInterface $reference) + { + return new Reference($reference->getTarget()); + } +} diff --git a/src/DefinitionConverterInterface.php b/src/DefinitionConverterInterface.php new file mode 100644 index 0000000..3a45bc9 --- /dev/null +++ b/src/DefinitionConverterInterface.php @@ -0,0 +1,22 @@ +addDefinition($instanceDefinition); + $compiler->addDumpableDefinition($instanceDefinition); - $code = $compiler->compile("MyNamespace\\MyContainer"); + $code = $compiler->compile('MyNamespace\\MyContainer'); file_put_contents(__DIR__.'/Fixtures/Generated/MyContainer.php', $code); require __DIR__.'/Fixtures/Generated/MyContainer.php'; $myContainer = new \MyNamespace\MyContainer(); - $result = $myContainer->get("test"); - $this->assertInstanceOf("\\stdClass", $result); + $result = $myContainer->get('test'); + $this->assertInstanceOf('\\stdClass', $result); - $code = $compiler->compile("MyContainerNoNamespace"); + $code = $compiler->compile('MyContainerNoNamespace'); file_put_contents(__DIR__.'/Fixtures/Generated/MyContainerNoNamespace.php', $code); require __DIR__.'/Fixtures/Generated/MyContainerNoNamespace.php'; $myContainer = new \MyContainerNoNamespace(); - $result = $myContainer->get("test"); - $this->assertInstanceOf("\\stdClass", $result); + $result = $myContainer->get('test'); + $this->assertInstanceOf('\\stdClass', $result); } - public function testParameter() { - $parameterDefinition = new ParameterDefinition("test", "value"); + public function testParameter() + { + $parameterDefinition = new ParameterDefinition('test', 'value'); $compiler = new Compiler(); - $compiler->addDefinition($parameterDefinition); + $compiler->addDumpableDefinition($parameterDefinition); - $code = $compiler->compile("MyNamespace\\MyContainerWithParameters"); + $code = $compiler->compile('MyNamespace\\MyContainerWithParameters'); file_put_contents(__DIR__.'/Fixtures/Generated/MyContainerWithParameters.php', $code); require __DIR__.'/Fixtures/Generated/MyContainerWithParameters.php'; $myContainer = new \MyNamespace\MyContainerWithParameters(); - $result = $myContainer->get("test"); - $this->assertEquals("value", $result); + $result = $myContainer->get('test'); + $this->assertEquals('value', $result); + } + + public function testStandardDefinition() + { + $instanceDefinition = new \Assembly\ObjectDefinition('test', '\\stdClass'); + + $compiler = new Compiler(); + $compiler->addDefinition($instanceDefinition); + + $code = $compiler->compile('MyNamespace\\MyContainerStandardDefinition'); + file_put_contents(__DIR__.'/Fixtures/Generated/MyContainerStandardDefinition.php', $code); + require __DIR__.'/Fixtures/Generated/MyContainerStandardDefinition.php'; + + $myContainer = new \MyNamespace\MyContainerStandardDefinition(); + $result = $myContainer->get('test'); + $this->assertInstanceOf('\\stdClass', $result); } /** * @expectedException \TheCodingMachine\Yaco\CompilerException */ - public function testException() { + public function testException() + { + $compiler = new Compiler(); + $compiler->addDumpableDefinition(new InvalidEntryDefinition()); + + $code = $compiler->compile('MyNamespace\\MyContainerWithParameters'); + } + + public function testRegister() { $compiler = new Compiler(); - $compiler->addDefinition(new InvalidEntryDefinition()); + $compiler->register(new TestDefinitionProvider()); - $code = $compiler->compile("MyNamespace\\MyContainerWithParameters"); + $code = $compiler->compile('MyNamespace\\MyContainerRegister'); + file_put_contents(__DIR__.'/Fixtures/Generated/MyContainerRegister.php', $code); + require __DIR__.'/Fixtures/Generated/MyContainerRegister.php'; + $myContainer = new \MyNamespace\MyContainerRegister(); + $result = $myContainer->get('test'); + $this->assertInstanceOf('\\stdClass', $result); } } - diff --git a/tests/Definition/AbstractDefinitionTest.php b/tests/Definition/AbstractDefinitionTest.php index 6c1d6d5..e18a1e7 100644 --- a/tests/Definition/AbstractDefinitionTest.php +++ b/tests/Definition/AbstractDefinitionTest.php @@ -1,19 +1,22 @@ $definition) { $inlineCodeDefinition = $definition->toPhpCode('$container', ['$container']); $code = $inlineCodeDefinition->getStatements(); - $code .= "return ".$inlineCodeDefinition->getExpression().";\n"; - $closures[$key] = eval("return function(\$container) {\n".$code."};"); + $code .= 'return '.$inlineCodeDefinition->getExpression().";\n"; + $closures[$key] = eval("return function(\$container) {\n".$code.'};'); } $picotainer = new Picotainer($closures); + return $picotainer; } } diff --git a/tests/Definition/AliasDefinitionTest.php b/tests/Definition/AliasDefinitionTest.php index d30eae5..bae5c43 100644 --- a/tests/Definition/AliasDefinitionTest.php +++ b/tests/Definition/AliasDefinitionTest.php @@ -1,26 +1,28 @@ assertEquals("test", $parameterDefinition->getIdentifier()); - $this->assertEquals("alias", $parameterDefinition->getAlias()); + $this->assertEquals('test', $parameterDefinition->getIdentifier()); + $this->assertEquals('alias', $parameterDefinition->getAlias()); } - public function testSimpleAlias() { - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $aliasDefinition = new AliasDefinition("alias", "test"); + public function testSimpleAlias() + { + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $aliasDefinition = new AliasDefinition('alias', 'test'); $container = $this->getContainer([ - "test" => $instanceDefinition, - "alias" => $aliasDefinition + 'test' => $instanceDefinition, + 'alias' => $aliasDefinition, ]); - $result = $container->get("test"); - $alias = $container->get("alias"); + $result = $container->get('test'); + $alias = $container->get('alias'); $this->assertEquals($result, $alias); } diff --git a/tests/Definition/ClosureDefinitionTest.php b/tests/Definition/ClosureDefinitionTest.php index fa0453e..fdb972c 100644 --- a/tests/Definition/ClosureDefinitionTest.php +++ b/tests/Definition/ClosureDefinitionTest.php @@ -1,71 +1,75 @@ assertEquals("test", $closureDefinition->getIdentifier()); + $this->assertEquals('test', $closureDefinition->getIdentifier()); $this->assertEquals($closure, $closureDefinition->getClosure()); } - public function testSimpleClosure() { - $closure = function() { return "foo"; }; - $closureDefinition = new ClosureDefinition("test", $closure); + public function testSimpleClosure() + { + $closure = function () { return 'foo'; }; + $closureDefinition = new ClosureDefinition('test', $closure); $container = $this->getContainer([ - "test" => $closureDefinition + 'test' => $closureDefinition, ]); - $result = $container->get("test"); + $result = $container->get('test'); - $this->assertEquals("foo", $result); + $this->assertEquals('foo', $result); } /** * @expectedException \TheCodingMachine\Yaco\Definition\DefinitionException */ - public function testFailOnThis() { - $closure = function() { return $this->testGetters(); }; - $closureDefinition = new ClosureDefinition("test", $closure); + public function testFailOnThis() + { + $closure = function () { return $this->testGetters(); }; + $closureDefinition = new ClosureDefinition('test', $closure); $container = $this->getContainer([ - "test" => $closureDefinition + 'test' => $closureDefinition, ]); - $container->get("test"); + $container->get('test'); } /** * @expectedException \TheCodingMachine\Yaco\Definition\DefinitionException */ - public function testFailOnUse() { + public function testFailOnUse() + { $a = 42; - $closure = function() use ($a) { return "foo"; }; - $closureDefinition = new ClosureDefinition("test", $closure); + $closure = function () use ($a) { return 'foo'; }; + $closureDefinition = new ClosureDefinition('test', $closure); $container = $this->getContainer([ - "test" => $closureDefinition + 'test' => $closureDefinition, ]); - $container->get("test"); + $container->get('test'); } - public function testInlineClosureDefinition() { - $closure = function() { return "foo"; }; + public function testInlineClosureDefinition() + { + $closure = function () { return 'foo'; }; // null passed as first parameter. This will generate an inline declaration. $dependencyDefinition = new ClosureDefinition(null, $closure); - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); $instanceDefinition->addConstructorArgument($dependencyDefinition); $container = $this->getContainer([ - "test" => $instanceDefinition + 'test' => $instanceDefinition, ]); - $result = $container->get("test"); + $result = $container->get('test'); - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals("foo", $result->cArg1); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals('foo', $result->cArg1); } } - diff --git a/tests/Definition/ConstParameterDefinitionTest.php b/tests/Definition/ConstParameterDefinitionTest.php index 16c2bd7..103e982 100644 --- a/tests/Definition/ConstParameterDefinitionTest.php +++ b/tests/Definition/ConstParameterDefinitionTest.php @@ -1,30 +1,33 @@ assertEquals("test", $parameterDefinition->getIdentifier()); - $this->assertEquals("value", $parameterDefinition->getConst()); + $this->assertEquals('test', $parameterDefinition->getIdentifier()); + $this->assertEquals('value', $parameterDefinition->getConst()); } - public function testInlineConstDeclaration() { + public function testInlineConstDeclaration() + { // null passed as first parameter. This will generate an inline declaration. - $dependencyDefinition = new ConstParameterDefinition(null, "TheCodingMachine\\Yaco\\Definition\\ConstParameterDefinitionTest::TEST_CONST"); + $dependencyDefinition = new ConstParameterDefinition(null, 'TheCodingMachine\\Yaco\\Definition\\ConstParameterDefinitionTest::TEST_CONST'); - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); $instanceDefinition->addConstructorArgument($dependencyDefinition); $container = $this->getContainer([ - "test" => $instanceDefinition + 'test' => $instanceDefinition, ]); - $result = $container->get("test"); + $result = $container->get('test'); - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals("const", $result->cArg1); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals('const', $result->cArg1); } } diff --git a/tests/Definition/FactoryCallDefinitionTest.php b/tests/Definition/FactoryCallDefinitionTest.php new file mode 100644 index 0000000..d57a308 --- /dev/null +++ b/tests/Definition/FactoryCallDefinitionTest.php @@ -0,0 +1,51 @@ +assertEquals('test', $factoryDefinition->getIdentifier()); + $this->assertEquals('factory', $factoryDefinition->getFactory()->getTarget()); + $this->assertEquals('getTest', $factoryDefinition->getMethodName()); + $this->assertEquals([42], $factoryDefinition->getMethodArguments()); + $factoryDefinition->addMethodArgument(43); + $this->assertEquals([42, 43], $factoryDefinition->getMethodArguments()); + } + + public function testFactory() + { + $factoryDefinition = new ObjectDefinition('factory', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\TestFactory', [43]); + + $instanceDefinition = new FactoryCallDefinition('test', new Reference('factory'), 'getTest', [42]); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + 'factory' => $factoryDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals(43, $result->cArg1); + $this->assertEquals(42, $result->cArg2); + } + + public function testStaticFactory() + { + $instanceDefinition = new FactoryCallDefinition('test', 'TheCodingMachine\Yaco\Definition\Fixtures\TestFactory', 'getStaticTest', [42]); + + $container = $this->getContainer([ + 'test' => $instanceDefinition + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals(42, $result->cArg1); + } + +} diff --git a/tests/Definition/Fixtures/Test.php b/tests/Definition/Fixtures/Test.php index e36d5f7..368981e 100644 --- a/tests/Definition/Fixtures/Test.php +++ b/tests/Definition/Fixtures/Test.php @@ -1,19 +1,20 @@ cArg1 = $cArg1; $this->cArg2 = $cArg2; } - public function setArg1($arg1) { + public function setArg1($arg1) + { $this->cArg1 = $arg1; } } diff --git a/tests/Definition/Fixtures/TestDefinitionProvider.php b/tests/Definition/Fixtures/TestDefinitionProvider.php new file mode 100644 index 0000000..f23a4ff --- /dev/null +++ b/tests/Definition/Fixtures/TestDefinitionProvider.php @@ -0,0 +1,25 @@ +arg = $arg; + } + + public function getTest($arg2 = null) + { + return new Test($this->arg, $arg2); + } + + public static function getStaticTest($arg1) { + return new Test($arg1); + } +} diff --git a/tests/Definition/InstanceDefinitionTest.php b/tests/Definition/InstanceDefinitionTest.php deleted file mode 100644 index f0d425b..0000000 --- a/tests/Definition/InstanceDefinitionTest.php +++ /dev/null @@ -1,123 +0,0 @@ -addConstructorArgument(42); - $instanceDefinition->addConstructorArgument([12, [24, 42]]); - - $this->assertEquals("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $instanceDefinition->getClassName()); - $this->assertEquals("test", $instanceDefinition->getIdentifier()); - $this->assertCount(2, $instanceDefinition->getConstructorParameters()); - } - - public function testSimpleEmptyConstructor() { - $instanceDefinition = new InstanceDefinition("test", "\\stdClass"); - - $container = $this->getContainer([ - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("\\stdClass", $result); - } - - public function testSimpleConstructorWithArguments() { - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->addConstructorArgument(42); - $instanceDefinition->addConstructorArgument([12, [24, 42]]); - - $container = $this->getContainer([ - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals(42, $result->cArg1); - $this->assertEquals([12, [24, 42]], $result->cArg2); - } - - public function testSimpleConstructorWithReferenceArguments() { - $dependencyDefinition = new InstanceDefinition("dependency", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $dependencyDefinition->addConstructorArgument("hello"); - - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->addConstructorArgument($dependencyDefinition); - - $container = $this->getContainer([ - "dependency" => $dependencyDefinition, - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result->cArg1); - $this->assertEquals("hello", $result->cArg1->cArg1); - } - - /** - * @expectedException \RuntimeException - */ - public function testSimpleConstructorWithException() { - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->addConstructorArgument(new Test()); - - $instanceDefinition->toPhpCode('$container', []); - } - - public function testMethodCall() { - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->addMethodCall("setArg1")->addArgument(42); - - $container = $this->getContainer([ - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals("42", $result->cArg1); - } - - public function testPropertyAssignment() { - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->setProperty("cArg1", 42); - - $container = $this->getContainer([ - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals("42", $result->cArg1); - } - - public function testInlineDeclaration() { - // null passed as first parameter. This will generate an inline declaration. - $dependencyDefinition = new InstanceDefinition(null, "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $dependencyDefinition->addConstructorArgument("hello"); - - $dependencyDefinition2 = new InstanceDefinition(null, "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $dependencyDefinition2->addConstructorArgument("hello2"); - - - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); - $instanceDefinition->addConstructorArgument($dependencyDefinition); - $instanceDefinition->addConstructorArgument([$dependencyDefinition2]); - - $container = $this->getContainer([ - "test" => $instanceDefinition - ]); - $result = $container->get("test"); - - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result->cArg1); - $this->assertEquals("hello", $result->cArg1->cArg1); - $this->assertEquals("hello2", $result->cArg2[0]->cArg1); - } -} - diff --git a/tests/Definition/ObjectDefinitionTest.php b/tests/Definition/ObjectDefinitionTest.php new file mode 100644 index 0000000..34925e1 --- /dev/null +++ b/tests/Definition/ObjectDefinitionTest.php @@ -0,0 +1,150 @@ +addConstructorArgument(42); + $instanceDefinition->addConstructorArgument([12, [24, 42]]); + + $this->assertEquals('\\TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $instanceDefinition->getClassName()); + $this->assertEquals('test', $instanceDefinition->getIdentifier()); + $this->assertCount(2, $instanceDefinition->getConstructorParameters()); + } + + public function testSimpleEmptyConstructor() + { + $instanceDefinition = new ObjectDefinition('test', '\\stdClass'); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('\\stdClass', $result); + } + + public function testSimpleConstructorWithArguments() + { + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addConstructorArgument(42); + $instanceDefinition->addConstructorArgument([12, [24, 42]]); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals(42, $result->cArg1); + $this->assertEquals([12, [24, 42]], $result->cArg2); + } + + public function testSimpleConstructorWithReferenceArguments() + { + $dependencyDefinition = new ObjectDefinition('dependency', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $dependencyDefinition->addConstructorArgument('hello'); + + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addConstructorArgument($dependencyDefinition); + + $container = $this->getContainer([ + 'dependency' => $dependencyDefinition, + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result->cArg1); + $this->assertEquals('hello', $result->cArg1->cArg1); + } + + public function testSimpleConstructorWithReferenceClassArguments() + { + $dependencyDefinition = new ObjectDefinition('dependency', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $dependencyDefinition->addConstructorArgument('hello'); + + $reference = new Reference('dependency'); + + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addConstructorArgument($reference); + + $container = $this->getContainer([ + 'dependency' => $dependencyDefinition, + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result->cArg1); + $this->assertEquals('hello', $result->cArg1->cArg1); + } + + /** + * @expectedException \RuntimeException + */ + public function testSimpleConstructorWithException() + { + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addConstructorArgument(new Test()); + + $instanceDefinition->toPhpCode('$container', []); + } + + public function testMethodCall() + { + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addMethodCall('setArg1')->addArgument(42); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals('42', $result->cArg1); + } + + public function testPropertyAssignment() + { + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->setProperty('cArg1', 42); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals('42', $result->cArg1); + } + + public function testInlineDeclaration() + { + // null passed as first parameter. This will generate an inline declaration. + $dependencyDefinition = new ObjectDefinition(null, 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $dependencyDefinition->addConstructorArgument('hello'); + + $dependencyDefinition2 = new ObjectDefinition(null, 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $dependencyDefinition2->addConstructorArgument('hello2'); + + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); + $instanceDefinition->addConstructorArgument($dependencyDefinition); + $instanceDefinition->addConstructorArgument([$dependencyDefinition2]); + + $container = $this->getContainer([ + 'test' => $instanceDefinition, + ]); + $result = $container->get('test'); + + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result->cArg1); + $this->assertEquals('hello', $result->cArg1->cArg1); + $this->assertEquals('hello2', $result->cArg2[0]->cArg1); + } +} diff --git a/tests/Definition/ParameterDefinitionTest.php b/tests/Definition/ParameterDefinitionTest.php index 0df8e12..4ddd724 100644 --- a/tests/Definition/ParameterDefinitionTest.php +++ b/tests/Definition/ParameterDefinitionTest.php @@ -1,37 +1,40 @@ assertEquals("test", $parameterDefinition->getIdentifier()); - $this->assertEquals("value", $parameterDefinition->getValue()); + $this->assertEquals('test', $parameterDefinition->getIdentifier()); + $this->assertEquals('value', $parameterDefinition->getValue()); } - public function testSimpleEncode() { - $parameterDefinition = new ParameterDefinition("test", "value"); + public function testSimpleEncode() + { + $parameterDefinition = new ParameterDefinition('test', 'value'); $inlineEntry = $parameterDefinition->toPhpCode('$container', []); $this->assertEquals("'value'", $inlineEntry->getExpression()); $this->assertEquals(false, $inlineEntry->isLazilyEvaluated()); $this->assertEquals(null, $inlineEntry->getStatements()); } - public function testInlineParameterDeclaration() { + public function testInlineParameterDeclaration() + { // null passed as first parameter. This will generate an inline declaration. - $dependencyDefinition = new ParameterDefinition(null, "hello"); + $dependencyDefinition = new ParameterDefinition(null, 'hello'); - $instanceDefinition = new InstanceDefinition("test", "TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test"); + $instanceDefinition = new ObjectDefinition('test', 'TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test'); $instanceDefinition->addConstructorArgument($dependencyDefinition); $container = $this->getContainer([ - "test" => $instanceDefinition + 'test' => $instanceDefinition, ]); - $result = $container->get("test"); + $result = $container->get('test'); - $this->assertInstanceOf("TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test", $result); - $this->assertEquals("hello", $result->cArg1); + $this->assertInstanceOf('TheCodingMachine\\Yaco\\Definition\\Fixtures\\Test', $result); + $this->assertEquals('hello', $result->cArg1); } } diff --git a/tests/Definition/VariableUtilsTest.php b/tests/Definition/VariableUtilsTest.php index eaab86d..49d7058 100644 --- a/tests/Definition/VariableUtilsTest.php +++ b/tests/Definition/VariableUtilsTest.php @@ -1,14 +1,11 @@ assertEquals('$a', VariableUtils::getNextAvailableVariableName('a', [])); $this->assertEquals('$a', VariableUtils::getNextAvailableVariableName('$a', [])); $this->assertEquals('$a1', VariableUtils::getNextAvailableVariableName('$a', ['$a'])); @@ -19,4 +16,3 @@ public function testGetNextAvailableVariableName() { $this->assertEquals('$b', VariableUtils::getNextAvailableVariableName('#${}b', [])); } } - diff --git a/tests/DefinitionInteropCompatibilityTest.php b/tests/DefinitionInteropCompatibilityTest.php new file mode 100644 index 0000000..90c6922 --- /dev/null +++ b/tests/DefinitionInteropCompatibilityTest.php @@ -0,0 +1,49 @@ +converter = new DefinitionConverter(); + } + + /** + * Takes a definition provider in parameter and returns a container containing the entries. + * + * @param DefinitionProviderInterface $definitionProvider + * @return ContainerInterface + */ + protected function getContainer(DefinitionProviderInterface $definitionProvider) + { + $definitions = $definitionProvider->getDefinitions(); + $closures = []; + foreach ($definitions as $definition) { + $key = $definition->getIdentifier(); + $yacoDefinition = $this->converter->convert($definition); + $inlineCodeDefinition = $yacoDefinition->toPhpCode('$container', ['$container']); + $code = $inlineCodeDefinition->getStatements(); + $code .= 'return '.$inlineCodeDefinition->getExpression().";\n"; + $closures[$key] = eval("return function(\$container) {\n".$code.'};'); + } + $picotainer = new Picotainer($closures); + + return $picotainer; + } +} diff --git a/tests/InvalidEntryDefinition.php b/tests/InvalidEntryDefinition.php index 1d4df69..a6c896a 100644 --- a/tests/InvalidEntryDefinition.php +++ b/tests/InvalidEntryDefinition.php @@ -1,4 +1,5 @@ container" - * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * @param array $usedVariables An array of variables that are already used and that should not be used when generating this code. + * * @return InlineEntryInterface */ public function toPhpCode($containerVariable, array $usedVariables = array()) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 51bede3..e91cc12 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,2 +1,3 @@