Skip to content

Added Unit tests for php 8 union types #37346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,25 @@ public function testTypeNotGuessableNoServicesFound()
$pass->process($container);
}

/**
* @requires PHP 8
*/
public function testTypeNotGuessableUnionType()
{
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');
$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.');
$container = new ContainerBuilder();

$container->register(CollisionA::class);
$container->register(CollisionB::class);

$aDefinition = $container->register('a', UnionClasses::class);
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}

public function testTypeNotGuessableWithTypeSet()
{
$container = new ContainerBuilder();
Expand Down Expand Up @@ -350,6 +369,40 @@ public function testOptionalParameter()
$this->assertEquals(Foo::class, $definition->getArgument(2));
}

/**
* @requires PHP 8
*/
public function testParameterWithNullUnionIsSkipped()
{
$container = new ContainerBuilder();

$optDefinition = $container->register('opt', UnionNull::class);
$optDefinition->setAutowired(true);

(new AutowirePass())->process($container);

$definition = $container->getDefinition('opt');
$this->assertNull($definition->getArgument(0));
}

/**
* @requires PHP 8
*/
public function testParameterWithNullUnionIsAutowired()
{
$container = new ContainerBuilder();

$container->register(CollisionInterface::class, CollisionA::class);

$optDefinition = $container->register('opt', UnionNull::class);
$optDefinition->setAutowired(true);

(new AutowirePass())->process($container);

$definition = $container->getDefinition('opt');
$this->assertEquals(CollisionInterface::class, $definition->getArgument(0));
}

public function testDontTriggerAutowiring()
{
$container = new ContainerBuilder();
Expand Down Expand Up @@ -459,6 +512,21 @@ public function testScalarArgsCannotBeAutowired()
(new AutowirePass())->process($container);
}

/**
* @requires PHP 8
*/
public function testUnionScalarArgsCannotBeAutowired()
{
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');
$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.');
$container = new ContainerBuilder();

$container->register('union_scalars', UnionScalars::class)
->setAutowired(true);

(new AutowirePass())->process($container);
}

public function testNoTypeArgsCannotBeAutowired()
{
$this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

if (PHP_VERSION_ID >= 80000) {
require __DIR__.'/uniontype_classes.php';
}

class Foo
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

class UnionScalars
{
public function __construct(int|float $timeout)
{
}
}

class UnionClasses
{
public function __construct(CollisionA|CollisionB $collision)
{
}
}

class UnionNull
{
public function __construct(CollisionInterface|null $c)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,15 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, \Ref

foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) {
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type;
if ('null' === $phpTypeOrClass) {
continue;
}

if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
$types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
} elseif ('void' === $phpTypeOrClass || 'null' === $phpTypeOrClass) {
} elseif ('void' === $phpTypeOrClass) {
$types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable);
} elseif ($reflectionType->isBuiltin()) {
} elseif ($type->isBuiltin()) {
$types[] = new Type($phpTypeOrClass, $nullable);
} else {
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,26 @@ public function php71TypesProvider()
];
}

/**
* @dataProvider php80TypesProvider
* @requires PHP 8
*/
public function testExtractPhp80Type($property, array $type = null)
{
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy', $property, []));
}

public function php80TypesProvider()
{
return [
['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)]],
['bar', [new Type(Type::BUILTIN_TYPE_INT, true)]],
['timeout', [new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_FLOAT)]],
['optional', [new Type(Type::BUILTIN_TYPE_INT, true), new Type(Type::BUILTIN_TYPE_FLOAT, true)]],
['string', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Stringable'), new Type(Type::BUILTIN_TYPE_STRING)]],
];
}

/**
* @dataProvider getReadableProperties
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Symfony\Component\PropertyInfo\Tests\Fixtures;

class Php80Dummy
{
public function getFoo(): array|null
{
}

public function setBar(int|null $bar)
{
}

public function setTimeout(int|float $timeout)
{
}

public function getOptional(): int|float|null
{
}

public function setString(string|\Stringable $string)
{
}
}