Skip to content

Commit 2bcaaa9

Browse files
committed
Refactor the symfony integration to use one service locator per test case
1 parent fe459c1 commit 2bcaaa9

File tree

5 files changed

+31
-45
lines changed

5 files changed

+31
-45
lines changed

depfile.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ ruleset:
7272
- TestCase
7373
- Symfony DependencyInjection
7474
Symfony TestCase:
75-
- Symfony Compiler
7675
- Psr Container
7776
- Symfony DependencyInjection
7877
- Symfony HttpKernel

src/Symfony/Compiler/ExposeServicesForTestsPass.php

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,32 @@
1212

1313
class ExposeServicesForTestsPass implements CompilerPassInterface
1414
{
15-
const DEFAULT_SERVICE_LOCATOR_ID = 'app.test.service_locator';
16-
17-
/**
18-
* @var string
19-
*/
20-
private $serviceLocatorId;
21-
2215
/**
2316
* @var PropertyDiscovery
2417
*/
2518
private $propertyDiscovery;
2619

27-
public function __construct(string $serviceLocatorId = self::DEFAULT_SERVICE_LOCATOR_ID, ?PropertyDiscovery $propertyDiscovery = null)
20+
public function __construct(?PropertyDiscovery $propertyDiscovery = null)
2821
{
29-
$this->serviceLocatorId = $serviceLocatorId;
3022
$this->propertyDiscovery = $propertyDiscovery ?? new PropertyDiscovery();
3123
}
3224

3325
public function process(ContainerBuilder $container): void
3426
{
35-
$container->register($this->serviceLocatorId, ServiceLocator::class)
36-
->setPublic(true)
37-
->addTag('container.service_locator')
38-
->addArgument($this->discoverServices());
27+
foreach ($this->discoverServices() as $testClass => $references) {
28+
$container->register($testClass, ServiceLocator::class)
29+
->setPublic(true)
30+
->addTag('container.service_locator')
31+
->addArgument($references);
32+
}
3933
}
4034

4135
private function discoverServices(): array
4236
{
43-
return $this->flatMap(
44-
function (Property $property) {
45-
return [$property->getServiceId() => new Reference($property->getServiceId())];
46-
},
47-
$this->propertyDiscovery->run()
48-
);
49-
}
37+
return \array_reduce($this->propertyDiscovery->run(), function (array $services, Property $property) {
38+
$services[$property->getClassName()][$property->getServiceId()] = new Reference($property->getServiceId());
5039

51-
private function flatMap(callable $callback, array $collection): array
52-
{
53-
return \array_merge([], ...\array_map($callback, $collection));
40+
return $services;
41+
}, []);
5442
}
5543
}

src/Symfony/TestCase/SymfonyContainer.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
namespace Zalas\Injector\PHPUnit\Symfony\TestCase;
55

66
use Psr\Container\ContainerInterface;
7-
use Zalas\Injector\PHPUnit\Symfony\Compiler\ExposeServicesForTestsPass;
87

98
/**
109
* Provides a `ServiceContainerTestCase` implementation with the container created by the Symfony Kernel.
@@ -15,11 +14,6 @@ trait SymfonyContainer
1514

1615
public function createContainer(): ContainerInterface
1716
{
18-
return static::bootKernel()->getContainer()->get($this->getTestServiceLocatorId());
19-
}
20-
21-
protected function getTestServiceLocatorId(): string
22-
{
23-
return ExposeServicesForTestsPass::DEFAULT_SERVICE_LOCATOR_ID;
17+
return static::bootKernel()->getContainer()->get(__CLASS__);
2418
}
2519
}

tests/Symfony/Compiler/ExposeServicesForTestsPassTest.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
use Zalas\Injector\PHPUnit\Tests\Symfony\Compiler\Fixtures\Service1;
1515
use Zalas\Injector\PHPUnit\Tests\Symfony\Compiler\Fixtures\Service2;
1616
use Zalas\Injector\PHPUnit\Tests\Symfony\Compiler\Fixtures\TestCase1;
17+
use Zalas\Injector\PHPUnit\Tests\Symfony\Compiler\Fixtures\TestCase2;
1718
use Zalas\Injector\Service\Property;
1819

1920
class ExposeServicesForTestsPassTest extends TestCase
2021
{
21-
const SERVICE_LOCATOR_ID = 'app.test.service_locator';
22-
2322
/**
2423
* @var ExposeServicesForTestsPass
2524
*/
@@ -33,42 +32,49 @@ class ExposeServicesForTestsPassTest extends TestCase
3332
protected function setUp()
3433
{
3534
$this->discovery = $this->prophesize(PropertyDiscovery::class);
36-
$this->pass = new ExposeServicesForTestsPass(self::SERVICE_LOCATOR_ID, $this->discovery->reveal());
35+
$this->pass = new ExposeServicesForTestsPass($this->discovery->reveal());
3736
}
3837

3938
public function test_it_is_a_compiler_pass()
4039
{
4140
$this->assertInstanceOf(CompilerPassInterface::class, $this->pass);
4241
}
4342

44-
public function test_it_registers_a_service_locator_for_services_used_in_tests()
43+
public function test_it_registers_a_service_locator_for_each_test_case_requiring_service_injection()
4544
{
4645
$this->discovery->run()->willReturn([
4746
new Property(TestCase1::class, 'service1', Service1::class),
4847
new Property(TestCase1::class, 'service2', Service2::class),
48+
new Property(TestCase2::class, 'service2', Service2::class),
4949
]);
5050

5151
$container = new ContainerBuilder();
5252

5353
$this->pass->process($container);
5454

55-
$this->assertTrue($container->hasDefinition(self::SERVICE_LOCATOR_ID), 'The service locator is registered as a service.');
56-
$this->assertSame(ServiceLocator::class, $container->getDefinition(self::SERVICE_LOCATOR_ID)->getClass());
57-
$this->assertFalse($container->getDefinition(self::SERVICE_LOCATOR_ID)->isPrivate(), 'The service locator is registered as a public service.');
58-
$this->assertTrue($container->getDefinition(self::SERVICE_LOCATOR_ID)->isPublic(), 'The service locator is registered as a public service.');
59-
$this->assertTrue($container->getDefinition(self::SERVICE_LOCATOR_ID)->hasTag('container.service_locator'), 'The service locator is tagged.');
60-
$this->assertEquals([Service1::class => new Reference(Service1::class), Service2::class => new Reference(Service2::class)], $container->getDefinition(self::SERVICE_LOCATOR_ID)->getArgument(0));
55+
$this->assertTrue($container->hasDefinition(TestCase1::class), 'The first test case service locator is registered as a service.');
56+
$this->assertSame(ServiceLocator::class, $container->getDefinition(TestCase1::class)->getClass());
57+
$this->assertSame(ServiceLocator::class, $container->getDefinition(TestCase2::class)->getClass());
58+
$this->assertFalse($container->getDefinition(TestCase1::class)->isPrivate(), 'The first test case service locator is registered as a public service.');
59+
$this->assertTrue($container->getDefinition(TestCase1::class)->isPublic(), 'The first test case service locator is registered as a public service.');
60+
$this->assertTrue($container->getDefinition(TestCase1::class)->hasTag('container.service_locator'), 'The first case service locator is tagged.');
61+
$this->assertEquals([Service1::class => new Reference(Service1::class), Service2::class => new Reference(Service2::class)], $container->getDefinition(TestCase1::class)->getArgument(0));
62+
$this->assertTrue($container->hasDefinition(TestCase2::class), 'The second test case service locator is registered as a service.');
63+
$this->assertFalse($container->getDefinition(TestCase2::class)->isPrivate(), 'The second test case service locator is registered as a public service.');
64+
$this->assertTrue($container->getDefinition(TestCase2::class)->isPublic(), 'The second test case service locator is registered as a public service.');
65+
$this->assertTrue($container->getDefinition(TestCase2::class)->hasTag('container.service_locator'), 'The second test case service locator is tagged.');
66+
$this->assertEquals([Service2::class => new Reference(Service2::class)], $container->getDefinition(TestCase2::class)->getArgument(0));
6167
}
6268

63-
public function test_it_registers_an_empty_service_locator_if_no_services_were_discovered()
69+
public function test_it_only_registers_a_service_locator_if_any_services_were_discovered()
6470
{
6571
$this->discovery->run()->willReturn([]);
6672

6773
$container = new ContainerBuilder();
6874

6975
$this->pass->process($container);
7076

71-
$this->assertTrue($container->hasDefinition(self::SERVICE_LOCATOR_ID), 'The service locator is registered as a service.');
72-
$this->assertEquals([], $container->getDefinition(self::SERVICE_LOCATOR_ID)->getArgument(0), 'No services were registered on the service locator.');
77+
$this->assertfalse($container->hasDefinition(TestCase1::class), 'The first test case service locator is not registered as a service.');
78+
$this->assertfalse($container->hasDefinition(TestCase2::class), 'The second test case service locator is not registered as a service.');
7379
}
7480
}

tests/Symfony/TestCase/Fixtures/TestKernel.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ protected function build(ContainerBuilder $container)
4343
if ('test' === $this->getEnvironment()) {
4444
$container->addCompilerPass(
4545
new ExposeServicesForTestsPass(
46-
ExposeServicesForTestsPass::DEFAULT_SERVICE_LOCATOR_ID,
4746
new PropertyDiscovery(new ClassFinder(__DIR__ . '/../'))
4847
)
4948
);

0 commit comments

Comments
 (0)