mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 04:46:04 +03:00
Fix CS in test/Language
This commit is contained in:
parent
ec54d6152b
commit
d1f49bedbd
@ -1,13 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
use GraphQL\Error\SyntaxError;
|
||||
use GraphQL\Language\Lexer;
|
||||
use GraphQL\Language\Source;
|
||||
use GraphQL\Language\SourceLocation;
|
||||
use GraphQL\Language\Token;
|
||||
use GraphQL\Error\SyntaxError;
|
||||
use GraphQL\Utils\Utils;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function count;
|
||||
use function json_decode;
|
||||
|
||||
class LexerTest extends TestCase
|
||||
{
|
||||
@ -23,17 +28,45 @@ class LexerTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
private function expectSyntaxError($text, $message, $location)
|
||||
{
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
try {
|
||||
$this->lexOne($text);
|
||||
} catch (SyntaxError $error) {
|
||||
$this->assertEquals([$location], $error->getLocations());
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
* @return Token
|
||||
*/
|
||||
private function lexOne($body)
|
||||
{
|
||||
$lexer = new Lexer(new Source($body));
|
||||
|
||||
return $lexer->advance();
|
||||
}
|
||||
|
||||
private function loc($line, $column)
|
||||
{
|
||||
return new SourceLocation($line, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('accepts BOM header')
|
||||
*/
|
||||
public function testAcceptsBomHeader() : void
|
||||
{
|
||||
$bom = Utils::chr(0xFEFF);
|
||||
$bom = Utils::chr(0xFEFF);
|
||||
$expected = [
|
||||
'kind' => Token::NAME,
|
||||
'kind' => Token::NAME,
|
||||
'start' => 2,
|
||||
'end' => 5,
|
||||
'value' => 'foo'
|
||||
'end' => 5,
|
||||
'value' => 'foo',
|
||||
];
|
||||
|
||||
$this->assertArraySubset($expected, (array) $this->lexOne($bom . ' foo'));
|
||||
@ -45,12 +78,12 @@ class LexerTest extends TestCase
|
||||
public function testRecordsLineAndColumn() : void
|
||||
{
|
||||
$expected = [
|
||||
'kind' => Token::NAME,
|
||||
'start' => 8,
|
||||
'end' => 11,
|
||||
'line' => 4,
|
||||
'kind' => Token::NAME,
|
||||
'start' => 8,
|
||||
'end' => 11,
|
||||
'line' => 4,
|
||||
'column' => 3,
|
||||
'value' => 'foo'
|
||||
'value' => 'foo',
|
||||
];
|
||||
$this->assertArraySubset($expected, (array) $this->lexOne("\n \r\n \r foo\n"));
|
||||
}
|
||||
@ -67,10 +100,10 @@ class LexerTest extends TestCase
|
||||
|
||||
';
|
||||
$expected = [
|
||||
'kind' => Token::NAME,
|
||||
'kind' => Token::NAME,
|
||||
'start' => 6,
|
||||
'end' => 9,
|
||||
'value' => 'foo'
|
||||
'end' => 9,
|
||||
'value' => 'foo',
|
||||
];
|
||||
$this->assertArraySubset($expected, (array) $this->lexOne($example1));
|
||||
|
||||
@ -80,18 +113,18 @@ class LexerTest extends TestCase
|
||||
';
|
||||
|
||||
$expected = [
|
||||
'kind' => Token::NAME,
|
||||
'kind' => Token::NAME,
|
||||
'start' => 18,
|
||||
'end' => 21,
|
||||
'value' => 'foo'
|
||||
'end' => 21,
|
||||
'value' => 'foo',
|
||||
];
|
||||
$this->assertArraySubset($expected, (array) $this->lexOne($example2));
|
||||
|
||||
$expected = [
|
||||
'kind' => Token::NAME,
|
||||
'kind' => Token::NAME,
|
||||
'start' => 3,
|
||||
'end' => 6,
|
||||
'value' => 'foo'
|
||||
'end' => 6,
|
||||
'value' => 'foo',
|
||||
];
|
||||
|
||||
$example3 = ',,,foo,,,';
|
||||
@ -131,7 +164,7 @@ class LexerTest extends TestCase
|
||||
*/
|
||||
public function testUpdatesLineNumbersInErrorForFileContext() : void
|
||||
{
|
||||
$str = '' .
|
||||
$str = '' .
|
||||
"\n" .
|
||||
"\n" .
|
||||
" ?\n" .
|
||||
@ -181,63 +214,86 @@ class LexerTest extends TestCase
|
||||
*/
|
||||
public function testLexesStrings() : void
|
||||
{
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 8,
|
||||
'value' => 'simple'
|
||||
], (array) $this->lexOne('"simple"'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 8,
|
||||
'value' => 'simple',
|
||||
],
|
||||
(array) $this->lexOne('"simple"')
|
||||
);
|
||||
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 15,
|
||||
'value' => ' white space ',
|
||||
],
|
||||
(array) $this->lexOne('" white space "')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 15,
|
||||
'value' => ' white space '
|
||||
], (array) $this->lexOne('" white space "'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 10,
|
||||
'value' => 'quote "',
|
||||
],
|
||||
(array) $this->lexOne('"quote \\""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 10,
|
||||
'value' => 'quote "'
|
||||
], (array) $this->lexOne('"quote \\""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 25,
|
||||
'value' => 'escaped \n\r\b\t\f',
|
||||
],
|
||||
(array) $this->lexOne('"escaped \\\\n\\\\r\\\\b\\\\t\\\\f"')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 25,
|
||||
'value' => 'escaped \n\r\b\t\f'
|
||||
], (array) $this->lexOne('"escaped \\\\n\\\\r\\\\b\\\\t\\\\f"'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 16,
|
||||
'value' => 'slashes \\ \/',
|
||||
],
|
||||
(array) $this->lexOne('"slashes \\\\ \\\\/"')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 16,
|
||||
'value' => 'slashes \\ \/'
|
||||
], (array) $this->lexOne('"slashes \\\\ \\\\/"'));
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 13,
|
||||
'value' => 'unicode яуц'
|
||||
], (array) $this->lexOne('"unicode яуц"'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 13,
|
||||
'value' => 'unicode яуц',
|
||||
],
|
||||
(array) $this->lexOne('"unicode яуц"')
|
||||
);
|
||||
|
||||
$unicode = json_decode('"\u1234\u5678\u90AB\uCDEF"');
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 34,
|
||||
'value' => 'unicode ' . $unicode
|
||||
], (array) $this->lexOne('"unicode \u1234\u5678\u90AB\uCDEF"'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 34,
|
||||
'value' => 'unicode ' . $unicode,
|
||||
],
|
||||
(array) $this->lexOne('"unicode \u1234\u5678\u90AB\uCDEF"')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 26,
|
||||
'value' => $unicode
|
||||
], (array) $this->lexOne('"\u1234\u5678\u90AB\uCDEF"'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::STRING,
|
||||
'start' => 0,
|
||||
'end' => 26,
|
||||
'value' => $unicode,
|
||||
],
|
||||
(array) $this->lexOne('"\u1234\u5678\u90AB\uCDEF"')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -245,86 +301,128 @@ class LexerTest extends TestCase
|
||||
*/
|
||||
public function testLexesBlockString() : void
|
||||
{
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 12,
|
||||
'value' => 'simple'
|
||||
], (array) $this->lexOne('"""simple"""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 12,
|
||||
'value' => 'simple',
|
||||
],
|
||||
(array) $this->lexOne('"""simple"""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 19,
|
||||
'value' => ' white space '
|
||||
], (array) $this->lexOne('""" white space """'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 19,
|
||||
'value' => ' white space ',
|
||||
],
|
||||
(array) $this->lexOne('""" white space """')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 22,
|
||||
'value' => 'contains " quote'
|
||||
], (array) $this->lexOne('"""contains " quote"""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 22,
|
||||
'value' => 'contains " quote',
|
||||
],
|
||||
(array) $this->lexOne('"""contains " quote"""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 31,
|
||||
'value' => 'contains """ triplequote'
|
||||
], (array) $this->lexOne('"""contains \\""" triplequote"""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 31,
|
||||
'value' => 'contains """ triplequote',
|
||||
],
|
||||
(array) $this->lexOne('"""contains \\""" triplequote"""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 16,
|
||||
'value' => "multi\nline"
|
||||
], (array) $this->lexOne("\"\"\"multi\nline\"\"\""));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 16,
|
||||
'value' => "multi\nline",
|
||||
],
|
||||
(array) $this->lexOne("\"\"\"multi\nline\"\"\"")
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 28,
|
||||
'value' => "multi\nline\nnormalized"
|
||||
], (array) $this->lexOne("\"\"\"multi\rline\r\nnormalized\"\"\""));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 28,
|
||||
'value' => "multi\nline\nnormalized",
|
||||
],
|
||||
(array) $this->lexOne("\"\"\"multi\rline\r\nnormalized\"\"\"")
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 32,
|
||||
'value' => 'unescaped \\n\\r\\b\\t\\f\\u1234'
|
||||
], (array) $this->lexOne('"""unescaped \\n\\r\\b\\t\\f\\u1234"""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 32,
|
||||
'value' => 'unescaped \\n\\r\\b\\t\\f\\u1234',
|
||||
],
|
||||
(array) $this->lexOne('"""unescaped \\n\\r\\b\\t\\f\\u1234"""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 19,
|
||||
'value' => 'slashes \\\\ \\/'
|
||||
], (array) $this->lexOne('"""slashes \\\\ \\/"""'));
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 19,
|
||||
'value' => 'slashes \\\\ \\/',
|
||||
],
|
||||
(array) $this->lexOne('"""slashes \\\\ \\/"""')
|
||||
);
|
||||
|
||||
$this->assertArraySubset([
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 68,
|
||||
'value' => "spans\n multiple\n lines"
|
||||
], (array) $this->lexOne("\"\"\"
|
||||
$this->assertArraySubset(
|
||||
[
|
||||
'kind' => Token::BLOCK_STRING,
|
||||
'start' => 0,
|
||||
'end' => 68,
|
||||
'value' => "spans\n multiple\n lines",
|
||||
],
|
||||
(array) $this->lexOne('"""
|
||||
|
||||
spans
|
||||
multiple
|
||||
lines
|
||||
|
||||
\"\"\""));
|
||||
"""')
|
||||
);
|
||||
}
|
||||
|
||||
public function reportsUsefulStringErrors() {
|
||||
public function reportsUsefulStringErrors()
|
||||
{
|
||||
return [
|
||||
['"', "Unterminated string.", $this->loc(1, 2)],
|
||||
['"no end quote', "Unterminated string.", $this->loc(1, 14)],
|
||||
["'single quotes'", "Unexpected single quote character ('), did you mean to use a double quote (\")?", $this->loc(1, 1)],
|
||||
['"contains unescaped \u0007 control char"', "Invalid character within String: \"\\u0007\"", $this->loc(1, 21)],
|
||||
['"', 'Unterminated string.', $this->loc(1, 2)],
|
||||
['"no end quote', 'Unterminated string.', $this->loc(1, 14)],
|
||||
[
|
||||
"'single quotes'",
|
||||
"Unexpected single quote character ('), did you mean to use a double quote (\")?",
|
||||
$this->loc(
|
||||
1,
|
||||
1
|
||||
),
|
||||
],
|
||||
[
|
||||
'"contains unescaped \u0007 control char"',
|
||||
"Invalid character within String: \"\\u0007\"",
|
||||
$this->loc(
|
||||
1,
|
||||
21
|
||||
),
|
||||
],
|
||||
['"null-byte is not \u0000 end of file"', 'Invalid character within String: "\\u0000"', $this->loc(1, 19)],
|
||||
['"multi' . "\n" . 'line"', "Unterminated string.", $this->loc(1, 7)],
|
||||
['"multi' . "\r" . 'line"', "Unterminated string.", $this->loc(1, 7)],
|
||||
['"bad \\z esc"', "Invalid character escape sequence: \\z", $this->loc(1, 7)],
|
||||
['"multi' . "\n" . 'line"', 'Unterminated string.', $this->loc(1, 7)],
|
||||
['"multi' . "\r" . 'line"', 'Unterminated string.', $this->loc(1, 7)],
|
||||
['"bad \\z esc"', 'Invalid character escape sequence: \\z', $this->loc(1, 7)],
|
||||
['"bad \\x esc"', "Invalid character escape sequence: \\x", $this->loc(1, 7)],
|
||||
['"bad \\u1 esc"', "Invalid character escape sequence: \\u1 es", $this->loc(1, 7)],
|
||||
['"bad \\u0XX1 esc"', "Invalid character escape sequence: \\u0XX1", $this->loc(1, 7)],
|
||||
@ -336,25 +434,40 @@ class LexerTest extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider reportsUsefulStringErrors
|
||||
* @see it('lex reports useful string errors')
|
||||
* @see it('lex reports useful string errors')
|
||||
*/
|
||||
public function testLexReportsUsefulStringErrors($str, $expectedMessage, $location) : void
|
||||
{
|
||||
$this->expectSyntaxError($str, $expectedMessage, $location);
|
||||
}
|
||||
|
||||
public function reportsUsefulBlockStringErrors() {
|
||||
public function reportsUsefulBlockStringErrors()
|
||||
{
|
||||
return [
|
||||
['"""', "Unterminated string.", $this->loc(1, 4)],
|
||||
['"""no end quote', "Unterminated string.", $this->loc(1, 16)],
|
||||
['"""contains unescaped ' . json_decode('"\u0007"') . ' control char"""', "Invalid character within String: \"\\u0007\"", $this->loc(1, 23)],
|
||||
['"""null-byte is not ' . json_decode('"\u0000"') . ' end of file"""', "Invalid character within String: \"\\u0000\"", $this->loc(1, 21)],
|
||||
['"""', 'Unterminated string.', $this->loc(1, 4)],
|
||||
['"""no end quote', 'Unterminated string.', $this->loc(1, 16)],
|
||||
[
|
||||
'"""contains unescaped ' . json_decode('"\u0007"') . ' control char"""',
|
||||
"Invalid character within String: \"\\u0007\"",
|
||||
$this->loc(
|
||||
1,
|
||||
23
|
||||
),
|
||||
],
|
||||
[
|
||||
'"""null-byte is not ' . json_decode('"\u0000"') . ' end of file"""',
|
||||
"Invalid character within String: \"\\u0000\"",
|
||||
$this->loc(
|
||||
1,
|
||||
21
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider reportsUsefulBlockStringErrors
|
||||
* @see it('lex reports useful block string errors')
|
||||
* @see it('lex reports useful block string errors')
|
||||
*/
|
||||
public function testReportsUsefulBlockStringErrors($str, $expectedMessage, $location) : void
|
||||
{
|
||||
@ -435,21 +548,21 @@ class LexerTest extends TestCase
|
||||
public function reportsUsefulNumberErrors()
|
||||
{
|
||||
return [
|
||||
[ '00', "Invalid number, unexpected digit after 0: \"0\"", $this->loc(1, 2)],
|
||||
[ '+1', "Cannot parse the unexpected character \"+\".", $this->loc(1, 1)],
|
||||
[ '1.', "Invalid number, expected digit but got: <EOF>", $this->loc(1, 3)],
|
||||
[ '1.e1', "Invalid number, expected digit but got: \"e\"", $this->loc(1, 3)],
|
||||
[ '.123', "Cannot parse the unexpected character \".\".", $this->loc(1, 1)],
|
||||
[ '1.A', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 3)],
|
||||
[ '-A', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 2)],
|
||||
[ '1.0e', "Invalid number, expected digit but got: <EOF>", $this->loc(1, 5)],
|
||||
[ '1.0eA', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 5)],
|
||||
['00', 'Invalid number, unexpected digit after 0: "0"', $this->loc(1, 2)],
|
||||
['+1', 'Cannot parse the unexpected character "+".', $this->loc(1, 1)],
|
||||
['1.', 'Invalid number, expected digit but got: <EOF>', $this->loc(1, 3)],
|
||||
['1.e1', 'Invalid number, expected digit but got: "e"', $this->loc(1, 3)],
|
||||
['.123', 'Cannot parse the unexpected character ".".', $this->loc(1, 1)],
|
||||
['1.A', 'Invalid number, expected digit but got: "A"', $this->loc(1, 3)],
|
||||
['-A', 'Invalid number, expected digit but got: "A"', $this->loc(1, 2)],
|
||||
['1.0e', 'Invalid number, expected digit but got: <EOF>', $this->loc(1, 5)],
|
||||
['1.0eA', 'Invalid number, expected digit but got: "A"', $this->loc(1, 5)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider reportsUsefulNumberErrors
|
||||
* @see it('lex reports useful number errors')
|
||||
* @see it('lex reports useful number errors')
|
||||
*/
|
||||
public function testReportsUsefulNumberErrors($str, $expectedMessage, $location) : void
|
||||
{
|
||||
@ -521,8 +634,8 @@ class LexerTest extends TestCase
|
||||
$unicode2 = json_decode('"\u200b"');
|
||||
|
||||
return [
|
||||
['..', "Cannot parse the unexpected character \".\".", $this->loc(1, 1)],
|
||||
['?', "Cannot parse the unexpected character \"?\".", $this->loc(1, 1)],
|
||||
['..', 'Cannot parse the unexpected character ".".', $this->loc(1, 1)],
|
||||
['?', 'Cannot parse the unexpected character "?".', $this->loc(1, 1)],
|
||||
[$unicode1, "Cannot parse the unexpected character \"\\u203b\".", $this->loc(1, 1)],
|
||||
[$unicode2, "Cannot parse the unexpected character \"\\u200b\".", $this->loc(1, 1)],
|
||||
];
|
||||
@ -530,7 +643,7 @@ class LexerTest extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider reportsUsefulUnknownCharErrors
|
||||
* @see it('lex reports useful unknown character error')
|
||||
* @see it('lex reports useful unknown character error')
|
||||
*/
|
||||
public function testReportsUsefulUnknownCharErrors($str, $expectedMessage, $location) : void
|
||||
{
|
||||
@ -542,17 +655,20 @@ class LexerTest extends TestCase
|
||||
*/
|
||||
public function testReportsUsefulDashesInfo() : void
|
||||
{
|
||||
$q = 'a-b';
|
||||
$q = 'a-b';
|
||||
$lexer = new Lexer(new Source($q));
|
||||
$this->assertArraySubset(['kind' => Token::NAME, 'start' => 0, 'end' => 1, 'value' => 'a'], (array) $lexer->advance());
|
||||
$this->assertArraySubset(
|
||||
['kind' => Token::NAME, 'start' => 0, 'end' => 1, 'value' => 'a'],
|
||||
(array) $lexer->advance()
|
||||
);
|
||||
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage('Syntax Error: Invalid number, expected digit but got: "b"');
|
||||
try {
|
||||
$lexer->advance();
|
||||
$this->fail('Expected exception not thrown');
|
||||
} catch(SyntaxError $error) {
|
||||
$this->assertEquals([$this->loc(1,3)], $error->getLocations());
|
||||
} catch (SyntaxError $error) {
|
||||
$this->assertEquals([$this->loc(1, 3)], $error->getLocations());
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
@ -580,49 +696,28 @@ class LexerTest extends TestCase
|
||||
|
||||
$tokens = [];
|
||||
for ($tok = $startToken; $tok; $tok = $tok->next) {
|
||||
if (!empty($tokens)) {
|
||||
if (! empty($tokens)) {
|
||||
// Tokens are double-linked, prev should point to last seen token.
|
||||
$this->assertSame($tokens[count($tokens) - 1], $tok->prev);
|
||||
}
|
||||
$tokens[] = $tok;
|
||||
}
|
||||
|
||||
$this->assertEquals([
|
||||
'<SOF>',
|
||||
'{',
|
||||
'Comment',
|
||||
'Name',
|
||||
'}',
|
||||
'<EOF>'
|
||||
], Utils::map($tokens, function ($tok) {
|
||||
return $tok->kind;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
* @return Token
|
||||
*/
|
||||
private function lexOne($body)
|
||||
{
|
||||
$lexer = new Lexer(new Source($body));
|
||||
return $lexer->advance();
|
||||
}
|
||||
|
||||
private function loc($line, $column)
|
||||
{
|
||||
return new SourceLocation($line, $column);
|
||||
}
|
||||
|
||||
private function expectSyntaxError($text, $message, $location)
|
||||
{
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
try {
|
||||
$this->lexOne($text);
|
||||
} catch (SyntaxError $error) {
|
||||
$this->assertEquals([$location], $error->getLocations());
|
||||
throw $error;
|
||||
}
|
||||
$this->assertEquals(
|
||||
[
|
||||
'<SOF>',
|
||||
'{',
|
||||
'Comment',
|
||||
'Name',
|
||||
'}',
|
||||
'<EOF>',
|
||||
],
|
||||
Utils::map(
|
||||
$tokens,
|
||||
function ($tok) {
|
||||
return $tok->kind;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Error\SyntaxError;
|
||||
use GraphQL\Language\AST\ArgumentNode;
|
||||
use GraphQL\Language\AST\FieldNode;
|
||||
use GraphQL\Language\AST\NameNode;
|
||||
@ -13,9 +17,10 @@ use GraphQL\Language\AST\StringValueNode;
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Language\Source;
|
||||
use GraphQL\Language\SourceLocation;
|
||||
use GraphQL\Error\SyntaxError;
|
||||
use GraphQL\Utils\Utils;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function file_get_contents;
|
||||
use function sprintf;
|
||||
|
||||
class ParserTest extends TestCase
|
||||
{
|
||||
@ -43,22 +48,40 @@ class ParserTest extends TestCase
|
||||
public function parseProvidesUsefulErrors()
|
||||
{
|
||||
return [
|
||||
['{', "Syntax Error: Expected Name, found <EOF>", "Syntax Error: Expected Name, found <EOF>\n\nGraphQL request (1:2)\n1: {\n ^\n", [1], [new SourceLocation(1, 2)]],
|
||||
['{ ...MissingOn }
|
||||
[
|
||||
'{',
|
||||
'Syntax Error: Expected Name, found <EOF>',
|
||||
"Syntax Error: Expected Name, found <EOF>\n\nGraphQL request (1:2)\n1: {\n ^\n",
|
||||
[1],
|
||||
[new SourceLocation(
|
||||
1,
|
||||
2
|
||||
),
|
||||
],
|
||||
],
|
||||
[
|
||||
'{ ...MissingOn }
|
||||
fragment MissingOn Type
|
||||
', "Syntax Error: Expected \"on\", found Name \"Type\"", "Syntax Error: Expected \"on\", found Name \"Type\"\n\nGraphQL request (2:20)\n1: { ...MissingOn }\n2: fragment MissingOn Type\n ^\n3: \n",],
|
||||
['{ field: {} }', "Syntax Error: Expected Name, found {", "Syntax Error: Expected Name, found {\n\nGraphQL request (1:10)\n1: { field: {} }\n ^\n"],
|
||||
['notanoperation Foo { field }', "Syntax Error: Unexpected Name \"notanoperation\"", "Syntax Error: Unexpected Name \"notanoperation\"\n\nGraphQL request (1:1)\n1: notanoperation Foo { field }\n ^\n"],
|
||||
['...', "Syntax Error: Unexpected ...", "Syntax Error: Unexpected ...\n\nGraphQL request (1:1)\n1: ...\n ^\n"],
|
||||
', 'Syntax Error: Expected "on", found Name "Type"',
|
||||
"Syntax Error: Expected \"on\", found Name \"Type\"\n\nGraphQL request (2:20)\n1: { ...MissingOn }\n2: fragment MissingOn Type\n ^\n3: \n",
|
||||
],
|
||||
['{ field: {} }', 'Syntax Error: Expected Name, found {', "Syntax Error: Expected Name, found {\n\nGraphQL request (1:10)\n1: { field: {} }\n ^\n"],
|
||||
['notanoperation Foo { field }', 'Syntax Error: Unexpected Name "notanoperation"', "Syntax Error: Unexpected Name \"notanoperation\"\n\nGraphQL request (1:1)\n1: notanoperation Foo { field }\n ^\n"],
|
||||
['...', 'Syntax Error: Unexpected ...', "Syntax Error: Unexpected ...\n\nGraphQL request (1:1)\n1: ...\n ^\n"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider parseProvidesUsefulErrors
|
||||
* @see it('parse provides useful errors')
|
||||
* @see it('parse provides useful errors')
|
||||
*/
|
||||
public function testParseProvidesUsefulErrors($str, $expectedMessage, $stringRepresentation, $expectedPositions = null, $expectedLocations = null) : void
|
||||
{
|
||||
public function testParseProvidesUsefulErrors(
|
||||
$str,
|
||||
$expectedMessage,
|
||||
$stringRepresentation,
|
||||
$expectedPositions = null,
|
||||
$expectedLocations = null
|
||||
) : void {
|
||||
try {
|
||||
Parser::parse($str);
|
||||
$this->fail('Expected exception not thrown');
|
||||
@ -110,10 +133,27 @@ fragment MissingOn Type
|
||||
$this->expectSyntaxError(
|
||||
'query Foo($x: Complex = { a: { b: [ $var ] } }) { field }',
|
||||
'Unexpected $',
|
||||
$this->loc(1,37)
|
||||
$this->loc(1, 37)
|
||||
);
|
||||
}
|
||||
|
||||
private function expectSyntaxError($text, $message, $location)
|
||||
{
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
try {
|
||||
Parser::parse($text);
|
||||
} catch (SyntaxError $error) {
|
||||
$this->assertEquals([$location], $error->getLocations());
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
private function loc($line, $column)
|
||||
{
|
||||
return new SourceLocation($line, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('does not accept fragments spread of "on"')
|
||||
*/
|
||||
@ -122,7 +162,7 @@ fragment MissingOn Type
|
||||
$this->expectSyntaxError(
|
||||
'fragment on on on { on }',
|
||||
'Unexpected Name "on"',
|
||||
$this->loc(1,10)
|
||||
$this->loc(1, 10)
|
||||
);
|
||||
}
|
||||
|
||||
@ -134,7 +174,7 @@ fragment MissingOn Type
|
||||
$this->expectSyntaxError(
|
||||
'{ ...on }',
|
||||
'Expected Name, found }',
|
||||
$this->loc(1,9)
|
||||
$this->loc(1, 9)
|
||||
);
|
||||
}
|
||||
|
||||
@ -145,7 +185,7 @@ fragment MissingOn Type
|
||||
{
|
||||
// Note: \u0A0A could be naively interpretted as two line-feed chars.
|
||||
|
||||
$char = Utils::chr(0x0A0A);
|
||||
$char = Utils::chr(0x0A0A);
|
||||
$query = <<<HEREDOC
|
||||
# This comment has a $char multi-byte character.
|
||||
{ field(arg: "Has a $char multi-byte character.") }
|
||||
@ -156,18 +196,18 @@ HEREDOC;
|
||||
$expected = new SelectionSetNode([
|
||||
'selections' => new NodeList([
|
||||
new FieldNode([
|
||||
'name' => new NameNode(['value' => 'field']),
|
||||
'arguments' => new NodeList([
|
||||
'name' => new NameNode(['value' => 'field']),
|
||||
'arguments' => new NodeList([
|
||||
new ArgumentNode([
|
||||
'name' => new NameNode(['value' => 'arg']),
|
||||
'value' => new StringValueNode([
|
||||
'value' => "Has a $char multi-byte character."
|
||||
])
|
||||
])
|
||||
'name' => new NameNode(['value' => 'arg']),
|
||||
'value' => new StringValueNode(
|
||||
['value' => sprintf('Has a %s multi-byte character.', $char)]
|
||||
),
|
||||
]),
|
||||
]),
|
||||
'directives' => new NodeList([])
|
||||
])
|
||||
])
|
||||
'directives' => new NodeList([]),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->assertEquals($expected, $result->definitions[0]->selectionSet);
|
||||
@ -180,7 +220,7 @@ HEREDOC;
|
||||
{
|
||||
// Following should not throw:
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$result = Parser::parse($kitchenSink);
|
||||
$result = Parser::parse($kitchenSink);
|
||||
$this->assertNotEmpty($result);
|
||||
}
|
||||
|
||||
@ -196,7 +236,7 @@ HEREDOC;
|
||||
'mutation',
|
||||
'subscription',
|
||||
'true',
|
||||
'false'
|
||||
'false',
|
||||
];
|
||||
foreach ($nonKeywords as $keyword) {
|
||||
$fragmentName = $keyword;
|
||||
@ -205,14 +245,19 @@ HEREDOC;
|
||||
}
|
||||
|
||||
// Expected not to throw:
|
||||
$result = Parser::parse("query $keyword {
|
||||
... $fragmentName
|
||||
... on $keyword { field }
|
||||
$result = Parser::parse(<<<GRAPHQL
|
||||
query $keyword {
|
||||
... $fragmentName
|
||||
... on $keyword { field }
|
||||
}
|
||||
fragment $fragmentName on Type {
|
||||
$keyword($keyword: \$$keyword) @$keyword($keyword: $keyword)
|
||||
}
|
||||
fragment $fragmentName on Type {
|
||||
$keyword($keyword: \$$keyword) @$keyword($keyword: $keyword)
|
||||
}
|
||||
");
|
||||
GRAPHQL
|
||||
);
|
||||
$this->assertNotEmpty($result);
|
||||
}
|
||||
}
|
||||
@ -286,94 +331,102 @@ fragment $fragmentName on Type {
|
||||
');
|
||||
$result = Parser::parse($source);
|
||||
|
||||
$loc = function($start, $end) use ($source) {
|
||||
$loc = function ($start, $end) use ($source) {
|
||||
return [
|
||||
'start' => $start,
|
||||
'end' => $end
|
||||
'end' => $end,
|
||||
];
|
||||
};
|
||||
|
||||
$expected = [
|
||||
'kind' => NodeKind::DOCUMENT,
|
||||
'loc' => $loc(0, 41),
|
||||
'kind' => NodeKind::DOCUMENT,
|
||||
'loc' => $loc(0, 41),
|
||||
'definitions' => [
|
||||
[
|
||||
'kind' => NodeKind::OPERATION_DEFINITION,
|
||||
'loc' => $loc(0, 40),
|
||||
'operation' => 'query',
|
||||
'name' => null,
|
||||
'kind' => NodeKind::OPERATION_DEFINITION,
|
||||
'loc' => $loc(0, 40),
|
||||
'operation' => 'query',
|
||||
'name' => null,
|
||||
'variableDefinitions' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => [
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(0, 40),
|
||||
'directives' => [],
|
||||
'selectionSet' => [
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(0, 40),
|
||||
'selections' => [
|
||||
[
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(4, 38),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(4, 8),
|
||||
'value' => 'node'
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(4, 38),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(4, 8),
|
||||
'value' => 'node',
|
||||
],
|
||||
'arguments' => [
|
||||
'arguments' => [
|
||||
[
|
||||
'kind' => NodeKind::ARGUMENT,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(9, 11),
|
||||
'value' => 'id'
|
||||
'kind' => NodeKind::ARGUMENT,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(9, 11),
|
||||
'value' => 'id',
|
||||
],
|
||||
'value' => [
|
||||
'kind' => NodeKind::INT,
|
||||
'loc' => $loc(13, 14),
|
||||
'value' => '4'
|
||||
'kind' => NodeKind::INT,
|
||||
'loc' => $loc(13, 14),
|
||||
'value' => '4',
|
||||
],
|
||||
'loc' => $loc(9, 14, $source)
|
||||
]
|
||||
'loc' => $loc(9, 14, $source),
|
||||
],
|
||||
],
|
||||
'directives' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => [
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(16, 38),
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(16, 38),
|
||||
'selections' => [
|
||||
[
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(22, 24),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(22, 24),
|
||||
'value' => 'id'
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(22, 24),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(22, 24),
|
||||
'value' => 'id',
|
||||
],
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null,
|
||||
],
|
||||
[
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(30, 34),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(30, 34),
|
||||
'value' => 'name'
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(30, 34),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(30, 34),
|
||||
'value' => 'name',
|
||||
],
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $this->nodeToArray($result));
|
||||
$this->assertEquals($expected, self::nodeToArray($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function nodeToArray(Node $node) : array
|
||||
{
|
||||
return TestUtils::nodeToArray($node);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -389,63 +442,63 @@ fragment $fragmentName on Type {
|
||||
');
|
||||
$result = Parser::parse($source);
|
||||
|
||||
$loc = function($start, $end) use ($source) {
|
||||
$loc = function ($start, $end) use ($source) {
|
||||
return [
|
||||
'start' => $start,
|
||||
'end' => $end
|
||||
'end' => $end,
|
||||
];
|
||||
};
|
||||
|
||||
$expected = [
|
||||
'kind' => NodeKind::DOCUMENT,
|
||||
'loc' => $loc(0, 30),
|
||||
'kind' => NodeKind::DOCUMENT,
|
||||
'loc' => $loc(0, 30),
|
||||
'definitions' => [
|
||||
[
|
||||
'kind' => NodeKind::OPERATION_DEFINITION,
|
||||
'loc' => $loc(0, 29),
|
||||
'operation' => 'query',
|
||||
'name' => null,
|
||||
'kind' => NodeKind::OPERATION_DEFINITION,
|
||||
'loc' => $loc(0, 29),
|
||||
'operation' => 'query',
|
||||
'name' => null,
|
||||
'variableDefinitions' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => [
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(6, 29),
|
||||
'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'
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(10, 27),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(10, 14),
|
||||
'value' => 'node',
|
||||
],
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => [
|
||||
'kind' => NodeKind::SELECTION_SET,
|
||||
'loc' => $loc(15, 27),
|
||||
'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'
|
||||
'kind' => NodeKind::FIELD,
|
||||
'loc' => $loc(21, 23),
|
||||
'alias' => null,
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => $loc(21, 23),
|
||||
'value' => 'id',
|
||||
],
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
'arguments' => [],
|
||||
'directives' => [],
|
||||
'selectionSet' => null,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $this->nodeToArray($result));
|
||||
@ -475,6 +528,8 @@ fragment $fragmentName on Type {
|
||||
Parser::parse($source);
|
||||
}
|
||||
|
||||
// Describe: parseValue
|
||||
|
||||
/**
|
||||
* @see it('contains location information that only stringifys start/end')
|
||||
*/
|
||||
@ -495,6 +550,8 @@ fragment $fragmentName on Type {
|
||||
$this->assertEquals($source, $result->loc->source);
|
||||
}
|
||||
|
||||
// Describe: parseType
|
||||
|
||||
/**
|
||||
* @see it('contains references to start and end tokens')
|
||||
*/
|
||||
@ -506,17 +563,18 @@ fragment $fragmentName on Type {
|
||||
$this->assertEquals('<EOF>', $result->loc->endToken->kind);
|
||||
}
|
||||
|
||||
// Describe: parseValue
|
||||
|
||||
/**
|
||||
* @see it('parses null value')
|
||||
*/
|
||||
public function testParsesNullValues() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::NULL,
|
||||
'loc' => ['start' => 0, 'end' => 4]
|
||||
], $this->nodeToArray(Parser::parseValue('null')));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::NULL,
|
||||
'loc' => ['start' => 0, 'end' => 4],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseValue('null'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -524,41 +582,45 @@ fragment $fragmentName on Type {
|
||||
*/
|
||||
public function testParsesListValues() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::LST,
|
||||
'loc' => ['start' => 0, 'end' => 11],
|
||||
'values' => [
|
||||
[
|
||||
'kind' => NodeKind::INT,
|
||||
'loc' => ['start' => 1, 'end' => 4],
|
||||
'value' => '123'
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::LST,
|
||||
'loc' => ['start' => 0, 'end' => 11],
|
||||
'values' => [
|
||||
[
|
||||
'kind' => NodeKind::INT,
|
||||
'loc' => ['start' => 1, 'end' => 4],
|
||||
'value' => '123',
|
||||
],
|
||||
[
|
||||
'kind' => NodeKind::STRING,
|
||||
'loc' => ['start' => 5, 'end' => 10],
|
||||
'value' => 'abc',
|
||||
'block' => false,
|
||||
],
|
||||
],
|
||||
[
|
||||
'kind' => NodeKind::STRING,
|
||||
'loc' => ['start' => 5, 'end' => 10],
|
||||
'value' => 'abc',
|
||||
'block' => false
|
||||
]
|
||||
]
|
||||
], $this->nodeToArray(Parser::parseValue('[123 "abc"]')));
|
||||
],
|
||||
$this->nodeToArray(Parser::parseValue('[123 "abc"]'))
|
||||
);
|
||||
}
|
||||
|
||||
// Describe: parseType
|
||||
|
||||
/**
|
||||
* @see it('parses well known types')
|
||||
*/
|
||||
public function testParsesWellKnownTypes() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'String'
|
||||
]
|
||||
], $this->nodeToArray(Parser::parseType('String')));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'String',
|
||||
],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseType('String'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -566,15 +628,18 @@ fragment $fragmentName on Type {
|
||||
*/
|
||||
public function testParsesCustomTypes() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'MyType'
|
||||
]
|
||||
], $this->nodeToArray(Parser::parseType('MyType')));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'MyType',
|
||||
],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseType('MyType'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -582,19 +647,22 @@ fragment $fragmentName on Type {
|
||||
*/
|
||||
public function testParsesListTypes() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::LIST_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 8],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'value' => 'MyType'
|
||||
]
|
||||
]
|
||||
], $this->nodeToArray(Parser::parseType('[MyType]')));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::LIST_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 8],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'value' => 'MyType',
|
||||
],
|
||||
],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseType('[MyType]'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -602,19 +670,22 @@ fragment $fragmentName on Type {
|
||||
*/
|
||||
public function testParsesNonNullTypes() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::NON_NULL_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 7],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'MyType'
|
||||
]
|
||||
]
|
||||
], $this->nodeToArray(Parser::parseType('MyType!')));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::NON_NULL_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 7],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 0, 'end' => 6],
|
||||
'value' => 'MyType',
|
||||
],
|
||||
],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseType('MyType!'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -622,48 +693,25 @@ fragment $fragmentName on Type {
|
||||
*/
|
||||
public function testParsesNestedTypes() : void
|
||||
{
|
||||
$this->assertEquals([
|
||||
'kind' => NodeKind::LIST_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 9],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NON_NULL_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 8],
|
||||
$this->assertEquals(
|
||||
[
|
||||
'kind' => NodeKind::LIST_TYPE,
|
||||
'loc' => ['start' => 0, 'end' => 9],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'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);
|
||||
}
|
||||
|
||||
private function loc($line, $column)
|
||||
{
|
||||
return new SourceLocation($line, $column);
|
||||
}
|
||||
|
||||
private function expectSyntaxError($text, $message, $location)
|
||||
{
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
try {
|
||||
Parser::parse($text);
|
||||
} catch (SyntaxError $error) {
|
||||
$this->assertEquals([$location], $error->getLocations());
|
||||
throw $error;
|
||||
}
|
||||
'kind' => NodeKind::NON_NULL_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 8],
|
||||
'type' => [
|
||||
'kind' => NodeKind::NAMED_TYPE,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'name' => [
|
||||
'kind' => NodeKind::NAME,
|
||||
'loc' => ['start' => 1, 'end' => 7],
|
||||
'value' => 'MyType',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
$this->nodeToArray(Parser::parseType('[MyType!]'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
use GraphQL\Language\AST\DocumentNode;
|
||||
use GraphQL\Language\AST\EnumValueNode;
|
||||
use GraphQL\Language\AST\FieldNode;
|
||||
use GraphQL\Language\AST\NameNode;
|
||||
use GraphQL\Language\AST\OperationDefinitionNode;
|
||||
use GraphQL\Language\AST\SelectionSetNode;
|
||||
use GraphQL\Language\AST\StringValueNode;
|
||||
use GraphQL\Language\AST\VariableNode;
|
||||
use GraphQL\Language\AST\VariableDefinitionNode;
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Language\Printer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function file_get_contents;
|
||||
|
||||
class PrinterTest extends TestCase
|
||||
{
|
||||
@ -22,7 +19,7 @@ class PrinterTest extends TestCase
|
||||
public function testDoesntAlterAST() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
|
||||
$astCopy = $ast->cloneDeep();
|
||||
$this->assertEquals($astCopy, $ast);
|
||||
@ -66,7 +63,7 @@ class PrinterTest extends TestCase
|
||||
$this->assertEquals($expected, Printer::doPrint($queryAstShorthanded));
|
||||
|
||||
$mutationAst = Parser::parse('mutation { id, name }');
|
||||
$expected = 'mutation {
|
||||
$expected = 'mutation {
|
||||
id
|
||||
name
|
||||
}
|
||||
@ -76,7 +73,7 @@ class PrinterTest extends TestCase
|
||||
$queryAstWithArtifacts = Parser::parse(
|
||||
'query ($foo: TestType) @testDirective { id, name }'
|
||||
);
|
||||
$expected = 'query ($foo: TestType) @testDirective {
|
||||
$expected = 'query ($foo: TestType) @testDirective {
|
||||
id
|
||||
name
|
||||
}
|
||||
@ -86,7 +83,7 @@ class PrinterTest extends TestCase
|
||||
$mutationAstWithArtifacts = Parser::parse(
|
||||
'mutation ($foo: TestType) @testDirective { id, name }'
|
||||
);
|
||||
$expected = 'mutation ($foo: TestType) @testDirective {
|
||||
$expected = 'mutation ($foo: TestType) @testDirective {
|
||||
id
|
||||
name
|
||||
}
|
||||
@ -100,13 +97,13 @@ class PrinterTest extends TestCase
|
||||
public function testCorrectlyPrintsSingleLineBlockStringsWithLeadingSpace() : void
|
||||
{
|
||||
$mutationAstWithArtifacts = Parser::parse(
|
||||
'{ field(arg: """ space-led value""") }'
|
||||
'{ field(arg: """ space-led value""") }'
|
||||
);
|
||||
$expected = '{
|
||||
$expected = '{
|
||||
field(arg: """ space-led value""")
|
||||
}
|
||||
';
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,8 +119,8 @@ class PrinterTest extends TestCase
|
||||
indentation
|
||||
""")
|
||||
}'
|
||||
);
|
||||
$expected = '{
|
||||
);
|
||||
$expected = '{
|
||||
field(arg: """
|
||||
first
|
||||
line
|
||||
@ -131,7 +128,7 @@ class PrinterTest extends TestCase
|
||||
""")
|
||||
}
|
||||
';
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +142,7 @@ class PrinterTest extends TestCase
|
||||
""")
|
||||
}
|
||||
');
|
||||
$expected = <<<END
|
||||
$expected = <<<END
|
||||
{
|
||||
field(arg: """ space-led value "quoted string"
|
||||
""")
|
||||
@ -160,7 +157,8 @@ END;
|
||||
*/
|
||||
public function testExperimentalCorrectlyPrintsFragmentDefinedVariables() : void
|
||||
{
|
||||
$fragmentWithVariable = Parser::parse('
|
||||
$fragmentWithVariable = Parser::parse(
|
||||
'
|
||||
fragment Foo($a: ComplexType, $b: Boolean = false) on TestType {
|
||||
id
|
||||
}
|
||||
@ -187,13 +185,13 @@ END;
|
||||
field(arg: """ space-led value "quoted string"
|
||||
""")
|
||||
}'
|
||||
);
|
||||
$expected = '{
|
||||
);
|
||||
$expected = '{
|
||||
field(arg: """ space-led value "quoted string"
|
||||
""")
|
||||
}
|
||||
';
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
$this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,7 +200,7 @@ END;
|
||||
public function testPrintsKitchenSink() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
|
||||
$printed = Printer::doPrint($ast);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests;
|
||||
|
||||
use GraphQL\Language\AST\NameNode;
|
||||
@ -7,6 +10,7 @@ use GraphQL\Language\Parser;
|
||||
use GraphQL\Language\Printer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Throwable;
|
||||
use function file_get_contents;
|
||||
|
||||
class SchemaPrinterTest extends TestCase
|
||||
{
|
||||
@ -16,7 +20,7 @@ class SchemaPrinterTest extends TestCase
|
||||
public function testPrintsMinimalAst() : void
|
||||
{
|
||||
$ast = new ScalarTypeDefinitionNode([
|
||||
'name' => new NameNode(['value' => 'foo'])
|
||||
'name' => new NameNode(['value' => 'foo']),
|
||||
]);
|
||||
$this->assertEquals('scalar foo', Printer::doPrint($ast));
|
||||
}
|
||||
@ -41,7 +45,7 @@ class SchemaPrinterTest extends TestCase
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/schema-kitchen-sink.graphql');
|
||||
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$astCopy = $ast->cloneDeep();
|
||||
Printer::doPrint($ast);
|
||||
|
||||
@ -52,7 +56,7 @@ class SchemaPrinterTest extends TestCase
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/schema-kitchen-sink.graphql');
|
||||
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$printed = Printer::doPrint($ast);
|
||||
|
||||
$expected = 'schema {
|
||||
|
@ -1,5 +1,8 @@
|
||||
<?php
|
||||
namespace GraphQL\Tests;
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
use GraphQL\Language\AST\Location;
|
||||
use GraphQL\Language\AST\Node;
|
||||
@ -7,80 +10,68 @@ use GraphQL\Language\AST\NodeList;
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Utils\AST;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_keys;
|
||||
use function count;
|
||||
use function file_get_contents;
|
||||
use function get_class;
|
||||
use function get_object_vars;
|
||||
use function implode;
|
||||
use function json_decode;
|
||||
|
||||
class SerializationTest extends TestCase
|
||||
{
|
||||
public function testSerializesAst() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$ast = Parser::parse($kitchenSink);
|
||||
$expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
|
||||
$this->assertEquals($expectedAst, $ast->toArray(true));
|
||||
}
|
||||
|
||||
public function testUnserializesAst() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
|
||||
$actualAst = AST::fromArray($serializedAst);
|
||||
$parsedAst = Parser::parse($kitchenSink);
|
||||
$this->assertNodesAreEqual($parsedAst, $actualAst);
|
||||
}
|
||||
|
||||
public function testSerializeSupportsNoLocationOption() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$ast = Parser::parse($kitchenSink, ['noLocation' => true]);
|
||||
$expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
||||
$this->assertEquals($expectedAst, $ast->toArray(true));
|
||||
}
|
||||
|
||||
public function testUnserializeSupportsNoLocationOption() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
||||
$actualAst = AST::fromArray($serializedAst);
|
||||
$parsedAst = Parser::parse($kitchenSink, ['noLocation' => true]);
|
||||
$actualAst = AST::fromArray($serializedAst);
|
||||
$parsedAst = Parser::parse($kitchenSink);
|
||||
$this->assertNodesAreEqual($parsedAst, $actualAst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two nodes by actually iterating over all NodeLists, properly comparing locations (ignoring tokens), etc
|
||||
*
|
||||
* @param $expected
|
||||
* @param $actual
|
||||
* @param array $path
|
||||
* @param string[] $path
|
||||
*/
|
||||
private function assertNodesAreEqual($expected, $actual, $path = [])
|
||||
private function assertNodesAreEqual(Node $expected, Node $actual, array $path = []) : void
|
||||
{
|
||||
$err = "Mismatch at AST path: " . implode(', ', $path);
|
||||
$err = 'Mismatch at AST path: ' . implode(', ', $path);
|
||||
|
||||
$this->assertInstanceOf(Node::class, $actual, $err);
|
||||
$this->assertEquals(get_class($expected), get_class($actual), $err);
|
||||
|
||||
$expectedVars = get_object_vars($expected);
|
||||
$actualVars = get_object_vars($actual);
|
||||
$actualVars = get_object_vars($actual);
|
||||
$this->assertSame(count($expectedVars), count($actualVars), $err);
|
||||
$this->assertEquals(array_keys($expectedVars), array_keys($actualVars), $err);
|
||||
|
||||
foreach ($expectedVars as $name => $expectedValue) {
|
||||
$actualValue = $actualVars[$name];
|
||||
$tmpPath = $path;
|
||||
$tmpPath[] = $name;
|
||||
$err = "Mismatch at AST path: " . implode(', ', $tmpPath);
|
||||
$tmpPath = $path;
|
||||
$tmpPath[] = $name;
|
||||
$err = 'Mismatch at AST path: ' . implode(', ', $tmpPath);
|
||||
|
||||
if ($expectedValue instanceof Node) {
|
||||
$this->assertNodesAreEqual($expectedValue, $actualValue, $tmpPath);
|
||||
} else if ($expectedValue instanceof NodeList) {
|
||||
} elseif ($expectedValue instanceof NodeList) {
|
||||
$this->assertEquals(count($expectedValue), count($actualValue), $err);
|
||||
$this->assertInstanceOf(NodeList::class, $actualValue, $err);
|
||||
|
||||
foreach ($expectedValue as $index => $listNode) {
|
||||
$tmpPath2 = $tmpPath;
|
||||
$tmpPath2 [] = $index;
|
||||
$tmpPath2 = $tmpPath;
|
||||
$tmpPath2[] = $index;
|
||||
$this->assertNodesAreEqual($listNode, $actualValue[$index], $tmpPath2);
|
||||
}
|
||||
} else if ($expectedValue instanceof Location) {
|
||||
} elseif ($expectedValue instanceof Location) {
|
||||
$this->assertInstanceOf(Location::class, $actualValue, $err);
|
||||
$this->assertSame($expectedValue->start, $actualValue->start, $err);
|
||||
$this->assertSame($expectedValue->end, $actualValue->end, $err);
|
||||
@ -89,4 +80,21 @@ class SerializationTest extends TestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testSerializeSupportsNoLocationOption() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$ast = Parser::parse($kitchenSink, ['noLocation' => true]);
|
||||
$expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
||||
$this->assertEquals($expectedAst, $ast->toArray(true));
|
||||
}
|
||||
|
||||
public function testUnserializeSupportsNoLocationOption() : void
|
||||
{
|
||||
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
||||
$serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
||||
$actualAst = AST::fromArray($serializedAst);
|
||||
$parsedAst = Parser::parse($kitchenSink, ['noLocation' => true]);
|
||||
$this->assertNodesAreEqual($parsedAst, $actualAst);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,41 @@
|
||||
<?php
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Language;
|
||||
|
||||
use GraphQL\Language\AST\Location;
|
||||
use GraphQL\Language\AST\Node;
|
||||
use GraphQL\Language\AST\NodeList;
|
||||
use function get_object_vars;
|
||||
use function is_array;
|
||||
use function is_scalar;
|
||||
|
||||
class TestUtils
|
||||
{
|
||||
/**
|
||||
* @param Node $node
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function nodeToArray(Node $node)
|
||||
public static function nodeToArray(Node $node) : array
|
||||
{
|
||||
$result = [
|
||||
'kind' => $node->kind,
|
||||
'loc' => self::locationToArray($node->loc)
|
||||
'loc' => self::locationToArray($node->loc),
|
||||
];
|
||||
|
||||
foreach (get_object_vars($node) as $prop => $propValue) {
|
||||
if (isset($result[$prop]))
|
||||
if (isset($result[$prop])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($propValue) || $propValue instanceof NodeList) {
|
||||
$tmp = [];
|
||||
foreach ($propValue as $tmp1) {
|
||||
$tmp[] = $tmp1 instanceof Node ? self::nodeToArray($tmp1) : (array) $tmp1;
|
||||
}
|
||||
} else if ($propValue instanceof Node) {
|
||||
} elseif ($propValue instanceof Node) {
|
||||
$tmp = self::nodeToArray($propValue);
|
||||
} else if (is_scalar($propValue) || null === $propValue) {
|
||||
} elseif (is_scalar($propValue) || $propValue === null) {
|
||||
$tmp = $propValue;
|
||||
} else {
|
||||
$tmp = null;
|
||||
@ -38,27 +43,25 @@ class TestUtils
|
||||
|
||||
$result[$prop] = $tmp;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Location $loc
|
||||
* @return array
|
||||
* @return int[]
|
||||
*/
|
||||
public static function locationToArray(Location $loc)
|
||||
public static function locationToArray(Location $loc) : array
|
||||
{
|
||||
return [
|
||||
'start' => $loc->start,
|
||||
'end' => $loc->end
|
||||
'end' => $loc->end,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $start
|
||||
* @param $end
|
||||
* @return array
|
||||
* @return int[]
|
||||
*/
|
||||
public static function locArray($start, $end)
|
||||
public static function locArray(int $start, int $end) : array
|
||||
{
|
||||
return ['start' => $start, 'end' => $end];
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests;
|
||||
|
||||
use GraphQL\Language\Token;
|
||||
@ -8,12 +11,12 @@ class TokenTest extends TestCase
|
||||
{
|
||||
public function testReturnTokenOnArray() : void
|
||||
{
|
||||
$token = new Token('Kind', 1, 10, 3, 5);
|
||||
$token = new Token('Kind', 1, 10, 3, 5);
|
||||
$expected = [
|
||||
'kind' => 'Kind',
|
||||
'value' => null,
|
||||
'line' => 3,
|
||||
'column' => 5
|
||||
'kind' => 'Kind',
|
||||
'value' => null,
|
||||
'line' => 3,
|
||||
'column' => 5,
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $token->toArray());
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user