2010-03-18 07:48:03 +00:00
< ? php
/*
2010-04-25 16:06:54 +01:00
* This file is part of the Symfony package .
2011-01-15 13:29:43 +00:00
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2010-04-07 02:07:59 +01:00
*
2010-03-18 07:48:03 +00:00
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2012-03-28 14:43:52 +01:00
namespace Symfony\Component\DependencyInjection\Tests ;
require_once __DIR__ . '/Fixtures/includes/classes.php' ;
require_once __DIR__ . '/Fixtures/includes/ProjectExtension.php' ;
2010-03-18 07:48:03 +00:00
2017-02-08 07:24:27 +00:00
use PHPUnit\Framework\TestCase ;
2017-02-16 11:05:13 +00:00
use Psr\Container\ContainerInterface as PsrContainerInterface ;
2019-08-01 08:31:22 +01:00
use Symfony\Bridge\PhpUnit\ForwardCompatTestTrait ;
2017-02-02 08:31:13 +00:00
use Symfony\Component\Config\Resource\ComposerResource ;
2017-01-30 09:47:16 +00:00
use Symfony\Component\Config\Resource\DirectoryResource ;
2018-07-26 10:03:18 +01:00
use Symfony\Component\Config\Resource\FileResource ;
2013-03-29 23:21:12 +00:00
use Symfony\Component\Config\Resource\ResourceInterface ;
2011-01-07 14:44:29 +00:00
use Symfony\Component\DependencyInjection\Alias ;
2016-12-13 17:37:51 +00:00
use Symfony\Component\DependencyInjection\Argument\IteratorArgument ;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator ;
2017-02-26 17:31:03 +00:00
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument ;
2016-11-28 07:50:06 +00:00
use Symfony\Component\DependencyInjection\ChildDefinition ;
2016-03-05 12:39:12 +00:00
use Symfony\Component\DependencyInjection\Compiler\PassConfig ;
2010-08-20 22:09:55 +01:00
use Symfony\Component\DependencyInjection\ContainerBuilder ;
use Symfony\Component\DependencyInjection\ContainerInterface ;
use Symfony\Component\DependencyInjection\Definition ;
2013-03-06 16:38:10 +00:00
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
2016-02-07 18:10:24 +00:00
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException ;
2013-11-09 11:47:52 +00:00
use Symfony\Component\DependencyInjection\Loader\ClosureLoader ;
2016-08-12 19:34:27 +01:00
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag ;
2010-08-20 22:09:55 +01:00
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag ;
2018-07-26 10:03:18 +01:00
use Symfony\Component\DependencyInjection\Reference ;
2017-02-06 23:00:41 +00:00
use Symfony\Component\DependencyInjection\ServiceLocator ;
2016-10-21 11:29:35 +01:00
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass ;
2016-11-23 17:45:56 +00:00
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition ;
2019-07-08 14:34:24 +01:00
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory ;
2018-07-26 10:06:28 +01:00
use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy ;
use Symfony\Component\DependencyInjection\TypedReference ;
2013-09-02 11:46:47 +01:00
use Symfony\Component\ExpressionLanguage\Expression ;
2010-03-18 07:48:03 +00:00
2017-02-08 07:24:27 +00:00
class ContainerBuilderTest extends TestCase
2010-03-18 07:48:03 +00:00
{
2019-08-01 08:31:22 +01:00
use ForwardCompatTestTrait ;
2017-02-16 11:05:13 +00:00
public function testDefaultRegisteredDefinitions ()
{
$builder = new ContainerBuilder ();
$this -> assertCount ( 1 , $builder -> getDefinitions ());
$this -> assertTrue ( $builder -> hasDefinition ( 'service_container' ));
$definition = $builder -> getDefinition ( 'service_container' );
$this -> assertInstanceOf ( Definition :: class , $definition );
$this -> assertTrue ( $definition -> isSynthetic ());
$this -> assertSame ( ContainerInterface :: class , $definition -> getClass ());
$this -> assertTrue ( $builder -> hasAlias ( PsrContainerInterface :: class ));
$this -> assertTrue ( $builder -> hasAlias ( ContainerInterface :: class ));
}
2010-05-06 12:25:53 +01:00
public function testDefinitions ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$definitions = [
2013-12-18 17:52:54 +00:00
'foo' => new Definition ( 'Bar\FooClass' ),
2010-05-06 12:25:53 +01:00
'bar' => new Definition ( 'BarClass' ),
2019-01-16 09:39:14 +00:00
];
2010-05-06 12:25:53 +01:00
$builder -> setDefinitions ( $definitions );
$this -> assertEquals ( $definitions , $builder -> getDefinitions (), '->setDefinitions() sets the service definitions' );
$this -> assertTrue ( $builder -> hasDefinition ( 'foo' ), '->hasDefinition() returns true if a service definition exists' );
$this -> assertFalse ( $builder -> hasDefinition ( 'foobar' ), '->hasDefinition() returns false if a service definition does not exist' );
$builder -> setDefinition ( 'foobar' , $foo = new Definition ( 'FooBarClass' ));
$this -> assertEquals ( $foo , $builder -> getDefinition ( 'foobar' ), '->getDefinition() returns a service definition if defined' );
2017-12-11 21:55:31 +00:00
$this -> assertSame ( $builder -> setDefinition ( 'foobar' , $foo = new Definition ( 'FooBarClass' )), $foo , '->setDefinition() implements a fluid interface by returning the service reference' );
2010-05-06 12:25:53 +01:00
2019-01-16 09:39:14 +00:00
$builder -> addDefinitions ( $defs = [ 'foobar' => new Definition ( 'FooBarClass' )]);
2010-05-06 12:25:53 +01:00
$this -> assertEquals ( array_merge ( $definitions , $defs ), $builder -> getDefinitions (), '->addDefinitions() adds the service definitions' );
2010-05-07 15:09:11 +01:00
try {
2010-05-06 12:25:53 +01:00
$builder -> getDefinition ( 'baz' );
2016-02-07 18:10:24 +00:00
$this -> fail ( '->getDefinition() throws a ServiceNotFoundException if the service definition does not exist' );
} catch ( ServiceNotFoundException $e ) {
$this -> assertEquals ( 'You have requested a non-existent service "baz".' , $e -> getMessage (), '->getDefinition() throws a ServiceNotFoundException if the service definition does not exist' );
2010-05-06 12:25:53 +01:00
}
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2016-07-01 07:55:04 +01:00
/**
2016-10-20 14:28:37 +01:00
* @ group legacy
* @ expectedDeprecation The " deprecated_foo " service is deprecated . You should stop using it , as it will soon be removed .
2016-07-01 07:55:04 +01:00
*/
2015-08-10 11:33:01 +01:00
public function testCreateDeprecatedService ()
{
2016-10-20 14:28:37 +01:00
$definition = new Definition ( 'stdClass' );
$definition -> setDeprecated ( true );
2015-08-10 11:33:01 +01:00
2016-10-20 14:28:37 +01:00
$builder = new ContainerBuilder ();
$builder -> setDefinition ( 'deprecated_foo' , $definition );
$builder -> get ( 'deprecated_foo' );
2015-08-10 11:33:01 +01:00
}
2010-05-06 12:25:53 +01:00
public function testRegister ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo' , 'Bar\FooClass' );
2010-05-06 12:25:53 +01:00
$this -> assertTrue ( $builder -> hasDefinition ( 'foo' ), '->register() registers a new service definition' );
2010-08-20 22:09:55 +01:00
$this -> assertInstanceOf ( 'Symfony\Component\DependencyInjection\Definition' , $builder -> getDefinition ( 'foo' ), '->register() returns the newly created Definition instance' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2016-11-26 16:34:50 +00:00
public function testAutowire ()
{
$builder = new ContainerBuilder ();
$builder -> autowire ( 'foo' , 'Bar\FooClass' );
$this -> assertTrue ( $builder -> hasDefinition ( 'foo' ), '->autowire() registers a new service definition' );
$this -> assertTrue ( $builder -> getDefinition ( 'foo' ) -> isAutowired (), '->autowire() creates autowired definitions' );
}
2010-06-27 17:28:29 +01:00
public function testHas ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-06-27 17:28:29 +01:00
$this -> assertFalse ( $builder -> has ( 'foo' ), '->has() returns false if the service does not exist' );
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo' , 'Bar\FooClass' );
2010-06-27 17:28:29 +01:00
$this -> assertTrue ( $builder -> has ( 'foo' ), '->has() returns true if a service definition exists' );
$builder -> set ( 'bar' , new \stdClass ());
$this -> assertTrue ( $builder -> has ( 'bar' ), '->has() returns true if a service exists' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2016-05-05 07:52:44 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
* @ expectedExceptionMessage You have requested a non - existent service " foo " .
*/
public function testGetThrowsExceptionIfServiceDoesNotExist ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2016-05-05 07:52:44 +01:00
$builder -> get ( 'foo' );
}
public function testGetReturnsNullIfServiceDoesNotExistAndInvalidReferenceIsUsed ()
{
$builder = new ContainerBuilder ();
2010-06-27 17:28:29 +01:00
$this -> assertNull ( $builder -> get ( 'foo' , ContainerInterface :: NULL_ON_INVALID_REFERENCE ), '->get() returns null if the service does not exist and NULL_ON_INVALID_REFERENCE is passed as a second argument' );
2016-05-05 07:52:44 +01:00
}
2010-06-27 17:28:29 +01:00
2016-05-05 07:52:44 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testGetThrowsCircularReferenceExceptionIfServiceHasReferenceToItself ()
{
$builder = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$builder -> register ( 'baz' , 'stdClass' ) -> setArguments ([ new Reference ( 'baz' )]);
2016-05-05 07:52:44 +01:00
$builder -> get ( 'baz' );
}
public function testGetReturnsSameInstanceWhenServiceIsShared ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'bar' , 'stdClass' );
$this -> assertTrue ( $builder -> get ( 'bar' ) === $builder -> get ( 'bar' ), '->get() always returns the same instance if the service is shared' );
}
public function testGetCreatesServiceBasedOnDefinition ()
{
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'foo' , 'stdClass' );
2016-05-05 07:52:44 +01:00
2019-08-01 08:31:22 +01:00
$this -> assertIsObject ( $builder -> get ( 'foo' ), '->get() returns the service definition associated with the id' );
2016-05-05 07:52:44 +01:00
}
public function testGetReturnsRegisteredService ()
{
$builder = new ContainerBuilder ();
2010-06-27 17:28:29 +01:00
$builder -> set ( 'bar' , $bar = new \stdClass ());
2010-05-06 12:25:53 +01:00
2016-05-05 07:52:44 +01:00
$this -> assertSame ( $bar , $builder -> get ( 'bar' ), '->get() returns the service associated with the id' );
}
2010-05-06 12:25:53 +01:00
2016-05-05 07:52:44 +01:00
public function testRegisterDoesNotOverrideExistingService ()
{
$builder = new ContainerBuilder ();
$builder -> set ( 'bar' , $bar = new \stdClass ());
$builder -> register ( 'bar' , 'stdClass' );
$this -> assertSame ( $bar , $builder -> get ( 'bar' ), '->get() returns the service associated with the id even if a definition has been defined' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2015-06-15 03:41:59 +01:00
public function testNonSharedServicesReturnsDifferentInstances ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'bar' , 'stdClass' ) -> setShared ( false );
$this -> assertNotSame ( $builder -> get ( 'bar' ), $builder -> get ( 'bar' ));
}
2019-04-02 18:55:56 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @ dataProvider provideBadId
*/
public function testBadAliasId ( $id )
{
$builder = new ContainerBuilder ();
$builder -> setAlias ( $id , 'foo' );
}
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @ dataProvider provideBadId
*/
public function testBadDefinitionId ( $id )
{
$builder = new ContainerBuilder ();
$builder -> setDefinition ( $id , new Definition ( 'Foo' ));
}
public function provideBadId ()
{
return [
[ '' ],
[ " \0 " ],
[ " \r " ],
[ " \n " ],
[ " ' " ],
[ 'ab\\' ],
];
}
2013-03-06 16:38:10 +00:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @ expectedExceptionMessage You have requested a synthetic service ( " foo " ) . The DIC does not know how to construct this service .
*/
2013-03-06 16:55:57 +00:00
public function testGetUnsetLoadingServiceWhenCreateServiceThrowsAnException ()
2013-03-06 16:38:10 +00:00
{
$builder = new ContainerBuilder ();
$builder -> register ( 'foo' , 'stdClass' ) -> setSynthetic ( true );
// we expect a RuntimeException here as foo is synthetic
try {
$builder -> get ( 'foo' );
} catch ( RuntimeException $e ) {
}
// we must also have the same RuntimeException here
$builder -> get ( 'foo' );
}
2010-05-06 12:25:53 +01:00
public function testGetServiceIds ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'foo' , 'stdClass' );
$builder -> bar = $bar = new \stdClass ();
$builder -> register ( 'bar' , 'stdClass' );
2017-02-16 11:05:13 +00:00
$this -> assertEquals (
2019-01-16 09:39:14 +00:00
[
2017-02-16 11:05:13 +00:00
'service_container' ,
'foo' ,
'bar' ,
'Psr\Container\ContainerInterface' ,
'Symfony\Component\DependencyInjection\ContainerInterface' ,
2019-01-16 09:39:14 +00:00
],
2017-02-16 11:05:13 +00:00
$builder -> getServiceIds (),
'->getServiceIds() returns all defined service ids'
);
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
public function testAliases ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'foo' , 'stdClass' );
$builder -> setAlias ( 'bar' , 'foo' );
$this -> assertTrue ( $builder -> hasAlias ( 'bar' ), '->hasAlias() returns true if the alias exists' );
$this -> assertFalse ( $builder -> hasAlias ( 'foobar' ), '->hasAlias() returns false if the alias does not exist' );
2011-01-07 14:44:29 +00:00
$this -> assertEquals ( 'foo' , ( string ) $builder -> getAlias ( 'bar' ), '->getAlias() returns the aliased service' );
2010-06-27 17:28:29 +01:00
$this -> assertTrue ( $builder -> has ( 'bar' ), '->setAlias() defines a new service' );
2017-12-11 21:55:31 +00:00
$this -> assertSame ( $builder -> get ( 'bar' ), $builder -> get ( 'foo' ), '->setAlias() creates a service that is an alias to another one' );
2010-05-06 12:25:53 +01:00
2015-04-25 17:37:49 +01:00
try {
$builder -> setAlias ( 'foobar' , 'foobar' );
$this -> fail ( '->setAlias() throws an InvalidArgumentException if the alias references itself' );
} catch ( \InvalidArgumentException $e ) {
$this -> assertEquals ( 'An alias can not reference itself, got a circular reference on "foobar".' , $e -> getMessage (), '->setAlias() throws an InvalidArgumentException if the alias references itself' );
}
2010-05-07 15:09:11 +01:00
try {
2010-05-06 12:25:53 +01:00
$builder -> getAlias ( 'foobar' );
$this -> fail ( '->getAlias() throws an InvalidArgumentException if the alias does not exist' );
2010-11-26 21:25:31 +00:00
} catch ( \InvalidArgumentException $e ) {
2010-05-06 12:25:53 +01:00
$this -> assertEquals ( 'The service alias "foobar" does not exist.' , $e -> getMessage (), '->getAlias() throws an InvalidArgumentException if the alias does not exist' );
}
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
public function testGetAliases ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> setAlias ( 'bar' , 'foo' );
$builder -> setAlias ( 'foobar' , 'foo' );
2011-01-07 14:44:29 +00:00
$builder -> setAlias ( 'moo' , new Alias ( 'foo' , false ));
$aliases = $builder -> getAliases ();
$this -> assertEquals ( 'foo' , ( string ) $aliases [ 'bar' ]);
$this -> assertTrue ( $aliases [ 'bar' ] -> isPublic ());
$this -> assertEquals ( 'foo' , ( string ) $aliases [ 'foobar' ]);
$this -> assertEquals ( 'foo' , ( string ) $aliases [ 'moo' ]);
$this -> assertFalse ( $aliases [ 'moo' ] -> isPublic ());
2010-05-06 12:25:53 +01:00
$builder -> register ( 'bar' , 'stdClass' );
2011-01-07 14:44:29 +00:00
$this -> assertFalse ( $builder -> hasAlias ( 'bar' ));
2010-06-27 17:28:29 +01:00
$builder -> set ( 'foobar' , 'stdClass' );
2011-01-07 14:44:29 +00:00
$builder -> set ( 'moo' , 'stdClass' );
2017-03-21 17:12:21 +00:00
$this -> assertCount ( 2 , $builder -> getAliases (), '->getAliases() does not return aliased services that have been overridden' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2010-06-27 17:28:29 +01:00
public function testSetAliases ()
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$builder -> setAliases ([ 'bar' => 'foo' , 'foobar' => 'foo' ]);
2011-01-07 14:44:29 +00:00
$aliases = $builder -> getAliases ();
2017-12-11 21:55:31 +00:00
$this -> assertArrayHasKey ( 'bar' , $aliases );
$this -> assertArrayHasKey ( 'foobar' , $aliases );
2010-06-27 17:28:29 +01:00
}
public function testAddAliases ()
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$builder -> setAliases ([ 'bar' => 'foo' ]);
$builder -> addAliases ([ 'foobar' => 'foo' ]);
2011-01-07 14:44:29 +00:00
$aliases = $builder -> getAliases ();
2017-12-11 21:55:31 +00:00
$this -> assertArrayHasKey ( 'bar' , $aliases );
$this -> assertArrayHasKey ( 'foobar' , $aliases );
2010-06-27 17:28:29 +01:00
}
2016-02-09 19:58:01 +00:00
public function testSetReplacesAlias ()
{
$builder = new ContainerBuilder ();
$builder -> setAlias ( 'alias' , 'aliased' );
$builder -> set ( 'aliased' , new \stdClass ());
$builder -> set ( 'alias' , $foo = new \stdClass ());
$this -> assertSame ( $foo , $builder -> get ( 'alias' ), '->set() replaces an existing alias' );
}
2016-11-22 18:19:49 +00:00
public function testAliasesKeepInvalidBehavior ()
{
$builder = new ContainerBuilder ();
$aliased = new Definition ( 'stdClass' );
2019-01-16 09:39:14 +00:00
$aliased -> addMethodCall ( 'setBar' , [ new Reference ( 'bar' , ContainerInterface :: IGNORE_ON_INVALID_REFERENCE )]);
2016-11-22 18:19:49 +00:00
$builder -> setDefinition ( 'aliased' , $aliased );
$builder -> setAlias ( 'alias' , 'aliased' );
$this -> assertEquals ( new \stdClass (), $builder -> get ( 'alias' ));
}
2011-02-20 12:23:32 +00:00
public function testAddGetCompilerPass ()
{
$builder = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$builder -> setResourceTracking ( false );
2016-03-05 12:39:12 +00:00
$defaultPasses = $builder -> getCompiler () -> getPassConfig () -> getPasses ();
2016-12-19 16:09:34 +00:00
$builder -> addCompilerPass ( $pass1 = $this -> getMockBuilder ( 'Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface' ) -> getMock (), PassConfig :: TYPE_BEFORE_OPTIMIZATION , - 5 );
$builder -> addCompilerPass ( $pass2 = $this -> getMockBuilder ( 'Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface' ) -> getMock (), PassConfig :: TYPE_BEFORE_OPTIMIZATION , 10 );
2016-03-05 12:39:12 +00:00
$passes = $builder -> getCompiler () -> getPassConfig () -> getPasses ();
2018-07-26 09:45:46 +01:00
$this -> assertCount ( \count ( $passes ) - 2 , $defaultPasses );
2016-03-05 12:39:12 +00:00
// Pass 1 is executed later
$this -> assertTrue ( array_search ( $pass1 , $passes , true ) > array_search ( $pass2 , $passes , true ));
2011-02-20 12:23:32 +00:00
}
2010-05-06 12:25:53 +01:00
public function testCreateService ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> setFile ( __DIR__ . '/Fixtures/includes/foo.php' );
$builder -> register ( 'foo2' , 'Bar\FooClass' ) -> setFile ( __DIR__ . '/Fixtures/includes/%file%.php' );
2010-05-06 12:25:53 +01:00
$builder -> setParameter ( 'file' , 'foo' );
2016-05-05 07:52:44 +01:00
$this -> assertInstanceOf ( '\Bar\FooClass' , $builder -> get ( 'foo1' ), '->createService() requires the file defined by the service definition' );
2013-12-18 17:52:54 +00:00
$this -> assertInstanceOf ( '\Bar\FooClass' , $builder -> get ( 'foo2' ), '->createService() replaces parameters in the file provided by the service definition' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2013-03-29 23:21:12 +00:00
public function testCreateProxyWithRealServiceInstantiator ()
{
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> setFile ( __DIR__ . '/Fixtures/includes/foo.php' );
2013-03-29 23:21:12 +00:00
$builder -> getDefinition ( 'foo1' ) -> setLazy ( true );
$foo1 = $builder -> get ( 'foo1' );
$this -> assertSame ( $foo1 , $builder -> get ( 'foo1' ), 'The same proxy is retrieved on multiple subsequent calls' );
2018-07-05 12:24:53 +01:00
$this -> assertSame ( 'Bar\FooClass' , \get_class ( $foo1 ));
2013-03-29 23:21:12 +00:00
}
2010-05-06 12:25:53 +01:00
public function testCreateServiceClass ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'foo1' , '%class%' );
$builder -> setParameter ( 'class' , 'stdClass' );
2010-06-27 17:28:29 +01:00
$this -> assertInstanceOf ( '\stdClass' , $builder -> get ( 'foo1' ), '->createService() replaces parameters in the class provided by the service definition' );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
public function testCreateServiceArguments ()
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'bar' , 'stdClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> addArgument ([ 'foo' => '%value%' , '%value%' => 'foo' , new Reference ( 'bar' ), '%%unescape_it%%' ]);
2010-05-06 12:25:53 +01:00
$builder -> setParameter ( 'value' , 'bar' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'foo' => 'bar' , 'bar' => 'foo' , $builder -> get ( 'bar' ), '%unescape_it%' ], $builder -> get ( 'foo1' ) -> arguments , '->createService() replaces parameters and service references in the arguments provided by the service definition' );
2010-05-06 12:25:53 +01:00
}
2010-03-18 07:48:03 +00:00
2014-09-27 17:06:30 +01:00
public function testCreateServiceFactory ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'foo' , 'Bar\FooClass' ) -> setFactory ( 'Bar\FooClass::getInstance' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'qux' , 'Bar\FooClass' ) -> setFactory ([ 'Bar\FooClass' , 'getInstance' ]);
$builder -> register ( 'bar' , 'Bar\FooClass' ) -> setFactory ([ new Definition ( 'Bar\FooClass' ), 'getInstance' ]);
$builder -> register ( 'baz' , 'Bar\FooClass' ) -> setFactory ([ new Reference ( 'bar' ), 'getInstance' ]);
2014-09-27 17:06:30 +01:00
$this -> assertTrue ( $builder -> get ( 'foo' ) -> called , '->createService() calls the factory method to create the service instance' );
$this -> assertTrue ( $builder -> get ( 'qux' ) -> called , '->createService() calls the factory method to create the service instance' );
$this -> assertTrue ( $builder -> get ( 'bar' ) -> called , '->createService() uses anonymous service as factory' );
$this -> assertTrue ( $builder -> get ( 'baz' ) -> called , '->createService() uses another service as factory' );
}
2010-05-06 12:25:53 +01:00
public function testCreateServiceMethodCalls ()
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder -> register ( 'bar' , 'stdClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> addMethodCall ( 'setBar' , [[ '%value%' , new Reference ( 'bar' )]]);
2010-05-06 12:25:53 +01:00
$builder -> setParameter ( 'value' , 'bar' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'bar' , $builder -> get ( 'bar' )], $builder -> get ( 'foo1' ) -> bar , '->createService() replaces the values in the method calls arguments' );
2010-05-06 12:25:53 +01:00
}
2010-03-18 07:48:03 +00:00
2015-10-20 13:28:37 +01:00
public function testCreateServiceMethodCallsWithEscapedParam ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'bar' , 'stdClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> addMethodCall ( 'setBar' , [[ '%%unescape_it%%' ]]);
2015-10-20 13:28:37 +01:00
$builder -> setParameter ( 'value' , 'bar' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ '%unescape_it%' ], $builder -> get ( 'foo1' ) -> bar , '->createService() replaces the values in the method calls arguments' );
2015-10-20 13:28:37 +01:00
}
public function testCreateServiceProperties ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'bar' , 'stdClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> setProperty ( 'bar' , [ '%value%' , new Reference ( 'bar' ), '%%unescape_it%%' ]);
2015-10-20 13:28:37 +01:00
$builder -> setParameter ( 'value' , 'bar' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'bar' , $builder -> get ( 'bar' ), '%unescape_it%' ], $builder -> get ( 'foo1' ) -> bar , '->createService() replaces the values in the properties' );
2015-10-20 13:28:37 +01:00
}
2010-05-06 12:25:53 +01:00
public function testCreateServiceConfigurator ()
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo1' , 'Bar\FooClass' ) -> setConfigurator ( 'sc_configure' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo2' , 'Bar\FooClass' ) -> setConfigurator ([ '%class%' , 'configureStatic' ]);
2010-05-06 12:25:53 +01:00
$builder -> setParameter ( 'class' , 'BazClass' );
$builder -> register ( 'baz' , 'BazClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo3' , 'Bar\FooClass' ) -> setConfigurator ([ new Reference ( 'baz' ), 'configure' ]);
$builder -> register ( 'foo4' , 'Bar\FooClass' ) -> setConfigurator ([ $builder -> getDefinition ( 'baz' ), 'configure' ]);
2016-05-05 07:52:44 +01:00
$builder -> register ( 'foo5' , 'Bar\FooClass' ) -> setConfigurator ( 'foo' );
$this -> assertTrue ( $builder -> get ( 'foo1' ) -> configured , '->createService() calls the configurator' );
$this -> assertTrue ( $builder -> get ( 'foo2' ) -> configured , '->createService() calls the configurator' );
$this -> assertTrue ( $builder -> get ( 'foo3' ) -> configured , '->createService() calls the configurator' );
2015-06-02 14:43:57 +01:00
$this -> assertTrue ( $builder -> get ( 'foo4' ) -> configured , '->createService() calls the configurator' );
2010-05-07 15:09:11 +01:00
try {
2015-06-02 14:43:57 +01:00
$builder -> get ( 'foo5' );
2010-05-06 12:25:53 +01:00
$this -> fail ( '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable' );
2010-11-26 21:25:31 +00:00
} catch ( \InvalidArgumentException $e ) {
2013-12-18 17:52:54 +00:00
$this -> assertEquals ( 'The configure callable for class "Bar\FooClass" is not a callable.' , $e -> getMessage (), '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable' );
2010-05-06 12:25:53 +01:00
}
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2016-12-13 17:37:51 +00:00
public function testCreateServiceWithIteratorArgument ()
{
$builder = new ContainerBuilder ();
$builder -> register ( 'bar' , 'stdClass' );
$builder
-> register ( 'lazy_context' , 'LazyContext' )
2019-01-16 09:39:14 +00:00
-> setArguments ([
new IteratorArgument ([ 'k1' => new Reference ( 'bar' ), new Reference ( 'invalid' , ContainerInterface :: IGNORE_ON_INVALID_REFERENCE )]),
new IteratorArgument ([]),
])
2016-12-13 17:37:51 +00:00
;
$lazyContext = $builder -> get ( 'lazy_context' );
$this -> assertInstanceOf ( RewindableGenerator :: class , $lazyContext -> lazyValues );
2017-05-19 22:03:53 +01:00
$this -> assertInstanceOf ( RewindableGenerator :: class , $lazyContext -> lazyEmptyValues );
2017-01-29 19:10:36 +00:00
$this -> assertCount ( 1 , $lazyContext -> lazyValues );
2017-05-19 22:03:53 +01:00
$this -> assertCount ( 0 , $lazyContext -> lazyEmptyValues );
2016-12-13 17:37:51 +00:00
$i = 0 ;
foreach ( $lazyContext -> lazyValues as $k => $v ) {
++ $i ;
$this -> assertEquals ( 'k1' , $k );
$this -> assertInstanceOf ( '\stdClass' , $v );
}
// The second argument should have been ignored.
$this -> assertEquals ( 1 , $i );
2017-05-19 22:03:53 +01:00
$i = 0 ;
foreach ( $lazyContext -> lazyEmptyValues as $k => $v ) {
++ $i ;
}
$this -> assertEquals ( 0 , $i );
2016-12-13 17:37:51 +00:00
}
2013-01-21 22:08:41 +00:00
/**
* @ expectedException \RuntimeException
*/
public function testCreateSyntheticService ()
{
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo' , 'Bar\FooClass' ) -> setSynthetic ( true );
2013-01-21 22:08:41 +00:00
$builder -> get ( 'foo' );
}
2013-09-02 11:46:47 +01:00
public function testCreateServiceWithExpression ()
{
$builder = new ContainerBuilder ();
$builder -> setParameter ( 'bar' , 'bar' );
$builder -> register ( 'bar' , 'BarClass' );
2019-01-16 09:39:14 +00:00
$builder -> register ( 'foo' , 'Bar\FooClass' ) -> addArgument ([ 'foo' => new Expression ( 'service("bar").foo ~ parameter("bar")' )]);
2013-09-02 11:46:47 +01:00
$this -> assertEquals ( 'foobar' , $builder -> get ( 'foo' ) -> arguments [ 'foo' ]);
}
2010-05-06 12:25:53 +01:00
public function testResolveServices ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$builder -> register ( 'foo' , 'Bar\FooClass' );
2010-06-27 17:28:29 +01:00
$this -> assertEquals ( $builder -> get ( 'foo' ), $builder -> resolveServices ( new Reference ( 'foo' )), '->resolveServices() resolves service references to service instances' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'foo' => [ 'foo' , $builder -> get ( 'foo' )]], $builder -> resolveServices ([ 'foo' => [ 'foo' , new Reference ( 'foo' )]]), '->resolveServices() resolves service references to service instances in nested arrays' );
2013-09-02 11:46:47 +01:00
$this -> assertEquals ( $builder -> get ( 'foo' ), $builder -> resolveServices ( new Expression ( 'service("foo")' )), '->resolveServices() resolves expressions' );
2010-03-18 07:48:03 +00:00
}
2016-11-17 00:37:44 +00:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
2016-11-24 10:37:50 +00:00
* @ expectedExceptionMessage Constructing service " foo " from a parent definition is not supported at build time .
2016-11-17 00:37:44 +00:00
*/
public function testResolveServicesWithDecoratedDefinition ()
{
$builder = new ContainerBuilder ();
$builder -> setDefinition ( 'grandpa' , new Definition ( 'stdClass' ));
2016-11-28 07:50:06 +00:00
$builder -> setDefinition ( 'parent' , new ChildDefinition ( 'grandpa' ));
$builder -> setDefinition ( 'foo' , new ChildDefinition ( 'parent' ));
2016-11-17 00:37:44 +00:00
$builder -> get ( 'foo' );
}
2016-11-23 17:45:56 +00:00
public function testResolveServicesWithCustomDefinitionClass ()
{
$builder = new ContainerBuilder ();
$builder -> setDefinition ( 'foo' , new CustomDefinition ( 'stdClass' ));
$this -> assertInstanceOf ( 'stdClass' , $builder -> get ( 'foo' ));
}
2010-05-06 12:25:53 +01:00
public function testMerge ()
2010-03-18 07:48:03 +00:00
{
2019-01-16 09:39:14 +00:00
$container = new ContainerBuilder ( new ParameterBag ([ 'bar' => 'foo' ]));
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2019-01-16 09:39:14 +00:00
$config = new ContainerBuilder ( new ParameterBag ([ 'foo' => 'bar' ]));
2010-05-06 12:25:53 +01:00
$container -> merge ( $config );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'bar' => 'foo' , 'foo' => 'bar' ], $container -> getParameterBag () -> all (), '->merge() merges current parameters with the loaded ones' );
2010-05-06 12:25:53 +01:00
2019-01-16 09:39:14 +00:00
$container = new ContainerBuilder ( new ParameterBag ([ 'bar' => 'foo' ]));
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2019-01-16 09:39:14 +00:00
$config = new ContainerBuilder ( new ParameterBag ([ 'foo' => '%bar%' ]));
2010-05-06 12:25:53 +01:00
$container -> merge ( $config );
2011-01-16 07:12:36 +00:00
$container -> compile ();
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'bar' => 'foo' , 'foo' => 'foo' ], $container -> getParameterBag () -> all (), '->merge() evaluates the values of the parameters towards already defined ones' );
2010-05-06 12:25:53 +01:00
2019-01-16 09:39:14 +00:00
$container = new ContainerBuilder ( new ParameterBag ([ 'bar' => 'foo' ]));
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2019-01-16 09:39:14 +00:00
$config = new ContainerBuilder ( new ParameterBag ([ 'foo' => '%bar%' , 'baz' => '%foo%' ]));
2010-05-06 12:25:53 +01:00
$container -> merge ( $config );
2011-01-16 07:12:36 +00:00
$container -> compile ();
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'bar' => 'foo' , 'foo' => 'foo' , 'baz' => 'foo' ], $container -> getParameterBag () -> all (), '->merge() evaluates the values of the parameters towards already defined ones' );
2010-05-06 12:25:53 +01:00
2010-07-15 14:11:33 +01:00
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2013-12-18 17:52:54 +00:00
$container -> register ( 'foo' , 'Bar\FooClass' );
2010-05-06 12:25:53 +01:00
$container -> register ( 'bar' , 'BarClass' );
2010-07-15 14:11:33 +01:00
$config = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$config -> setDefinition ( 'baz' , new Definition ( 'BazClass' ));
$config -> setAlias ( 'alias_for_foo' , 'foo' );
$container -> merge ( $config );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'service_container' , 'foo' , 'bar' , 'baz' ], array_keys ( $container -> getDefinitions ()), '->merge() merges definitions already defined ones' );
2011-01-07 14:44:29 +00:00
$aliases = $container -> getAliases ();
2017-12-11 21:55:31 +00:00
$this -> assertArrayHasKey ( 'alias_for_foo' , $aliases );
2011-01-07 14:44:29 +00:00
$this -> assertEquals ( 'foo' , ( string ) $aliases [ 'alias_for_foo' ]);
2010-05-06 12:25:53 +01:00
2010-07-15 14:11:33 +01:00
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2013-12-18 17:52:54 +00:00
$container -> register ( 'foo' , 'Bar\FooClass' );
2010-05-06 12:25:53 +01:00
$config -> setDefinition ( 'foo' , new Definition ( 'BazClass' ));
$container -> merge ( $config );
$this -> assertEquals ( 'BazClass' , $container -> getDefinition ( 'foo' ) -> getClass (), '->merge() overrides already defined services' );
2016-08-12 19:34:27 +01:00
$container = new ContainerBuilder ();
$bag = new EnvPlaceholderParameterBag ();
$bag -> get ( 'env(Foo)' );
$config = new ContainerBuilder ( $bag );
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ '%env(Bar)%' ], $config -> resolveEnvPlaceholders ([ $bag -> get ( 'env(Bar)' )]));
2016-08-12 19:34:27 +01:00
$container -> merge ( $config );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'Foo' => 0 , 'Bar' => 1 ], $container -> getEnvCounters ());
2017-03-31 11:45:36 +01:00
$container = new ContainerBuilder ();
$config = new ContainerBuilder ();
$childDefA = $container -> registerForAutoconfiguration ( 'AInterface' );
$childDefB = $config -> registerForAutoconfiguration ( 'BInterface' );
$container -> merge ( $config );
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'AInterface' => $childDefA , 'BInterface' => $childDefB ], $container -> getAutoconfiguredInstanceof ());
2017-03-31 11:45:36 +01:00
}
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
2017-04-20 18:21:47 +01:00
* @ expectedExceptionMessage " AInterface " has already been autoconfigured and merge () does not support merging autoconfiguration for the same class / interface .
2017-03-31 11:45:36 +01:00
*/
public function testMergeThrowsExceptionForDuplicateAutomaticInstanceofDefinitions ()
{
$container = new ContainerBuilder ();
$config = new ContainerBuilder ();
$container -> registerForAutoconfiguration ( 'AInterface' );
$config -> registerForAutoconfiguration ( 'AInterface' );
$container -> merge ( $config );
2010-03-18 07:48:03 +00:00
}
2010-05-06 12:25:53 +01:00
2016-11-24 09:31:58 +00:00
public function testResolveEnvValues ()
{
$_ENV [ 'DUMMY_ENV_VAR' ] = 'du%%y' ;
2017-08-16 09:13:36 +01:00
$_SERVER [ 'DUMMY_SERVER_VAR' ] = 'ABC' ;
$_SERVER [ 'HTTP_DUMMY_VAR' ] = 'DEF' ;
2016-11-24 09:31:58 +00:00
$container = new ContainerBuilder ();
2017-08-16 09:13:36 +01:00
$container -> setParameter ( 'bar' , '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%' );
$container -> setParameter ( 'env(HTTP_DUMMY_VAR)' , '123' );
2016-11-24 09:31:58 +00:00
2017-08-16 09:13:36 +01:00
$this -> assertSame ( '%% du%%%%y ABC 123' , $container -> resolveEnvPlaceholders ( '%bar%' , true ));
2016-11-24 09:31:58 +00:00
2017-08-16 09:13:36 +01:00
unset ( $_ENV [ 'DUMMY_ENV_VAR' ], $_SERVER [ 'DUMMY_SERVER_VAR' ], $_SERVER [ 'HTTP_DUMMY_VAR' ]);
2016-11-24 09:31:58 +00:00
}
2017-12-05 12:50:29 +00:00
public function testResolveEnvValuesWithArray ()
{
$_ENV [ 'ANOTHER_DUMMY_ENV_VAR' ] = 'dummy' ;
2019-01-16 09:39:14 +00:00
$dummyArray = [ '1' => 'one' , '2' => 'two' ];
2017-12-05 12:50:29 +00:00
$container = new ContainerBuilder ();
$container -> setParameter ( 'dummy' , '%env(ANOTHER_DUMMY_ENV_VAR)%' );
$container -> setParameter ( 'dummy2' , $dummyArray );
$container -> resolveEnvPlaceholders ( '%dummy%' , true );
$container -> resolveEnvPlaceholders ( '%dummy2%' , true );
2019-08-01 08:31:22 +01:00
$this -> assertIsArray ( $container -> resolveEnvPlaceholders ( '%dummy2%' , true ));
2017-12-05 12:50:29 +00:00
foreach ( $dummyArray as $key => $value ) {
$this -> assertArrayHasKey ( $key , $container -> resolveEnvPlaceholders ( '%dummy2%' , true ));
}
unset ( $_ENV [ 'ANOTHER_DUMMY_ENV_VAR' ]);
}
2017-01-29 18:27:06 +00:00
public function testCompileWithResolveEnv ()
{
2017-08-16 09:13:36 +01:00
putenv ( 'DUMMY_ENV_VAR=du%%y' );
$_SERVER [ 'DUMMY_SERVER_VAR' ] = 'ABC' ;
$_SERVER [ 'HTTP_DUMMY_VAR' ] = 'DEF' ;
2017-01-29 18:27:06 +00:00
$container = new ContainerBuilder ();
$container -> setParameter ( 'env(FOO)' , 'Foo' );
2017-08-18 16:51:40 +01:00
$container -> setParameter ( 'env(DUMMY_ENV_VAR)' , 'GHI' );
2017-08-16 09:13:36 +01:00
$container -> setParameter ( 'bar' , '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%' );
2017-01-29 18:27:06 +00:00
$container -> setParameter ( 'foo' , '%env(FOO)%' );
2017-08-16 09:13:36 +01:00
$container -> setParameter ( 'baz' , '%foo%' );
$container -> setParameter ( 'env(HTTP_DUMMY_VAR)' , '123' );
2017-08-18 16:51:40 +01:00
$container -> register ( 'teatime' , 'stdClass' )
-> setProperty ( 'foo' , '%env(DUMMY_ENV_VAR)%' )
2017-09-19 21:53:21 +01:00
-> setPublic ( true )
2017-08-18 16:51:40 +01:00
;
2017-01-29 18:27:06 +00:00
$container -> compile ( true );
2017-08-16 09:13:36 +01:00
$this -> assertSame ( '% du%%y ABC 123' , $container -> getParameter ( 'bar' ));
$this -> assertSame ( 'Foo' , $container -> getParameter ( 'baz' ));
2017-08-18 16:51:40 +01:00
$this -> assertSame ( 'du%%y' , $container -> get ( 'teatime' ) -> foo );
2017-01-29 18:27:06 +00:00
2017-08-16 09:13:36 +01:00
unset ( $_SERVER [ 'DUMMY_SERVER_VAR' ], $_SERVER [ 'HTTP_DUMMY_VAR' ]);
putenv ( 'DUMMY_ENV_VAR' );
2017-01-29 18:27:06 +00:00
}
2018-05-14 18:29:05 +01:00
public function testCompileWithArrayResolveEnv ()
{
putenv ( 'ARRAY={"foo":"bar"}' );
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , '%env(json:ARRAY)%' );
$container -> compile ( true );
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'foo' => 'bar' ], $container -> getParameter ( 'foo' ));
2018-05-14 18:29:05 +01:00
putenv ( 'ARRAY' );
}
public function testCompileWithArrayAndAnotherResolveEnv ()
{
putenv ( 'DUMMY_ENV_VAR=abc' );
putenv ( 'ARRAY={"foo":"bar"}' );
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , '%env(json:ARRAY)%' );
$container -> setParameter ( 'bar' , '%env(DUMMY_ENV_VAR)%' );
$container -> compile ( true );
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'foo' => 'bar' ], $container -> getParameter ( 'foo' ));
2018-05-14 18:29:05 +01:00
$this -> assertSame ( 'abc' , $container -> getParameter ( 'bar' ));
putenv ( 'DUMMY_ENV_VAR' );
putenv ( 'ARRAY' );
}
2017-08-18 16:51:40 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
2018-05-14 18:29:05 +01:00
* @ expectedExceptionMessage A string value must be composed of strings and / or numbers , but found parameter " env(json:ARRAY) " of type array inside string value " ABC %env(json:ARRAY)% " .
2017-08-18 16:51:40 +01:00
*/
2018-05-14 18:29:05 +01:00
public function testCompileWithArrayInStringResolveEnv ()
2017-08-18 16:51:40 +01:00
{
2018-05-14 18:29:05 +01:00
putenv ( 'ARRAY={"foo":"bar"}' );
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , 'ABC %env(json:ARRAY)%' );
2017-08-18 16:51:40 +01:00
$container -> compile ( true );
2018-05-14 18:29:05 +01:00
putenv ( 'ARRAY' );
2017-08-18 16:51:40 +01:00
}
2017-01-29 18:27:06 +00:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\EnvNotFoundException
* @ expectedExceptionMessage Environment variable not found : " FOO " .
*/
public function testCompileWithResolveMissingEnv ()
{
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , '%env(FOO)%' );
$container -> compile ( true );
}
2016-10-22 17:25:15 +01:00
public function testDynamicEnv ()
{
putenv ( 'DUMMY_FOO=some%foo%' );
putenv ( 'DUMMY_BAR=%bar%' );
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , 'Foo%env(resolve:DUMMY_BAR)%' );
$container -> setParameter ( 'bar' , 'Bar' );
$container -> setParameter ( 'baz' , '%env(resolve:DUMMY_FOO)%' );
$container -> compile ( true );
putenv ( 'DUMMY_FOO' );
putenv ( 'DUMMY_BAR' );
$this -> assertSame ( 'someFooBar' , $container -> getParameter ( 'baz' ));
}
public function testCastEnv ()
{
$container = new ContainerBuilder ();
$container -> setParameter ( 'env(FAKE)' , '123' );
2017-09-19 21:53:21 +01:00
$container -> register ( 'foo' , 'stdClass' )
-> setPublic ( true )
2019-01-16 09:39:14 +00:00
-> setProperties ([
2017-09-19 21:53:21 +01:00
'fake' => '%env(int:FAKE)%' ,
2019-01-16 09:39:14 +00:00
]);
2016-10-22 17:25:15 +01:00
$container -> compile ( true );
$this -> assertSame ( 123 , $container -> get ( 'foo' ) -> fake );
}
public function testEnvAreNullable ()
{
$container = new ContainerBuilder ();
$container -> setParameter ( 'env(FAKE)' , null );
2017-09-19 21:53:21 +01:00
$container -> register ( 'foo' , 'stdClass' )
-> setPublic ( true )
2019-01-16 09:39:14 +00:00
-> setProperties ([
2016-10-22 17:25:15 +01:00
'fake' => '%env(int:FAKE)%' ,
2019-01-16 09:39:14 +00:00
]);
2016-10-22 17:25:15 +01:00
$container -> compile ( true );
$this -> assertNull ( $container -> get ( 'foo' ) -> fake );
}
2017-11-24 11:48:20 +00:00
public function testEnvInId ()
{
$container = include __DIR__ . '/Fixtures/containers/container_env_in_id.php' ;
$container -> compile ( true );
2019-01-16 09:39:14 +00:00
$expected = [
2017-11-24 11:48:20 +00:00
'service_container' ,
'foo' ,
'bar' ,
'bar_%env(BAR)%' ,
2019-01-16 09:39:14 +00:00
];
2017-11-24 11:48:20 +00:00
$this -> assertSame ( $expected , array_keys ( $container -> getDefinitions ()));
2019-01-16 09:39:14 +00:00
$expected = [
2017-11-24 14:13:49 +00:00
PsrContainerInterface :: class => true ,
ContainerInterface :: class => true ,
'baz_%env(BAR)%' => true ,
2017-12-01 11:51:22 +00:00
'bar_%env(BAR)%' => true ,
2019-01-16 09:39:14 +00:00
];
2017-11-24 14:13:49 +00:00
$this -> assertSame ( $expected , $container -> getRemovedIds ());
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'baz_bar' ], array_keys ( $container -> getDefinition ( 'foo' ) -> getArgument ( 1 )));
2017-11-24 11:48:20 +00:00
}
2016-10-22 17:25:15 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException
* @ expectedExceptionMessage Circular reference detected for parameter " env(resolve:DUMMY_ENV_VAR) " ( " env(resolve:DUMMY_ENV_VAR) " > " env(resolve:DUMMY_ENV_VAR) " ) .
*/
public function testCircularDynamicEnv ()
{
putenv ( 'DUMMY_ENV_VAR=some%foo%' );
$container = new ContainerBuilder ();
$container -> setParameter ( 'foo' , '%bar%' );
$container -> setParameter ( 'bar' , '%env(resolve:DUMMY_ENV_VAR)%' );
try {
$container -> compile ( true );
} finally {
putenv ( 'DUMMY_ENV_VAR' );
}
}
2010-10-17 16:26:47 +01:00
/**
2013-11-25 08:44:14 +00:00
* @ expectedException \LogicException
2010-10-17 16:26:47 +01:00
*/
public function testMergeLogicException ()
{
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2011-01-16 07:12:36 +00:00
$container -> compile ();
2010-10-17 16:26:47 +01:00
$container -> merge ( new ContainerBuilder ());
}
2010-08-05 06:34:53 +01:00
public function testfindTaggedServiceIds ()
2010-03-18 07:48:03 +00:00
{
2010-07-15 14:11:33 +01:00
$builder = new ContainerBuilder ();
2010-05-06 12:25:53 +01:00
$builder
2013-12-18 17:52:54 +00:00
-> register ( 'foo' , 'Bar\FooClass' )
2019-01-16 09:39:14 +00:00
-> addTag ( 'foo' , [ 'foo' => 'foo' ])
-> addTag ( 'bar' , [ 'bar' => 'bar' ])
-> addTag ( 'foo' , [ 'foofoo' => 'foofoo' ])
2010-05-06 12:25:53 +01:00
;
2019-01-16 09:39:14 +00:00
$this -> assertEquals ( $builder -> findTaggedServiceIds ( 'foo' ), [
'foo' => [
[ 'foo' => 'foo' ],
[ 'foofoo' => 'foofoo' ],
],
], '->findTaggedServiceIds() returns an array of service ids and its tag attributes' );
$this -> assertEquals ([], $builder -> findTaggedServiceIds ( 'foobar' ), '->findTaggedServiceIds() returns an empty array if there is annotated services' );
2010-03-18 07:48:03 +00:00
}
2010-07-15 14:11:33 +01:00
2014-10-29 09:15:52 +00:00
public function testFindUnusedTags ()
{
$builder = new ContainerBuilder ();
$builder
-> register ( 'foo' , 'Bar\FooClass' )
2019-01-16 09:39:14 +00:00
-> addTag ( 'kernel.event_listener' , [ 'foo' => 'foo' ])
-> addTag ( 'kenrel.event_listener' , [ 'bar' => 'bar' ])
2014-10-29 09:15:52 +00:00
;
$builder -> findTaggedServiceIds ( 'kernel.event_listener' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'kenrel.event_listener' ], $builder -> findUnusedTags (), '->findUnusedTags() returns an array with unused tags' );
2014-10-29 09:15:52 +00:00
}
2010-07-15 14:11:33 +01:00
public function testFindDefinition ()
{
$container = new ContainerBuilder ();
2013-12-18 17:52:54 +00:00
$container -> setDefinition ( 'foo' , $definition = new Definition ( 'Bar\FooClass' ));
2010-07-15 14:11:33 +01:00
$container -> setAlias ( 'bar' , 'foo' );
$container -> setAlias ( 'foobar' , 'bar' );
$this -> assertEquals ( $definition , $container -> findDefinition ( 'foobar' ), '->findDefinition() returns a Definition' );
}
2013-03-29 23:21:12 +00:00
public function testAddObjectResource ()
{
$container = new ContainerBuilder ();
$container -> setResourceTracking ( false );
$container -> addObjectResource ( new \BarClass ());
$this -> assertEmpty ( $container -> getResources (), 'No resources get registered without resource tracking' );
$container -> setResourceTracking ( true );
$container -> addObjectResource ( new \BarClass ());
$resources = $container -> getResources ();
2017-02-02 08:31:13 +00:00
$this -> assertCount ( 2 , $resources , '2 resources were registered' );
2013-03-29 23:21:12 +00:00
/* @var $resource \Symfony\Component\Config\Resource\FileResource */
$resource = end ( $resources );
$this -> assertInstanceOf ( 'Symfony\Component\Config\Resource\FileResource' , $resource );
$this -> assertSame ( realpath ( __DIR__ . '/Fixtures/includes/classes.php' ), realpath ( $resource -> getResource ()));
}
2017-01-26 15:09:57 +00:00
/**
* @ group legacy
*/
2013-03-29 23:21:12 +00:00
public function testAddClassResource ()
{
$container = new ContainerBuilder ();
$container -> setResourceTracking ( false );
$container -> addClassResource ( new \ReflectionClass ( 'BarClass' ));
$this -> assertEmpty ( $container -> getResources (), 'No resources get registered without resource tracking' );
$container -> setResourceTracking ( true );
$container -> addClassResource ( new \ReflectionClass ( 'BarClass' ));
$resources = $container -> getResources ();
2017-02-02 08:31:13 +00:00
$this -> assertCount ( 2 , $resources , '2 resources were registered' );
2013-03-29 23:21:12 +00:00
/* @var $resource \Symfony\Component\Config\Resource\FileResource */
$resource = end ( $resources );
$this -> assertInstanceOf ( 'Symfony\Component\Config\Resource\FileResource' , $resource );
$this -> assertSame ( realpath ( __DIR__ . '/Fixtures/includes/classes.php' ), realpath ( $resource -> getResource ()));
}
2017-01-26 15:09:57 +00:00
public function testGetReflectionClass ()
{
$container = new ContainerBuilder ();
$container -> setResourceTracking ( false );
$r1 = $container -> getReflectionClass ( 'BarClass' );
$this -> assertEmpty ( $container -> getResources (), 'No resources get registered without resource tracking' );
$container -> setResourceTracking ( true );
$r2 = $container -> getReflectionClass ( 'BarClass' );
$r3 = $container -> getReflectionClass ( 'BarClass' );
$this -> assertNull ( $container -> getReflectionClass ( 'BarMissingClass' ));
$this -> assertEquals ( $r1 , $r2 );
$this -> assertSame ( $r2 , $r3 );
$resources = $container -> getResources ();
2017-02-02 08:31:13 +00:00
$this -> assertCount ( 3 , $resources , '3 resources were registered' );
2017-01-26 15:09:57 +00:00
2017-02-02 08:31:13 +00:00
$this -> assertSame ( 'reflection.BarClass' , ( string ) $resources [ 1 ]);
2017-01-26 15:09:57 +00:00
$this -> assertSame ( 'BarMissingClass' , ( string ) end ( $resources ));
}
2018-04-24 08:18:57 +01:00
public function testGetReflectionClassOnInternalTypes ()
{
$container = new ContainerBuilder ();
$this -> assertNull ( $container -> getReflectionClass ( 'int' ));
$this -> assertNull ( $container -> getReflectionClass ( 'float' ));
$this -> assertNull ( $container -> getReflectionClass ( 'string' ));
$this -> assertNull ( $container -> getReflectionClass ( 'bool' ));
$this -> assertNull ( $container -> getReflectionClass ( 'resource' ));
$this -> assertNull ( $container -> getReflectionClass ( 'object' ));
$this -> assertNull ( $container -> getReflectionClass ( 'array' ));
$this -> assertNull ( $container -> getReflectionClass ( 'null' ));
$this -> assertNull ( $container -> getReflectionClass ( 'callable' ));
$this -> assertNull ( $container -> getReflectionClass ( 'iterable' ));
$this -> assertNull ( $container -> getReflectionClass ( 'mixed' ));
}
2013-03-29 23:21:12 +00:00
public function testCompilesClassDefinitionsOfLazyServices ()
{
$container = new ContainerBuilder ();
$this -> assertEmpty ( $container -> getResources (), 'No resources get registered without resource tracking' );
2017-09-19 21:53:21 +01:00
$container -> register ( 'foo' , 'BarClass' ) -> setPublic ( true );
2013-03-29 23:21:12 +00:00
$container -> getDefinition ( 'foo' ) -> setLazy ( true );
$container -> compile ();
$matchingResources = array_filter (
$container -> getResources (),
2017-01-26 15:09:57 +00:00
function ( ResourceInterface $resource ) {
return 'reflection.BarClass' === ( string ) $resource ;
2013-03-29 23:21:12 +00:00
}
);
$this -> assertNotEmpty ( $matchingResources );
}
2010-07-15 14:11:33 +01:00
public function testResources ()
{
$container = new ContainerBuilder ();
$container -> addResource ( $a = new FileResource ( __DIR__ . '/Fixtures/xml/services1.xml' ));
$container -> addResource ( $b = new FileResource ( __DIR__ . '/Fixtures/xml/services2.xml' ));
2019-01-16 09:39:14 +00:00
$resources = [];
2011-01-16 07:38:41 +00:00
foreach ( $container -> getResources () as $resource ) {
if ( false === strpos ( $resource , '.php' )) {
$resources [] = $resource ;
}
}
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ $a , $b ], $resources , '->getResources() returns an array of resources read for the current configuration' );
$this -> assertSame ( $container , $container -> setResources ([]));
$this -> assertEquals ([], $container -> getResources ());
2010-07-15 14:11:33 +01:00
}
2010-07-16 08:12:58 +01:00
2017-01-30 09:47:16 +00:00
public function testFileExists ()
{
$container = new ContainerBuilder ();
2017-02-02 08:31:13 +00:00
$A = new ComposerResource ();
2017-01-30 09:47:16 +00:00
$a = new FileResource ( __DIR__ . '/Fixtures/xml/services1.xml' );
$b = new FileResource ( __DIR__ . '/Fixtures/xml/services2.xml' );
2018-07-26 09:45:46 +01:00
$c = new DirectoryResource ( $dir = \dirname ( $b ));
2017-01-30 09:47:16 +00:00
$this -> assertTrue ( $container -> fileExists (( string ) $a ) && $container -> fileExists (( string ) $b ) && $container -> fileExists ( $dir ));
2019-01-16 09:39:14 +00:00
$resources = [];
2017-01-30 09:47:16 +00:00
foreach ( $container -> getResources () as $resource ) {
if ( false === strpos ( $resource , '.php' )) {
$resources [] = $resource ;
}
}
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ $A , $a , $b , $c ], $resources , '->getResources() returns an array of resources read for the current configuration' );
2017-01-30 09:47:16 +00:00
}
2010-07-16 08:12:58 +01:00
public function testExtension ()
{
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2010-07-16 08:12:58 +01:00
$container -> registerExtension ( $extension = new \ProjectExtension ());
2017-12-11 21:55:31 +00:00
$this -> assertSame ( $container -> getExtension ( 'project' ), $extension , '->registerExtension() registers an extension' );
2010-10-17 16:26:47 +01:00
2017-02-20 14:23:32 +00:00
$this -> { method_exists ( $this , $_ = 'expectException' ) ? $_ : 'setExpectedException' }( 'LogicException' );
2010-10-17 16:26:47 +01:00
$container -> getExtension ( 'no_registered' );
2010-07-16 08:12:58 +01:00
}
2010-10-02 15:47:35 +01:00
2011-03-03 12:53:29 +00:00
public function testRegisteredButNotLoadedExtension ()
{
2016-12-19 16:09:34 +00:00
$extension = $this -> getMockBuilder ( 'Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' ) -> getMock ();
2019-05-30 15:56:20 +01:00
$extension -> expects ( $this -> once ()) -> method ( 'getAlias' ) -> willReturn ( 'project' );
2011-03-03 12:53:29 +00:00
$extension -> expects ( $this -> never ()) -> method ( 'load' );
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2011-03-03 12:53:29 +00:00
$container -> registerExtension ( $extension );
$container -> compile ();
}
public function testRegisteredAndLoadedExtension ()
{
2016-12-19 16:09:34 +00:00
$extension = $this -> getMockBuilder ( 'Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' ) -> getMock ();
2019-05-30 15:56:20 +01:00
$extension -> expects ( $this -> exactly ( 2 )) -> method ( 'getAlias' ) -> willReturn ( 'project' );
2019-01-16 09:39:14 +00:00
$extension -> expects ( $this -> once ()) -> method ( 'load' ) -> with ([[ 'foo' => 'bar' ]]);
2011-03-03 12:53:29 +00:00
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2011-03-03 12:53:29 +00:00
$container -> registerExtension ( $extension );
2019-01-16 09:39:14 +00:00
$container -> loadFromExtension ( 'project' , [ 'foo' => 'bar' ]);
2011-03-03 12:53:29 +00:00
$container -> compile ();
}
2011-05-23 20:28:47 +01:00
public function testPrivateServiceUser ()
{
2014-10-22 19:27:13 +01:00
$fooDefinition = new Definition ( 'BarClass' );
2019-01-16 09:39:14 +00:00
$fooUserDefinition = new Definition ( 'BarUserClass' , [ new Reference ( 'bar' )]);
2014-10-22 19:27:13 +01:00
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2011-05-23 20:28:47 +01:00
$fooDefinition -> setPublic ( false );
2019-01-16 09:39:14 +00:00
$container -> addDefinitions ([
2014-10-22 19:27:13 +01:00
'bar' => $fooDefinition ,
2017-09-19 21:53:21 +01:00
'bar_user' => $fooUserDefinition -> setPublic ( true ),
2019-01-16 09:39:14 +00:00
]);
2011-05-23 20:28:47 +01:00
$container -> compile ();
$this -> assertInstanceOf ( 'BarClass' , $container -> get ( 'bar_user' ) -> bar );
}
2010-10-02 15:47:35 +01:00
/**
2013-11-25 08:44:14 +00:00
* @ expectedException \BadMethodCallException
2010-10-02 15:47:35 +01:00
*/
2016-08-19 13:18:08 +01:00
public function testThrowsExceptionWhenSetServiceOnACompiledContainer ()
2010-10-02 15:47:35 +01:00
{
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2017-09-19 21:53:21 +01:00
$container -> register ( 'a' , 'stdClass' ) -> setPublic ( true );
2011-01-16 07:12:36 +00:00
$container -> compile ();
2010-10-02 15:47:35 +01:00
$container -> set ( 'a' , new \stdClass ());
}
2016-08-19 13:18:08 +01:00
public function testThrowsExceptionWhenAddServiceOnACompiledContainer ()
2012-12-28 08:42:17 +00:00
{
$container = new ContainerBuilder ();
$container -> compile ();
2016-09-06 14:11:47 +01:00
$container -> set ( 'a' , $foo = new \stdClass ());
$this -> assertSame ( $foo , $container -> get ( 'a' ));
2012-12-28 08:42:17 +00:00
}
2016-08-19 13:18:08 +01:00
public function testNoExceptionWhenSetSyntheticServiceOnACompiledContainer ()
2012-12-28 08:42:17 +00:00
{
$container = new ContainerBuilder ();
$def = new Definition ( 'stdClass' );
2017-09-19 21:53:21 +01:00
$def -> setSynthetic ( true ) -> setPublic ( true );
2012-12-28 08:42:17 +00:00
$container -> setDefinition ( 'a' , $def );
$container -> compile ();
$container -> set ( 'a' , $a = new \stdClass ());
$this -> assertEquals ( $a , $container -> get ( 'a' ));
}
2010-10-02 15:47:35 +01:00
/**
2013-11-25 08:44:14 +00:00
* @ expectedException \BadMethodCallException
2010-10-02 15:47:35 +01:00
*/
2016-08-19 13:18:08 +01:00
public function testThrowsExceptionWhenSetDefinitionOnACompiledContainer ()
2010-10-02 15:47:35 +01:00
{
$container = new ContainerBuilder ();
2012-12-28 09:40:13 +00:00
$container -> setResourceTracking ( false );
2011-01-16 07:12:36 +00:00
$container -> compile ();
2010-10-02 15:47:35 +01:00
$container -> setDefinition ( 'a' , new Definition ());
}
2012-09-20 22:20:53 +01:00
public function testExtensionConfig ()
{
$container = new ContainerBuilder ();
$configs = $container -> getExtensionConfig ( 'foo' );
$this -> assertEmpty ( $configs );
2019-01-16 09:39:14 +00:00
$first = [ 'foo' => 'bar' ];
2012-09-20 22:20:53 +01:00
$container -> prependExtensionConfig ( 'foo' , $first );
$configs = $container -> getExtensionConfig ( 'foo' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ $first ], $configs );
2012-09-20 22:20:53 +01:00
2019-01-16 09:39:14 +00:00
$second = [ 'ding' => 'dong' ];
2012-09-20 22:20:53 +01:00
$container -> prependExtensionConfig ( 'foo' , $second );
$configs = $container -> getExtensionConfig ( 'foo' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ $second , $first ], $configs );
2012-09-20 22:20:53 +01:00
}
2013-11-09 11:47:52 +00:00
2016-04-05 14:46:37 +01:00
public function testAbstractAlias ()
{
$container = new ContainerBuilder ();
$abstract = new Definition ( 'AbstractClass' );
2017-09-19 21:53:21 +01:00
$abstract -> setAbstract ( true ) -> setPublic ( true );
2016-04-05 14:46:37 +01:00
$container -> setDefinition ( 'abstract_service' , $abstract );
2017-09-19 21:53:21 +01:00
$container -> setAlias ( 'abstract_alias' , 'abstract_service' ) -> setPublic ( true );
2016-04-05 14:46:37 +01:00
$container -> compile ();
$this -> assertSame ( 'abstract_service' , ( string ) $container -> getAlias ( 'abstract_alias' ));
}
2013-11-09 11:47:52 +00:00
public function testLazyLoadedService ()
{
$loader = new ClosureLoader ( $container = new ContainerBuilder ());
$loader -> load ( function ( ContainerBuilder $container ) {
2016-10-30 09:34:06 +00:00
$container -> set ( 'a' , new \BazClass ());
$definition = new Definition ( 'BazClass' );
$definition -> setLazy ( true );
2017-09-19 21:53:21 +01:00
$definition -> setPublic ( true );
2016-10-30 09:34:06 +00:00
$container -> setDefinition ( 'a' , $definition );
});
2013-11-09 11:47:52 +00:00
$container -> setResourceTracking ( true );
$container -> compile ();
$r = new \ReflectionProperty ( $container , 'resources' );
$r -> setAccessible ( true );
$resources = $r -> getValue ( $container );
$classInList = false ;
foreach ( $resources as $resource ) {
2017-01-26 15:09:57 +00:00
if ( 'reflection.BazClass' === ( string ) $resource ) {
2013-11-09 11:47:52 +00:00
$classInList = true ;
break ;
}
}
2014-03-27 14:19:35 +00:00
$this -> assertTrue ( $classInList );
2013-11-09 11:47:52 +00:00
}
2015-08-24 02:36:41 +01:00
2017-11-23 08:59:26 +00:00
public function testInlinedDefinitions ()
{
$container = new ContainerBuilder ();
$definition = new Definition ( 'BarClass' );
$container -> register ( 'bar_user' , 'BarUserClass' )
-> addArgument ( $definition )
-> setProperty ( 'foo' , $definition );
$container -> register ( 'bar' , 'BarClass' )
-> setProperty ( 'foo' , $definition )
2019-01-16 09:39:14 +00:00
-> addMethodCall ( 'setBaz' , [ $definition ]);
2017-11-23 08:59:26 +00:00
$barUser = $container -> get ( 'bar_user' );
$bar = $container -> get ( 'bar' );
$this -> assertSame ( $barUser -> foo , $barUser -> bar );
$this -> assertSame ( $bar -> foo , $bar -> getBaz ());
$this -> assertNotSame ( $bar -> foo , $barUser -> foo );
}
2017-12-06 16:27:14 +00:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
2017-12-07 17:06:18 +00:00
* @ expectedExceptionMessage Circular reference detected for service " app.test_class " , path : " app.test_class -> App \T estClass -> app.test_class " .
2017-12-06 16:27:14 +00:00
*/
public function testThrowsCircularExceptionForCircularAliases ()
{
$builder = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$builder -> setAliases ([
2017-12-07 17:06:18 +00:00
'foo' => new Alias ( 'app.test_class' ),
2017-12-06 16:27:14 +00:00
'app.test_class' => new Alias ( 'App\\TestClass' ),
'App\\TestClass' => new Alias ( 'app.test_class' ),
2019-01-16 09:39:14 +00:00
]);
2017-12-06 16:27:14 +00:00
2017-12-07 17:06:18 +00:00
$builder -> findDefinition ( 'foo' );
2017-12-06 16:27:14 +00:00
}
2016-11-19 11:21:18 +00:00
public function testInitializePropertiesBeforeMethodCalls ()
{
$container = new ContainerBuilder ();
$container -> register ( 'foo' , 'stdClass' );
$container -> register ( 'bar' , 'MethodCallClass' )
2017-09-19 21:53:21 +01:00
-> setPublic ( true )
2016-11-19 11:21:18 +00:00
-> setProperty ( 'simple' , 'bar' )
-> setProperty ( 'complex' , new Reference ( 'foo' ))
-> addMethodCall ( 'callMe' );
$container -> compile ();
$this -> assertTrue ( $container -> get ( 'bar' ) -> callPassed (), '->compile() initializes properties before method calls' );
}
2016-11-25 12:26:42 +00:00
2015-08-24 02:36:41 +01:00
public function testAutowiring ()
{
$container = new ContainerBuilder ();
2017-09-19 21:53:21 +01:00
$container -> register ( A :: class ) -> setPublic ( true );
2015-08-24 02:36:41 +01:00
$bDefinition = $container -> register ( 'b' , __NAMESPACE__ . '\B' );
$bDefinition -> setAutowired ( true );
2017-09-19 21:53:21 +01:00
$bDefinition -> setPublic ( true );
2015-08-24 02:36:41 +01:00
$container -> compile ();
2017-04-04 18:35:51 +01:00
$this -> assertEquals ( A :: class , ( string ) $container -> getDefinition ( 'b' ) -> getArgument ( 0 ));
2015-08-24 02:36:41 +01:00
}
2016-12-15 07:56:11 +00:00
2016-10-21 11:29:35 +01:00
public function testClassFromId ()
{
$container = new ContainerBuilder ();
2017-01-29 15:34:49 +00:00
$unknown = $container -> register ( 'Acme\UnknownClass' );
2016-10-21 11:29:35 +01:00
$autoloadClass = $container -> register ( CaseSensitiveClass :: class );
$container -> compile ();
2017-01-29 15:34:49 +00:00
$this -> assertSame ( 'Acme\UnknownClass' , $unknown -> getClass ());
2016-10-21 11:29:35 +01:00
$this -> assertEquals ( CaseSensitiveClass :: class , $autoloadClass -> getClass ());
}
2017-01-29 15:34:49 +00:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
2017-03-24 22:57:27 +00:00
* @ expectedExceptionMessage The definition for " DateTime " has no class attribute , and appears to reference a class or interface in the global namespace .
2017-01-29 15:34:49 +00:00
*/
public function testNoClassFromGlobalNamespaceClassId ()
{
$container = new ContainerBuilder ();
$definition = $container -> register ( \DateTime :: class );
$container -> compile ();
}
2018-07-25 11:20:49 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @ expectedExceptionMessage The definition for " \ DateTime " has no class attribute , and appears to reference a class or interface in the global namespace .
*/
public function testNoClassFromGlobalNamespaceClassIdWithLeadingSlash ()
{
$container = new ContainerBuilder ();
$container -> register ( '\\' . \DateTime :: class );
$container -> compile ();
}
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @ expectedExceptionMessage The definition for " \ Symfony \ Component \ DependencyInjection \T ests \ FooClass " has no class attribute , and appears to reference a class or interface . Please specify the class attribute explicitly or remove the leading backslash by renaming the service to " Symfony \ Component \ DependencyInjection \T ests \ FooClass " to get rid of this error .
*/
public function testNoClassFromNamespaceClassIdWithLeadingSlash ()
{
$container = new ContainerBuilder ();
$container -> register ( '\\' . FooClass :: class );
$container -> compile ();
}
2016-10-21 11:29:35 +01:00
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @ expectedExceptionMessage The definition for " 123_abc " has no class .
*/
public function testNoClassFromNonClassId ()
{
$container = new ContainerBuilder ();
$definition = $container -> register ( '123_abc' );
$container -> compile ();
}
/**
* @ expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @ expectedExceptionMessage The definition for " \ foo " has no class .
*/
public function testNoClassFromNsSeparatorId ()
{
$container = new ContainerBuilder ();
$definition = $container -> register ( '\\foo' );
$container -> compile ();
}
2017-02-26 17:31:03 +00:00
public function testServiceLocator ()
{
$container = new ContainerBuilder ();
$container -> register ( 'foo_service' , ServiceLocator :: class )
2017-09-19 21:53:21 +01:00
-> setPublic ( true )
2019-01-16 09:39:14 +00:00
-> addArgument ([
2017-02-26 17:31:03 +00:00
'bar' => new ServiceClosureArgument ( new Reference ( 'bar_service' )),
'baz' => new ServiceClosureArgument ( new TypedReference ( 'baz_service' , 'stdClass' )),
2019-01-16 09:39:14 +00:00
])
2017-02-26 17:31:03 +00:00
;
2019-01-16 09:39:14 +00:00
$container -> register ( 'bar_service' , 'stdClass' ) -> setArguments ([ new Reference ( 'baz_service' )]) -> setPublic ( true );
2017-02-26 17:31:03 +00:00
$container -> register ( 'baz_service' , 'stdClass' ) -> setPublic ( false );
$container -> compile ();
$this -> assertInstanceOf ( ServiceLocator :: class , $foo = $container -> get ( 'foo_service' ));
$this -> assertSame ( $container -> get ( 'bar_service' ), $foo -> get ( 'bar' ));
}
2017-03-31 11:45:36 +01:00
2017-08-30 08:27:55 +01:00
public function testUninitializedReference ()
{
$container = include __DIR__ . '/Fixtures/containers/container_uninitialized_ref.php' ;
$container -> compile ();
$bar = $container -> get ( 'bar' );
$this -> assertNull ( $bar -> foo1 );
$this -> assertNull ( $bar -> foo2 );
$this -> assertNull ( $bar -> foo3 );
$this -> assertNull ( $bar -> closures [ 0 ]());
$this -> assertNull ( $bar -> closures [ 1 ]());
$this -> assertNull ( $bar -> closures [ 2 ]());
2019-01-16 09:39:14 +00:00
$this -> assertSame ([], iterator_to_array ( $bar -> iter ));
2017-08-30 08:27:55 +01:00
$container = include __DIR__ . '/Fixtures/containers/container_uninitialized_ref.php' ;
$container -> compile ();
$container -> get ( 'foo1' );
$container -> get ( 'baz' );
$bar = $container -> get ( 'bar' );
$this -> assertEquals ( new \stdClass (), $bar -> foo1 );
$this -> assertNull ( $bar -> foo2 );
$this -> assertEquals ( new \stdClass (), $bar -> foo3 );
$this -> assertEquals ( new \stdClass (), $bar -> closures [ 0 ]());
$this -> assertNull ( $bar -> closures [ 1 ]());
$this -> assertEquals ( new \stdClass (), $bar -> closures [ 2 ]());
2019-01-16 09:39:14 +00:00
$this -> assertEquals ([ 'foo1' => new \stdClass (), 'foo3' => new \stdClass ()], iterator_to_array ( $bar -> iter ));
2017-08-30 08:27:55 +01:00
}
2017-11-27 20:00:44 +00:00
/**
* @ dataProvider provideAlmostCircular
*/
public function testAlmostCircular ( $visibility )
2017-11-04 20:24:26 +00:00
{
2017-11-05 17:53:02 +00:00
$container = include __DIR__ . '/Fixtures/containers/container_almost_circular.php' ;
$foo = $container -> get ( 'foo' );
$this -> assertSame ( $foo , $foo -> bar -> foobar -> foo );
2017-11-27 20:00:44 +00:00
$foo2 = $container -> get ( 'foo2' );
$this -> assertSame ( $foo2 , $foo2 -> bar -> foobar -> foo );
2017-11-04 20:24:26 +00:00
2019-01-16 09:39:14 +00:00
$this -> assertSame ([], ( array ) $container -> get ( 'foobar4' ));
2017-12-01 13:14:10 +00:00
$foo5 = $container -> get ( 'foo5' );
$this -> assertSame ( $foo5 , $foo5 -> bar -> foo );
2018-07-24 10:19:17 +01:00
$manager = $container -> get ( 'manager' );
$this -> assertEquals ( new \stdClass (), $manager );
$manager = $container -> get ( 'manager2' );
$this -> assertEquals ( new \stdClass (), $manager );
2018-10-01 22:02:25 +01:00
$foo6 = $container -> get ( 'foo6' );
2019-01-16 09:39:14 +00:00
$this -> assertEquals (( object ) [ 'bar6' => ( object ) []], $foo6 );
2018-10-16 17:02:29 +01:00
$this -> assertInstanceOf ( \stdClass :: class , $container -> get ( 'root' ));
2019-06-24 17:50:01 +01:00
$manager3 = $container -> get ( 'manager3' );
$listener3 = $container -> get ( 'listener3' );
$this -> assertSame ( $manager3 , $listener3 -> manager , 'Both should identically be the manager3 service' );
$listener4 = $container -> get ( 'listener4' );
$this -> assertInstanceOf ( 'stdClass' , $listener4 );
2017-11-27 20:00:44 +00:00
}
2017-11-04 20:24:26 +00:00
2017-11-27 20:00:44 +00:00
public function provideAlmostCircular ()
{
2019-01-16 09:39:14 +00:00
yield [ 'public' ];
yield [ 'private' ];
2017-11-04 20:24:26 +00:00
}
2017-03-31 11:45:36 +01:00
public function testRegisterForAutoconfiguration ()
{
$container = new ContainerBuilder ();
$childDefA = $container -> registerForAutoconfiguration ( 'AInterface' );
$childDefB = $container -> registerForAutoconfiguration ( 'BInterface' );
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'AInterface' => $childDefA , 'BInterface' => $childDefB ], $container -> getAutoconfiguredInstanceof ());
2017-03-31 11:45:36 +01:00
// when called multiple times, the same instance is returned
$this -> assertSame ( $childDefA , $container -> registerForAutoconfiguration ( 'AInterface' ));
}
2017-07-17 10:57:18 +01:00
/**
* This test checks the trigger of a deprecation note and should not be removed in major releases .
*
* @ group legacy
* @ expectedDeprecation The " foo " service is deprecated . You should stop using it , as it will soon be removed .
*/
public function testPrivateServiceTriggersDeprecation ()
{
$container = new ContainerBuilder ();
$container -> register ( 'foo' , 'stdClass' )
-> setPublic ( false )
-> setDeprecated ( true );
$container -> register ( 'bar' , 'stdClass' )
-> setPublic ( true )
-> setProperty ( 'foo' , new Reference ( 'foo' ));
$container -> compile ();
$container -> get ( 'bar' );
}
2017-08-12 10:16:19 +01:00
/**
* @ group legacy
2017-12-31 06:25:36 +00:00
* @ expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0 . Using " FOO " instead of " foo " is deprecated since Symfony 3.4 .
2017-08-12 10:16:19 +01:00
*/
public function testParameterWithMixedCase ()
{
2019-01-16 09:39:14 +00:00
$container = new ContainerBuilder ( new ParameterBag ([ 'foo' => 'bar' ]));
2017-08-12 10:16:19 +01:00
$container -> register ( 'foo' , 'stdClass' )
2017-09-19 21:53:21 +01:00
-> setPublic ( true )
2017-08-12 10:16:19 +01:00
-> setProperty ( 'foo' , '%FOO%' );
$container -> compile ();
$this -> assertSame ( 'bar' , $container -> get ( 'foo' ) -> foo );
}
2017-11-17 08:40:56 +00:00
public function testArgumentsHaveHigherPriorityThanBindings ()
{
$container = new ContainerBuilder ();
2019-01-16 09:39:14 +00:00
$container -> register ( 'class.via.bindings' , CaseSensitiveClass :: class ) -> setArguments ([
2017-11-17 08:40:56 +00:00
'via-bindings' ,
2019-01-16 09:39:14 +00:00
]);
$container -> register ( 'class.via.argument' , CaseSensitiveClass :: class ) -> setArguments ([
2017-11-17 08:40:56 +00:00
'via-argument' ,
2019-01-16 09:39:14 +00:00
]);
$container -> register ( 'foo' , SimilarArgumentsDummy :: class ) -> setPublic ( true ) -> setBindings ([
2017-11-17 08:40:56 +00:00
CaseSensitiveClass :: class => new Reference ( 'class.via.bindings' ),
'$token' => '1234' ,
2019-01-16 09:39:14 +00:00
]) -> setArguments ([
2017-11-17 08:40:56 +00:00
'$class1' => new Reference ( 'class.via.argument' ),
2019-01-16 09:39:14 +00:00
]);
2017-11-17 08:40:56 +00:00
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'service_container' , 'class.via.bindings' , 'class.via.argument' , 'foo' , 'Psr\Container\ContainerInterface' , 'Symfony\Component\DependencyInjection\ContainerInterface' ], $container -> getServiceIds ());
2017-11-17 08:40:56 +00:00
$container -> compile ();
$this -> assertSame ( 'via-argument' , $container -> get ( 'foo' ) -> class1 -> identifier );
$this -> assertSame ( 'via-bindings' , $container -> get ( 'foo' ) -> class2 -> identifier );
}
2018-06-30 08:08:55 +01:00
public function testUninitializedSyntheticReference ()
{
$container = new ContainerBuilder ();
$container -> register ( 'foo' , 'stdClass' ) -> setPublic ( true ) -> setSynthetic ( true );
$container -> register ( 'bar' , 'stdClass' ) -> setPublic ( true ) -> setShared ( false )
-> setProperty ( 'foo' , new Reference ( 'foo' , ContainerInterface :: IGNORE_ON_UNINITIALIZED_REFERENCE ));
$container -> compile ();
2019-01-16 09:39:14 +00:00
$this -> assertEquals (( object ) [ 'foo' => null ], $container -> get ( 'bar' ));
2018-06-30 08:08:55 +01:00
2019-01-16 09:39:14 +00:00
$container -> set ( 'foo' , ( object ) [ 123 ]);
$this -> assertEquals (( object ) [ 'foo' => ( object ) [ 123 ]], $container -> get ( 'bar' ));
2018-06-30 08:08:55 +01:00
}
2018-09-19 13:33:19 +01:00
public function testDecoratedSelfReferenceInvolvingPrivateServices ()
{
$container = new ContainerBuilder ();
$container -> register ( 'foo' , 'stdClass' )
-> setPublic ( false )
-> setProperty ( 'bar' , new Reference ( 'foo' ));
$container -> register ( 'baz' , 'stdClass' )
-> setPublic ( false )
-> setProperty ( 'inner' , new Reference ( 'baz.inner' ))
-> setDecoratedService ( 'foo' );
$container -> compile ();
2019-01-16 09:39:14 +00:00
$this -> assertSame ([ 'service_container' ], array_keys ( $container -> getDefinitions ()));
2018-09-19 13:33:19 +01:00
}
2019-07-08 14:34:24 +01:00
public function testScalarService ()
{
$c = new ContainerBuilder ();
$c -> register ( 'foo' , 'string' )
-> setPublic ( true )
-> setFactory ([ ScalarFactory :: class , 'getSomeValue' ])
;
$c -> compile ();
$this -> assertTrue ( $c -> has ( 'foo' ));
$this -> assertSame ( 'some value' , $c -> get ( 'foo' ));
}
2010-03-18 07:48:03 +00:00
}
2010-10-02 15:47:35 +01:00
2014-09-21 19:53:12 +01:00
class FooClass
{
}
2014-03-27 14:19:35 +00:00
2015-08-24 02:36:41 +01:00
class A
{
}
class B
{
public function __construct ( A $a )
{
}
}