Skip to content

Commit 657b013

Browse files
committed
Added Unit tests for php 8 union types.
1 parent cf66f03 commit 657b013

File tree

6 files changed

+146
-1
lines changed

6 files changed

+146
-1
lines changed

src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,25 @@ public function testTypeNotGuessableNoServicesFound()
254254
$pass->process($container);
255255
}
256256

257+
/**
258+
* @requires PHP 8
259+
*/
260+
public function testTypeNotGuessableUnionType()
261+
{
262+
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');
263+
$this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionClasses::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionA|Symfony\Component\DependencyInjection\Tests\Compiler\CollisionB" but this class was not found.');
264+
$container = new ContainerBuilder();
265+
266+
$container->register(CollisionA::class);
267+
$container->register(CollisionB::class);
268+
269+
$aDefinition = $container->register('a', UnionClasses::class);
270+
$aDefinition->setAutowired(true);
271+
272+
$pass = new AutowirePass();
273+
$pass->process($container);
274+
}
275+
257276
public function testTypeNotGuessableWithTypeSet()
258277
{
259278
$container = new ContainerBuilder();
@@ -350,6 +369,40 @@ public function testOptionalParameter()
350369
$this->assertEquals(Foo::class, $definition->getArgument(2));
351370
}
352371

372+
/**
373+
* @requires PHP 8
374+
*/
375+
public function testParameterWithNullUnionIsSkipped()
376+
{
377+
$container = new ContainerBuilder();
378+
379+
$optDefinition = $container->register('opt', UnionNull::class);
380+
$optDefinition->setAutowired(true);
381+
382+
(new AutowirePass())->process($container);
383+
384+
$definition = $container->getDefinition('opt');
385+
$this->assertNull($definition->getArgument(0));
386+
}
387+
388+
/**
389+
* @requires PHP 8
390+
*/
391+
public function testParameterWithNullUnionIsAutowired()
392+
{
393+
$container = new ContainerBuilder();
394+
395+
$container->register(CollisionInterface::class, CollisionA::class);
396+
397+
$optDefinition = $container->register('opt', UnionNull::class);
398+
$optDefinition->setAutowired(true);
399+
400+
(new AutowirePass())->process($container);
401+
402+
$definition = $container->getDefinition('opt');
403+
$this->assertEquals(CollisionInterface::class, $definition->getArgument(0));
404+
}
405+
353406
public function testDontTriggerAutowiring()
354407
{
355408
$container = new ContainerBuilder();
@@ -459,6 +512,21 @@ public function testScalarArgsCannotBeAutowired()
459512
(new AutowirePass())->process($container);
460513
}
461514

515+
/**
516+
* @requires PHP 8
517+
*/
518+
public function testUnionScalarArgsCannotBeAutowired()
519+
{
520+
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');
521+
$this->expectExceptionMessage('Cannot autowire service "union_scalars": argument "$timeout" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionScalars::__construct()" is type-hinted "int|float", you should configure its value explicitly.');
522+
$container = new ContainerBuilder();
523+
524+
$container->register('union_scalars', UnionScalars::class)
525+
->setAutowired(true);
526+
527+
(new AutowirePass())->process($container);
528+
}
529+
462530
public function testNoTypeArgsCannotBeAutowired()
463531
{
464532
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
44

5+
if (PHP_VERSION_ID >= 80000) {
6+
require __DIR__.'/uniontype_classes.php';
7+
}
8+
59
class Foo
610
{
711
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
4+
5+
class UnionScalars
6+
{
7+
public function __construct(int|float $timeout)
8+
{
9+
}
10+
}
11+
12+
class UnionClasses
13+
{
14+
public function __construct(CollisionA|CollisionB $collision)
15+
{
16+
}
17+
}
18+
19+
class UnionNull
20+
{
21+
public function __construct(CollisionInterface|null $c)
22+
{
23+
}
24+
}

src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,15 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, \Ref
243243

244244
foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) {
245245
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type;
246+
if ('null' === $phpTypeOrClass && $reflectionType instanceof \ReflectionUnionType) {
247+
continue;
248+
}
246249

247250
if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
248251
$types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
249252
} elseif ('void' === $phpTypeOrClass || 'null' === $phpTypeOrClass) {
250253
$types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable);
251-
} elseif ($reflectionType->isBuiltin()) {
254+
} elseif ($type->isBuiltin()) {
252255
$types[] = new Type($phpTypeOrClass, $nullable);
253256
} else {
254257
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ public function php71TypesProvider()
204204
];
205205
}
206206

207+
/**
208+
* @dataProvider php80TypesProvider
209+
* @requires PHP 8
210+
*/
211+
public function testExtractPhp80Type($property, array $type = null)
212+
{
213+
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy', $property, []));
214+
}
215+
216+
public function php80TypesProvider()
217+
{
218+
return [
219+
['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)]],
220+
['bar', [new Type(Type::BUILTIN_TYPE_INT, true)]],
221+
['timeout', [new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_FLOAT)]],
222+
['optional', [new Type(Type::BUILTIN_TYPE_INT, true), new Type(Type::BUILTIN_TYPE_FLOAT, true)]],
223+
['string', [new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Stringable')]],
224+
];
225+
}
226+
207227
/**
208228
* @dataProvider getReadableProperties
209229
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
4+
5+
class Php80Dummy
6+
{
7+
public function getFoo(): array|null
8+
{
9+
}
10+
11+
public function setBar(int|null $bar)
12+
{
13+
}
14+
15+
public function setTimeout(int|float $timeout)
16+
{
17+
}
18+
19+
public function getOptional(): int|float|null
20+
{
21+
}
22+
23+
public function setString(string|\Stringable $string)
24+
{
25+
}
26+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy