Skip to content

Commit c9afcd7

Browse files
committed
fix: Allows union types in native returns
1 parent da8a377 commit c9afcd7

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

src/Mappers/Parameters/TypeHandler.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use ReflectionParameter;
2828
use ReflectionProperty;
2929
use ReflectionType;
30+
use ReflectionUnionType;
3031
use TheCodingMachine\GraphQLite\Annotations\HideParameter;
3132
use TheCodingMachine\GraphQLite\Annotations\ParameterAnnotations;
3233
use TheCodingMachine\GraphQLite\Annotations\UseInputType;
@@ -42,6 +43,7 @@
4243
use TheCodingMachine\GraphQLite\Types\TypeResolver;
4344
use Webmozart\Assert\Assert;
4445

46+
use function array_map;
4547
use function array_merge;
4648
use function array_unique;
4749
use function assert;
@@ -408,17 +410,35 @@ private function appendTypes(Type $type, ?Type $docBlockType): Type
408410
*/
409411
private function reflectionTypeToPhpDocType(ReflectionType $type, ReflectionClass $reflectionClass): Type
410412
{
411-
assert($type instanceof ReflectionNamedType);
412-
$phpdocType = $this->phpDocumentorTypeResolver->resolve($type->getName());
413-
Assert::notNull($phpdocType);
413+
assert($type instanceof ReflectionNamedType || $type instanceof ReflectionUnionType);
414+
if ($type instanceof ReflectionNamedType) {
415+
$phpdocType = $this->phpDocumentorTypeResolver->resolve($type->getName());
416+
Assert::notNull($phpdocType);
414417

415-
$phpdocType = $this->resolveSelf($phpdocType, $reflectionClass);
418+
$phpdocType = $this->resolveSelf($phpdocType, $reflectionClass);
416419

417-
if ($type->allowsNull()) {
418-
$phpdocType = new Nullable($phpdocType);
419-
}
420+
if ($type->allowsNull()) {
421+
$phpdocType = new Nullable($phpdocType);
422+
}
420423

421-
return $phpdocType;
424+
return $phpdocType;
425+
}
426+
return new Compound(
427+
array_map(
428+
function (ReflectionNamedType $namedType) use ($reflectionClass): Type {
429+
$phpdocType = $this->phpDocumentorTypeResolver->resolve($namedType->getName());
430+
Assert::notNull($phpdocType);
431+
432+
$phpdocType = $this->resolveSelf($phpdocType, $reflectionClass);
433+
434+
if ($namedType->allowsNull()) {
435+
$phpdocType = new Nullable($phpdocType);
436+
}
437+
return $phpdocType;
438+
},
439+
$type->getTypes()
440+
)
441+
);
422442
}
423443

424444
/**

tests/Mappers/Parameters/TypeMapperTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
namespace TheCodingMachine\GraphQLite\Mappers\Parameters;
44

55
use DateTimeImmutable;
6+
use GraphQL\Type\Definition\NonNull;
67
use GraphQL\Type\Definition\ResolveInfo;
8+
use GraphQL\Type\Definition\UnionType;
79
use ReflectionMethod;
810
use Symfony\Component\Cache\Adapter\ArrayAdapter;
911
use Symfony\Component\Cache\Psr16Cache;
1012
use Symfony\Component\Cache\Simple\ArrayCache;
1113
use TheCodingMachine\GraphQLite\AbstractQueryProviderTest;
1214
use TheCodingMachine\GraphQLite\Annotations\HideParameter;
15+
use TheCodingMachine\GraphQLite\Fixtures\TestObject;
16+
use TheCodingMachine\GraphQLite\Fixtures\TestObject2;
1317
use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException;
1418
use TheCodingMachine\GraphQLite\Mappers\Root\BaseTypeMapper;
1519
use TheCodingMachine\GraphQLite\Mappers\Root\CompositeRootTypeMapper;
@@ -34,6 +38,26 @@ public function testMapScalarUnionException(): void
3438
$typeMapper->mapReturnType($refMethod, $docBlockObj);
3539
}
3640

41+
public function testMapObjectUnionWorks(): void
42+
{
43+
$typeMapper = new TypeHandler($this->getArgumentResolver(), $this->getRootTypeMapper(), $this->getTypeResolver());
44+
45+
$cachedDocBlockFactory = new CachedDocBlockFactory(new Psr16Cache(new ArrayAdapter()));
46+
47+
$refMethod = new ReflectionMethod($this, 'objectUnion');
48+
$docBlockObj = $cachedDocBlockFactory->getDocBlock($refMethod);
49+
50+
$gqType = $typeMapper->mapReturnType($refMethod, $docBlockObj);
51+
$this->assertInstanceOf(NonNull::class, $gqType);
52+
assert($gqType instanceof NonNull);
53+
$memberType = $gqType->getOfType();
54+
$this->assertInstanceOf(UnionType::class, $memberType);
55+
assert($memberType instanceof UnionType);
56+
$unionTypes = $memberType->getTypes();
57+
$this->assertEquals('TestObject', $unionTypes[0]->name);
58+
$this->assertEquals('TestObject2', $unionTypes[1]->name);
59+
}
60+
3761
public function testHideParameter(): void
3862
{
3963
$typeMapper = new TypeHandler($this->getArgumentResolver(), $this->getRootTypeMapper(), $this->getTypeResolver());
@@ -77,6 +101,10 @@ private function dummy() {
77101

78102
}
79103

104+
private function objectUnion(): TestObject|TestObject2 {
105+
return new TestObject((''));
106+
}
107+
80108
/**
81109
* @HideParameter(for="$foo")
82110
*/

0 commit comments

Comments
 (0)