2015-07-15 20:05:46 +03:00
< ? php
2016-04-09 10:36:53 +03:00
namespace GraphQL\Tests\Language ;
2015-07-15 20:05:46 +03:00
2017-07-05 13:31:35 +03:00
use GraphQL\Error\InvariantViolation ;
2016-11-19 02:12:18 +03:00
use GraphQL\Language\AST\ArgumentNode ;
use GraphQL\Language\AST\FieldNode ;
use GraphQL\Language\AST\NameNode ;
2016-10-16 22:57:24 +03:00
use GraphQL\Language\AST\Node ;
2016-11-19 13:31:47 +03:00
use GraphQL\Language\AST\NodeKind ;
2017-07-21 18:29:59 +03:00
use GraphQL\Language\AST\NodeList ;
2016-11-19 02:12:18 +03:00
use GraphQL\Language\AST\SelectionSetNode ;
use GraphQL\Language\AST\StringValueNode ;
2016-04-09 10:36:53 +03:00
use GraphQL\Language\Parser ;
use GraphQL\Language\Source ;
use GraphQL\Language\SourceLocation ;
2016-10-21 12:39:57 +03:00
use GraphQL\Error\SyntaxError ;
2017-07-10 15:50:26 +03:00
use GraphQL\Utils\Utils ;
2018-07-29 18:43:10 +03:00
use PHPUnit\Framework\TestCase ;
2015-07-15 20:05:46 +03:00
2018-07-29 18:43:10 +03:00
class ParserTest extends TestCase
2015-07-15 20:05:46 +03:00
{
2017-12-21 09:52:43 +03:00
public function testAssertsThatASourceToParseIsNotNull ()
2017-07-05 13:31:35 +03:00
{
2018-07-29 18:43:10 +03:00
$this -> expectException ( InvariantViolation :: class );
$this -> expectExceptionMessage ( 'GraphQL query body is expected to be string, but got NULL' );
2017-12-21 09:52:43 +03:00
Parser :: parse ( null );
}
2017-07-05 13:31:35 +03:00
2017-12-21 09:52:43 +03:00
public function testAssertsThatASourceToParseIsNotArray ()
{
2018-07-29 18:43:10 +03:00
$this -> expectException ( InvariantViolation :: class );
$this -> expectExceptionMessage ( 'GraphQL query body is expected to be string, but got array' );
2017-12-21 09:52:43 +03:00
Parser :: parse ([ 'a' => 'b' ]);
}
2017-07-05 13:31:35 +03:00
2017-12-21 09:52:43 +03:00
public function testAssertsThatASourceToParseIsNotObject ()
{
2018-07-29 18:43:10 +03:00
$this -> expectException ( InvariantViolation :: class );
$this -> expectExceptionMessage ( 'GraphQL query body is expected to be string, but got stdClass' );
2017-12-21 09:52:43 +03:00
Parser :: parse ( new \stdClass ());
}
public function parseProvidesUsefulErrors ()
{
return [
2018-02-12 14:23:39 +03:00
[ '{' , " Syntax Error: Expected Name, found <EOF> " , " Syntax Error: Expected Name, found <EOF> \n \n GraphQL request (1:2) \n 1: { \n ^ \n " , [ 1 ], [ new SourceLocation ( 1 , 2 )]],
2017-12-21 09:52:43 +03:00
[ ' { ... MissingOn }
fragment MissingOn Type
2018-02-12 14:23:39 +03:00
' , " Syntax Error: Expected \" on \" , found Name \" Type \" " , " Syntax Error: Expected \" on \" , found Name \" Type \" \n \n GraphQL request (2:20) \n 1: { ...MissingOn } \n 2: fragment MissingOn Type \n ^ \n 3: \n " ,],
[ '{ field: {} }' , " Syntax Error: Expected Name, found { " , " Syntax Error: Expected Name, found { \n \n GraphQL request (1:10) \n 1: { field: { } } \n ^ \n " ],
[ 'notanoperation Foo { field }' , " Syntax Error: Unexpected Name \" notanoperation \" " , " Syntax Error: Unexpected Name \" notanoperation \" \n \n GraphQL request (1:1) \n 1: notanoperation Foo { field } \n ^ \n " ],
[ '...' , " Syntax Error: Unexpected ... " , " Syntax Error: Unexpected ... \n \n GraphQL request (1:1) \n 1: ... \n ^ \n " ],
2017-12-21 09:52:43 +03:00
];
2017-07-05 13:31:35 +03:00
}
2016-04-23 21:24:41 +03:00
/**
2017-12-21 09:52:43 +03:00
* @ dataProvider parseProvidesUsefulErrors
2016-04-23 21:24:41 +03:00
* @ it parse provides useful errors
*/
2018-02-12 14:23:39 +03:00
public function testParseProvidesUsefulErrors ( $str , $expectedMessage , $stringRepresentation , $expectedPositions = null , $expectedLocations = null )
2015-07-15 20:05:46 +03:00
{
2017-12-21 09:52:43 +03:00
try {
Parser :: parse ( $str );
$this -> fail ( 'Expected exception not thrown' );
} catch ( SyntaxError $e ) {
$this -> assertEquals ( $expectedMessage , $e -> getMessage ());
2018-02-12 14:23:39 +03:00
$this -> assertEquals ( $stringRepresentation , ( string ) $e );
2015-08-16 23:53:11 +03:00
2017-12-21 09:52:43 +03:00
if ( $expectedPositions ) {
$this -> assertEquals ( $expectedPositions , $e -> getPositions ());
2015-07-15 20:05:46 +03:00
}
2017-12-21 09:52:43 +03:00
if ( $expectedLocations ) {
$this -> assertEquals ( $expectedLocations , $e -> getLocations ());
}
}
2015-07-15 20:05:46 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it parse provides useful error when using source
*/
2015-07-15 20:05:46 +03:00
public function testParseProvidesUsefulErrorWhenUsingSource ()
{
2018-02-12 14:23:39 +03:00
try {
Parser :: parse ( new Source ( 'query' , 'MyQuery.graphql' ));
$this -> fail ( 'Expected exception not thrown' );
} catch ( SyntaxError $error ) {
$this -> assertEquals (
" Syntax Error: Expected { , found <EOF> \n \n MyQuery.graphql (1:6) \n 1: query \n ^ \n " ,
( string ) $error
);
}
2015-07-15 20:05:46 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it parses variable inline values
*/
2015-07-15 20:05:46 +03:00
public function testParsesVariableInlineValues ()
{
2018-08-07 19:59:48 +03:00
$this -> expectNotToPerformAssertions ();
2015-07-15 20:05:46 +03:00
// Following line should not throw:
Parser :: parse ( '{ field(complex: { a: { b: [ $var ] } }) }' );
}
2016-04-23 21:24:41 +03:00
/**
* @ it parses constant default values
*/
2015-07-15 20:05:46 +03:00
public function testParsesConstantDefaultValues ()
{
2018-02-12 14:23:39 +03:00
$this -> expectSyntaxError (
'query Foo($x: Complex = { a: { b: [ $var ] } }) { field }' ,
'Unexpected $' ,
$this -> loc ( 1 , 37 )
);
2015-07-15 20:05:46 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it does not accept fragments spread of " on "
*/
2015-08-16 23:53:11 +03:00
public function testDoesNotAcceptFragmentsNamedOn ()
{
2018-02-12 14:23:39 +03:00
$this -> expectSyntaxError (
'fragment on on on { on }' ,
'Unexpected Name "on"' ,
$this -> loc ( 1 , 10 )
);
2015-08-16 23:53:11 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it does not accept fragments spread of " on "
*/
2015-08-16 23:53:11 +03:00
public function testDoesNotAcceptFragmentSpreadOfOn ()
{
2018-02-12 14:23:39 +03:00
$this -> expectSyntaxError (
'{ ...on }' ,
'Expected Name, found }' ,
$this -> loc ( 1 , 9 )
);
2015-08-16 23:53:11 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it parses multi - byte characters
*/
public function testParsesMultiByteCharacters ()
{
// Note: \u0A0A could be naively interpretted as two line-feed chars.
$char = Utils :: chr ( 0x0A0A );
$query = <<< HEREDOC
# This comment has a $char multi-byte character.
{ field ( arg : " Has a $char multi-byte character. " ) }
HEREDOC ;
$result = Parser :: parse ( $query , [ 'noLocation' => true ]);
2016-11-19 02:12:18 +03:00
$expected = new SelectionSetNode ([
2017-07-21 18:29:59 +03:00
'selections' => new NodeList ([
2016-11-19 02:12:18 +03:00
new FieldNode ([
'name' => new NameNode ([ 'value' => 'field' ]),
2017-07-21 18:29:59 +03:00
'arguments' => new NodeList ([
2016-11-19 02:12:18 +03:00
new ArgumentNode ([
'name' => new NameNode ([ 'value' => 'arg' ]),
'value' => new StringValueNode ([
2016-04-23 21:24:41 +03:00
'value' => " Has a $char multi-byte character. "
])
])
2017-07-21 18:29:59 +03:00
]),
'directives' => new NodeList ([])
2016-04-23 21:24:41 +03:00
])
2017-07-21 18:29:59 +03:00
])
2016-04-23 21:24:41 +03:00
]);
$this -> assertEquals ( $expected , $result -> definitions [ 0 ] -> selectionSet );
}
/**
* @ it parses kitchen sink
*/
2015-07-15 20:05:46 +03:00
public function testParsesKitchenSink ()
{
// Following should not throw:
$kitchenSink = file_get_contents ( __DIR__ . '/kitchen-sink.graphql' );
2015-08-16 23:53:11 +03:00
$result = Parser :: parse ( $kitchenSink );
$this -> assertNotEmpty ( $result );
}
2016-04-23 21:24:41 +03:00
/**
* allows non - keywords anywhere a Name is allowed
*/
2015-08-16 23:53:11 +03:00
public function testAllowsNonKeywordsAnywhereANameIsAllowed ()
{
$nonKeywords = [
'on' ,
'fragment' ,
'query' ,
'mutation' ,
2016-04-23 21:24:41 +03:00
'subscription' ,
2015-08-16 23:53:11 +03:00
'true' ,
'false'
];
foreach ( $nonKeywords as $keyword ) {
$fragmentName = $keyword ;
if ( $keyword === 'on' ) {
$fragmentName = 'a' ;
}
// Expected not to throw:
$result = Parser :: parse ( " query $keyword {
... $fragmentName
... on $keyword { field }
}
fragment $fragmentName on Type {
$keyword ( $keyword : \ $$keyword ) @ $keyword ( $keyword : $keyword )
}
" );
$this -> assertNotEmpty ( $result );
}
2015-07-15 20:05:46 +03:00
}
2016-04-23 21:24:41 +03:00
/**
* @ it parses anonymous mutation operations
*/
public function testParsessAnonymousMutationOperations ()
{
2018-08-07 19:59:48 +03:00
$this -> expectNotToPerformAssertions ();
2016-04-23 21:24:41 +03:00
// Should not throw:
Parser :: parse ( '
mutation {
mutationField
}
' );
}
/**
* @ it parses anonymous subscription operations
*/
public function testParsesAnonymousSubscriptionOperations ()
{
2018-08-07 19:59:48 +03:00
$this -> expectNotToPerformAssertions ();
2016-04-23 21:24:41 +03:00
// Should not throw:
Parser :: parse ( '
subscription {
subscriptionField
}
' );
}
/**
* @ it parses named mutation operations
*/
public function testParsesNamedMutationOperations ()
{
2018-08-07 19:59:48 +03:00
$this -> expectNotToPerformAssertions ();
2016-04-23 21:24:41 +03:00
// Should not throw:
Parser :: parse ( '
mutation Foo {
mutationField
}
' );
}
/**
* @ it parses named subscription operations
*/
public function testParsesNamedSubscriptionOperations ()
{
2018-08-07 19:59:48 +03:00
$this -> expectNotToPerformAssertions ();
2016-04-23 21:24:41 +03:00
Parser :: parse ( '
subscription Foo {
subscriptionField
}
' );
}
/**
2016-10-16 22:57:24 +03:00
* @ it creates ast
2016-04-23 21:24:41 +03:00
*/
2015-07-15 20:05:46 +03:00
public function testParseCreatesAst ()
{
$source = new Source ( ' {
node ( id : 4 ) {
id ,
name
}
}
' );
$result = Parser :: parse ( $source );
2016-10-16 22:57:24 +03:00
$loc = function ( $start , $end ) use ( $source ) {
return [
'start' => $start ,
'end' => $end
];
};
$expected = [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: DOCUMENT ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 0 , 41 ),
'definitions' => [
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: OPERATION_DEFINITION ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 0 , 40 ),
2015-07-15 20:05:46 +03:00
'operation' => 'query' ,
'name' => null ,
2018-02-08 17:30:30 +03:00
'variableDefinitions' => [],
2016-10-16 22:57:24 +03:00
'directives' => [],
'selectionSet' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: SELECTION_SET ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 0 , 40 ),
'selections' => [
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: FIELD ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 4 , 38 ),
2015-07-15 20:05:46 +03:00
'alias' => null ,
2016-10-16 22:57:24 +03:00
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 4 , 8 ),
2015-07-15 20:05:46 +03:00
'value' => 'node'
2016-10-16 22:57:24 +03:00
],
'arguments' => [
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: ARGUMENT ,
2016-10-16 22:57:24 +03:00
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 9 , 11 ),
2015-07-15 20:05:46 +03:00
'value' => 'id'
2016-10-16 22:57:24 +03:00
],
'value' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: INT ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 13 , 14 ),
2015-07-15 20:05:46 +03:00
'value' => '4'
2016-10-16 22:57:24 +03:00
],
'loc' => $loc ( 9 , 14 , $source )
]
],
2015-07-15 20:05:46 +03:00
'directives' => [],
2016-10-16 22:57:24 +03:00
'selectionSet' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: SELECTION_SET ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 16 , 38 ),
'selections' => [
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: FIELD ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 22 , 24 ),
2015-07-15 20:05:46 +03:00
'alias' => null ,
2016-10-16 22:57:24 +03:00
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 22 , 24 ),
2015-07-15 20:05:46 +03:00
'value' => 'id'
2016-10-16 22:57:24 +03:00
],
2015-07-15 20:05:46 +03:00
'arguments' => [],
'directives' => [],
'selectionSet' => null
2016-10-16 22:57:24 +03:00
],
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: FIELD ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 30 , 34 ),
2015-07-15 20:05:46 +03:00
'alias' => null ,
2016-10-16 22:57:24 +03:00
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => $loc ( 30 , 34 ),
2015-07-15 20:05:46 +03:00
'value' => 'name'
2016-10-16 22:57:24 +03:00
],
2015-07-15 20:05:46 +03:00
'arguments' => [],
'directives' => [],
'selectionSet' => null
2016-10-16 22:57:24 +03:00
]
]
]
]
]
]
]
]
];
$this -> assertEquals ( $expected , $this -> nodeToArray ( $result ));
}
2018-02-08 17:30:30 +03:00
/**
* @ it creates ast from nameless query without variables
*/
public function testParseCreatesAstFromNamelessQueryWithoutVariables ()
{
$source = new Source ( ' query {
node {
id
}
}
' );
$result = Parser :: parse ( $source );
$loc = function ( $start , $end ) use ( $source ) {
return [
'start' => $start ,
'end' => $end
];
};
$expected = [
'kind' => NodeKind :: DOCUMENT ,
'loc' => $loc ( 0 , 30 ),
'definitions' => [
[
'kind' => NodeKind :: OPERATION_DEFINITION ,
'loc' => $loc ( 0 , 29 ),
'operation' => 'query' ,
'name' => null ,
'variableDefinitions' => [],
'directives' => [],
'selectionSet' => [
'kind' => NodeKind :: SELECTION_SET ,
'loc' => $loc ( 6 , 29 ),
'selections' => [
[
'kind' => NodeKind :: FIELD ,
'loc' => $loc ( 10 , 27 ),
'alias' => null ,
'name' => [
'kind' => NodeKind :: NAME ,
'loc' => $loc ( 10 , 14 ),
'value' => 'node'
],
'arguments' => [],
'directives' => [],
'selectionSet' => [
'kind' => NodeKind :: SELECTION_SET ,
'loc' => $loc ( 15 , 27 ),
'selections' => [
[
'kind' => NodeKind :: FIELD ,
'loc' => $loc ( 21 , 23 ),
'alias' => null ,
'name' => [
'kind' => NodeKind :: NAME ,
'loc' => $loc ( 21 , 23 ),
'value' => 'id'
],
'arguments' => [],
'directives' => [],
'selectionSet' => null
]
]
]
]
]
]
]
]
];
$this -> assertEquals ( $expected , $this -> nodeToArray ( $result ));
}
2016-10-16 22:57:24 +03:00
/**
* @ it allows parsing without source location information
*/
public function testAllowsParsingWithoutSourceLocationInformation ()
{
$source = new Source ( '{ id }' );
$result = Parser :: parse ( $source , [ 'noLocation' => true ]);
$this -> assertEquals ( null , $result -> loc );
}
2018-02-15 15:37:45 +03:00
/**
* @ it Experimental : allows parsing fragment defined variables
*/
public function testExperimentalAllowsParsingFragmentDefinedVariables ()
{
$source = new Source ( 'fragment a($v: Boolean = false) on t { f(v: $v) }' );
// not throw
Parser :: parse ( $source , [ 'experimentalFragmentVariables' => true ]);
2018-07-29 18:43:10 +03:00
$this -> expectException ( SyntaxError :: class );
2018-02-15 15:37:45 +03:00
Parser :: parse ( $source );
}
2016-10-16 22:57:24 +03:00
/**
* @ it contains location information that only stringifys start / end
*/
2018-02-15 15:37:45 +03:00
public function testContainsLocationInformationThatOnlyStringifysStartEnd ()
2016-10-16 22:57:24 +03:00
{
$source = new Source ( '{ id }' );
$result = Parser :: parse ( $source );
$this -> assertEquals ([ 'start' => 0 , 'end' => '6' ], TestUtils :: locationToArray ( $result -> loc ));
}
/**
* @ it contains references to source
*/
public function testContainsReferencesToSource ()
{
$source = new Source ( '{ id }' );
$result = Parser :: parse ( $source );
$this -> assertEquals ( $source , $result -> loc -> source );
}
/**
* @ it contains references to start and end tokens
*/
public function testContainsReferencesToStartAndEndTokens ()
{
$source = new Source ( '{ id }' );
$result = Parser :: parse ( $source );
$this -> assertEquals ( '<SOF>' , $result -> loc -> startToken -> kind );
$this -> assertEquals ( '<EOF>' , $result -> loc -> endToken -> kind );
}
// Describe: parseValue
2016-11-18 19:59:28 +03:00
/**
* @ it parses null value
*/
public function testParsesNullValues ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NULL ,
2016-11-18 19:59:28 +03:00
'loc' => [ 'start' => 0 , 'end' => 4 ]
], $this -> nodeToArray ( Parser :: parseValue ( 'null' )));
}
2016-10-16 22:57:24 +03:00
/**
* @ it parses list values
*/
public function testParsesListValues ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: LST ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 11 ],
'values' => [
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: INT ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 4 ],
'value' => '123'
],
[
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: STRING ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 5 , 'end' => 10 ],
2018-02-08 16:58:08 +03:00
'value' => 'abc' ,
'block' => false
2016-10-16 22:57:24 +03:00
]
]
], $this -> nodeToArray ( Parser :: parseValue ( '[123 "abc"]' )));
}
// Describe: parseType
/**
* @ it parses well known types
*/
public function testParsesWellKnownTypes ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAMED_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'value' => 'String'
]
], $this -> nodeToArray ( Parser :: parseType ( 'String' )));
}
/**
* @ it parses custom types
*/
public function testParsesCustomTypes ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAMED_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'value' => 'MyType'
]
], $this -> nodeToArray ( Parser :: parseType ( 'MyType' )));
}
/**
* @ it parses list types
*/
public function testParsesListTypes ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: LIST_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 8 ],
'type' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAMED_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 7 ],
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 7 ],
'value' => 'MyType'
]
]
], $this -> nodeToArray ( Parser :: parseType ( '[MyType]' )));
}
/**
* @ it parses non - null types
*/
public function testParsesNonNullTypes ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NON_NULL_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 7 ],
'type' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAMED_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 6 ],
'value' => 'MyType'
]
]
], $this -> nodeToArray ( Parser :: parseType ( 'MyType!' )));
}
/**
* @ it parses nested types
*/
public function testParsesNestedTypes ()
{
$this -> assertEquals ([
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: LIST_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 0 , 'end' => 9 ],
'type' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NON_NULL_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 8 ],
'type' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAMED_TYPE ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 7 ],
'name' => [
2016-11-19 13:31:47 +03:00
'kind' => NodeKind :: NAME ,
2016-10-16 22:57:24 +03:00
'loc' => [ 'start' => 1 , 'end' => 7 ],
'value' => 'MyType'
]
]
]
], $this -> nodeToArray ( Parser :: parseType ( '[MyType!]' )));
}
/**
* @ param Node $node
* @ return array
*/
public static function nodeToArray ( Node $node )
{
return TestUtils :: nodeToArray ( $node );
2015-07-15 20:05:46 +03:00
}
2018-02-12 14:23:39 +03:00
private function loc ( $line , $column )
{
return new SourceLocation ( $line , $column );
}
private function expectSyntaxError ( $text , $message , $location )
{
2018-07-29 18:43:10 +03:00
$this -> expectException ( SyntaxError :: class );
$this -> expectExceptionMessage ( $message );
2018-02-12 14:23:39 +03:00
try {
Parser :: parse ( $text );
} catch ( SyntaxError $error ) {
$this -> assertEquals ([ $location ], $error -> getLocations ());
throw $error ;
}
}
2015-07-15 20:05:46 +03:00
}