PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

http://github.com/symfony/symfony
PHP | 1504 lines | 1315 code | 169 blank | 20 comment | 3 complexity | 38941d899f83ddfeea79929661d27ce8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DependencyInjection\Tests\Dumper;
  11. use PHPUnit\Framework\TestCase;
  12. use Psr\Container\ContainerInterface;
  13. use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
  14. use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
  15. use Symfony\Component\Config\FileLocator;
  16. use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
  17. use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
  18. use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
  19. use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
  20. use Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator;
  21. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  22. use Symfony\Component\DependencyInjection\Compiler\PassConfig;
  23. use Symfony\Component\DependencyInjection\ContainerBuilder;
  24. use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
  25. use Symfony\Component\DependencyInjection\Definition;
  26. use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
  27. use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
  28. use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  29. use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
  30. use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
  31. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
  32. use Symfony\Component\DependencyInjection\Reference;
  33. use Symfony\Component\DependencyInjection\ServiceLocator;
  34. use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
  35. use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
  36. use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
  37. use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
  38. use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
  39. use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
  40. use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
  41. use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
  42. use Symfony\Component\DependencyInjection\Tests\Fixtures\WitherStaticReturnType;
  43. use Symfony\Component\DependencyInjection\TypedReference;
  44. use Symfony\Component\DependencyInjection\Variable;
  45. use Symfony\Component\ExpressionLanguage\Expression;
  46. require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php';
  47. require_once __DIR__.'/../Fixtures/includes/classes.php';
  48. require_once __DIR__.'/../Fixtures/includes/foo.php';
  49. require_once __DIR__.'/../Fixtures/includes/foo_lazy.php';
  50. class PhpDumperTest extends TestCase
  51. {
  52. use ExpectDeprecationTrait;
  53. protected static $fixturesPath;
  54. public static function setUpBeforeClass(): void
  55. {
  56. self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
  57. }
  58. public function testDump()
  59. {
  60. $container = new ContainerBuilder();
  61. $container->compile();
  62. $dumper = new PhpDumper($container);
  63. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
  64. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1-1.php', $dumper->dump(['class' => 'Container', 'base_class' => 'AbstractContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Dump']), '->dump() takes a class and a base_class options');
  65. }
  66. public function testDumpOptimizationString()
  67. {
  68. $definition = new Definition();
  69. $definition->setClass('stdClass');
  70. $definition->addArgument([
  71. 'only dot' => '.',
  72. 'concatenation as value' => '.\'\'.',
  73. 'concatenation from the start value' => '\'\'.',
  74. '.' => 'dot as a key',
  75. '.\'\'.' => 'concatenation as a key',
  76. '\'\'.' => 'concatenation from the start key',
  77. 'optimize concatenation' => 'string1%some_string%string2',
  78. 'optimize concatenation with empty string' => 'string1%empty_value%string2',
  79. 'optimize concatenation from the start' => '%empty_value%start',
  80. 'optimize concatenation at the end' => 'end%empty_value%',
  81. 'new line' => "string with \nnew line",
  82. ]);
  83. $definition->setPublic(true);
  84. $container = new ContainerBuilder();
  85. $container->setResourceTracking(false);
  86. $container->setDefinition('test', $definition);
  87. $container->setParameter('empty_value', '');
  88. $container->setParameter('some_string', '-');
  89. $container->compile();
  90. $dumper = new PhpDumper($container);
  91. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services10.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
  92. }
  93. public function testDumpRelativeDir()
  94. {
  95. $definition = new Definition();
  96. $definition->setClass('stdClass');
  97. $definition->addArgument('%foo%');
  98. $definition->addArgument(['%foo%' => '%buz%/']);
  99. $definition->setPublic(true);
  100. $container = new ContainerBuilder();
  101. $container->setDefinition('test', $definition);
  102. $container->setParameter('foo', 'wiz'.\dirname(__DIR__));
  103. $container->setParameter('bar', __DIR__);
  104. $container->setParameter('baz', '%bar%/PhpDumperTest.php');
  105. $container->setParameter('buz', \dirname(__DIR__, 2));
  106. $container->compile();
  107. $dumper = new PhpDumper($container);
  108. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(['file' => __FILE__]), '->dump() dumps __DIR__ relative strings');
  109. }
  110. public function testDumpCustomContainerClassWithoutConstructor()
  111. {
  112. $container = new ContainerBuilder();
  113. $container->compile();
  114. $dumper = new PhpDumper($container);
  115. $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_without_constructor.php', $dumper->dump(['base_class' => 'NoConstructorContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container']));
  116. }
  117. public function testDumpCustomContainerClassConstructorWithoutArguments()
  118. {
  119. $container = new ContainerBuilder();
  120. $container->compile();
  121. $dumper = new PhpDumper($container);
  122. $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_constructor_without_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithoutArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container']));
  123. }
  124. public function testDumpCustomContainerClassWithOptionalArgumentLessConstructor()
  125. {
  126. $container = new ContainerBuilder();
  127. $container->compile();
  128. $dumper = new PhpDumper($container);
  129. $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_optional_constructor_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithOptionalArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container']));
  130. }
  131. public function testDumpCustomContainerClassWithMandatoryArgumentLessConstructor()
  132. {
  133. $container = new ContainerBuilder();
  134. $container->compile();
  135. $dumper = new PhpDumper($container);
  136. $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_mandatory_constructor_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithMandatoryArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container']));
  137. }
  138. /**
  139. * @dataProvider provideInvalidParameters
  140. */
  141. public function testExportParameters($parameters)
  142. {
  143. $this->expectException('InvalidArgumentException');
  144. $container = new ContainerBuilder(new ParameterBag($parameters));
  145. $container->compile();
  146. $dumper = new PhpDumper($container);
  147. $dumper->dump();
  148. }
  149. public function provideInvalidParameters()
  150. {
  151. return [
  152. [['foo' => new Definition('stdClass')]],
  153. [['foo' => new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]],
  154. [['foo' => new Reference('foo')]],
  155. [['foo' => new Variable('foo')]],
  156. ];
  157. }
  158. public function testAddParameters()
  159. {
  160. $container = include self::$fixturesPath.'/containers/container8.php';
  161. $container->compile();
  162. $dumper = new PhpDumper($container);
  163. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services8.php', $dumper->dump(), '->dump() dumps parameters');
  164. }
  165. public function testAddServiceWithoutCompilation()
  166. {
  167. $this->expectException('Symfony\Component\DependencyInjection\Exception\LogicException');
  168. $this->expectExceptionMessage('Cannot dump an uncompiled container.');
  169. $container = include self::$fixturesPath.'/containers/container9.php';
  170. new PhpDumper($container);
  171. }
  172. public function testAddService()
  173. {
  174. $container = include self::$fixturesPath.'/containers/container9.php';
  175. $container->compile();
  176. $dumper = new PhpDumper($container);
  177. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services');
  178. $container = new ContainerBuilder();
  179. $container->register('foo', 'FooClass')->addArgument(new \stdClass())->setPublic(true);
  180. $container->compile();
  181. $dumper = new PhpDumper($container);
  182. try {
  183. $dumper->dump();
  184. $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
  185. } catch (\Exception $e) {
  186. $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
  187. $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
  188. }
  189. }
  190. public function testDumpAsFiles()
  191. {
  192. $container = include self::$fixturesPath.'/containers/container9.php';
  193. $container->getDefinition('bar')->addTag('hot');
  194. $container->register('non_shared_foo', \Bar\FooClass::class)
  195. ->setFile(realpath(self::$fixturesPath.'/includes/foo.php'))
  196. ->setShared(false)
  197. ->setPublic(true);
  198. $container->register('throwing_one', \Bar\FooClass::class)
  199. ->addArgument(new Reference('errored_one', ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE))
  200. ->setPublic(true);
  201. $container->register('errored_one', 'stdClass')
  202. ->addError('No-no-no-no');
  203. $container->compile();
  204. $dumper = new PhpDumper($container);
  205. $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
  206. if ('\\' === \DIRECTORY_SEPARATOR) {
  207. $dump = str_replace('\\\\Fixtures\\\\includes\\\\foo.php', '/Fixtures/includes/foo.php', $dump);
  208. }
  209. $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
  210. }
  211. public function testDumpAsFilesWithFactoriesInlined()
  212. {
  213. $container = include self::$fixturesPath.'/containers/container9.php';
  214. $container->setParameter('container.dumper.inline_factories', true);
  215. $container->setParameter('container.dumper.inline_class_loader', true);
  216. $container->getDefinition('bar')->addTag('hot');
  217. $container->register('non_shared_foo', \Bar\FooClass::class)
  218. ->setFile(realpath(self::$fixturesPath.'/includes/foo.php'))
  219. ->setShared(false)
  220. ->setPublic(true);
  221. $container->register('throwing_one', \Bar\FooClass::class)
  222. ->addArgument(new Reference('errored_one', ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE))
  223. ->setPublic(true);
  224. $container->register('errored_one', 'stdClass')
  225. ->addError('No-no-no-no');
  226. $container->compile();
  227. $dumper = new PhpDumper($container);
  228. $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'build_time' => 1563381341]), true);
  229. if ('\\' === \DIRECTORY_SEPARATOR) {
  230. $dump = str_replace('\\\\Fixtures\\\\includes\\\\', '/Fixtures/includes/', $dump);
  231. }
  232. $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_inlined_factories.txt', $dump);
  233. }
  234. /**
  235. * @requires function \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper::getProxyCode
  236. */
  237. public function testDumpAsFilesWithLazyFactoriesInlined()
  238. {
  239. $container = new ContainerBuilder();
  240. $container->setParameter('container.dumper.inline_factories', true);
  241. $container->setParameter('container.dumper.inline_class_loader', true);
  242. $container->register('lazy_foo', \Bar\FooClass::class)
  243. ->addArgument(new Definition(\Bar\FooLazyClass::class))
  244. ->setPublic(true)
  245. ->setLazy(true);
  246. $container->compile();
  247. $dumper = new PhpDumper($container);
  248. $dumper->setProxyDumper(new ProxyDumper());
  249. $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'build_time' => 1563381341]), true);
  250. if ('\\' === \DIRECTORY_SEPARATOR) {
  251. $dump = str_replace('\\\\Fixtures\\\\includes\\\\', '/Fixtures/includes/', $dump);
  252. }
  253. $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_lazy_inlined_factories.txt', $dump);
  254. }
  255. public function testNonSharedLazyDumpAsFiles()
  256. {
  257. $container = include self::$fixturesPath.'/containers/container_non_shared_lazy.php';
  258. $container->register('non_shared_foo', \Bar\FooLazyClass::class)
  259. ->setFile(realpath(self::$fixturesPath.'/includes/foo_lazy.php'))
  260. ->setShared(false)
  261. ->setPublic(true)
  262. ->setLazy(true);
  263. $container->compile();
  264. $dumper = new PhpDumper($container);
  265. $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
  266. if ('\\' === \DIRECTORY_SEPARATOR) {
  267. $dump = str_replace('\\\\Fixtures\\\\includes\\\\foo_lazy.php', '/Fixtures/includes/foo_lazy.php', $dump);
  268. }
  269. $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services_non_shared_lazy_as_files.txt', $dump);
  270. }
  271. public function testServicesWithAnonymousFactories()
  272. {
  273. $container = include self::$fixturesPath.'/containers/container19.php';
  274. $container->compile();
  275. $dumper = new PhpDumper($container);
  276. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services19.php', $dumper->dump(), '->dump() dumps services with anonymous factories');
  277. }
  278. public function testAddServiceIdWithUnsupportedCharacters()
  279. {
  280. $class = 'Symfony_DI_PhpDumper_Test_Unsupported_Characters';
  281. $container = new ContainerBuilder();
  282. $container->setParameter("'", 'oh-no');
  283. $container->register('foo*/oh-no', 'FooClass')->setPublic(true);
  284. $container->register('bar$', 'FooClass')->setPublic(true);
  285. $container->register('bar$!', 'FooClass')->setPublic(true);
  286. $container->compile();
  287. $dumper = new PhpDumper($container);
  288. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_unsupported_characters.php', $dumper->dump(['class' => $class]));
  289. require_once self::$fixturesPath.'/php/services_unsupported_characters.php';
  290. $this->assertTrue(method_exists($class, 'getFooOhNoService'));
  291. $this->assertTrue(method_exists($class, 'getBarService'));
  292. $this->assertTrue(method_exists($class, 'getBar2Service'));
  293. }
  294. public function testConflictingServiceIds()
  295. {
  296. $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Service_Ids';
  297. $container = new ContainerBuilder();
  298. $container->register('foo_bar', 'FooClass')->setPublic(true);
  299. $container->register('foobar', 'FooClass')->setPublic(true);
  300. $container->compile();
  301. $dumper = new PhpDumper($container);
  302. eval('?>'.$dumper->dump(['class' => $class]));
  303. $this->assertTrue(method_exists($class, 'getFooBarService'));
  304. $this->assertTrue(method_exists($class, 'getFoobar2Service'));
  305. }
  306. public function testConflictingMethodsWithParent()
  307. {
  308. $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Method_With_Parent';
  309. $container = new ContainerBuilder();
  310. $container->register('bar', 'FooClass')->setPublic(true);
  311. $container->register('foo_bar', 'FooClass')->setPublic(true);
  312. $container->compile();
  313. $dumper = new PhpDumper($container);
  314. eval('?>'.$dumper->dump([
  315. 'class' => $class,
  316. 'base_class' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\containers\CustomContainer',
  317. ]));
  318. $this->assertTrue(method_exists($class, 'getBar2Service'));
  319. $this->assertTrue(method_exists($class, 'getFoobar2Service'));
  320. }
  321. /**
  322. * @dataProvider provideInvalidFactories
  323. */
  324. public function testInvalidFactories($factory)
  325. {
  326. $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException');
  327. $this->expectExceptionMessage('Cannot dump definition');
  328. $container = new ContainerBuilder();
  329. $def = new Definition('stdClass');
  330. $def->setPublic(true);
  331. $def->setFactory($factory);
  332. $container->setDefinition('bar', $def);
  333. $container->compile();
  334. $dumper = new PhpDumper($container);
  335. $dumper->dump();
  336. }
  337. public function provideInvalidFactories()
  338. {
  339. return [
  340. [['', 'method']],
  341. [['class', '']],
  342. [['...', 'method']],
  343. [['class', '...']],
  344. ];
  345. }
  346. public function testAliases()
  347. {
  348. $container = include self::$fixturesPath.'/containers/container9.php';
  349. $container->setParameter('foo_bar', 'foo_bar');
  350. $container->compile();
  351. $dumper = new PhpDumper($container);
  352. eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Aliases']));
  353. $container = new \Symfony_DI_PhpDumper_Test_Aliases();
  354. $foo = $container->get('foo');
  355. $this->assertSame($foo, $container->get('alias_for_foo'));
  356. $this->assertSame($foo, $container->get('alias_for_alias'));
  357. }
  358. /**
  359. * @group legacy
  360. */
  361. public function testAliasesDeprecation()
  362. {
  363. $this->expectDeprecation('The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will be removed in the future.');
  364. $container = include self::$fixturesPath.'/containers/container_alias_deprecation.php';
  365. $container->compile();
  366. $dumper = new PhpDumper($container);
  367. $this->assertStringEqualsFile(self::$fixturesPath.'/php/container_alias_deprecation.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Aliases_Deprecation']));
  368. require self::$fixturesPath.'/php/container_alias_deprecation.php';
  369. $container = new \Symfony_DI_PhpDumper_Test_Aliases_Deprecation();
  370. $container->get('alias_for_foo_non_deprecated');
  371. $container->get('alias_for_foo_deprecated');
  372. }
  373. public function testFrozenContainerWithoutAliases()
  374. {
  375. $container = new ContainerBuilder();
  376. $container->compile();
  377. $dumper = new PhpDumper($container);
  378. eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Frozen_No_Aliases']));
  379. $container = new \Symfony_DI_PhpDumper_Test_Frozen_No_Aliases();
  380. $this->assertFalse($container->has('foo'));
  381. }
  382. public function testOverrideServiceWhenUsingADumpedContainer()
  383. {
  384. $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException');
  385. $this->expectExceptionMessage('The "decorator_service" service is already initialized, you cannot replace it.');
  386. require_once self::$fixturesPath.'/php/services9_compiled.php';
  387. $container = new \ProjectServiceContainer();
  388. $container->get('decorator_service');
  389. $container->set('decorator_service', $decorator = new \stdClass());
  390. $this->assertSame($decorator, $container->get('decorator_service'), '->set() overrides an already defined service');
  391. }
  392. public function testDumpAutowireData()
  393. {
  394. $container = include self::$fixturesPath.'/containers/container24.php';
  395. $container->compile();
  396. $dumper = new PhpDumper($container);
  397. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services24.php', $dumper->dump());
  398. }
  399. public function testEnvInId()
  400. {
  401. $container = include self::$fixturesPath.'/containers/container_env_in_id.php';
  402. $container->compile();
  403. $dumper = new PhpDumper($container);
  404. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_env_in_id.php', $dumper->dump());
  405. }
  406. public function testEnvParameter()
  407. {
  408. $rand = mt_rand();
  409. putenv('Baz='.$rand);
  410. $container = new ContainerBuilder();
  411. $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
  412. $loader->load('services26.yml');
  413. $container->setParameter('env(json_file)', self::$fixturesPath.'/array.json');
  414. $container->compile();
  415. $dumper = new PhpDumper($container);
  416. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services26.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_EnvParameters', 'file' => self::$fixturesPath.'/php/services26.php', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]));
  417. require self::$fixturesPath.'/php/services26.php';
  418. $container = new \Symfony_DI_PhpDumper_Test_EnvParameters();
  419. $this->assertSame($rand, $container->getParameter('baz'));
  420. $this->assertSame([123, 'abc'], $container->getParameter('json'));
  421. $this->assertSame('sqlite:///foo/bar/var/data.db', $container->getParameter('db_dsn'));
  422. putenv('Baz');
  423. }
  424. public function testResolvedBase64EnvParameters()
  425. {
  426. $container = new ContainerBuilder();
  427. $container->setParameter('env(foo)', base64_encode('world'));
  428. $container->setParameter('hello', '%env(base64:foo)%');
  429. $container->compile(true);
  430. $expected = [
  431. 'env(foo)' => 'd29ybGQ=',
  432. 'hello' => 'world',
  433. ];
  434. $this->assertSame($expected, $container->getParameterBag()->all());
  435. }
  436. public function testDumpedBase64EnvParameters()
  437. {
  438. $container = new ContainerBuilder();
  439. $container->setParameter('env(foo)', base64_encode('world'));
  440. $container->setParameter('hello', '%env(base64:foo)%');
  441. $container->compile();
  442. $dumper = new PhpDumper($container);
  443. $dumper->dump();
  444. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_base64_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Base64Parameters']));
  445. require self::$fixturesPath.'/php/services_base64_env.php';
  446. $container = new \Symfony_DI_PhpDumper_Test_Base64Parameters();
  447. $this->assertSame('world', $container->getParameter('hello'));
  448. }
  449. public function testDumpedCsvEnvParameters()
  450. {
  451. $container = new ContainerBuilder();
  452. $container->setParameter('env(foo)', 'foo,bar');
  453. $container->setParameter('hello', '%env(csv:foo)%');
  454. $container->compile();
  455. $dumper = new PhpDumper($container);
  456. $dumper->dump();
  457. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_csv_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_CsvParameters']));
  458. require self::$fixturesPath.'/php/services_csv_env.php';
  459. $container = new \Symfony_DI_PhpDumper_Test_CsvParameters();
  460. $this->assertSame(['foo', 'bar'], $container->getParameter('hello'));
  461. }
  462. public function testDumpedDefaultEnvParameters()
  463. {
  464. $container = new ContainerBuilder();
  465. $container->setParameter('fallback_param', 'baz');
  466. $container->setParameter('fallback_env', '%env(foobar)%');
  467. $container->setParameter('env(foobar)', 'foobaz');
  468. $container->setParameter('env(foo)', '{"foo": "bar"}');
  469. $container->setParameter('hello', '%env(default:fallback_param:bar)%');
  470. $container->setParameter('hello-bar', '%env(default:fallback_env:key:baz:json:foo)%');
  471. $container->compile();
  472. $dumper = new PhpDumper($container);
  473. $dumper->dump();
  474. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_default_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_DefaultParameters']));
  475. require self::$fixturesPath.'/php/services_default_env.php';
  476. $container = new \Symfony_DI_PhpDumper_Test_DefaultParameters();
  477. $this->assertSame('baz', $container->getParameter('hello'));
  478. $this->assertSame('foobaz', $container->getParameter('hello-bar'));
  479. }
  480. public function testDumpedUrlEnvParameters()
  481. {
  482. $container = new ContainerBuilder();
  483. $container->setParameter('env(foo)', 'postgres://user@localhost:5432/database?sslmode=disable');
  484. $container->setParameter('hello', '%env(url:foo)%');
  485. $container->compile();
  486. $dumper = new PhpDumper($container);
  487. $dumper->dump();
  488. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_url_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_UrlParameters']));
  489. require self::$fixturesPath.'/php/services_url_env.php';
  490. $container = new \Symfony_DI_PhpDumper_Test_UrlParameters();
  491. $this->assertSame([
  492. 'scheme' => 'postgres',
  493. 'host' => 'localhost',
  494. 'port' => 5432,
  495. 'user' => 'user',
  496. 'path' => 'database',
  497. 'query' => 'sslmode=disable',
  498. 'pass' => null,
  499. 'fragment' => null,
  500. ], $container->getParameter('hello'));
  501. }
  502. public function testDumpedQueryEnvParameters()
  503. {
  504. $container = new ContainerBuilder();
  505. $container->setParameter('env(foo)', 'foo=bar&baz[]=qux');
  506. $container->setParameter('hello', '%env(query_string:foo)%');
  507. $container->compile();
  508. $dumper = new PhpDumper($container);
  509. $dumper->dump();
  510. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_query_string_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_QueryStringParameters']));
  511. require self::$fixturesPath.'/php/services_query_string_env.php';
  512. $container = new \Symfony_DI_PhpDumper_Test_QueryStringParameters();
  513. $this->assertSame([
  514. 'foo' => 'bar',
  515. 'baz' => ['qux'],
  516. ], $container->getParameter('hello'));
  517. }
  518. public function testDumpedJsonEnvParameters()
  519. {
  520. $container = new ContainerBuilder();
  521. $container->setParameter('env(foo)', '["foo","bar"]');
  522. $container->setParameter('env(bar)', 'null');
  523. $container->setParameter('hello', '%env(json:foo)%');
  524. $container->setParameter('hello-bar', '%env(json:bar)%');
  525. $container->compile();
  526. $dumper = new PhpDumper($container);
  527. $dumper->dump();
  528. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_json_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_JsonParameters']));
  529. putenv('foobar="hello"');
  530. require self::$fixturesPath.'/php/services_json_env.php';
  531. $container = new \Symfony_DI_PhpDumper_Test_JsonParameters();
  532. $this->assertSame(['foo', 'bar'], $container->getParameter('hello'));
  533. $this->assertNull($container->getParameter('hello-bar'));
  534. }
  535. public function testCustomEnvParameters()
  536. {
  537. $container = new ContainerBuilder();
  538. $container->setParameter('env(foo)', str_rot13('world'));
  539. $container->setParameter('hello', '%env(rot13:foo)%');
  540. $container->register(Rot13EnvVarProcessor::class)->addTag('container.env_var_processor')->setPublic(true);
  541. $container->compile();
  542. $dumper = new PhpDumper($container);
  543. $dumper->dump();
  544. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_rot13_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Rot13Parameters']));
  545. require self::$fixturesPath.'/php/services_rot13_env.php';
  546. $container = new \Symfony_DI_PhpDumper_Test_Rot13Parameters();
  547. $this->assertSame('world', $container->getParameter('hello'));
  548. }
  549. public function testFileEnvProcessor()
  550. {
  551. $container = new ContainerBuilder();
  552. $container->setParameter('env(foo)', __FILE__);
  553. $container->setParameter('random', '%env(file:foo)%');
  554. $container->compile(true);
  555. $this->assertStringEqualsFile(__FILE__, $container->getParameter('random'));
  556. }
  557. public function testUnusedEnvParameter()
  558. {
  559. $this->expectException('Symfony\Component\DependencyInjection\Exception\EnvParameterException');
  560. $this->expectExceptionMessage('Environment variables "FOO" are never used. Please, check your container\'s configuration.');
  561. $container = new ContainerBuilder();
  562. $container->getParameter('env(FOO)');
  563. $container->compile();
  564. $dumper = new PhpDumper($container);
  565. $dumper->dump();
  566. }
  567. public function testCircularDynamicEnv()
  568. {
  569. $this->expectException('Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException');
  570. $this->expectExceptionMessage('Circular reference detected for parameter "env(resolve:DUMMY_ENV_VAR)" ("env(resolve:DUMMY_ENV_VAR)" > "env(resolve:DUMMY_ENV_VAR)").');
  571. $container = new ContainerBuilder();
  572. $container->setParameter('foo', '%bar%');
  573. $container->setParameter('bar', '%env(resolve:DUMMY_ENV_VAR)%');
  574. $container->compile();
  575. $dumper = new PhpDumper($container);
  576. $dump = $dumper->dump(['class' => $class = __FUNCTION__]);
  577. eval('?>'.$dump);
  578. $container = new $class();
  579. putenv('DUMMY_ENV_VAR=%foo%');
  580. try {
  581. $container->getParameter('bar');
  582. } finally {
  583. putenv('DUMMY_ENV_VAR');
  584. }
  585. }
  586. public function testInlinedDefinitionReferencingServiceContainer()
  587. {
  588. $container = new ContainerBuilder();
  589. $container->register('foo', 'stdClass')->addMethodCall('add', [new Reference('service_container')])->setPublic(false);
  590. $container->register('bar', 'stdClass')->addArgument(new Reference('foo'))->setPublic(true);
  591. $container->compile();
  592. $dumper = new PhpDumper($container);
  593. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
  594. }
  595. public function testNonSharedLazyDefinitionReferences()
  596. {
  597. $container = new ContainerBuilder();
  598. $container->register('foo', 'stdClass')->setShared(false)->setLazy(true);
  599. $container->register('bar', 'stdClass')->addArgument(new Reference('foo', ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, false))->setPublic(true);
  600. $container->compile();
  601. $dumper = new PhpDumper($container);
  602. $dumper->setProxyDumper(new \DummyProxyDumper());
  603. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_non_shared_lazy.php', $dumper->dump());
  604. }
  605. public function testInitializePropertiesBeforeMethodCalls()
  606. {
  607. require_once self::$fixturesPath.'/includes/classes.php';
  608. $container = new ContainerBuilder();
  609. $container->register('foo', 'stdClass')->setPublic(true);
  610. $container->register('bar', 'MethodCallClass')
  611. ->setPublic(true)
  612. ->setProperty('simple', 'bar')
  613. ->setProperty('complex', new Reference('foo'))
  614. ->addMethodCall('callMe');
  615. $container->compile();
  616. $dumper = new PhpDumper($container);
  617. eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls']));
  618. $container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
  619. $this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
  620. }
  621. public function testCircularReferenceAllowanceForLazyServices()
  622. {
  623. $container = new ContainerBuilder();
  624. $container->register('foo', 'stdClass')->addArgument(new Reference('bar'))->setPublic(true);
  625. $container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'))->setPublic(true);
  626. $container->compile();
  627. $dumper = new PhpDumper($container);
  628. $dumper->setProxyDumper(new \DummyProxyDumper());
  629. $dumper->dump();
  630. $this->addToAssertionCount(1);
  631. $dumper = new PhpDumper($container);
  632. $message = 'Circular reference detected for service "foo", path: "foo -> bar -> foo". Try running "composer require symfony/proxy-manager-bridge".';
  633. $this->expectException(ServiceCircularReferenceException::class);
  634. $this->expectExceptionMessage($message);
  635. $dumper->dump();
  636. }
  637. public function testDedupLazyProxy()
  638. {
  639. $container = new ContainerBuilder();
  640. $container->register('foo', 'stdClass')->setLazy(true)->setPublic(true);
  641. $container->register('bar', 'stdClass')->setLazy(true)->setPublic(true);
  642. $container->compile();
  643. $dumper = new PhpDumper($container);
  644. $dumper->setProxyDumper(new \DummyProxyDumper());
  645. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dedup_lazy_proxy.php', $dumper->dump());
  646. }
  647. public function testLazyArgumentProvideGenerator()
  648. {
  649. require_once self::$fixturesPath.'/includes/classes.php';
  650. $container = new ContainerBuilder();
  651. $container->register('lazy_referenced', 'stdClass')->setPublic(true);
  652. $container
  653. ->register('lazy_context', 'LazyContext')
  654. ->setPublic(true)
  655. ->setArguments([
  656. new IteratorArgument(['k1' => new Reference('lazy_referenced'), 'k2' => new Reference('service_container')]),
  657. new IteratorArgument([]),
  658. ])
  659. ;
  660. $container->compile();
  661. $dumper = new PhpDumper($container);
  662. eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator']));
  663. $container = new \Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator();
  664. $lazyContext = $container->get('lazy_context');
  665. $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyValues);
  666. $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyEmptyValues);
  667. $this->assertCount(2, $lazyContext->lazyValues);
  668. $this->assertCount(0, $lazyContext->lazyEmptyValues);
  669. $i = -1;
  670. foreach ($lazyContext->lazyValues as $k => $v) {
  671. switch (++$i) {
  672. case 0:
  673. $this->assertEquals('k1', $k);
  674. $this->assertInstanceOf('stdCLass', $v);
  675. break;
  676. case 1:
  677. $this->assertEquals('k2', $k);
  678. $this->assertInstanceOf('Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator', $v);
  679. break;
  680. }
  681. }
  682. $this->assertEmpty(iterator_to_array($lazyContext->lazyEmptyValues));
  683. }
  684. public function testNormalizedId()
  685. {
  686. $container = include self::$fixturesPath.'/containers/container33.php';
  687. $container->compile();
  688. $dumper = new PhpDumper($container);
  689. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services33.php', $dumper->dump());
  690. }
  691. public function testDumpContainerBuilderWithFrozenConstructorIncludingPrivateServices()
  692. {
  693. $container = new ContainerBuilder();
  694. $container->register('foo_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true);
  695. $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true);
  696. $container->register('baz_service', 'stdClass')->setPublic(false);
  697. $container->compile();
  698. $dumper = new PhpDumper($container);
  699. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_frozen.php', $dumper->dump());
  700. }
  701. public function testServiceLocator()
  702. {
  703. $container = new ContainerBuilder();
  704. $container->register('foo_service', ServiceLocator::class)
  705. ->setPublic(true)
  706. ->addArgument([
  707. 'bar' => new ServiceClosureArgument(new Reference('bar_service')),
  708. 'baz' => new ServiceClosureArgument(new TypedReference('baz_service', 'stdClass')),
  709. 'nil' => $nil = new ServiceClosureArgument(new Reference('nil')),
  710. ])
  711. ;
  712. // no method calls
  713. $container->register('translator.loader_1', 'stdClass')->setPublic(true);
  714. $container->register('translator.loader_1_locator', ServiceLocator::class)
  715. ->setPublic(false)
  716. ->addArgument([
  717. 'translator.loader_1' => new ServiceClosureArgument(new Reference('translator.loader_1')),
  718. ]);
  719. $container->register('translator_1', StubbedTranslator::class)
  720. ->setPublic(true)
  721. ->addArgument(new Reference('translator.loader_1_locator'));
  722. // one method calls
  723. $container->register('translator.loader_2', 'stdClass')->setPublic(true);
  724. $container->register('translator.loader_2_locator', ServiceLocator::class)
  725. ->setPublic(false)
  726. ->addArgument([
  727. 'translator.loader_2' => new ServiceClosureArgument(new Reference('translator.loader_2')),
  728. ]);
  729. $container->register('translator_2', StubbedTranslator::class)
  730. ->setPublic(true)
  731. ->addArgument(new Reference('translator.loader_2_locator'))
  732. ->addMethodCall('addResource', ['db', new Reference('translator.loader_2'), 'nl']);
  733. // two method calls
  734. $container->register('translator.loader_3', 'stdClass')->setPublic(true);
  735. $container->register('translator.loader_3_locator', ServiceLocator::class)
  736. ->setPublic(false)
  737. ->addArgument([
  738. 'translator.loader_3' => new ServiceClosureArgument(new Reference('translator.loader_3')),
  739. ]);
  740. $container->register('translator_3', StubbedTranslator::class)
  741. ->setPublic(true)
  742. ->addArgument(new Reference('translator.loader_3_locator'))
  743. ->addMethodCall('addResource', ['db', new Reference('translator.loader_3'), 'nl'])
  744. ->addMethodCall('addResource', ['db', new Reference('translator.loader_3'), 'en']);
  745. $nil->setValues([null]);
  746. $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true);
  747. $container->register('baz_service', 'stdClass')->setPublic(false);
  748. $container->compile();
  749. $dumper = new PhpDumper($container);
  750. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_locator.php', $dumper->dump());
  751. }
  752. public function testServiceSubscriber()
  753. {
  754. $container = new ContainerBuilder();
  755. $container->register('foo_service', TestServiceSubscriber::class)
  756. ->setPublic(true)
  757. ->setAutowired(true)
  758. ->addArgument(new Reference(ContainerInterface::class))
  759. ->addTag('container.service_subscriber', [
  760. 'key' => 'bar',
  761. 'id' => TestServiceSubscriber::class,
  762. ])
  763. ;
  764. $container->register(TestServiceSubscriber::class, TestServiceSubscriber::class)->setPublic(true);
  765. $container->register(CustomDefinition::class, CustomDefinition::class)
  766. ->setPublic(false);
  767. $container->register(TestDefinition1::class, TestDefinition1::class)->setPublic(true);
  768. $container->addCompilerPass(new class() implements CompilerPassInterface {
  769. /**
  770. * {@inheritdoc}
  771. */
  772. public function process(ContainerBuilder $container)
  773. {
  774. $container->setDefinition('late_alias', new Definition(TestDefinition1::class));
  775. $container->setAlias(TestDefinition1::class, 'late_alias');
  776. }
  777. }, PassConfig::TYPE_AFTER_REMOVING);
  778. $container->compile();
  779. $dumper = new PhpDumper($container);
  780. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump());
  781. }
  782. public function testPrivateWithIgnoreOnInvalidReference()
  783. {
  784. require_once self::$fixturesPath.'/includes/classes.php';
  785. $container = new ContainerBuilder();
  786. $container->register('not_invalid', 'BazClass')
  787. ->setPublic(false);
  788. $container->register('bar', 'BarClass')
  789. ->setPublic(true)
  790. ->addMethodCall('setBaz', [new Reference('not_invalid', SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)]);
  791. $container->compile();
  792. $dumper = new PhpDumper($container);
  793. eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference']));
  794. $container = new \Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference();
  795. $this->assertInstanceOf('BazClass', $container->get('bar')->getBaz());
  796. }
  797. public function testArrayParameters()
  798. {
  799. $container = new ContainerBuilder();
  800. $container->setParameter('array_1', [123]);
  801. $container->setParameter('array_2', [__DIR__]);
  802. $container->register('bar', 'BarClass')
  803. ->setPublic(true)
  804. ->addMethodCall('setBaz', ['%array_1%', '%array_2%', '%%array_1%%', [123]]);
  805. $container->compile();
  806. $dumper = new PhpDumper($container);
  807. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_array_params.php', str_replace('\\\\Dumper', '/Dumper', $dumper->dump(['file' => self::$fixturesPath.'/php/services_array_params.php', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false])));
  808. }
  809. public function testExpressionReferencingPrivateService()
  810. {
  811. $container = new ContainerBuilder();
  812. $container->register('private_bar', 'stdClass')
  813. ->setPublic(false);
  814. $container->register('private_foo', 'stdClass')
  815. ->setPublic(false);
  816. $container->register('public_foo', 'stdClass')
  817. ->setPublic(true)
  818. ->addArgument(new Expression('service("private_foo").bar'));
  819. $container->compile();
  820. $dumper = new PhpDumper($container);
  821. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_in_expression.php', $dumper->dump());
  822. }
  823. public function testUninitializedReference()
  824. {
  825. $container = include self::$fixturesPath.'/containers/container_uninitialized_ref.php';
  826. $container->compile();
  827. $dumper = new PhpDumper($container);
  828. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_uninitialized_ref.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Uninitialized_Reference']));
  829. require self::$fixturesPath.'/php/services_uninitialized_ref.php';
  830. $container = new \Symfony_DI_PhpDumper_Test_Uninitialized_Reference();
  831. $bar = $container->get('bar');
  832. $this->assertNull($bar->foo1);
  833. $this->assertNull($bar->foo2);
  834. $this->assertNull($bar->foo3);
  835. $this->assertNull($bar->closures[0]());
  836. $this->assertNull($bar->closures[1]());
  837. $this->assertNull($bar->closures[2]());
  838. $this->assertSame([], iterator_to_array($bar->iter));
  839. $container = new \Symfony_DI_PhpDumper_Test_Uninitialized_Reference();
  840. $container->get('foo1');
  841. $container->get('baz');
  842. $bar = $container->get('bar');
  843. $this->assertEquals(new \stdClass(), $bar->foo1);
  844. $this->assertNull($bar->foo2);
  845. $this->assertEquals(new \stdClass(), $bar->foo3);
  846. $this->assertEquals(new \stdClass(), $bar->closures[0]());
  847. $this->assertNull($bar->closures[1]());
  848. $this->assertEquals(new \stdClass(), $bar->closures[2]());
  849. $this->assertEquals(['foo1' => new \stdClass(), 'foo3' => new \stdClass()], iterator_to_array($bar->iter));
  850. }
  851. /**
  852. * @dataProvider provideAlmostCircular
  853. */
  854. public function testAlmostCircular($visibility)
  855. {
  856. $container = include self::$fixturesPath.'/containers/container_almost_circular.php';
  857. $container->compile();
  858. $dumper = new PhpDumper($container);
  859. $container = 'Symfony_DI_PhpDumper_Test_Almost_Circular_'.ucfirst($visibility);
  860. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php', $dumper->dump(['class' => $container]));
  861. require self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php';
  862. $container = new $container();
  863. $foo = $container->get('foo');
  864. $this->assertSame($foo, $foo->bar->foobar->foo);
  865. $foo2 = $container->get('foo2');
  866. $this->assertSame($foo2, $foo2->bar->foobar->foo);
  867. $this->assertSame([], (array) $container->get('foobar4'));
  868. $foo5 = $container->get('foo5');
  869. $this->assertSame($foo5, $foo5->bar->foo);
  870. $manager = $container->get('manager');
  871. $this->assertEquals(new \stdClass(), $manager);
  872. $manager = $container->get('manager2');
  873. $this->assertEquals(new \stdClass(), $manager);
  874. $foo6 = $container->get('foo6');
  875. $this->assertEquals((object) ['bar6' => (object) []], $foo6);
  876. $this->assertInstanceOf(\stdClass::class, $container->get('root'));
  877. $manager3 = $container->get('manager3');
  878. $listener3 = $container->get('listener3');
  879. $this->assertSame($manager3, $listener3->manager);
  880. $listener4 = $container->get('listener4');
  881. $this->assertInstanceOf('stdClass', $listener4);
  882. }
  883. public function provideAlmostCircular()
  884. {
  885. yield ['public'];
  886. yield ['private'];
  887. }
  888. public function testDeepServiceGraph()
  889. {
  890. $container = new ContainerBuilder();
  891. $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
  892. $loader->load('services_deep_graph.yml');
  893. $container->compile();
  894. $dumper = new PhpDumper($container);
  895. $dumper->dump();
  896. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_deep_graph.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Deep_Graph']));
  897. require self::$fixturesPath.'/php/services_deep_graph.php';
  898. $container = new \Symfony_DI_PhpDumper_Test_Deep_Graph();
  899. $this->assertInstanceOf(FooForDeepGraph::class, $container->get('foo'));
  900. $this->assertEquals((object) ['p2' => (object) ['p3' => (object) []]], $container->get('foo')->bClone);
  901. }
  902. public function testInlineSelfRef()
  903. {
  904. $container = new ContainerBuilder();
  905. $bar = (new Definition('App\Bar'))
  906. ->setProperty('foo', new Reference('App\Foo'));
  907. $baz = (new Definition('App\Baz'))
  908. ->setProperty('bar', $bar)
  909. ->addArgument($bar);
  910. $container->register('App\Foo')
  911. ->setPublic(true)
  912. ->addArgument($baz);
  913. $container->getCompiler()->getPassConfig();
  914. $container->compile();
  915. $dumper = new PhpDumper($container);
  916. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_self_ref.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Inline_Self_Ref']));
  917. }
  918. public function testHotPathOptimizations()
  919. {
  920. $container = include self::$fixturesPath.'/containers/container_inline_requires.php';
  921. $container->setParameter('inline_requires', true);
  922. $container->compile();
  923. $dumper = new PhpDumper($container);
  924. $dump = $dumper->dump(['hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'inline_requires', 'file' => self::$fixturesPath.'/php/services_inline_requires.php']);
  925. if ('\\' === \DIRECTORY_SEPARATOR) {
  926. $dump = str_replace("'\\\\includes\\\\HotPath\\\\", "'/includes/HotPath/", $dump);
  927. }
  928. $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_requires.php', $dump);
  929. }
  930. public function testDumpHandlesLiteralClassWithRootNamespace()
  931. {
  932. $container = new ContainerBuilder();
  933. $container->register('foo', '\\stdClass')->setPublic(tru

Large files files are truncated, but you can click here to view the full file