‪TYPO3CMS  ‪main
ServiceProviderCompilationPassTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\Test;
21 use Psr\Log\NullLogger;
22 use Symfony\Component\DependencyInjection\ContainerBuilder;
23 use Symfony\Component\DependencyInjection\Definition;
27 use TYPO3\CMS\Core\Package\PackageManager;
32 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
33 
34 final class ‪ServiceProviderCompilationPassTest extends UnitTestCase
35 {
36  protected function ‪getContainer(array $serviceProviders, callable $configure = null): ContainerBuilder
37  {
38  static $id = 0;
39 
40  $packages = [];
41  foreach ($serviceProviders as $serviceProvider) {
42  $package = $this->createMock(Package::class);
43  $package->method('getPackageKey')->willReturn($serviceProvider);
44  $package->method('getServiceProvider')->willReturn($serviceProvider);
45  $packages[$serviceProvider] = $package;
46  }
47 
48  $packageManager = $this->createMock(PackageManager::class);
49  $packageManager->method('getActivePackages')->willReturn($packages);
50 
51  $registry = new ‪ServiceProviderRegistry($packageManager);
52  $registryServiceName = 'service_provider_registry_' . ++$id;
53 
54  $container = new ContainerBuilder();
55  if ($configure !== null) {
56  $configure($container);
57  }
58  $logger = new Definition(NullLogger::class);
59  $logger->setPublic(true);
60  $container->setDefinition('logger', $logger);
61 
62  $container->addCompilerPass(new ‪ServiceProviderCompilationPass($registry, $registryServiceName));
63  $container->compile();
64  $container->set($registryServiceName, $registry);
65 
66  return $container;
67  }
68 
69  #[Test]
70  public function ‪simpleServiceProvider(): void
71  {
72  $container = $this->‪getContainer([
73  TestServiceProvider::class,
74  ]);
75 
76  $serviceA = $container->get('serviceA');
77  $serviceD = $container->get('serviceD');
78  $serviceE = $container->get('serviceE');
79 
80  self::assertInstanceOf(\stdClass::class, $serviceA);
81  self::assertInstanceOf(\stdClass::class, $serviceD);
82  self::assertInstanceOf(\stdClass::class, $serviceE);
83  self::assertIsObject($container->get('function'));
84  }
85 
86  #[Test]
87  public function ‪serviceProviderOverrides(): void
88  {
89  $container = $this->‪getContainer([
90  TestServiceProvider::class,
91  TestServiceProviderOverride::class,
92  TestServiceProviderOverride2::class,
93  ]);
94 
95  $serviceA = $container->get('serviceA');
96  $serviceC = $container->get('serviceC');
97  $serviceE = $container->get('serviceE');
98 
99  self::assertInstanceOf(\stdClass::class, $serviceA);
100  self::assertEquals('foo', $serviceA->newProperty);
101  self::assertEquals('bar', $serviceA->newProperty2);
102  self::assertEquals('localhost', $serviceC->serviceB->parameter);
103  self::assertEquals('baz', $serviceE->parameter);
104  }
105 
106  #[Test]
107  public function ‪serviceProviderFactoryOverrides(): void
108  {
109  $container = $this->‪getContainer([
110  TestServiceProvider::class,
111  TestServiceProviderFactoryOverride::class,
112  ]);
113 
114  $serviceA = $container->get('serviceA');
115 
116  self::assertInstanceOf(\stdClass::class, $serviceA);
117  self::assertEquals('remotehost', $serviceA->serviceB->parameter);
118  }
119 
120  #[Test]
122  {
123  $container = $this->‪getContainer(
124  [
125  TestServiceProvider::class,
126  TestServiceProviderFactoryOverride::class,
127  ],
128  static function (ContainerBuilder $container) {
129  $definition = new Definition(\stdClass::class);
130  // property should be overridden by service provider
131  $definition->setProperty('parameter', 'remotehost');
132  // property should not be "deleted" by service provider
133  $definition->setProperty('symfony_defined_parameter', 'foobar');
134  $container->setDefinition('serviceB', $definition);
135  }
136  );
137 
138  $serviceA = $container->get('serviceA');
139 
140  self::assertInstanceOf(\stdClass::class, $serviceA);
141  self::assertEquals('remotehost', $serviceA->serviceB->parameter);
142  self::assertEquals('foobar', $serviceA->serviceB->symfony_defined_parameter);
143  }
144 
145  #[Test]
147  {
148  $container = $this->‪getContainer(
149  [
150  TestServiceProvider::class,
151  TestServiceProviderFactoryOverride::class,
152  ],
153  static function (ContainerBuilder $container) {
154  $definition = new Definition(\stdClass::class);
155  // property should be overridden by service provider
156  $definition->setProperty('parameter', 'remotehost');
157  // property should not be "deleted" by service provider
158  $definition->setProperty('symfony_defined_parameter', 'foobar');
159  $definition->setAutowired(true);
160  $container->setDefinition('serviceB', $definition);
161  }
162  );
163 
164  $serviceA = $container->get('serviceA');
165 
166  self::assertInstanceOf(\stdClass::class, $serviceA);
167  self::assertEquals('remotehost', $serviceA->serviceB->parameter);
168  self::assertEquals('foobar', $serviceA->serviceB->symfony_defined_parameter);
169  self::assertFalse($container->getDefinition('serviceB')->isAutowired());
170  }
171 
172  #[Test]
174  {
175  $this->expectException(\Exception::class);
176  $this->expectExceptionMessage('A registered extension for the service "serviceA" requires the service to be available, which is missing.');
177 
178  $this->‪getContainer([
179  TestServiceProviderOverride::class,
180  ]);
181  }
182 }
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\serviceProviderOverrides
‪serviceProviderOverrides()
Definition: ServiceProviderCompilationPassTest.php:87
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\serviceProviderFactoryOverrideResetsAutowiring
‪serviceProviderFactoryOverrideResetsAutowiring()
Definition: ServiceProviderCompilationPassTest.php:146
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\Fixtures\TestServiceProviderOverride2
Definition: TestServiceProviderOverride2.php:24
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\serviceProviderFactoryOverridesForSymfonyDefinedServices
‪serviceProviderFactoryOverridesForSymfonyDefinedServices()
Definition: ServiceProviderCompilationPassTest.php:121
‪TYPO3\CMS\Core\DependencyInjection\ServiceProviderCompilationPass
Definition: ServiceProviderCompilationPass.php:29
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\exceptionForNonNullableExtensionArgument
‪exceptionForNonNullableExtensionArgument()
Definition: ServiceProviderCompilationPassTest.php:173
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\Fixtures\TestServiceProvider
Definition: TestServiceProvider.php:35
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\Fixtures\TestServiceProviderFactoryOverride
Definition: TestServiceProviderFactoryOverride.php:24
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection
Definition: ConsoleCommandPassTest.php:18
‪TYPO3\CMS\Core\Package\Package
Definition: Package.php:30
‪TYPO3\CMS\Core\DependencyInjection\ServiceProviderRegistry
Definition: ServiceProviderRegistry.php:31
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\getContainer
‪getContainer(array $serviceProviders, callable $configure=null)
Definition: ServiceProviderCompilationPassTest.php:36
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\Fixtures\TestServiceProviderOverride
Definition: TestServiceProviderOverride.php:24
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\simpleServiceProvider
‪simpleServiceProvider()
Definition: ServiceProviderCompilationPassTest.php:70
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest\serviceProviderFactoryOverrides
‪serviceProviderFactoryOverrides()
Definition: ServiceProviderCompilationPassTest.php:107
‪TYPO3\CMS\Core\Tests\Unit\DependencyInjection\ServiceProviderCompilationPassTest
Definition: ServiceProviderCompilationPassTest.php:35