From 3e2d9459aaf06b0e837666dda1cef8922f26b944 Mon Sep 17 00:00:00 2001 From: vladar Date: Tue, 18 Oct 2016 22:23:20 +0700 Subject: [PATCH] resolveType for interface/unions is now allowed to return type name vs instance --- src/Executor/Executor.php | 5 ++ tests/Executor/AbstractTest.php | 81 ++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 3a46f5e..91271e1 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -734,6 +734,11 @@ class Executor call_user_func($resolveType, $result, $exeContext->contextValue, $info) : Type::getTypeOf($result, $exeContext->contextValue, $info, $returnType); + // If resolveType returns a string, we assume it's a ObjectType name. + if (is_string($runtimeType)) { + $runtimeType = $exeContext->schema->getType($runtimeType); + } + if (!($runtimeType instanceof ObjectType)) { throw new Error( "Abstract type {$returnType} must resolve to an Object type at runtime " . diff --git a/tests/Executor/AbstractTest.php b/tests/Executor/AbstractTest.php index f5f87c2..ea6687c 100644 --- a/tests/Executor/AbstractTest.php +++ b/tests/Executor/AbstractTest.php @@ -1,6 +1,8 @@ assertEquals($expected, $result); } + + /** + * @it resolveType allows resolving with type name + */ + public function testResolveTypeAllowsResolvingWithTypeName() + { + $PetType = new InterfaceType([ + 'name' => 'Pet', + 'resolveType' => function($obj) { + if ($obj instanceof Dog) return 'Dog'; + if ($obj instanceof Cat) return 'Cat'; + return null; + }, + 'fields' => [ + 'name' => [ 'type' => Type::string() ] + ] + ]); + + $DogType = new ObjectType([ + 'name' => 'Dog', + 'interfaces' => [ $PetType ], + 'fields' => [ + 'name' => [ 'type' => Type::string() ], + 'woofs' => [ 'type' => Type::boolean() ], + ] + ]); + + $CatType = new ObjectType([ + 'name' => 'Cat', + 'interfaces' => [ $PetType ], + 'fields' => [ + 'name' => [ 'type' => Type::string() ], + 'meows' => [ 'type' => Type::boolean() ], + ] + ]); + + $schema = new Schema([ + 'query' => new ObjectType([ + 'name' => 'Query', + 'fields' => [ + 'pets' => [ + 'type' => Type::listOf($PetType), + 'resolve' => function() { + return [ + new Dog('Odie', true), + new Cat('Garfield', false) + ]; + } + ] + ] + ]), + 'types' => [ $CatType, $DogType ] + ]); + + $query = '{ + pets { + name + ... on Dog { + woofs + } + ... on Cat { + meows + } + } + }'; + + $result = GraphQL::execute($schema, $query); + + $this->assertEquals([ + 'data' => [ + 'pets' => [ + ['name' => 'Odie', 'woofs' => true], + ['name' => 'Garfield', 'meows' => false] + ] + ] + ], $result); + } }