Skip to content

Commit 8b2b4d5

Browse files
authored
Implement Utils::getOperationAST (#755)
1 parent cf6eddf commit 8b2b4d5

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

src/Utils/AST.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ public static function typeFromAST(Schema $schema, $inputTypeNode)
603603
}
604604

605605
/**
606+
* @deprecated use getOperationAST instead.
607+
*
606608
* Returns operation type ("query", "mutation" or "subscription") given a document and operation name
607609
*
608610
* @param string $operationName
@@ -627,4 +629,33 @@ public static function getOperation(DocumentNode $document, $operationName = nul
627629

628630
return false;
629631
}
632+
633+
/**
634+
* Returns the operation within a document by name.
635+
*
636+
* If a name is not provided, an operation is only returned if the document has exactly one.
637+
*
638+
* @api
639+
*/
640+
public static function getOperationAST(DocumentNode $document, ?string $operationName = null) : ?OperationDefinitionNode
641+
{
642+
$operation = null;
643+
foreach ($document->definitions->getIterator() as $node) {
644+
if (! $node instanceof OperationDefinitionNode) {
645+
continue;
646+
}
647+
648+
if ($operationName === null) {
649+
// We found a second operation, so we bail instead of returning an ambiguous result.
650+
if ($operation !== null) {
651+
return null;
652+
}
653+
$operation = $node;
654+
} elseif ($node->name instanceof NameNode && $node->name->value === $operationName) {
655+
return $node;
656+
}
657+
}
658+
659+
return $operation;
660+
}
630661
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GraphQL\Tests\Utils;
6+
7+
use GraphQL\Language\Parser;
8+
use GraphQL\Utils\AST;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class AstGetOperationAstTest extends TestCase
12+
{
13+
// Describe: getOperationAST
14+
15+
/**
16+
* @see it('Gets an operation from a simple document')
17+
*/
18+
public function testGetsAnOperationFromASimpleDocument() : void
19+
{
20+
$doc = Parser::parse('{ field }');
21+
self::assertEquals(
22+
AST::getOperationAST($doc),
23+
$doc->definitions->offsetGet(0)
24+
);
25+
}
26+
27+
/**
28+
* @see it('Gets an operation from a document with named op (mutation)')
29+
*/
30+
public function testGetsAnOperationFromADcoumentWithNamedOpMutation() : void
31+
{
32+
$doc = Parser::parse('mutation Test { field }');
33+
self::assertEquals(AST::getOperationAST($doc), $doc->definitions->offsetGet(0));
34+
}
35+
36+
/**
37+
* @see it('Gets an operation from a document with named op (subscription)')
38+
*/
39+
public function testGetsAnOperationFromADcoumentWithNamedOpSubscription() : void
40+
{
41+
$doc = Parser::parse('subscription Test { field }');
42+
self::assertEquals(AST::getOperationAST($doc), $doc->definitions->offsetGet(0));
43+
}
44+
45+
/**
46+
* @see it('Does not get missing operation')
47+
*/
48+
public function testDoesNotGetMissingOperation() : void
49+
{
50+
$doc = Parser::parse('type Foo { field: String }');
51+
self::assertEquals(AST::getOperationAST($doc), null);
52+
}
53+
54+
/**
55+
* @see it('Does not get ambiguous unnamed operation')
56+
*/
57+
public function testDoesNotGetAmbiguousUnnamedOperation() : void
58+
{
59+
$doc = Parser::parse('
60+
{ field }
61+
mutation Test { field }
62+
subscription TestSub { field }
63+
');
64+
self::assertEquals(AST::getOperationAST($doc), null);
65+
}
66+
67+
/**
68+
* @see it('Does not get ambiguous named operation')
69+
*/
70+
public function testDoesNotGetAmbiguousNamedOperation() : void
71+
{
72+
$doc = Parser::parse('
73+
query TestQ { field }
74+
mutation TestM { field }
75+
subscription TestS { field }
76+
');
77+
self::assertEquals(AST::getOperationAST($doc), null);
78+
}
79+
80+
/**
81+
* @see it('Does not get misnamed operation')
82+
*/
83+
public function testDoesNotGetMisnamedOperation() : void
84+
{
85+
$doc = Parser::parse('
86+
{ field }
87+
query TestQ { field }
88+
mutation TestM { field }
89+
subscription TestS { field }
90+
');
91+
self::assertEquals(AST::getOperationAST($doc, 'Unknown'), null);
92+
}
93+
94+
/**
95+
* @see it('Gets named operation')
96+
*/
97+
public function testGetsNamedOperation() : void
98+
{
99+
$doc = Parser::parse('
100+
query TestQ { field }
101+
mutation TestM { field }
102+
subscription TestS { field }
103+
');
104+
self::assertEquals(AST::getOperationAST($doc, 'TestQ'), $doc->definitions->offsetGet(0));
105+
self::assertEquals(AST::getOperationAST($doc, 'TestM'), $doc->definitions->offsetGet(1));
106+
self::assertEquals(AST::getOperationAST($doc, 'TestS'), $doc->definitions->offsetGet(2));
107+
}
108+
}

0 commit comments

Comments
 (0)