PageRenderTime 186ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

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

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

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