diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
index 093f4bb1da..b8508809ae 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
@@ -4,6 +4,7 @@ CHANGELOG
4.4.0
-----
+ * Added `lint:container` to check that services wiring matches type declarations
* Added `MailerAssertionsTrait`
* Deprecated support for `templating` engine in `TemplateController`, use Twig instead
* Deprecated the `$parser` argument of `ControllerResolver::__construct()` and `DelegatingLoader::__construct()`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
index c7c6cb4507..04ecff767f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
@@ -11,19 +11,21 @@
namespace Symfony\Bundle\FrameworkBundle\Command;
+use Symfony\Component\Config\ConfigCache;
+use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Config\ConfigCache;
-use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Compiler\CheckTypeHintsPass;
+use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
-use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
-class ContainerLintCommand extends Command
+final class ContainerLintCommand extends Command
{
+ protected static $defaultName = 'lint:container';
+
/**
* @var ContainerBuilder
*/
@@ -35,37 +37,33 @@ class ContainerLintCommand extends Command
protected function configure()
{
$this
- ->setDescription('Lints container for services arguments type hints')
- ->setHelp('This command will parse all your defined services and check that you are injecting service without type error based on type hints.')
- ->addOption('only-used-services', 'o', InputOption::VALUE_NONE, 'Check only services that are used in your application')
+ ->setDescription('Ensures that arguments injected into services match type declarations')
+ ->setHelp('This command parses service definitions and ensures that injected values match the type declarations of each services\' class.')
+ ->addOption('ignore-unused-services', 'o', InputOption::VALUE_NONE, 'Ignore unused services')
;
}
/**
* {@inheritdoc}
*/
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
$container = $this->getContainerBuilder();
$container->setParameter('container.build_id', 'lint_container');
$container->addCompilerPass(
- new CheckTypeHintsPass(),
- $input->getOption('only-used-services') ? PassConfig::TYPE_AFTER_REMOVING : PassConfig::TYPE_BEFORE_OPTIMIZATION
+ new CheckTypeDeclarationsPass(true),
+ $input->getOption('ignore-unused-services') ? PassConfig::TYPE_AFTER_REMOVING : PassConfig::TYPE_OPTIMIZE,
+ -5
);
$container->compile();
+
+ return 0;
}
- /**
- * Loads the ContainerBuilder from the cache.
- *
- * @return ContainerBuilder
- *
- * @throws \LogicException
- */
- protected function getContainerBuilder()
+ private function getContainerBuilder(): ContainerBuilder
{
if ($this->containerBuilder) {
return $this->containerBuilder;
@@ -74,10 +72,9 @@ class ContainerLintCommand extends Command
$kernel = $this->getApplication()->getKernel();
if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
- $buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, get_class($kernel));
+ $buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
$container = $buildContainer();
- $container->getCompilerPassConfig()->setRemovingPasses(array());
- $container->compile();
+ $container->getCompilerPassConfig()->setRemovingPasses([]);
} else {
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
}
diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
index 7da5b6b534..d1771da846 100644
--- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md
+++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
@@ -4,7 +4,7 @@ CHANGELOG
4.4.0
-----
- * added `CheckTypeHintsPass` to check injected parameters type during compilation
+ * added `CheckTypeDeclarationsPass` to check injected parameters type during compilation
* added support for opcache.preload by generating a preloading script in the cache folder
* added support for dumping the container in one file instead of many files
* deprecated support for short factories and short configurators in Yaml
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php
new file mode 100644
index 0000000000..0dfd9ae6f6
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php
@@ -0,0 +1,172 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
+use Symfony\Component\DependencyInjection\Parameter;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ServiceLocator;
+
+/**
+ * Checks whether injected parameters are compatible with type declarations.
+ *
+ * This pass should be run after all optimization passes.
+ *
+ * It can be added either:
+ * * before removing passes to check all services even if they are not currently used,
+ * * after removing passes to check only services are used in the app.
+ *
+ * @author Nicolas Grekas
+ * @author Julien Maulny
+ */
+final class CheckTypeDeclarationsPass extends AbstractRecursivePass
+{
+ private const SCALAR_TYPES = ['int', 'float', 'bool', 'string'];
+
+ private $autoload;
+
+ /**
+ * @param bool $autoload Whether services who's class in not loaded should be checked or not.
+ * Defaults to false to save loading code during compilation.
+ */
+ public function __construct(bool $autoload = false)
+ {
+ $this->autoload = $autoload;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function processValue($value, $isRoot = false)
+ {
+ if (!$value instanceof Definition) {
+ return parent::processValue($value, $isRoot);
+ }
+
+ if (!$this->autoload && !class_exists($class = $value->getClass(), false) && !interface_exists($class, false)) {
+ return parent::processValue($value, $isRoot);
+ }
+
+ if (ServiceLocator::class === $value->getClass()) {
+ return parent::processValue($value, $isRoot);
+ }
+
+ if ($constructor = $this->getConstructor($value, false)) {
+ $this->checkTypeDeclarations($value, $constructor, $value->getArguments());
+ }
+
+ foreach ($value->getMethodCalls() as $methodCall) {
+ $reflectionMethod = $this->getReflectionMethod($value, $methodCall[0]);
+
+ $this->checkTypeDeclarations($value, $reflectionMethod, $methodCall[1]);
+ }
+
+ return parent::processValue($value, $isRoot);
+ }
+
+ /**
+ * @throws InvalidArgumentException When not enough parameters are defined for the method
+ */
+ private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $configurationArguments): void
+ {
+ $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters();
+
+ if (\count($configurationArguments) < $numberOfRequiredParameters) {
+ throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($configurationArguments)));
+ }
+
+ $reflectionParameters = $reflectionFunction->getParameters();
+ $checksCount = min($reflectionFunction->getNumberOfParameters(), \count($configurationArguments));
+
+ for ($i = 0; $i < $checksCount; ++$i) {
+ if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) {
+ continue;
+ }
+
+ $this->checkType($checkedDefinition, $configurationArguments[$i], $reflectionParameters[$i]);
+ }
+
+ if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) {
+ $variadicParameters = \array_slice($configurationArguments, $lastParameter->getPosition());
+
+ foreach ($variadicParameters as $variadicParameter) {
+ $this->checkType($checkedDefinition, $variadicParameter, $lastParameter);
+ }
+ }
+ }
+
+ /**
+ * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type
+ */
+ private function checkType(Definition $checkedDefinition, $configurationArgument, \ReflectionParameter $parameter): void
+ {
+ $parameterTypeName = $parameter->getType()->getName();
+
+ $referencedDefinition = $configurationArgument;
+
+ if ($referencedDefinition instanceof Reference) {
+ if (!$this->container->has($referencedDefinition)) {
+ return;
+ }
+
+ $referencedDefinition = $this->container->findDefinition((string) $referencedDefinition);
+ }
+
+ if ('self' === $parameterTypeName) {
+ $parameterTypeName = $parameter->getDeclaringClass()->getName();
+ }
+ if ('static' === $parameterTypeName) {
+ $parameterTypeName = $checkedDefinition->getClass();
+ }
+
+ if ($referencedDefinition instanceof Definition) {
+ $class = $referencedDefinition->getClass();
+
+ if (!$class || (!$this->autoload && !class_exists($class, false) && !interface_exists($class, false))) {
+ return;
+ }
+
+ if (!is_a($class, $parameterTypeName, true)) {
+ throw new InvalidParameterTypeException($this->currentId, $class, $parameter);
+ }
+ } else {
+ if (null === $configurationArgument && $parameter->allowsNull()) {
+ return;
+ }
+
+ if (\in_array($parameterTypeName, self::SCALAR_TYPES, true) && is_scalar($configurationArgument)) {
+ return;
+ }
+
+ if ('iterable' === $parameterTypeName && $configurationArgument instanceof IteratorArgument) {
+ return;
+ }
+
+ if ('Traversable' === $parameterTypeName && $configurationArgument instanceof IteratorArgument) {
+ return;
+ }
+
+ if ($configurationArgument instanceof Parameter) {
+ return;
+ }
+
+ $checkFunction = sprintf('is_%s', $parameter->getType()->getName());
+
+ if (!$parameter->getType()->isBuiltin() || !$checkFunction($configurationArgument)) {
+ throw new InvalidParameterTypeException($this->currentId, \gettype($configurationArgument), $parameter);
+ }
+ }
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeHintsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeHintsPass.php
deleted file mode 100644
index 41085b8e68..0000000000
--- a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeHintsPass.php
+++ /dev/null
@@ -1,184 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\DependencyInjection\Compiler;
-
-use Symfony\Component\DependencyInjection\Definition;
-use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\DependencyInjection\ServiceLocator;
-use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
-use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeHintException;
-use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
-
-/**
- * Checks whether injected parameters types are compatible with type hints.
- * This pass should be run after all optimization passes.
- * So it can be added either:
- * * before removing (PassConfig::TYPE_BEFORE_REMOVING) so that it will check
- * all services, even if they are not currently used,
- * * after removing (PassConfig::TYPE_AFTER_REMOVING) so that it will check
- * only services you are using.
- *
- * @author Nicolas Grekas
- * @author Julien Maulny
- */
-class CheckTypeHintsPass extends AbstractRecursivePass
-{
- /**
- * If set to true, allows to autoload classes during compilation
- * in order to check type hints on parameters that are not yet loaded.
- * Defaults to false to prevent code loading during compilation.
- *
- * @param bool
- */
- private $autoload;
-
- public function __construct(bool $autoload = false)
- {
- $this->autoload = $autoload;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function processValue($value, $isRoot = false)
- {
- if (!$value instanceof Definition) {
- return parent::processValue($value, $isRoot);
- }
-
- if (!$this->autoload && !class_exists($className = $this->getClassName($value), false) && !interface_exists($className, false)) {
- return parent::processValue($value, $isRoot);
- }
-
- if (ServiceLocator::class === $value->getClass()) {
- return parent::processValue($value, $isRoot);
- }
-
- if (null !== $constructor = $this->getConstructor($value, false)) {
- $this->checkArgumentsTypeHints($constructor, $value->getArguments());
- }
-
- foreach ($value->getMethodCalls() as $methodCall) {
- $reflectionMethod = $this->getReflectionMethod($value, $methodCall[0]);
-
- $this->checkArgumentsTypeHints($reflectionMethod, $methodCall[1]);
- }
-
- return parent::processValue($value, $isRoot);
- }
-
- /**
- * Check type hints for every parameter of a method/constructor.
- *
- * @throws InvalidArgumentException on type hint incompatibility
- */
- private function checkArgumentsTypeHints(\ReflectionFunctionAbstract $reflectionFunction, array $configurationArguments): void
- {
- $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters();
-
- if (count($configurationArguments) < $numberOfRequiredParameters) {
- throw new InvalidArgumentException(sprintf(
- 'Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, count($configurationArguments)));
- }
-
- $reflectionParameters = $reflectionFunction->getParameters();
- $checksCount = min($reflectionFunction->getNumberOfParameters(), count($configurationArguments));
-
- for ($i = 0; $i < $checksCount; ++$i) {
- if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) {
- continue;
- }
-
- $this->checkTypeHint($configurationArguments[$i], $reflectionParameters[$i]);
- }
-
- if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) {
- $variadicParameters = array_slice($configurationArguments, $lastParameter->getPosition());
-
- foreach ($variadicParameters as $variadicParameter) {
- $this->checkTypeHint($variadicParameter, $lastParameter);
- }
- }
- }
-
- /**
- * Check type hints compatibility between
- * a definition argument and a reflection parameter.
- *
- * @throws InvalidArgumentException on type hint incompatibility
- */
- private function checkTypeHint($configurationArgument, \ReflectionParameter $parameter): void
- {
- $referencedDefinition = $configurationArgument;
-
- if ($referencedDefinition instanceof Reference) {
- $referencedDefinition = $this->container->findDefinition((string) $referencedDefinition);
- }
-
- if ($referencedDefinition instanceof Definition) {
- $class = $this->getClassName($referencedDefinition);
-
- if (!$this->autoload && !class_exists($class, false)) {
- return;
- }
-
- if (!is_a($class, $parameter->getType()->getName(), true)) {
- throw new InvalidParameterTypeHintException($this->currentId, null === $class ? 'null' : $class, $parameter);
- }
- } else {
- if (null === $configurationArgument && $parameter->allowsNull()) {
- return;
- }
-
- if ($parameter->getType()->isBuiltin() && is_scalar($configurationArgument)) {
- return;
- }
-
- if ('iterable' === $parameter->getType()->getName() && $configurationArgument instanceof IteratorArgument) {
- return;
- }
-
- if ('Traversable' === $parameter->getType()->getName() && $configurationArgument instanceof IteratorArgument) {
- return;
- }
-
- $checkFunction = 'is_'.$parameter->getType()->getName();
-
- if (!$parameter->getType()->isBuiltin() || !$checkFunction($configurationArgument)) {
- throw new InvalidParameterTypeHintException($this->currentId, gettype($configurationArgument), $parameter);
- }
- }
- }
-
- /**
- * Get class name from value that can have a factory.
- *
- * @return string|null
- */
- private function getClassName($value)
- {
- if (is_array($factory = $value->getFactory())) {
- list($class, $method) = $factory;
- if ($class instanceof Reference) {
- $class = $this->container->findDefinition((string) $class)->getClass();
- } elseif (null === $class) {
- $class = $value->getClass();
- } elseif ($class instanceof Definition) {
- $class = $this->getClassName($class);
- }
- } else {
- $class = $value->getClass();
- }
-
- return $class;
- }
-}
diff --git a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php
new file mode 100644
index 0000000000..206561fa95
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Exception;
+
+/**
+ * Thrown when trying to inject a parameter into a constructor/method with an incompatible type.
+ *
+ * @author Nicolas Grekas
+ * @author Julien Maulny
+ */
+class InvalidParameterTypeException extends InvalidArgumentException
+{
+ public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter)
+ {
+ parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $parameter->getType()->getName(), $type));
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeHintException.php b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeHintException.php
deleted file mode 100644
index a04d071972..0000000000
--- a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeHintException.php
+++ /dev/null
@@ -1,28 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\DependencyInjection\Exception;
-
-/**
- * Thrown when trying to inject a parameter into a constructor/method
- * with a type that does not match type hint.
- *
- * @author Nicolas Grekas
- * @author Julien Maulny
- */
-class InvalidParameterTypeHintException extends InvalidArgumentException
-{
- public function __construct(string $serviceId, string $typeHint, \ReflectionParameter $parameter)
- {
- parent::__construct(sprintf(
- 'Invalid definition for service "%s": argument %d of "%s::%s" requires a "%s", "%s" passed.', $serviceId, $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $parameter->getType()->getName(), $typeHint));
- }
-}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeHintsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php
similarity index 50%
rename from src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeHintsPassTest.php
rename to src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php
index 690c628cb6..51bc7c6779 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeHintsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php
@@ -12,77 +12,73 @@
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
+use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
-use Symfony\Component\DependencyInjection\Compiler\CheckTypeHintsPass;
-use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Bar;
-use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarOptionalArgument;
-use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarOptionalArgumentNotNull;
-use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall;
-use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Bar;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarMethodCall;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarOptionalArgument;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarOptionalArgumentNotNull;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo;
/**
* @author Nicolas Grekas
* @author Julien Maulny
*/
-class CheckTypeHintsPassTest extends TestCase
+class CheckTypeDeclarationsPassTest extends TestCase
{
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Bar::__construct" requires a "stdClass", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo" passed
- */
- public function testProcessThrowsExceptionOnInvalidTypeHintsConstructorArguments()
+ public function testProcessThrowsExceptionOnInvalidTypesConstructorArguments()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Bar::__construct" accepts "stdClass", "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo" passed.');
+
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', Bar::class)
->addArgument(new Reference('foo'));
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoo" requires a "stdClass", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo" passed
- */
- public function testProcessThrowsExceptionOnInvalidTypeHintsMethodCallArguments()
+ public function testProcessThrowsExceptionOnInvalidTypesMethodCallArguments()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoo" accepts "stdClass", "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo" passed.');
+
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoo', array(new Reference('foo')));
+ ->addMethodCall('setFoo', [new Reference('foo')]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Bar::__construct" requires a "stdClass", "NULL" passed
- */
public function testProcessFailsWhenPassingNullToRequiredArgument()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Bar::__construct" accepts "stdClass", "NULL" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', Bar::class)
->addArgument(null);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Bar::__construct()" requires 1 arguments, 0 passed
- */
public function testProcessThrowsExceptionWhenMissingArgumentsInConstructor()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Bar::__construct()" requires 1 arguments, 0 passed.');
+
$container = new ContainerBuilder();
$container->register('bar', Bar::class);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
public function testProcessSuccessWhenPassingTooManyArgumentInConstructor()
@@ -94,7 +90,7 @@ class CheckTypeHintsPassTest extends TestCase
->addArgument(new Reference('foo'))
->addArgument(new Reference('foo'));
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
@@ -105,62 +101,59 @@ class CheckTypeHintsPassTest extends TestCase
$container->register(Foo::class, Foo::class);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(Foo::class, $container->get(Foo::class));
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoo()" requires 1 arguments, 0 passed
- */
public function testProcessThrowsExceptionWhenMissingArgumentsInMethodCall()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoo()" requires 1 arguments, 0 passed.');
+
$container = new ContainerBuilder();
$container->register('foo', \stdClass::class);
$container->register('bar', BarMethodCall::class)
->addArgument(new Reference('foo'))
- ->addMethodCall('setFoo', array());
+ ->addMethodCall('setFoo', []);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoosVariadic" requires a "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo", "stdClass" passed
- */
public function testProcessVariadicFails()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 2 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoosVariadic" accepts "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo", "stdClass" passed.');
+
$container = new ContainerBuilder();
$container->register('stdClass', \stdClass::class);
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosVariadic', array(
+ ->addMethodCall('setFoosVariadic', [
new Reference('foo'),
new Reference('foo'),
new Reference('stdClass'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoosVariadic" requires a "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo", "stdClass" passed
- */
public function testProcessVariadicFailsOnPassingBadTypeOnAnotherArgument()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoosVariadic" accepts "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo", "stdClass" passed.');
+
$container = new ContainerBuilder();
$container->register('stdClass', \stdClass::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosVariadic', array(
+ ->addMethodCall('setFoosVariadic', [
new Reference('stdClass'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
public function testProcessVariadicSuccess()
@@ -169,13 +162,13 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosVariadic', array(
+ ->addMethodCall('setFoosVariadic', [
new Reference('foo'),
new Reference('foo'),
new Reference('foo'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(Foo::class, $container->get('bar')->foo);
}
@@ -186,11 +179,11 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosOptional', array(
+ ->addMethodCall('setFoosOptional', [
new Reference('foo'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(Foo::class, $container->get('bar')->foo);
}
@@ -201,33 +194,32 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosOptional', array(
+ ->addMethodCall('setFoosOptional', [
new Reference('foo'),
new Reference('foo'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(Foo::class, $container->get('bar')->foo);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoosOptional" requires a "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo", "stdClass" passed
- */
public function testProcessFailsWhenUsingOptionalArgumentWithBadType()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 2 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoosOptional" accepts "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo", "stdClass" passed.');
+
$container = new ContainerBuilder();
$container->register('stdClass', \stdClass::class);
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoosOptional', array(
+ ->addMethodCall('setFoosOptional', [
new Reference('foo'),
new Reference('stdClass'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
public function testProcessSuccessWhenPassingNullToOptional()
@@ -237,37 +229,35 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', BarOptionalArgument::class)
->addArgument(null);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertNull($container->get('bar')->foo);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarOptionalArgumentNotNull::__construct" requires a "int", "NULL" passed
- */
public function testProcessSuccessWhenPassingNullToOptionalThatDoesNotAcceptNull()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarOptionalArgumentNotNull::__construct" accepts "int", "NULL" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', BarOptionalArgumentNotNull::class)
->addArgument(null);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarOptionalArgument::__construct" requires a "stdClass", "string" passed
- */
public function testProcessFailsWhenPassingBadTypeToOptional()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarOptionalArgument::__construct" accepts "stdClass", "string" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', BarOptionalArgument::class)
->addArgument('string instead of stdClass');
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertNull($container->get('bar')->foo);
}
@@ -277,97 +267,88 @@ class CheckTypeHintsPassTest extends TestCase
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setScalars', array(
+ ->addMethodCall('setScalars', [
1,
'string',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(BarMethodCall::class, $container->get('bar'));
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Bar::__construct" requires a "stdClass", "integer" passed
- */
- public function testProcessFailsOnPassingScalarTypeToConstructorTypeHintedWithClass()
+ public function testProcessFailsOnPassingScalarTypeToConstructorTypedWithClass()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Bar::__construct" accepts "stdClass", "integer" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', Bar::class)
->addArgument(1);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setFoo" requires a "stdClass", "string" passed
- */
- public function testProcessFailsOnPassingScalarTypeToMethodTypeHintedWithClass()
+ public function testProcessFailsOnPassingScalarTypeToMethodTypedWithClass()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setFoo" accepts "stdClass", "string" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setFoo', array(
+ ->addMethodCall('setFoo', [
'builtin type instead of class',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\BarMethodCall::setScalars" requires a "int", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo" passed
- */
- public function testProcessFailsOnPassingClassToScalarTypeHintedParameter()
+ public function testProcessFailsOnPassingClassToScalarTypedParameter()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setScalars" accepts "int", "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo" passed.');
+
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setScalars', array(
+ ->addMethodCall('setScalars', [
new Reference('foo'),
new Reference('foo'),
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * Strict mode not yet handled.
- */
public function testProcessSuccessOnPassingBadScalarType()
{
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setScalars', array(
+ ->addMethodCall('setScalars', [
1,
true,
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(BarMethodCall::class, $container->get('bar'));
}
- /**
- * Strict mode not yet handled.
- */
public function testProcessSuccessPassingBadScalarTypeOptionalArgument()
{
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setScalars', array(
+ ->addMethodCall('setScalars', [
1,
'string',
'string instead of optional boolean',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(BarMethodCall::class, $container->get('bar'));
}
@@ -377,27 +358,24 @@ class CheckTypeHintsPassTest extends TestCase
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setArray', array(
- array(),
- ));
+ ->addMethodCall('setArray', [[]]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(BarMethodCall::class, $container->get('bar'));
}
- public function testProcessSuccessWhenPassingIntegerToArrayTypeHintedParameter()
+ public function testProcessSuccessWhenPassingIntegerToArrayTypedParameter()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarMethodCall::setArray" accepts "array", "integer" passed.');
+
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setArray', array(
- 1,
- ));
+ ->addMethodCall('setArray', [1]);
- (new CheckTypeHintsPass(true))->process($container);
-
- $this->addToAssertionCount(1);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
public function testProcessSuccessWhenPassingAnIteratorArgumentToIterable()
@@ -405,11 +383,9 @@ class CheckTypeHintsPassTest extends TestCase
$container = new ContainerBuilder();
$container->register('bar', BarMethodCall::class)
- ->addMethodCall('setIterable', array(
- new IteratorArgument(array()),
- ));
+ ->addMethodCall('setIterable', [new IteratorArgument([])]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
@@ -420,57 +396,43 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', Foo::class);
$container->register('bar', Bar::class)
- ->setFactory(array(
+ ->setFactory([
new Reference('foo'),
'createBar',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ /* Asserts that the class of Bar is well detected */
+ $container->register('bar_call', BarMethodCall::class)
+ ->addMethodCall('setBar', [new Reference('bar')]);
+
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(Bar::class, $container->get('bar'));
}
- public function testProcessFactoryWhithClassName()
- {
- $container = new ContainerBuilder();
-
- $container->register(Foo::class, Foo::class);
- $container->register(Bar::class, Bar::class)
- ->setFactory(array(
- new Reference(Foo::class),
- 'createBar',
- ));
-
- (new CheckTypeHintsPass(true))->process($container);
-
- $this->assertInstanceOf(Bar::class, $container->get(Bar::class));
- }
-
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 0 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo::createBarArguments" requires a "stdClass", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo" passed
- */
public function testProcessFactoryFailsOnInvalidParameterType()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo::createBarArguments" accepts "stdClass", "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo" passed.');
+
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', Bar::class)
->addArgument(new Reference('foo'))
- ->setFactory(array(
+ ->setFactory([
new Reference('foo'),
'createBarArguments',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
- * @expectedExceptionMessage Invalid definition for service "bar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo::createBarArguments" requires a "stdClass", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeHintsPass\Foo" passed
- */
public function testProcessFactoryFailsOnInvalidParameterTypeOptional()
{
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar": argument 2 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo::createBarArguments" accepts "stdClass", "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\Foo" passed.');
+
$container = new ContainerBuilder();
$container->register('stdClass', \stdClass::class);
@@ -478,12 +440,12 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', Bar::class)
->addArgument(new Reference('stdClass'))
->addArgument(new Reference('foo'))
- ->setFactory(array(
+ ->setFactory([
new Reference('foo'),
'createBarArguments',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
}
public function testProcessFactorySuccessOnValidTypes()
@@ -495,12 +457,12 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', Bar::class)
->addArgument(new Reference('stdClass'))
->addArgument(new Reference('stdClass'))
- ->setFactory(array(
+ ->setFactory([
new Reference('foo'),
'createBarArguments',
- ));
+ ]);
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
@@ -512,7 +474,7 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', \DateTime::class)
->setFactory('date_create');
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(\DateTime::class, $container->get('bar'));
}
@@ -524,13 +486,13 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', FooNotExisting::class);
$container->register('bar', BarNotExisting::class)
->addArgument(new Reference('foo'))
- ->addMethodCall('setFoo', array(
+ ->addMethodCall('setFoo', [
new Reference('foo'),
'string',
1,
- ));
+ ]);
- (new CheckTypeHintsPass())->process($container);
+ (new CheckTypeDeclarationsPass())->process($container);
$this->addToAssertionCount(1);
}
@@ -541,12 +503,12 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('foo', FooNotExisting::class);
$container->register('bar', BarNotExisting::class)
- ->setFactory(array(
+ ->setFactory([
new Reference('foo'),
'notExistingMethod',
- ));
+ ]);
- (new CheckTypeHintsPass())->process($container);
+ (new CheckTypeDeclarationsPass())->process($container);
$this->addToAssertionCount(1);
}
@@ -558,12 +520,12 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', BarNotExisting::class)
->addArgument(1);
- (new CheckTypeHintsPass())->process($container);
+ (new CheckTypeDeclarationsPass())->process($container);
$this->addToAssertionCount(1);
}
- public function testProcessDoesNotThrowsExceptionOnValidTypeHints()
+ public function testProcessDoesNotThrowsExceptionOnValidTypes()
{
$container = new ContainerBuilder();
@@ -571,7 +533,22 @@ class CheckTypeHintsPassTest extends TestCase
$container->register('bar', Bar::class)
->addArgument(new Reference('foo'));
- (new CheckTypeHintsPass(true))->process($container);
+ (new CheckTypeDeclarationsPass(true))->process($container);
+
+ $this->assertInstanceOf(\stdClass::class, $container->get('bar')->foo);
+ }
+
+ public function testProcessThrowsOnIterableTypeWhenScalarPassed()
+ {
+ $this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid definition for service "bar_call": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setIterable" accepts "iterable", "integer" passed.');
+
+ $container = new ContainerBuilder();
+
+ $container->register('bar_call', BarMethodCall::class)
+ ->addMethodCall('setIterable', [2]);
+
+ (new CheckTypeDeclarationsPass(true))->process($container);
$this->assertInstanceOf(\stdClass::class, $container->get('bar')->foo);
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/Bar.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/Bar.php
similarity index 88%
rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/Bar.php
rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/Bar.php
index 85a1289815..403841ce88 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/Bar.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/Bar.php
@@ -1,6 +1,6 @@
foo = $foo;
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/BarOptionalArgument.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/BarOptionalArgument.php
similarity index 89%
rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/BarOptionalArgument.php
rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/BarOptionalArgument.php
index 3b6daa77f8..4f34889513 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeHintsPass/BarOptionalArgument.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/BarOptionalArgument.php
@@ -1,6 +1,6 @@