/** * @param Schema $schema * @param $request * @param mixed $root * @param array|null $variables * @param string|null $operation * * @return array */ public static function execute(Schema $schema, $request, $root = NULL, $variables = NULL, $operation = NULL) { try { $source = new Source($request ?: '', 'GraphQL request'); $parser = new Parser(); $ast = $parser->parse($source); return Executor::execute($schema, $root, $ast, $operation, $variables); } catch (\Exception $exception) { return ['errors' => $exception->getMessage()]; } }
public function testExecutesUsingASchema() { $blogArticle = NULL; $blogImage = new ObjectType('Image', ['url' => ['type' => Type::stringType()], 'width' => ['type' => Type::intType()], 'height' => ['type' => Type::intType()]]); $blogAuthor = new ObjectType('Author', ['id' => ['type' => Type::stringType()], 'name' => ['type' => Type::stringType()], 'pic' => ['args' => ['width' => ['type' => Type::intType()], 'height' => ['type' => Type::intType()]], 'type' => $blogImage, 'resolve' => function ($obj, $args) { return $obj['pic']($args['width'], $args['height']); }], 'recentArticle' => ['type' => function () use(&$blogArticle) { return $blogArticle; }]]); $blogArticle = new ObjectType('Article', ['id' => ['type' => new NonNullModifier(Type::stringType())], 'isPublished' => ['type' => Type::booleanType()], 'author' => ['type' => $blogAuthor], 'title' => ['type' => Type::stringType()], 'body' => ['type' => Type::stringType()], 'keywords' => ['type' => new ListModifier(Type::stringType())]]); $blogQuery = new ObjectType('Query', ['article' => ['type' => $blogArticle, 'args' => ['id' => ['type' => Type::idType()]], 'resolve' => function ($_, $args) { return $this->article($args['id']); }], 'feed' => ['type' => new ListModifier($blogArticle), 'resolve' => function () { return [$this->article(1), $this->article(2), $this->article(3), $this->article(4), $this->article(5), $this->article(6), $this->article(7), $this->article(8), $this->article(9), $this->article(10)]; }]]); $blogSchema = new Schema($blogQuery); $request = ' { feed { id, title }, article(id: "1") { ...articleFields, author { id, name, pic(width: 640, height: 480) { url, width, height }, recentArticle { ...articleFields, keywords } } } } fragment articleFields on Article { id, isPublished, title, body, hidden, notdefined } '; $expected = ['data' => ['feed' => [['id' => '1', 'title' => 'My Article 1'], ['id' => '2', 'title' => 'My Article 2'], ['id' => '3', 'title' => 'My Article 3'], ['id' => '4', 'title' => 'My Article 4'], ['id' => '5', 'title' => 'My Article 5'], ['id' => '6', 'title' => 'My Article 6'], ['id' => '7', 'title' => 'My Article 7'], ['id' => '8', 'title' => 'My Article 8'], ['id' => '9', 'title' => 'My Article 9'], ['id' => '10', 'title' => 'My Article 10']], 'article' => ['id' => '1', 'isPublished' => TRUE, 'title' => 'My Article 1', 'body' => 'This is a post', 'author' => ['id' => '123', 'name' => 'John Smith', 'pic' => ['url' => 'cdn://123', 'width' => 640, 'height' => 480], 'recentArticle' => ['id' => '1', 'isPublished' => TRUE, 'title' => 'My Article 1', 'body' => 'This is a post', 'keywords' => ['foo', 'bar', '1', 'true', NULL]]]]]]; $parser = new Parser(); $this->assertEquals($expected, Executor::execute($blogSchema, NULL, $parser->parse(new Source($request)), '', [])); }
public function testParseCreatesAst() { $source = new Source(' { node(id: 4) { id, name } } '); $parser = new Parser(); $result = $parser->parse($source); $expected = new Document([new OperationDefinition('query', NULL, [], [], new SelectionSet([new Field(new Name('node', new Location(31, 35, $source)), NULL, [new Argument(new Name('id', new Location(36, 38, $source)), new IntValue('4', new Location(40, 41, $source)), new Location(36, 41, $source))], [], new SelectionSet([new Field(new Name('id', new Location(65, 67, $source)), NULL, [], [], NULL, new Location(65, 67, $source)), new Field(new Name('name', new Location(89, 93, $source)), NULL, [], [], NULL, new Location(89, 93, $source))], new Location(43, 111, $source)), new Location(31, 111, $source))], new Location(13, 125, $source)), new Location(13, 125, $source))], new Location(13, 134, $source)); $this->assertEquals($expected, $result); }
public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull() { $document = 'query Q { nonNullSync }'; $expected = ['data' => NULL, 'errors' => [new \Exception('Cannot return null for non-nullable type.')]]; $parser = new Parser(); $ast = $parser->parse(new Source($document)); $this->assertEquals($expected, Executor::execute($this->schema, $this->NULLingData, $ast)); }
public function testDoesNotAllowNonNullListsOfNonNullsToContainNull() { $document = ' query q($input:[String!]!) { nnListNN(input: $input) } '; $parser = new Parser(); $ast = $parser->parse(new Source($document)); $expected = ['data' => NULL, 'errors' => [new \Exception('Variable $input expected value of different type.')]]; $this->assertEquals($expected, Executor::execute($this->getSchema(), NULL, $ast, NULL, ['input' => ['A', NULL, 'B']])); }
public function testHandlesNonNullListsOfNonNullsWhenTheyReturnNull() { $document = ' query Q { nest { nonNullListOfNonNullReturnsNull, } } '; $parser = new Parser(); $ast = $parser->parse(new Source($document)); $expected = ['data' => ['nest' => NULL], 'errors' => [new \Exception('Cannot return null for non-nullable type.')]]; $this->assertEquals($expected, Executor::execute($this->getSchema(), $this->getData(), $ast, 'Q', [])); }
public function testAllowsFragmentConditionsToBeAbstractTypes() { $parser = new Parser(); $ast = $parser->parse(new Source(' { __typename name pets { ...PetFields } friends { ...FriendFields } } fragment PetFields on Pet { __typename ... on Dog { name barks } ... on Cat { name meows } } fragment FriendFields on Named { __typename name ... on Dog { barks } ... on Cat { meows } } ')); $expected = ['data' => ['__typename' => 'Person', 'name' => 'John', 'pets' => [['__typename' => 'Cat', 'name' => 'Garfield', 'meows' => FALSE], ['__typename' => 'Dog', 'name' => 'Odie', 'barks' => TRUE]], 'friends' => [['__typename' => 'Person', 'name' => 'Liz'], ['__typename' => 'Dog', 'name' => 'Odie', 'barks' => TRUE]]]]; $this->assertEquals($expected, Executor::execute($this->schema, $this->john, $ast)); }
protected function executeTestQuery($document) { $data = ['a' => function () { return 'a'; }, 'b' => function () { return 'b'; }]; $schema = new Schema(new ObjectType('TestType', ['a' => ['type' => Type::stringType()], 'b' => ['type' => Type::stringType()]])); $parser = new Parser(); return Executor::execute($schema, $data, $parser->parse(new Source($document))); }
public function testDoesNotIncludeIllegalFieldsInOutput() { $document = ' mutation M { thisIsIllegalDontIncludeMe } '; $parser = new Parser(); $ast = $parser->parse(new Source($document)); $schema = new Schema(new ObjectType('Q', ['a' => ['type' => Type::stringType()]]), new ObjectType('M', ['c' => ['type' => Type::stringType()]])); $result = Executor::execute($schema, NULL, $ast); $this->assertEquals(['data' => []], $result); }