mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-06 07:49:24 +03:00
New: printError()
Lifted from / inspired by a similar change in graphql/graphql-js#722, this creates a new function `printError()` (and uses it as the implementation for `GraphQLError#toString()`) which prints location information in the context of an error. This is moved from the syntax error where it used to be hard-coded, so it may now be used to format validation errors, value coercion errors, or any other error which may be associated with a location. ref: graphql/graphql-js BREAKING CHANGE: The SyntaxError message does not contain the codeframe anymore and only the message, (string) $error will print the codeframe.
This commit is contained in:
parent
f661f38215
commit
15374a31dd
@ -324,4 +324,12 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
{
|
{
|
||||||
return $this->toSerializableArray();
|
return $this->toSerializableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return FormattedError::printError($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use GraphQL\Language\Source;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\WrappingType;
|
use GraphQL\Type\Definition\WrappingType;
|
||||||
@ -27,6 +28,97 @@ class FormattedError
|
|||||||
self::$internalErrorMessage = $msg;
|
self::$internalErrorMessage = $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a GraphQLError to a string, representing useful location information
|
||||||
|
* about the error's position in the source.
|
||||||
|
*
|
||||||
|
* @param Error $error
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function printError(Error $error)
|
||||||
|
{
|
||||||
|
$source = $error->getSource();
|
||||||
|
$locations = $error->getLocations();
|
||||||
|
|
||||||
|
$message = $error->getMessage();
|
||||||
|
|
||||||
|
foreach($locations as $location) {
|
||||||
|
$message .= $source
|
||||||
|
? self::highlightSourceAtLocation($source, $location)
|
||||||
|
: " ({$location->line}:{$location->column})";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a helpful description of the location of the error in the GraphQL
|
||||||
|
* Source document.
|
||||||
|
*
|
||||||
|
* @param Source $source
|
||||||
|
* @param SourceLocation $location
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function highlightSourceAtLocation(Source $source, SourceLocation $location)
|
||||||
|
{
|
||||||
|
$line = $location->line;
|
||||||
|
$lineOffset = $source->locationOffset->line - 1;
|
||||||
|
$columnOffset = self::getColumnOffset($source, $location);
|
||||||
|
$contextLine = $line + $lineOffset;
|
||||||
|
$contextColumn = $location->column + $columnOffset;
|
||||||
|
$prevLineNum = (string) ($contextLine - 1);
|
||||||
|
$lineNum = (string) $contextLine;
|
||||||
|
$nextLineNum = (string) ($contextLine + 1);
|
||||||
|
$padLen = strlen($nextLineNum);
|
||||||
|
$lines = preg_split('/\r\n|[\n\r]/', $source->body);
|
||||||
|
|
||||||
|
$lines[0] = self::whitespace($source->locationOffset->column - 1) . $lines[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
"\n\n{$source->name} ($contextLine:$contextColumn)\n" .
|
||||||
|
($line >= 2
|
||||||
|
? (self::lpad($padLen, $prevLineNum) . ': ' . $lines[$line - 2] . "\n")
|
||||||
|
: ''
|
||||||
|
) .
|
||||||
|
self::lpad($padLen, $lineNum) .
|
||||||
|
': ' .
|
||||||
|
$lines[$line - 1] .
|
||||||
|
"\n" .
|
||||||
|
self::whitespace(2 + $padLen + $contextColumn - 1) .
|
||||||
|
"^\n" .
|
||||||
|
($line < count($lines)
|
||||||
|
? (self::lpad($padLen, $nextLineNum) . ': ' . $lines[$line] . "\n")
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Source $source
|
||||||
|
* @param SourceLocation $location
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private static function getColumnOffset(Source $source, SourceLocation $location)
|
||||||
|
{
|
||||||
|
return $location->line === 1 ? $source->locationOffset->column - 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $len
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function whitespace($len) {
|
||||||
|
return str_repeat(' ', $len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $len
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function lpad($len, $str) {
|
||||||
|
return self::whitespace($len - mb_strlen($str)) . $str;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard GraphQL error formatter. Converts any exception to array
|
* Standard GraphQL error formatter. Converts any exception to array
|
||||||
* conforming to GraphQL spec.
|
* conforming to GraphQL spec.
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
use GraphQL\Language\Source;
|
use GraphQL\Language\Source;
|
||||||
use GraphQL\Language\SourceLocation;
|
|
||||||
|
|
||||||
class SyntaxError extends Error
|
class SyntaxError extends Error
|
||||||
{
|
{
|
||||||
@ -13,59 +12,11 @@ class SyntaxError extends Error
|
|||||||
*/
|
*/
|
||||||
public function __construct(Source $source, $position, $description)
|
public function __construct(Source $source, $position, $description)
|
||||||
{
|
{
|
||||||
$location = $source->getLocation($position);
|
parent::__construct(
|
||||||
$line = $location->line + $source->locationOffset->line - 1;
|
"Syntax Error: $description",
|
||||||
$columnOffset = self::getColumnOffset($source, $location);
|
null,
|
||||||
$column = $location->column + $columnOffset;
|
$source,
|
||||||
|
[$position]
|
||||||
$syntaxError =
|
);
|
||||||
"Syntax Error {$source->name} ({$line}:{$column}) $description\n" .
|
|
||||||
"\n".
|
|
||||||
self::highlightSourceAtLocation($source, $location);
|
|
||||||
|
|
||||||
parent::__construct($syntaxError, null, $source, [$position]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Source $source
|
|
||||||
* @param SourceLocation $location
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function highlightSourceAtLocation(Source $source, SourceLocation $location)
|
|
||||||
{
|
|
||||||
$line = $location->line;
|
|
||||||
$lineOffset = $source->locationOffset->line - 1;
|
|
||||||
$columnOffset = self::getColumnOffset($source, $location);
|
|
||||||
|
|
||||||
$contextLine = $line + $lineOffset;
|
|
||||||
$prevLineNum = (string) ($contextLine - 1);
|
|
||||||
$lineNum = (string) $contextLine;
|
|
||||||
$nextLineNum = (string) ($contextLine + 1);
|
|
||||||
$padLen = mb_strlen($nextLineNum, 'UTF-8');
|
|
||||||
|
|
||||||
$unicodeChars = json_decode('"\u2028\u2029"'); // Quick hack to get js-compatible representation of these chars
|
|
||||||
$lines = preg_split('/\r\n|[\n\r' . $unicodeChars . ']/su', $source->body);
|
|
||||||
|
|
||||||
$whitespace = function ($len) {
|
|
||||||
return str_repeat(' ', $len);
|
|
||||||
};
|
|
||||||
|
|
||||||
$lpad = function ($len, $str) {
|
|
||||||
return str_pad($str, $len - mb_strlen($str, 'UTF-8') + 1, ' ', STR_PAD_LEFT);
|
|
||||||
};
|
|
||||||
|
|
||||||
$lines[0] = $whitespace($source->locationOffset->column - 1) . $lines[0];
|
|
||||||
|
|
||||||
return
|
|
||||||
($line >= 2 ? $lpad($padLen, $prevLineNum) . ': ' . $lines[$line - 2] . "\n" : '') .
|
|
||||||
($lpad($padLen, $lineNum) . ': ' . $lines[$line - 1] . "\n") .
|
|
||||||
($whitespace(2 + $padLen + $location->column - 1 + $columnOffset) . "^\n") .
|
|
||||||
($line < count($lines) ? $lpad($padLen, $nextLineNum) . ': ' . $lines[$line] . "\n" : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getColumnOffset(Source $source, SourceLocation $location)
|
|
||||||
{
|
|
||||||
return $location->line === 1 ? $source->locationOffset->column - 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ class Source
|
|||||||
* be "Foo.graphql" and location to be `{ line: 40, column: 0 }`.
|
* be "Foo.graphql" and location to be `{ line: 40, column: 0 }`.
|
||||||
* line and column in locationOffset are 1-indexed
|
* line and column in locationOffset are 1-indexed
|
||||||
*
|
*
|
||||||
* @param $body
|
* @param string $body
|
||||||
* @param null $name
|
* @param string|null $name
|
||||||
* @param SourceLocation|null $location
|
* @param SourceLocation|null $location
|
||||||
*/
|
*/
|
||||||
public function __construct($body, $name = null, SourceLocation $location = null)
|
public function __construct($body, $name = null, SourceLocation $location = null)
|
||||||
@ -52,7 +52,7 @@ class Source
|
|||||||
|
|
||||||
$this->body = $body;
|
$this->body = $body;
|
||||||
$this->length = mb_strlen($body, 'UTF-8');
|
$this->length = mb_strlen($body, 'UTF-8');
|
||||||
$this->name = $name ?: 'GraphQL';
|
$this->name = $name ?: 'GraphQL request';
|
||||||
$this->locationOffset = $location ?: new SourceLocation(1, 1);
|
$this->locationOffset = $location ?: new SourceLocation(1, 1);
|
||||||
|
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
|
@ -15,10 +15,11 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testDissallowsUncommonControlCharacters()
|
public function testDissallowsUncommonControlCharacters()
|
||||||
{
|
{
|
||||||
$char = Utils::chr(0x0007);
|
$this->expectSyntaxError(
|
||||||
|
Utils::chr(0x0007),
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:1) Cannot contain the invalid character "\u0007"', '/') . '/');
|
'Cannot contain the invalid character "\u0007"',
|
||||||
$this->lexOne($char);
|
$this->loc(1, 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,14 +108,21 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
" ?\n" .
|
" ?\n" .
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
$this->setExpectedException(SyntaxError::class,
|
try {
|
||||||
'Syntax Error GraphQL (3:5) Cannot parse the unexpected character "?".' . "\n" .
|
$this->lexOne($str);
|
||||||
"\n" .
|
$this->fail('Expected exception not thrown');
|
||||||
"2: \n" .
|
} catch (SyntaxError $error) {
|
||||||
"3: ?\n" .
|
$this->assertEquals(
|
||||||
" ^\n" .
|
'Syntax Error: Cannot parse the unexpected character "?".' . "\n" .
|
||||||
"4: \n");
|
"\n" .
|
||||||
$this->lexOne($str);
|
"GraphQL request (3:5)\n" .
|
||||||
|
"2: \n" .
|
||||||
|
"3: ?\n" .
|
||||||
|
" ^\n" .
|
||||||
|
"4: \n",
|
||||||
|
(string) $error
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,34 +137,42 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
"\n";
|
"\n";
|
||||||
$source = new Source($str, 'foo.js', new SourceLocation(11, 12));
|
$source = new Source($str, 'foo.js', new SourceLocation(11, 12));
|
||||||
|
|
||||||
$this->setExpectedException(
|
try {
|
||||||
SyntaxError::class,
|
$lexer = new Lexer($source);
|
||||||
'Syntax Error foo.js (13:6) ' .
|
$lexer->advance();
|
||||||
'Cannot parse the unexpected character "?".' . "\n" .
|
$this->fail('Expected exception not thrown');
|
||||||
"\n" .
|
} catch (SyntaxError $error) {
|
||||||
'12: ' . "\n" .
|
$this->assertEquals(
|
||||||
'13: ?' . "\n" .
|
'Syntax Error: Cannot parse the unexpected character "?".' . "\n" .
|
||||||
' ^' . "\n" .
|
"\n" .
|
||||||
'14: ' . "\n"
|
"foo.js (13:6)\n" .
|
||||||
);
|
"12: \n" .
|
||||||
$lexer = new Lexer($source);
|
"13: ?\n" .
|
||||||
$lexer->advance();
|
" ^\n" .
|
||||||
|
"14: \n",
|
||||||
|
(string) $error
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdatesColumnNumbersInErrorForFileContext()
|
public function testUpdatesColumnNumbersInErrorForFileContext()
|
||||||
{
|
{
|
||||||
$source = new Source('?', 'foo.js', new SourceLocation(1, 5));
|
$source = new Source('?', 'foo.js', new SourceLocation(1, 5));
|
||||||
|
|
||||||
$this->setExpectedException(
|
try {
|
||||||
SyntaxError::class,
|
$lexer = new Lexer($source);
|
||||||
'Syntax Error foo.js (1:5) ' .
|
$lexer->advance();
|
||||||
'Cannot parse the unexpected character "?".' . "\n" .
|
$this->fail('Expected exception not thrown');
|
||||||
"\n" .
|
} catch (SyntaxError $error) {
|
||||||
'1: ?' . "\n" .
|
$this->assertEquals(
|
||||||
' ^' . "\n"
|
'Syntax Error: Cannot parse the unexpected character "?".' . "\n" .
|
||||||
);
|
"\n" .
|
||||||
$lexer = new Lexer($source);
|
"foo.js (1:5)\n" .
|
||||||
$lexer->advance();
|
'1: ?' . "\n" .
|
||||||
|
' ^' . "\n",
|
||||||
|
(string) $error
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -298,41 +314,22 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
\"\"\""));
|
\"\"\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reportsUsefulBlockStringErrors() {
|
|
||||||
return [
|
|
||||||
['"""', "Syntax Error GraphQL (1:4) Unterminated string.\n\n1: \"\"\"\n ^\n"],
|
|
||||||
['"""no end quote', "Syntax Error GraphQL (1:16) Unterminated string.\n\n1: \"\"\"no end quote\n ^\n"],
|
|
||||||
['"""contains unescaped ' . json_decode('"\u0007"') . ' control char"""', "Syntax Error GraphQL (1:23) Invalid character within String: \"\\u0007\""],
|
|
||||||
['"""null-byte is not ' . json_decode('"\u0000"') . ' end of file"""', "Syntax Error GraphQL (1:21) Invalid character within String: \"\\u0000\""],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider reportsUsefulBlockStringErrors
|
|
||||||
* @it lex reports useful block string errors
|
|
||||||
*/
|
|
||||||
public function testReportsUsefulBlockStringErrors($str, $expectedMessage)
|
|
||||||
{
|
|
||||||
$this->setExpectedException(SyntaxError::class, $expectedMessage);
|
|
||||||
$this->lexOne($str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reportsUsefulStringErrors() {
|
public function reportsUsefulStringErrors() {
|
||||||
return [
|
return [
|
||||||
['"', "Syntax Error GraphQL (1:2) Unterminated string.\n\n1: \"\n ^\n"],
|
['"', "Unterminated string.", $this->loc(1, 2)],
|
||||||
['"no end quote', "Syntax Error GraphQL (1:14) Unterminated string.\n\n1: \"no end quote\n ^\n"],
|
['"no end quote', "Unterminated string.", $this->loc(1, 14)],
|
||||||
["'single quotes'", "Syntax Error GraphQL (1:1) Unexpected single quote character ('), did you mean to use a double quote (\")?\n\n1: 'single quotes'\n ^\n"],
|
["'single quotes'", "Unexpected single quote character ('), did you mean to use a double quote (\")?", $this->loc(1, 1)],
|
||||||
['"contains unescaped \u0007 control char"', "Syntax Error GraphQL (1:21) Invalid character within String: \"\\u0007\"\n\n1: \"contains unescaped \\u0007 control char\"\n ^\n"],
|
['"contains unescaped \u0007 control char"', "Invalid character within String: \"\\u0007\"", $this->loc(1, 21)],
|
||||||
['"null-byte is not \u0000 end of file"', 'Syntax Error GraphQL (1:19) Invalid character within String: "\\u0000"' . "\n\n1: \"null-byte is not \\u0000 end of file\"\n ^\n"],
|
['"null-byte is not \u0000 end of file"', 'Invalid character within String: "\\u0000"', $this->loc(1, 19)],
|
||||||
['"multi' . "\n" . 'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n"],
|
['"multi' . "\n" . 'line"', "Unterminated string.", $this->loc(1, 7)],
|
||||||
['"multi' . "\r" . 'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n"],
|
['"multi' . "\r" . 'line"', "Unterminated string.", $this->loc(1, 7)],
|
||||||
['"bad \\z esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\z\n\n1: \"bad \\z esc\"\n ^\n"],
|
['"bad \\z esc"', "Invalid character escape sequence: \\z", $this->loc(1, 7)],
|
||||||
['"bad \\x esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\x\n\n1: \"bad \\x esc\"\n ^\n"],
|
['"bad \\x esc"', "Invalid character escape sequence: \\x", $this->loc(1, 7)],
|
||||||
['"bad \\u1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u1 es\n\n1: \"bad \\u1 esc\"\n ^\n"],
|
['"bad \\u1 esc"', "Invalid character escape sequence: \\u1 es", $this->loc(1, 7)],
|
||||||
['"bad \\u0XX1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u0XX1\n\n1: \"bad \\u0XX1 esc\"\n ^\n"],
|
['"bad \\u0XX1 esc"', "Invalid character escape sequence: \\u0XX1", $this->loc(1, 7)],
|
||||||
['"bad \\uXXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXX\n\n1: \"bad \\uXXXX esc\"\n ^\n"],
|
['"bad \\uXXXX esc"', "Invalid character escape sequence: \\uXXXX", $this->loc(1, 7)],
|
||||||
['"bad \\uFXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uFXXX\n\n1: \"bad \\uFXXX esc\"\n ^\n"],
|
['"bad \\uFXXX esc"', "Invalid character escape sequence: \\uFXXX", $this->loc(1, 7)],
|
||||||
['"bad \\uXXXF esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXF\n\n1: \"bad \\uXXXF esc\"\n ^\n"],
|
['"bad \\uXXXF esc"', "Invalid character escape sequence: \\uXXXF", $this->loc(1, 7)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +337,27 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @dataProvider reportsUsefulStringErrors
|
* @dataProvider reportsUsefulStringErrors
|
||||||
* @it lex reports useful string errors
|
* @it lex reports useful string errors
|
||||||
*/
|
*/
|
||||||
public function testLexReportsUsefulStringErrors($str, $expectedMessage)
|
public function testLexReportsUsefulStringErrors($str, $expectedMessage, $location)
|
||||||
{
|
{
|
||||||
$this->setExpectedException(SyntaxError::class, $expectedMessage);
|
$this->expectSyntaxError($str, $expectedMessage, $location);
|
||||||
$this->lexOne($str);
|
}
|
||||||
|
|
||||||
|
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)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider reportsUsefulBlockStringErrors
|
||||||
|
* @it lex reports useful block string errors
|
||||||
|
*/
|
||||||
|
public function testReportsUsefulBlockStringErrors($str, $expectedMessage, $location)
|
||||||
|
{
|
||||||
|
$this->expectSyntaxError($str, $expectedMessage, $location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -420,15 +434,15 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function reportsUsefulNumberErrors()
|
public function reportsUsefulNumberErrors()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[ '00', "Syntax Error GraphQL (1:2) Invalid number, unexpected digit after 0: \"0\"\n\n1: 00\n ^\n"],
|
[ '00', "Invalid number, unexpected digit after 0: \"0\"", $this->loc(1, 2)],
|
||||||
[ '+1', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"+\".\n\n1: +1\n ^\n"],
|
[ '+1', "Cannot parse the unexpected character \"+\".", $this->loc(1, 1)],
|
||||||
[ '1.', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: <EOF>\n\n1: 1.\n ^\n"],
|
[ '1.', "Invalid number, expected digit but got: <EOF>", $this->loc(1, 3)],
|
||||||
[ '1.e1', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"e\"\n\n1: 1.e1\n ^\n"],
|
[ '1.e1', "Invalid number, expected digit but got: \"e\"", $this->loc(1, 3)],
|
||||||
[ '.123', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: .123\n ^\n"],
|
[ '.123', "Cannot parse the unexpected character \".\".", $this->loc(1, 1)],
|
||||||
[ '1.A', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"A\"\n\n1: 1.A\n ^\n"],
|
[ '1.A', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 3)],
|
||||||
[ '-A', "Syntax Error GraphQL (1:2) Invalid number, expected digit but got: \"A\"\n\n1: -A\n ^\n"],
|
[ '-A', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 2)],
|
||||||
[ '1.0e', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: <EOF>\n\n1: 1.0e\n ^\n"],
|
[ '1.0e', "Invalid number, expected digit but got: <EOF>", $this->loc(1, 5)],
|
||||||
[ '1.0eA', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: \"A\"\n\n1: 1.0eA\n ^\n"],
|
[ '1.0eA', "Invalid number, expected digit but got: \"A\"", $this->loc(1, 5)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,10 +450,9 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @dataProvider reportsUsefulNumberErrors
|
* @dataProvider reportsUsefulNumberErrors
|
||||||
* @it lex reports useful number errors
|
* @it lex reports useful number errors
|
||||||
*/
|
*/
|
||||||
public function testReportsUsefulNumberErrors($str, $expectedMessage)
|
public function testReportsUsefulNumberErrors($str, $expectedMessage, $location)
|
||||||
{
|
{
|
||||||
$this->setExpectedException(SyntaxError::class, $expectedMessage);
|
$this->expectSyntaxError($str, $expectedMessage, $location);
|
||||||
$this->lexOne($str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -507,10 +520,10 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$unicode2 = json_decode('"\u200b"');
|
$unicode2 = json_decode('"\u200b"');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['..', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: ..\n ^\n"],
|
['..', "Cannot parse the unexpected character \".\".", $this->loc(1, 1)],
|
||||||
['?', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"?\".\n\n1: ?\n ^\n"],
|
['?', "Cannot parse the unexpected character \"?\".", $this->loc(1, 1)],
|
||||||
[$unicode1, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u203b\".\n\n1: $unicode1\n ^\n"],
|
[$unicode1, "Cannot parse the unexpected character \"\\u203b\".", $this->loc(1, 1)],
|
||||||
[$unicode2, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u200b\".\n\n1: $unicode2\n ^\n"],
|
[$unicode2, "Cannot parse the unexpected character \"\\u200b\".", $this->loc(1, 1)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,10 +531,9 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @dataProvider reportsUsefulUnknownCharErrors
|
* @dataProvider reportsUsefulUnknownCharErrors
|
||||||
* @it lex reports useful unknown character error
|
* @it lex reports useful unknown character error
|
||||||
*/
|
*/
|
||||||
public function testReportsUsefulUnknownCharErrors($str, $expectedMessage)
|
public function testReportsUsefulUnknownCharErrors($str, $expectedMessage, $location)
|
||||||
{
|
{
|
||||||
$this->setExpectedException(SyntaxError::class, $expectedMessage);
|
$this->expectSyntaxError($str, $expectedMessage, $location);
|
||||||
$this->lexOne($str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -533,8 +545,14 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$lexer = new Lexer(new Source($q));
|
$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->setExpectedException(SyntaxError::class, 'Syntax Error GraphQL (1:3) Invalid number, expected digit but got: "b"' . "\n\n1: a-b\n ^\n");
|
$this->setExpectedException(SyntaxError::class, 'Syntax Error: Invalid number, expected digit but got: "b"');
|
||||||
$lexer->advance();
|
try {
|
||||||
|
$lexer->advance();
|
||||||
|
$this->fail('Expected exception not thrown');
|
||||||
|
} catch(SyntaxError $error) {
|
||||||
|
$this->assertEquals([$this->loc(1,3)], $error->getLocations());
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -588,4 +606,20 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$lexer = new Lexer(new Source($body));
|
$lexer = new Lexer(new Source($body));
|
||||||
return $lexer->advance();
|
return $lexer->advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loc($line, $column)
|
||||||
|
{
|
||||||
|
return new SourceLocation($line, $column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function expectSyntaxError($text, $message, $location)
|
||||||
|
{
|
||||||
|
$this->setExpectedException(SyntaxError::class, $message);
|
||||||
|
try {
|
||||||
|
$this->lexOne($text);
|
||||||
|
} catch (SyntaxError $error) {
|
||||||
|
$this->assertEquals([$location], $error->getLocations());
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,13 +39,13 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function parseProvidesUsefulErrors()
|
public function parseProvidesUsefulErrors()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['{', "Syntax Error GraphQL (1:2) Expected Name, found <EOF>\n\n1: {\n ^\n", [1], [new SourceLocation(1, 2)]],
|
['{', "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 }
|
['{ ...MissingOn }
|
||||||
fragment MissingOn Type
|
fragment MissingOn Type
|
||||||
', "Syntax Error GraphQL (2:20) Expected \"on\", found Name \"Type\"\n\n1: { ...MissingOn }\n2: fragment MissingOn Type\n ^\n3: \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 GraphQL (1:10) Expected Name, found {\n\n1: { field: {} }\n ^\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 GraphQL (1:1) Unexpected Name \"notanoperation\"\n\n1: notanoperation Foo { 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 GraphQL (1:1) Unexpected ...\n\n1: ...\n ^\n"],
|
['...', "Syntax Error: Unexpected ...", "Syntax Error: Unexpected ...\n\nGraphQL request (1:1)\n1: ...\n ^\n"],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,13 +53,14 @@ fragment MissingOn Type
|
|||||||
* @dataProvider parseProvidesUsefulErrors
|
* @dataProvider parseProvidesUsefulErrors
|
||||||
* @it parse provides useful errors
|
* @it parse provides useful errors
|
||||||
*/
|
*/
|
||||||
public function testParseProvidesUsefulErrors($str, $expectedMessage, $expectedPositions = null, $expectedLocations = null)
|
public function testParseProvidesUsefulErrors($str, $expectedMessage, $stringRepresentation, $expectedPositions = null, $expectedLocations = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Parser::parse($str);
|
Parser::parse($str);
|
||||||
$this->fail('Expected exception not thrown');
|
$this->fail('Expected exception not thrown');
|
||||||
} catch (SyntaxError $e) {
|
} catch (SyntaxError $e) {
|
||||||
$this->assertEquals($expectedMessage, $e->getMessage());
|
$this->assertEquals($expectedMessage, $e->getMessage());
|
||||||
|
$this->assertEquals($stringRepresentation, (string) $e);
|
||||||
|
|
||||||
if ($expectedPositions) {
|
if ($expectedPositions) {
|
||||||
$this->assertEquals($expectedPositions, $e->getPositions());
|
$this->assertEquals($expectedPositions, $e->getPositions());
|
||||||
@ -76,8 +77,15 @@ fragment MissingOn Type
|
|||||||
*/
|
*/
|
||||||
public function testParseProvidesUsefulErrorWhenUsingSource()
|
public function testParseProvidesUsefulErrorWhenUsingSource()
|
||||||
{
|
{
|
||||||
$this->setExpectedException(SyntaxError::class, "Syntax Error MyQuery.graphql (1:6) Expected {, found <EOF>\n\n1: query\n ^\n");
|
try {
|
||||||
Parser::parse(new Source('query', 'MyQuery.graphql'));
|
Parser::parse(new Source('query', 'MyQuery.graphql'));
|
||||||
|
$this->fail('Expected exception not thrown');
|
||||||
|
} catch (SyntaxError $error) {
|
||||||
|
$this->assertEquals(
|
||||||
|
"Syntax Error: Expected {, found <EOF>\n\nMyQuery.graphql (1:6)\n1: query\n ^\n",
|
||||||
|
(string) $error
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,8 +102,11 @@ fragment MissingOn Type
|
|||||||
*/
|
*/
|
||||||
public function testParsesConstantDefaultValues()
|
public function testParsesConstantDefaultValues()
|
||||||
{
|
{
|
||||||
$this->setExpectedException(SyntaxError::class, "Syntax Error GraphQL (1:37) Unexpected $\n\n" . '1: query Foo($x: Complex = { a: { b: [ $var ] } }) { field }' . "\n ^\n");
|
$this->expectSyntaxError(
|
||||||
Parser::parse('query Foo($x: Complex = { a: { b: [ $var ] } }) { field }');
|
'query Foo($x: Complex = { a: { b: [ $var ] } }) { field }',
|
||||||
|
'Unexpected $',
|
||||||
|
$this->loc(1,37)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,8 +114,11 @@ fragment MissingOn Type
|
|||||||
*/
|
*/
|
||||||
public function testDoesNotAcceptFragmentsNamedOn()
|
public function testDoesNotAcceptFragmentsNamedOn()
|
||||||
{
|
{
|
||||||
$this->setExpectedException('GraphQL\Error\SyntaxError', 'Syntax Error GraphQL (1:10) Unexpected Name "on"');
|
$this->expectSyntaxError(
|
||||||
Parser::parse('fragment on on on { on }');
|
'fragment on on on { on }',
|
||||||
|
'Unexpected Name "on"',
|
||||||
|
$this->loc(1,10)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,8 +126,11 @@ fragment MissingOn Type
|
|||||||
*/
|
*/
|
||||||
public function testDoesNotAcceptFragmentSpreadOfOn()
|
public function testDoesNotAcceptFragmentSpreadOfOn()
|
||||||
{
|
{
|
||||||
$this->setExpectedException('GraphQL\Error\SyntaxError', 'Syntax Error GraphQL (1:9) Expected Name, found }');
|
$this->expectSyntaxError(
|
||||||
Parser::parse('{ ...on }');
|
'{ ...on }',
|
||||||
|
'Expected Name, found }',
|
||||||
|
$this->loc(1,9)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -610,4 +627,20 @@ fragment $fragmentName on Type {
|
|||||||
{
|
{
|
||||||
return TestUtils::nodeToArray($node);
|
return TestUtils::nodeToArray($node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loc($line, $column)
|
||||||
|
{
|
||||||
|
return new SourceLocation($line, $column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function expectSyntaxError($text, $message, $location)
|
||||||
|
{
|
||||||
|
$this->setExpectedException(SyntaxError::class, $message);
|
||||||
|
try {
|
||||||
|
Parser::parse($text);
|
||||||
|
} catch (SyntaxError $error) {
|
||||||
|
$this->assertEquals([$location], $error->getLocations());
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ namespace GraphQL\Tests\Language;
|
|||||||
use GraphQL\Error\SyntaxError;
|
use GraphQL\Error\SyntaxError;
|
||||||
use GraphQL\Language\AST\NodeKind;
|
use GraphQL\Language\AST\NodeKind;
|
||||||
use GraphQL\Language\Parser;
|
use GraphQL\Language\Parser;
|
||||||
|
use GraphQL\Language\SourceLocation;
|
||||||
|
|
||||||
class SchemaParserTest extends \PHPUnit_Framework_TestCase
|
class SchemaParserTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
@ -199,31 +200,49 @@ extend type Hello {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @it Extension do not include descriptions
|
* @it Extension without anything throws
|
||||||
* @expectedException \GraphQL\Error\SyntaxError
|
|
||||||
* @expectedExceptionMessage Syntax Error GraphQL (3:7)
|
|
||||||
*/
|
*/
|
||||||
public function testExtensionDoNotIncludeDescriptions() {
|
public function testExtensionWithoutAnythingThrows()
|
||||||
|
{
|
||||||
|
$this->expectSyntaxError(
|
||||||
|
'extend type Hello',
|
||||||
|
'Unexpected <EOF>',
|
||||||
|
$this->loc(1, 18)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @it Extension do not include descriptions
|
||||||
|
*/
|
||||||
|
public function testExtensionDoNotIncludeDescriptions()
|
||||||
|
{
|
||||||
$body = '
|
$body = '
|
||||||
"Description"
|
"Description"
|
||||||
extend type Hello {
|
extend type Hello {
|
||||||
world: String
|
world: String
|
||||||
}';
|
}';
|
||||||
Parser::parse($body);
|
$this->expectSyntaxError(
|
||||||
|
$body,
|
||||||
|
'Unexpected Name "extend"',
|
||||||
|
$this->loc(3, 7)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @it Extension do not include descriptions
|
* @it Extension do not include descriptions
|
||||||
* @expectedException \GraphQL\Error\SyntaxError
|
|
||||||
* @expectedExceptionMessage Syntax Error GraphQL (2:14)
|
|
||||||
*/
|
*/
|
||||||
public function testExtensionDoNotIncludeDescriptions2() {
|
public function testExtensionDoNotIncludeDescriptions2()
|
||||||
|
{
|
||||||
$body = '
|
$body = '
|
||||||
extend "Description" type Hello {
|
extend "Description" type Hello {
|
||||||
world: String
|
world: String
|
||||||
}
|
}
|
||||||
}';
|
}';
|
||||||
Parser::parse($body);
|
$this->expectSyntaxError(
|
||||||
|
$body,
|
||||||
|
'Unexpected String "Description"',
|
||||||
|
$this->loc(2, 14)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -707,9 +726,11 @@ type Hello {
|
|||||||
*/
|
*/
|
||||||
public function testUnionFailsWithNoTypes()
|
public function testUnionFailsWithNoTypes()
|
||||||
{
|
{
|
||||||
$body = 'union Hello = |';
|
$this->expectSyntaxError(
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:16) Expected Name, found <EOF>', '/') . '/');
|
'union Hello = |',
|
||||||
Parser::parse($body);
|
'Expected Name, found <EOF>',
|
||||||
|
$this->loc(1, 16)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -717,9 +738,11 @@ type Hello {
|
|||||||
*/
|
*/
|
||||||
public function testUnionFailsWithLeadingDoublePipe()
|
public function testUnionFailsWithLeadingDoublePipe()
|
||||||
{
|
{
|
||||||
$body = 'union Hello = || Wo | Rld';
|
$this->expectSyntaxError(
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:16) Expected Name, found |', '/') . '/');
|
'union Hello = || Wo | Rld',
|
||||||
Parser::parse($body);
|
'Expected Name, found |',
|
||||||
|
$this->loc(1, 16)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -727,9 +750,11 @@ type Hello {
|
|||||||
*/
|
*/
|
||||||
public function testUnionFailsWithDoublePipe()
|
public function testUnionFailsWithDoublePipe()
|
||||||
{
|
{
|
||||||
$body = 'union Hello = Wo || Rld';
|
$this->expectSyntaxError(
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:19) Expected Name, found |', '/') . '/');
|
'union Hello = Wo || Rld',
|
||||||
Parser::parse($body);
|
'Expected Name, found |',
|
||||||
|
$this->loc(1, 19)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -737,9 +762,11 @@ type Hello {
|
|||||||
*/
|
*/
|
||||||
public function testUnionFailsWithTrailingPipe()
|
public function testUnionFailsWithTrailingPipe()
|
||||||
{
|
{
|
||||||
$body = 'union Hello = | Wo | Rld |';
|
$this->expectSyntaxError(
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:27) Expected Name, found <EOF>', '/') . '/');
|
'union Hello = | Wo | Rld |',
|
||||||
Parser::parse($body);
|
'Expected Name, found <EOF>',
|
||||||
|
$this->loc(1, 27)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -804,28 +831,33 @@ input Hello {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @it Simple input object with args should fail
|
* @it Simple input object with args should fail
|
||||||
* @expectedException \GraphQL\Error\SyntaxError
|
|
||||||
*/
|
*/
|
||||||
public function testSimpleInputObjectWithArgsShouldFail()
|
public function testSimpleInputObjectWithArgsShouldFail()
|
||||||
{
|
{
|
||||||
$body = '
|
$body = '
|
||||||
input Hello {
|
input Hello {
|
||||||
world(foo: Int): String
|
world(foo: Int): String
|
||||||
}';
|
}';
|
||||||
Parser::parse($body);
|
$this->expectSyntaxError(
|
||||||
|
$body,
|
||||||
|
'Expected :, found (',
|
||||||
|
$this->loc(3, 14)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @it Directive with incorrect locations
|
* @it Directive with incorrect locations
|
||||||
* @expectedException \GraphQL\Error\SyntaxError
|
|
||||||
* @expectedExceptionMessage Syntax Error GraphQL (2:33) Unexpected Name "INCORRECT_LOCATION"
|
|
||||||
*/
|
*/
|
||||||
public function testDirectiveWithIncorrectLocationShouldFail()
|
public function testDirectiveWithIncorrectLocationShouldFail()
|
||||||
{
|
{
|
||||||
$body = '
|
$body = '
|
||||||
directive @foo on FIELD | INCORRECT_LOCATION
|
directive @foo on FIELD | INCORRECT_LOCATION
|
||||||
';
|
';
|
||||||
Parser::parse($body);
|
$this->expectSyntaxError(
|
||||||
|
$body,
|
||||||
|
'Unexpected Name "INCORRECT_LOCATION"',
|
||||||
|
$this->loc(2, 33)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function typeNode($name, $loc)
|
private function typeNode($name, $loc)
|
||||||
@ -887,4 +919,20 @@ input Hello {
|
|||||||
'description' => null
|
'description' => null
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loc($line, $column)
|
||||||
|
{
|
||||||
|
return new SourceLocation($line, $column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function expectSyntaxError($text, $message, $location)
|
||||||
|
{
|
||||||
|
$this->setExpectedException(SyntaxError::class, $message);
|
||||||
|
try {
|
||||||
|
Parser::parse($text);
|
||||||
|
} catch (SyntaxError $error) {
|
||||||
|
$this->assertEquals([$location], $error->getLocations());
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class QueryExecutionTest extends TestCase
|
|||||||
$this->assertSame(null, $result->data);
|
$this->assertSame(null, $result->data);
|
||||||
$this->assertCount(1, $result->errors);
|
$this->assertCount(1, $result->errors);
|
||||||
$this->assertContains(
|
$this->assertContains(
|
||||||
'Syntax Error GraphQL (1:4) Expected Name, found <EOF>',
|
'Syntax Error: Expected Name, found <EOF>',
|
||||||
$result->errors[0]->getMessage()
|
$result->errors[0]->getMessage()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -303,10 +303,18 @@ class ServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$server = Server::create();
|
$server = Server::create();
|
||||||
$ast = $server->parse('{q}');
|
$ast = $server->parse('{q}');
|
||||||
$this->assertInstanceOf('GraphQL\Language\AST\DocumentNode', $ast);
|
$this->assertInstanceOf('GraphQL\Language\AST\DocumentNode', $ast);
|
||||||
|
}
|
||||||
|
|
||||||
$this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('{q', '/') . '/');
|
public function testParseFailure()
|
||||||
$server->parse('{q');
|
{
|
||||||
$this->fail('Expected exception not thrown');
|
$server = Server::create();
|
||||||
|
try {
|
||||||
|
$server->parse('{q');
|
||||||
|
$this->fail('Expected exception not thrown');
|
||||||
|
} catch (SyntaxError $error) {
|
||||||
|
$this->assertContains('{q', (string) $error);
|
||||||
|
$this->assertEquals('Syntax Error: Expected Name, found <EOF>', $error->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidate()
|
public function testValidate()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user