Leverage PHPUnit setExpectedException() instead of custom code

Closes #219
This commit is contained in:
Adrien Crivelli 2017-12-21 15:52:43 +09:00
parent a3f18b51f7
commit 5cbaf973e1
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
13 changed files with 637 additions and 649 deletions

View File

@ -40,12 +40,8 @@ class SyncPromiseAdapterTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('GraphQL\Executor\Promise\Promise', $result); $this->assertInstanceOf('GraphQL\Executor\Promise\Promise', $result);
$this->assertInstanceOf('GraphQL\Executor\Promise\Adapter\SyncPromise', $result->adoptedPromise); $this->assertInstanceOf('GraphQL\Executor\Promise\Adapter\SyncPromise', $result->adoptedPromise);
try { $this->setExpectedException(InvariantViolation::class, 'Expected instance of GraphQL\Deferred, got (empty string)');
$this->promises->convertThenable(''); $this->promises->convertThenable('');
$this->fail('Expected exception no thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Expected instance of GraphQL\Deferred, got (empty string)', $e->getMessage());
}
} }
public function testThen() public function testThen()

View File

@ -33,7 +33,7 @@ class SyncPromiseTest extends \PHPUnit_Framework_TestCase
/** /**
* @dataProvider getFulfilledPromiseResolveData * @dataProvider getFulfilledPromiseResolveData
*/ */
public function testFulfilledPromise( public function testFulfilledPromiseCannotChangeValue(
$resolvedValue, $resolvedValue,
$onFulfilled, $onFulfilled,
$expectedNextValue, $expectedNextValue,
@ -47,19 +47,47 @@ class SyncPromiseTest extends \PHPUnit_Framework_TestCase
$promise->resolve($resolvedValue); $promise->resolve($resolvedValue);
$this->assertEquals(SyncPromise::FULFILLED, $promise->state); $this->assertEquals(SyncPromise::FULFILLED, $promise->state);
try { $this->setExpectedException(\Exception::class, 'Cannot change value of fulfilled promise');
$promise->resolve($resolvedValue . '-other-value'); $promise->resolve($resolvedValue . '-other-value');
$this->fail('Expected exception not thrown'); }
} catch (\Exception $e) {
$this->assertEquals('Cannot change value of fulfilled promise', $e->getMessage());
}
try { /**
$promise->reject(new \Exception('anything')); * @dataProvider getFulfilledPromiseResolveData
$this->fail('Expected exception not thrown'); */
} catch (\Exception $e) { public function testFulfilledPromiseCannotBeRejected(
$this->assertEquals('Cannot reject fulfilled promise', $e->getMessage()); $resolvedValue,
} $onFulfilled,
$expectedNextValue,
$expectedNextReason,
$expectedNextState
)
{
$promise = new SyncPromise();
$this->assertEquals(SyncPromise::PENDING, $promise->state);
$promise->resolve($resolvedValue);
$this->assertEquals(SyncPromise::FULFILLED, $promise->state);
$this->setExpectedException(\Exception::class, 'Cannot reject fulfilled promise');
$promise->reject(new \Exception('anything'));
}
/**
* @dataProvider getFulfilledPromiseResolveData
*/
public function testFulfilledPromise(
$resolvedValue,
$onFulfilled,
$expectedNextValue,
$expectedNextReason,
$expectedNextState
)
{
$promise = new SyncPromise();
$this->assertEquals(SyncPromise::PENDING, $promise->state);
$promise->resolve($resolvedValue);
$this->assertEquals(SyncPromise::FULFILLED, $promise->state);
$nextPromise = $promise->then(null, function() {}); $nextPromise = $promise->then(null, function() {});
$this->assertSame($promise, $nextPromise); $this->assertSame($promise, $nextPromise);
@ -117,6 +145,49 @@ class SyncPromiseTest extends \PHPUnit_Framework_TestCase
]; ];
} }
/**
* @dataProvider getRejectedPromiseData
*/
public function testRejectedPromiseCannotChangeReason(
$rejectedReason,
$onRejected,
$expectedNextValue,
$expectedNextReason,
$expectedNextState
)
{
$promise = new SyncPromise();
$this->assertEquals(SyncPromise::PENDING, $promise->state);
$promise->reject($rejectedReason);
$this->assertEquals(SyncPromise::REJECTED, $promise->state);
$this->setExpectedException(\Exception::class, 'Cannot change rejection reason');
$promise->reject(new \Exception('other-reason'));
}
/**
* @dataProvider getRejectedPromiseData
*/
public function testRejectedPromiseCannotBeResolved(
$rejectedReason,
$onRejected,
$expectedNextValue,
$expectedNextReason,
$expectedNextState
)
{
$promise = new SyncPromise();
$this->assertEquals(SyncPromise::PENDING, $promise->state);
$promise->reject($rejectedReason);
$this->assertEquals(SyncPromise::REJECTED, $promise->state);
$this->setExpectedException(\Exception::class, 'Cannot resolve rejected promise');
$promise->resolve('anything');
}
/** /**
* @dataProvider getRejectedPromiseData * @dataProvider getRejectedPromiseData
*/ */

View File

@ -15,17 +15,10 @@ class LexerTest extends \PHPUnit_Framework_TestCase
*/ */
public function testDissallowsUncommonControlCharacters() public function testDissallowsUncommonControlCharacters()
{ {
try { $char = Utils::chr(0x0007);
$char = Utils::chr(0x0007);
$this->lexOne($char); $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:1) Cannot contain the invalid character "\u0007"', '/') . '/');
$this->fail('Expected exception not thrown'); $this->lexOne($char);
} catch (SyntaxError $error) {
$msg = mb_substr($error->getMessage(), 0, 72, 'UTF-8');
$this->assertEquals(
'Syntax Error GraphQL (1:1) Cannot contain the invalid character "\u0007"',
$msg
);
}
} }
/** /**
@ -114,20 +107,14 @@ class LexerTest extends \PHPUnit_Framework_TestCase
" ?\n" . " ?\n" .
"\n"; "\n";
try { $this->setExpectedException(SyntaxError::class,
$this->lexOne($str); 'Syntax Error GraphQL (3:5) Cannot parse the unexpected character "?".' . "\n" .
$this->fail('Expected exception not thrown'); "\n" .
} catch (SyntaxError $e) { "2: \n" .
$this->assertEquals( "3: ?\n" .
'Syntax Error GraphQL (3:5) Cannot parse the unexpected character "?".' . "\n" . " ^\n" .
"\n" . "4: \n");
"2: \n" . $this->lexOne($str);
"3: ?\n" .
" ^\n" .
"4: \n",
$e->getMessage()
);
}
} }
/** /**
@ -236,34 +223,33 @@ class LexerTest extends \PHPUnit_Framework_TestCase
], (array) $this->lexOne('"\u1234\u5678\u90AB\uCDEF"')); ], (array) $this->lexOne('"\u1234\u5678\u90AB\uCDEF"'));
} }
public function reportsUsefulErrors() {
return [
['"', "Syntax Error GraphQL (1:2) Unterminated string.\n\n1: \"\n ^\n"],
['"no end quote', "Syntax Error GraphQL (1:14) Unterminated string.\n\n1: \"no end quote\n ^\n"],
["'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"],
['"contains unescaped \u0007 control char"', "Syntax Error GraphQL (1:21) Invalid character within String: \"\\u0007\"\n\n1: \"contains unescaped \\u0007 control char\"\n ^\n"],
['"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"],
['"multi' . "\n" . 'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n"],
['"multi' . "\r" . 'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n"],
['"bad \\z esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\z\n\n1: \"bad \\z esc\"\n ^\n"],
['"bad \\x esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\x\n\n1: \"bad \\x esc\"\n ^\n"],
['"bad \\u1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u1 es\n\n1: \"bad \\u1 esc\"\n ^\n"],
['"bad \\u0XX1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u0XX1\n\n1: \"bad \\u0XX1 esc\"\n ^\n"],
['"bad \\uXXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXX\n\n1: \"bad \\uXXXX esc\"\n ^\n"],
['"bad \\uFXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uFXXX\n\n1: \"bad \\uFXXX esc\"\n ^\n"],
['"bad \\uXXXF esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXF\n\n1: \"bad \\uXXXF esc\"\n ^\n"],
];
}
/** /**
* @dataProvider reportsUsefulErrors
* @it lex reports useful string errors * @it lex reports useful string errors
*/ */
public function testReportsUsefulErrors() public function testReportsUsefulErrors($str, $expectedMessage)
{ {
$run = function($num, $str, $expectedMessage) { $this->setExpectedException(SyntaxError::class, $expectedMessage);
try { $this->lexOne($str);
$this->lexOne($str);
$this->fail('Expected exception not thrown in example: ' . $num);
} catch (SyntaxError $e) {
$this->assertEquals($expectedMessage, $e->getMessage(), "Test case $num failed");
}
};
$run(1, '"', "Syntax Error GraphQL (1:2) Unterminated string.\n\n1: \"\n ^\n");
$run(2, '"no end quote', "Syntax Error GraphQL (1:14) Unterminated string.\n\n1: \"no end quote\n ^\n");
$run(3, "'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");
$run(4, '"contains unescaped \u0007 control char"', "Syntax Error GraphQL (1:21) Invalid character within String: \"\\u0007\"\n\n1: \"contains unescaped \\u0007 control char\"\n ^\n");
$run(5, '"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");
$run(6, '"multi'."\n".'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n");
$run(7, '"multi'."\r".'line"', "Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n ^\n2: line\"\n");
$run(8, '"bad \\z esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\z\n\n1: \"bad \\z esc\"\n ^\n");
$run(9, '"bad \\x esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\x\n\n1: \"bad \\x esc\"\n ^\n");
$run(10, '"bad \\u1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u1 es\n\n1: \"bad \\u1 esc\"\n ^\n");
$run(11, '"bad \\u0XX1 esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u0XX1\n\n1: \"bad \\u0XX1 esc\"\n ^\n");
$run(12, '"bad \\uXXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXX\n\n1: \"bad \\uXXXX esc\"\n ^\n");
$run(13, '"bad \\uFXXX esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uFXXX\n\n1: \"bad \\uFXXX esc\"\n ^\n");
$run(14, '"bad \\uXXXF esc"', "Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXF\n\n1: \"bad \\uXXXF esc\"\n ^\n");
} }
/** /**
@ -337,28 +323,28 @@ class LexerTest extends \PHPUnit_Framework_TestCase
); );
} }
public function reportsUsefulNumberErrors()
{
return [
[ '00', "Syntax Error GraphQL (1:2) Invalid number, unexpected digit after 0: \"0\"\n\n1: 00\n ^\n"],
[ '+1', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"+\".\n\n1: +1\n ^\n"],
[ '1.', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: <EOF>\n\n1: 1.\n ^\n"],
[ '.123', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: .123\n ^\n"],
[ '1.A', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"A\"\n\n1: 1.A\n ^\n"],
[ '-A', "Syntax Error GraphQL (1:2) Invalid number, expected digit but got: \"A\"\n\n1: -A\n ^\n"],
[ '1.0e', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: <EOF>\n\n1: 1.0e\n ^\n"],
[ '1.0eA', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: \"A\"\n\n1: 1.0eA\n ^\n"],
];
}
/** /**
* @dataProvider reportsUsefulNumberErrors
* @it lex reports useful number errors * @it lex reports useful number errors
*/ */
public function testReportsUsefulNumberErrors() public function testReportsUsefulNumberErrors($str, $expectedMessage)
{ {
$run = function($num, $str, $expectedMessage) { $this->setExpectedException(SyntaxError::class, $expectedMessage);
try { $this->lexOne($str);
$this->lexOne($str);
$this->fail('Expected exception not thrown in example: ' . $num);
} catch (SyntaxError $e) {
$this->assertEquals($expectedMessage, $e->getMessage(), "Test case $num failed");
}
};
$run(0, '00', "Syntax Error GraphQL (1:2) Invalid number, unexpected digit after 0: \"0\"\n\n1: 00\n ^\n");
$run(1, '+1', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"+\".\n\n1: +1\n ^\n");
$run(2, '1.', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: <EOF>\n\n1: 1.\n ^\n");
$run(3, '.123', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: .123\n ^\n");
$run(4, '1.A', "Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"A\"\n\n1: 1.A\n ^\n");
$run(5, '-A', "Syntax Error GraphQL (1:2) Invalid number, expected digit but got: \"A\"\n\n1: -A\n ^\n");
$run(6, '1.0e', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: <EOF>\n\n1: 1.0e\n ^\n");
$run(7, '1.0eA', "Syntax Error GraphQL (1:5) Invalid number, expected digit but got: \"A\"\n\n1: 1.0eA\n ^\n");
} }
/** /**
@ -420,27 +406,27 @@ class LexerTest extends \PHPUnit_Framework_TestCase
); );
} }
public function reportsUsefulUnknownCharErrors()
{
$unicode1 = json_decode('"\u203B"');
$unicode2 = json_decode('"\u200b"');
return [
['..', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: ..\n ^\n"],
['?', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"?\".\n\n1: ?\n ^\n"],
[$unicode1, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u203b\".\n\n1: $unicode1\n ^\n"],
[$unicode2, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u200b\".\n\n1: $unicode2\n ^\n"],
];
}
/** /**
* @dataProvider reportsUsefulUnknownCharErrors
* @it lex reports useful unknown character error * @it lex reports useful unknown character error
*/ */
public function testReportsUsefulUnknownCharErrors() public function testReportsUsefulUnknownCharErrors($str, $expectedMessage)
{ {
$run = function($num, $str, $expectedMessage) { $this->setExpectedException(SyntaxError::class, $expectedMessage);
try { $this->lexOne($str);
$this->lexOne($str);
$this->fail('Expected exception not thrown in example: ' . $num);
} catch (SyntaxError $e) {
$this->assertEquals($expectedMessage, $e->getMessage(), "Test case $num failed");
}
};
$run(1, '..', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \".\".\n\n1: ..\n ^\n");
$run(2, '?', "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"?\".\n\n1: ?\n ^\n");
$unicode = json_decode('"\u203B"');
$run(3, $unicode, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u203b\".\n\n1: $unicode\n ^\n");
$unicode = json_decode('"\u200b"');
$run(4, $unicode, "Syntax Error GraphQL (1:1) Cannot parse the unexpected character \"\\u200b\".\n\n1: $unicode\n ^\n");
} }
/** /**
@ -452,12 +438,8 @@ 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());
try { $this->setExpectedException(SyntaxError::class, 'Syntax Error GraphQL (1:3) Invalid number, expected digit but got: "b"' . "\n\n1: a-b\n ^\n");
$lexer->advance(); $lexer->advance();
$this->fail('Expected exception not thrown');
} catch (SyntaxError $err) {
$this->assertEquals('Syntax Error GraphQL (1:3) Invalid number, expected digit but got: "b"'."\n\n1: a-b\n ^\n", $err->getMessage());
}
} }
/** /**

View File

@ -18,65 +18,57 @@ use GraphQL\Utils\Utils;
class ParserTest extends \PHPUnit_Framework_TestCase class ParserTest extends \PHPUnit_Framework_TestCase
{ {
/** public function testAssertsThatASourceToParseIsNotNull()
* @it asserts that a source to parse was provided
*/
public function testAssertsThatASourceToParseWasProvided()
{ {
try { $this->setExpectedException(InvariantViolation::class, 'GraphQL query body is expected to be string, but got NULL');
Parser::parse(null); Parser::parse(null);
$this->fail('Expected exception was not thrown'); }
} catch (InvariantViolation $e) {
$this->assertEquals('GraphQL query body is expected to be string, but got NULL', $e->getMessage());
}
try { public function testAssertsThatASourceToParseIsNotArray()
Parser::parse(['a' => 'b']); {
$this->fail('Expected exception was not thrown'); $this->setExpectedException(InvariantViolation::class, 'GraphQL query body is expected to be string, but got array');
} catch (InvariantViolation $e) { Parser::parse(['a' => 'b']);
$this->assertEquals('GraphQL query body is expected to be string, but got array', $e->getMessage()); }
}
try { public function testAssertsThatASourceToParseIsNotObject()
Parser::parse(new \stdClass()); {
$this->fail('Expected exception was not thrown'); $this->setExpectedException(InvariantViolation::class, 'GraphQL query body is expected to be string, but got stdClass');
} catch (InvariantViolation $e) { Parser::parse(new \stdClass());
$this->assertEquals('GraphQL query body is expected to be string, but got stdClass', $e->getMessage()); }
}
public function parseProvidesUsefulErrors()
{
return [
['{', "Syntax Error GraphQL (1:2) Expected Name, found <EOF>\n\n1: {\n ^\n", [1], [new SourceLocation(1, 2)]],
['{ ...MissingOn }
fragment MissingOn Type
', "Syntax Error GraphQL (2:20) Expected \"on\", found Name \"Type\"\n\n1: { ...MissingOn }\n2: fragment MissingOn Type\n ^\n3: \n",],
['{ field: {} }', "Syntax Error GraphQL (1:10) Expected Name, found {\n\n1: { field: {} }\n ^\n"],
['notanoperation Foo { field }', "Syntax Error GraphQL (1:1) Unexpected Name \"notanoperation\"\n\n1: notanoperation Foo { field }\n ^\n"],
['...', "Syntax Error GraphQL (1:1) Unexpected ...\n\n1: ...\n ^\n"],
];
} }
/** /**
* @dataProvider parseProvidesUsefulErrors
* @it parse provides useful errors * @it parse provides useful errors
*/ */
public function testParseProvidesUsefulErrors() public function testParseProvidesUsefulErrors($str, $expectedMessage, $expectedPositions = null, $expectedLocations = null)
{ {
$run = function($num, $str, $expectedMessage, $expectedPositions = null, $expectedLocations = null) { try {
try { Parser::parse($str);
Parser::parse($str); $this->fail('Expected exception not thrown');
$this->fail('Expected exception not thrown in example: ' . $num); } catch (SyntaxError $e) {
} catch (SyntaxError $e) { $this->assertEquals($expectedMessage, $e->getMessage());
$this->assertEquals($expectedMessage, $e->getMessage(), "Test case $num failed");
if ($expectedPositions) { if ($expectedPositions) {
$this->assertEquals($expectedPositions, $e->getPositions()); $this->assertEquals($expectedPositions, $e->getPositions());
}
if ($expectedLocations) {
$this->assertEquals($expectedLocations, $e->getLocations());
}
} }
};
$run(0, '{', "Syntax Error GraphQL (1:2) Expected Name, found <EOF>\n\n1: {\n ^\n", [1], [new SourceLocation(1,2)]); if ($expectedLocations) {
$run(1, $this->assertEquals($expectedLocations, $e->getLocations());
'{ ...MissingOn } }
fragment MissingOn Type }
',
"Syntax Error GraphQL (2:20) Expected \"on\", found Name \"Type\"\n\n1: { ...MissingOn }\n2: fragment MissingOn Type\n ^\n3: \n"
);
$run(2, '{ field: {} }', "Syntax Error GraphQL (1:10) Expected Name, found {\n\n1: { field: {} }\n ^\n");
$run(3, 'notanoperation Foo { field }', "Syntax Error GraphQL (1:1) Unexpected Name \"notanoperation\"\n\n1: notanoperation Foo { field }\n ^\n");
$run(4, '...', "Syntax Error GraphQL (1:1) Unexpected ...\n\n1: ...\n ^\n");
} }
/** /**
@ -84,12 +76,8 @@ fragment MissingOn Type
*/ */
public function testParseProvidesUsefulErrorWhenUsingSource() public function testParseProvidesUsefulErrorWhenUsingSource()
{ {
try { $this->setExpectedException(SyntaxError::class, "Syntax Error MyQuery.graphql (1:6) Expected {, found <EOF>\n\n1: query\n ^\n");
Parser::parse(new Source('query', 'MyQuery.graphql')); Parser::parse(new Source('query', 'MyQuery.graphql'));
$this->fail('Expected exception not thrown');
} catch (SyntaxError $e) {
$this->assertEquals("Syntax Error MyQuery.graphql (1:6) Expected {, found <EOF>\n\n1: query\n ^\n", $e->getMessage());
}
} }
/** /**
@ -106,15 +94,8 @@ fragment MissingOn Type
*/ */
public function testParsesConstantDefaultValues() public function testParsesConstantDefaultValues()
{ {
try { $this->setExpectedException(SyntaxError::class, "Syntax Error GraphQL (1:37) Unexpected $\n\n" . '1: query Foo($x: Complex = { a: { b: [ $var ] } }) { field }' . "\n ^\n");
Parser::parse('query Foo($x: Complex = { a: { b: [ $var ] } }) { field }'); Parser::parse('query Foo($x: Complex = { a: { b: [ $var ] } }) { field }');
$this->fail('Expected exception not thrown');
} catch (SyntaxError $e) {
$this->assertEquals(
"Syntax Error GraphQL (1:37) Unexpected $\n\n" . '1: query Foo($x: Complex = { a: { b: [ $var ] } }) { field }' . "\n ^\n",
$e->getMessage()
);
}
} }
/** /**

View File

@ -44,13 +44,9 @@ class PrinterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testProducesHelpfulErrorMessages() public function testProducesHelpfulErrorMessages()
{ {
$badAst1 = new \ArrayObject(array('random' => 'Data')); $badAst1 = new \ArrayObject(['random' => 'Data']);
try { $this->setExpectedException(\Exception::class, 'Invalid AST Node: {"random":"Data"}');
Printer::doPrint($badAst1); Printer::doPrint($badAst1);
$this->fail('Expected exception not thrown');
} catch (\Exception $e) {
$this->assertEquals('Invalid AST Node: {"random":"Data"}', $e->getMessage());
}
} }
/** /**

View File

@ -557,11 +557,8 @@ type Hello {
public function testUnionFailsWithNoTypes() public function testUnionFailsWithNoTypes()
{ {
$body = 'union Hello = |'; $body = 'union Hello = |';
try { $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:16) Expected Name, found <EOF>', '/') . '/');
Parser::parse($body); Parser::parse($body);
} catch (SyntaxError $e) {
$this->assertContains('Syntax Error GraphQL (1:16) Expected Name, found <EOF>', $e->getMessage());
}
} }
/** /**
@ -570,11 +567,8 @@ type Hello {
public function testUnionFailsWithLeadingDoublePipe() public function testUnionFailsWithLeadingDoublePipe()
{ {
$body = 'union Hello = || Wo | Rld'; $body = 'union Hello = || Wo | Rld';
try { $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:16) Expected Name, found |', '/') . '/');
Parser::parse($body); Parser::parse($body);
} catch (SyntaxError $e) {
$this->assertContains('Syntax Error GraphQL (1:16) Expected Name, found |', $e->getMessage());
}
} }
/** /**
@ -583,11 +577,8 @@ type Hello {
public function testUnionFailsWithDoublePipe() public function testUnionFailsWithDoublePipe()
{ {
$body = 'union Hello = Wo || Rld'; $body = 'union Hello = Wo || Rld';
try { $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:19) Expected Name, found |', '/') . '/');
Parser::parse($body); Parser::parse($body);
} catch (SyntaxError $e) {
$this->assertContains('Syntax Error GraphQL (1:19) Expected Name, found |', $e->getMessage());
}
} }
/** /**
@ -596,11 +587,8 @@ type Hello {
public function testUnionFailsWithTrailingPipe() public function testUnionFailsWithTrailingPipe()
{ {
$body = 'union Hello = | Wo | Rld |'; $body = 'union Hello = | Wo | Rld |';
try { $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('Syntax Error GraphQL (1:27) Expected Name, found <EOF>', '/') . '/');
Parser::parse($body); Parser::parse($body);
} catch (SyntaxError $e) {
$this->assertContains('Syntax Error GraphQL (1:27) Expected Name, found <EOF>', $e->getMessage());
}
} }
/** /**

View File

@ -158,103 +158,85 @@ class RequestParsingTest extends \PHPUnit_Framework_TestCase
} }
} }
public function testFailsParsingInvalidRawJsonRequest() public function testFailsParsingInvalidRawJsonRequestRaw()
{ {
$body = 'not really{} a json'; $body = 'not really{} a json';
try { $this->setExpectedException(RequestError::class, 'Could not parse JSON: Syntax error');
$this->parseRawRequest('application/json', $body); $this->parseRawRequest('application/json', $body);
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('Could not parse JSON: Syntax error', $e->getMessage());
} }
try { public function testFailsParsingInvalidRawJsonRequestPsr()
{
$body = 'not really{} a json';
$this->setExpectedException(InvariantViolation::class, 'PSR-7 request is expected to provide parsed body for "application/json" requests but got null');
$this->parsePsrRequest('application/json', $body); $this->parsePsrRequest('application/json', $body);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
// Expecting parsing exception to be thrown somewhere else:
$this->assertEquals(
'PSR-7 request is expected to provide parsed body for "application/json" requests but got null',
$e->getMessage()
);
}
} }
// There is no equivalent for psr request, because it should throw // There is no equivalent for psr request, because it should throw
public function testFailsParsingNonArrayOrObjectJsonRequest() public function testFailsParsingNonArrayOrObjectJsonRequestRaw()
{ {
$body = '"str"'; $body = '"str"';
try { $this->setExpectedException(RequestError::class, 'GraphQL Server expects JSON object or array, but got "str"');
$this->parseRawRequest('application/json', $body); $this->parseRawRequest('application/json', $body);
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('GraphQL Server expects JSON object or array, but got "str"', $e->getMessage());
} }
try { public function testFailsParsingNonArrayOrObjectJsonRequestPsr()
{
$body = '"str"';
$this->setExpectedException(RequestError::class, 'GraphQL Server expects JSON object or array, but got "str"');
$this->parsePsrRequest('application/json', $body); $this->parsePsrRequest('application/json', $body);
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('GraphQL Server expects JSON object or array, but got "str"', $e->getMessage());
} }
} public function testFailsParsingInvalidContentTypeRaw()
public function testFailsParsingInvalidContentType()
{ {
$contentType = 'not-supported-content-type'; $contentType = 'not-supported-content-type';
$body = 'test'; $body = 'test';
try { $this->setExpectedException(RequestError::class, 'Unexpected content type: "not-supported-content-type"');
$this->parseRawRequest($contentType, $body);
}
public function testFailsParsingInvalidContentTypePsr()
{
$contentType = 'not-supported-content-type';
$body = 'test';
$this->setExpectedException(RequestError::class, 'Unexpected content type: "not-supported-content-type"');
$this->parseRawRequest($contentType, $body); $this->parseRawRequest($contentType, $body);
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('Unexpected content type: "not-supported-content-type"', $e->getMessage());
} }
try { public function testFailsWithMissingContentTypeRaw()
$this->parsePsrRequest($contentType, $body);
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('Unexpected content type: "not-supported-content-type"', $e->getMessage());
}
}
public function testFailsWithMissingContentType()
{ {
try { $this->setExpectedException(RequestError::class, 'Missing "Content-Type" header');
$this->parseRawRequest(null, 'test'); $this->parseRawRequest(null, 'test');
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('Missing "Content-Type" header', $e->getMessage());
} }
try { public function testFailsWithMissingContentTypePsr()
{
$this->setExpectedException(RequestError::class, 'Missing "Content-Type" header');
$this->parsePsrRequest(null, 'test'); $this->parsePsrRequest(null, 'test');
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('Missing "Content-Type" header', $e->getMessage());
}
} }
public function testFailsOnMethodsOtherThanPostOrGet() public function testFailsOnMethodsOtherThanPostOrGetRaw()
{ {
try {
$this->setExpectedException(RequestError::class, 'HTTP Method "PUT" is not supported');
$this->parseRawRequest('application/json', json_encode([]), "PUT"); $this->parseRawRequest('application/json', json_encode([]), "PUT");
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('HTTP Method "PUT" is not supported', $e->getMessage());
} }
try { public function testFailsOnMethodsOtherThanPostOrGetPsr()
{
$body = [
'query' => '{my query}',
];
$this->setExpectedException(RequestError::class, 'HTTP Method "PUT" is not supported');
$this->parsePsrRequest('application/json', json_encode([]), "PUT"); $this->parsePsrRequest('application/json', json_encode([]), "PUT");
$this->fail('Expected exception not thrown');
} catch (RequestError $e) {
$this->assertEquals('HTTP Method "PUT" is not supported', $e->getMessage());
}
} }
/** /**

View File

@ -4,6 +4,7 @@ namespace GraphQL\Tests;
use GraphQL\Error\Debug; use GraphQL\Error\Debug;
use GraphQL\Error\FormattedError; use GraphQL\Error\FormattedError;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Error\SyntaxError;
use GraphQL\Error\UserError; use GraphQL\Error\UserError;
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter; use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
use GraphQL\Schema; use GraphQL\Schema;
@ -38,197 +39,227 @@ class ServerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(500, $server->getUnexpectedErrorStatus()); $this->assertEquals(500, $server->getUnexpectedErrorStatus());
$this->assertEquals(DocumentValidator::allRules(), $server->getValidationRules()); $this->assertEquals(DocumentValidator::allRules(), $server->getValidationRules());
try { $this->setExpectedException(InvariantViolation::class, 'Schema query must be Object Type but got: NULL');
$server->getSchema(); $server->getSchema();
$this->fail('Expected exception not thrown'); }
} catch (InvariantViolation $e) {
$this->assertEquals('Schema query must be Object Type but got: NULL', $e->getMessage()); public function testCannotUseSetQueryTypeAndSetSchema()
} {
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Query Type is already set ' .
'(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setQueryType($queryType)
->setSchema($schema);
}
public function testCannotUseSetMutationTypeAndSetSchema()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Mutation Type is already set ' .
'(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setMutationType($mutationType)
->setSchema($schema);
}
public function testCannotUseSetSubscriptionTypeAndSetSchema()
{
$subscriptionType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Subscription Type is already set ' .
'(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSubscriptionType($subscriptionType)
->setSchema($schema);
}
public function testCannotUseSetDirectivesAndSetSchema()
{
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Directives are already set ' .
'(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setDirectives(Directive::getInternalDirectives())
->setSchema($schema);
}
public function testCannotUseAddTypesAndSetSchema()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Additional types are already set ' .
'(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->addTypes([$queryType, $mutationType])
->setSchema($schema);
}
public function testCannotUseSetTypeResolutionStrategyAndSetSchema()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Type Resolution Strategy is already set ' .
'(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType]))
->setSchema($schema);
}
public function testCannotUseSetSchemaAndSetQueryType()
{
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Query Type on Server: Schema is already set ' .
'(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->setQueryType($queryType);
}
public function testCannotUseSetSchemaAndSetMutationType()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Mutation Type on Server: Schema is already set ' .
'(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->setMutationType($mutationType);
}
public function testCannotUseSetSchemaAndSetSubscriptionType()
{
$subscriptionType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Subscription Type on Server: Schema is already set ' .
'(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->setSubscriptionType($subscriptionType);
}
public function testCannotUseSetSchemaAndSetDirectives()
{
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Directives on Server: Schema is already set ' .
'(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->setDirectives([]);
}
public function testCannotUseSetSchemaAndAddTypes()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Types on Server: Schema is already set ' .
'(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->addTypes([$queryType, $mutationType]);
}
public function testCanUseSetSchemaAndAddEmptyTypes()
{
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
// But empty types should work (as they don't change anything):
Server::create()
->setSchema($schema)
->addTypes([]);
}
public function testCannotUseSetSchemaAndSetTypeResolutionStrategy()
{
$mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Type Resolution Strategy on Server: Schema is already set ' .
'(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)');
Server::create()
->setSchema($schema)
->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType]));
}
public function testCannotUseSetSchemaAndSetSchema()
{
$queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([
'query' => $queryType,
]);
$this->setExpectedException(InvariantViolation::class,
'Cannot set Schema on Server: Different schema is already set');
Server::create()
->setSchema($schema)
->setSchema(new Schema(['query' => $queryType]));
$this->fail('Expected exception not thrown');
} }
public function testSchemaDefinition() public function testSchemaDefinition()
{ {
$mutationType = $queryType = $subscriptionType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); $mutationType = $queryType = $subscriptionType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]);
$schema = new Schema([ $schema = new Schema([
'query' => $queryType 'query' => $queryType,
]); ]);
try {
Server::create()
->setQueryType($queryType)
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Query Type is already set '.
'(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setMutationType($mutationType)
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Mutation Type is already set '.
'(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSubscriptionType($subscriptionType)
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Subscription Type is already set '.
'(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setDirectives(Directive::getInternalDirectives())
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Directives are already set '.
'(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->addTypes([$queryType, $mutationType])
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Additional types are already set '.
'(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType]))
->setSchema($schema);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Type Resolution Strategy is already set '.
'(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->setQueryType($queryType);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Query Type on Server: Schema is already set '.
'(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->setMutationType($mutationType);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Mutation Type on Server: Schema is already set '.
'(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->setSubscriptionType($subscriptionType);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Subscription Type on Server: Schema is already set '.
'(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->setDirectives([]);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Directives on Server: Schema is already set '.
'(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->addTypes([$queryType, $mutationType]);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Types on Server: Schema is already set '.
'(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
// But empty types should work (as they don't change anything):
Server::create()
->setSchema($schema)
->addTypes([]);
try {
Server::create()
->setSchema($schema)
->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType]));
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Type Resolution Strategy on Server: Schema is already set '.
'(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)',
$e->getMessage()
);
}
try {
Server::create()
->setSchema($schema)
->setSchema(new Schema(['query' => $queryType]));
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set Schema on Server: Different schema is already set',
$e->getMessage()
);
}
// This should not throw:
$server = Server::create() $server = Server::create()
->setSchema($schema); ->setSchema($schema);
@ -273,12 +304,9 @@ class ServerTest extends \PHPUnit_Framework_TestCase
$ast = $server->parse('{q}'); $ast = $server->parse('{q}');
$this->assertInstanceOf('GraphQL\Language\AST\DocumentNode', $ast); $this->assertInstanceOf('GraphQL\Language\AST\DocumentNode', $ast);
try { $this->setExpectedExceptionRegExp(SyntaxError::class, '/' . preg_quote('{q', '/') . '/');
$server->parse('{q'); $server->parse('{q');
$this->fail('Expected exception not thrown'); $this->fail('Expected exception not thrown');
} catch (\GraphQL\Error\SyntaxError $e) {
$this->assertContains('{q', $e->getMessage());
}
} }
public function testValidate() public function testValidate()
@ -292,16 +320,9 @@ class ServerTest extends \PHPUnit_Framework_TestCase
$this->assertInternalType('array', $errors); $this->assertInternalType('array', $errors);
$this->assertNotEmpty($errors); $this->assertNotEmpty($errors);
try { $this->setExpectedException(InvariantViolation::class, 'Cannot validate, schema contains errors: Schema query must be Object Type but got: NULL');
$server = Server::create(); $server = Server::create();
$server->validate($ast); $server->validate($ast);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot validate, schema contains errors: Schema query must be Object Type but got: NULL',
$e->getMessage()
);
}
} }
public function testPromiseAdapter() public function testPromiseAdapter()
@ -315,15 +336,8 @@ class ServerTest extends \PHPUnit_Framework_TestCase
$this->assertSame($adapter1, $server->getPromiseAdapter()); $this->assertSame($adapter1, $server->getPromiseAdapter());
$server->setPromiseAdapter($adapter1); $server->setPromiseAdapter($adapter1);
try { $this->setExpectedException(InvariantViolation::class, 'Cannot set promise adapter: Different adapter is already set');
$server->setPromiseAdapter($adapter2); $server->setPromiseAdapter($adapter2);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'Cannot set promise adapter: Different adapter is already set',
$e->getMessage()
);
}
} }
public function testValidationRules() public function testValidationRules()
@ -583,4 +597,4 @@ class ServerTest extends \PHPUnit_Framework_TestCase
$this->assertInternalType('array', $output); $this->assertInternalType('array', $output);
$this->assertEquals($expectedOutput, $output); $this->assertEquals($expectedOutput, $output);
} }
} }

View File

@ -526,8 +526,8 @@ class ResolutionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention)); $this->assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
} }
public function testLazyThrowsOnInvalidLoadedType() private function createLazy(){
{
$descriptor = [ $descriptor = [
'version' => '1.0', 'version' => '1.0',
'typeMap' => [ 'typeMap' => [
@ -557,37 +557,29 @@ class ResolutionTest extends \PHPUnit_Framework_TestCase
$value = $lazy->resolveType('null'); $value = $lazy->resolveType('null');
$this->assertEquals(null, $value); $this->assertEquals(null, $value);
try { return $lazy;
$lazy->resolveType('int'); }
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
"Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer",
$e->getMessage()
);
} public function testLazyThrowsOnInvalidLoadedType()
{
$lazy = $this->createLazy();
$this->setExpectedException(InvariantViolation::class, "Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer");
$lazy->resolveType('int');
}
try { public function testLazyThrowsOnInvalidLoadedPossibleType()
$tmp = new InterfaceType(['name' => 'a', 'fields' => []]); {
$lazy->resolvePossibleTypes($tmp); $tmp = new InterfaceType(['name' => 'a', 'fields' => []]);
$this->fail('Expected exception not thrown'); $lazy = $this->createLazy();
} catch (InvariantViolation $e) { $this->setExpectedException(InvariantViolation::class, 'Lazy Type Resolution Error: Implementation null of interface a is expected to be instance of ObjectType, but got NULL');
$this->assertEquals( $lazy->resolvePossibleTypes($tmp);
'Lazy Type Resolution Error: Implementation null of interface a is expected to be instance of ObjectType, but got NULL', }
$e->getMessage()
);
}
try { public function testLazyThrowsOnInvalidLoadedPossibleTypeWithInteger()
$tmp = new InterfaceType(['name' => 'b', 'fields' => []]); {
$lazy->resolvePossibleTypes($tmp); $tmp = new InterfaceType(['name' => 'b', 'fields' => []]);
$this->fail('Expected exception not thrown'); $lazy = $this->createLazy();
} catch (InvariantViolation $e) { $this->setExpectedException(InvariantViolation::class, 'Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer');
$this->assertEquals( $lazy->resolvePossibleTypes($tmp);
'Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer',
$e->getMessage()
);
}
} }
} }

View File

@ -22,82 +22,89 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase
$this->assertSame(-1, $intType->serialize(-1)); $this->assertSame(-1, $intType->serialize(-1));
$this->assertSame(100000, $intType->serialize(1e5)); $this->assertSame(100000, $intType->serialize(1e5));
$this->assertSame(0, $intType->serialize(0e5)); $this->assertSame(0, $intType->serialize(0e5));
// The GraphQL specification does not allow serializing non-integer values
// as Int to avoid accidental data loss.
try {
$intType->serialize(0.1);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non-integer value: 0.1', $e->getMessage());
}
try {
$intType->serialize(1.1);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non-integer value: 1.1', $e->getMessage());
}
try {
$intType->serialize(-1.1);
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non-integer value: -1.1', $e->getMessage());
}
try {
$intType->serialize('-1.1');
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non-integer value: "-1.1"', $e->getMessage());
}
// Maybe a safe PHP int, but bigger than 2^32, so not
// representable as a GraphQL Int
try {
$intType->serialize(9876504321);
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: 9876504321', $e->getMessage());
}
try {
$intType->serialize(-9876504321);
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: -9876504321', $e->getMessage());
}
try {
$intType->serialize(1e100);
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: 1.0E+100', $e->getMessage());
}
try {
$intType->serialize(-1e100);
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: -1.0E+100', $e->getMessage());
}
try {
$intType->serialize('one');
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: "one"', $e->getMessage());
}
try {
$intType->serialize('');
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Int cannot represent non 32-bit signed integer value: (empty string)', $e->getMessage());
}
$this->assertSame(0, $intType->serialize(false)); $this->assertSame(0, $intType->serialize(false));
$this->assertSame(1, $intType->serialize(true)); $this->assertSame(1, $intType->serialize(true));
} }
public function testSerializesOutputIntCannotRepresentFloat1()
{
// The GraphQL specification does not allow serializing non-integer values
// as Int to avoid accidental data loss.
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non-integer value: 0.1');
$intType->serialize(0.1);
}
public function testSerializesOutputIntCannotRepresentFloat2()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non-integer value: 1.1');
$intType->serialize(1.1);
}
public function testSerializesOutputIntCannotRepresentNegativeFloat()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non-integer value: -1.1');
$intType->serialize(-1.1);
}
public function testSerializesOutputIntCannotRepresentNumericString()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, '');
$intType->serialize('Int cannot represent non-integer value: "-1.1"');
}
public function testSerializesOutputIntCannotRepresentBiggerThan32Bits()
{
// Maybe a safe PHP int, but bigger than 2^32, so not
// representable as a GraphQL Int
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: 9876504321');
$intType->serialize(9876504321);
}
public function testSerializesOutputIntCannotRepresentLowerThan32Bits()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: -9876504321');
$intType->serialize(-9876504321);
}
public function testSerializesOutputIntCannotRepresentBiggerThanSigned32Bits()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: 1.0E+100');
$intType->serialize(1e100);
}
public function testSerializesOutputIntCannotRepresentLowerThanSigned32Bits()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: -1.0E+100');
$intType->serialize(-1e100);
}
public function testSerializesOutputIntCannotRepresentString()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: "one"');
$intType->serialize('one');
}
public function testSerializesOutputIntCannotRepresentEmptyString()
{
$intType = Type::int();
$this->setExpectedException(InvariantViolation::class, 'Int cannot represent non 32-bit signed integer value: (empty string)');
$intType->serialize('');
}
/** /**
* @it serializes output float * @it serializes output float
*/ */
@ -113,25 +120,24 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase
$this->assertSame(1.1, $floatType->serialize(1.1)); $this->assertSame(1.1, $floatType->serialize(1.1));
$this->assertSame(-1.1, $floatType->serialize(-1.1)); $this->assertSame(-1.1, $floatType->serialize(-1.1));
$this->assertSame(-1.1, $floatType->serialize('-1.1')); $this->assertSame(-1.1, $floatType->serialize('-1.1'));
try {
$floatType->serialize('one');
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Float cannot represent non numeric value: "one"', $e->getMessage());
}
try {
$floatType->serialize('');
$this->fail('Expected exception was not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals('Float cannot represent non numeric value: (empty string)', $e->getMessage());
}
$this->assertSame(0.0, $floatType->serialize(false)); $this->assertSame(0.0, $floatType->serialize(false));
$this->assertSame(1.0, $floatType->serialize(true)); $this->assertSame(1.0, $floatType->serialize(true));
} }
public function testSerializesOutputFloatCannotRepresentString()
{
$floatType = Type::float();
$this->setExpectedException(InvariantViolation::class, 'Float cannot represent non numeric value: "one"');
$floatType->serialize('one');
}
public function testSerializesOutputFloatCannotRepresentEmptyString()
{
$floatType = Type::float();
$this->setExpectedException(InvariantViolation::class, 'Float cannot represent non numeric value: (empty string)');
$floatType->serialize('');
}
/** /**
* @it serializes output strings * @it serializes output strings
*/ */
@ -145,20 +151,20 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase
$this->assertSame('true', $stringType->serialize(true)); $this->assertSame('true', $stringType->serialize(true));
$this->assertSame('false', $stringType->serialize(false)); $this->assertSame('false', $stringType->serialize(false));
$this->assertSame('null', $stringType->serialize(null)); $this->assertSame('null', $stringType->serialize(null));
}
try { public function testSerializesOutputStringsCannotRepresentArray()
$stringType->serialize([]); {
$this->fail('Expected exception was not thrown'); $stringType = Type::string();
} catch (InvariantViolation $e) { $this->setExpectedException(InvariantViolation::class, 'String cannot represent non scalar value: array(0)');
$this->assertEquals('String cannot represent non scalar value: array(0)', $e->getMessage()); $stringType->serialize([]);
} }
try { public function testSerializesOutputStringsCannotRepresentObject()
$stringType->serialize(new \stdClass()); {
$this->fail('Expected exception was not thrown'); $stringType = Type::string();
} catch (InvariantViolation $e) { $this->setExpectedException(InvariantViolation::class, 'String cannot represent non scalar value: instance of stdClass');
$this->assertEquals('String cannot represent non scalar value: instance of stdClass', $e->getMessage()); $stringType->serialize(new \stdClass());
}
} }
/** /**
@ -191,12 +197,12 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase
$this->assertSame('true', $idType->serialize(true)); $this->assertSame('true', $idType->serialize(true));
$this->assertSame('false', $idType->serialize(false)); $this->assertSame('false', $idType->serialize(false));
$this->assertSame('2', $idType->serialize(new ObjectIdStub(2))); $this->assertSame('2', $idType->serialize(new ObjectIdStub(2)));
}
try { public function testSerializesOutputIDCannotRepresentObject()
$idType->serialize(new \stdClass()); {
$this->fail('Expected exception was not thrown'); $idType = Type::id();
} catch (InvariantViolation $e) { $this->setExpectedException(InvariantViolation::class, 'ID type cannot represent non scalar value: instance of stdClass');
$this->assertEquals('ID type cannot represent non scalar value: instance of stdClass', $e->getMessage()); $idType->serialize(new \stdClass());
}
} }
} }

View File

@ -1600,19 +1600,14 @@ class ValidationTest extends \PHPUnit_Framework_TestCase
$type->assertValid(); $type->assertValid();
} }
/** public function invalidEnumValueName()
* @it rejects an Enum type with incorrectly named values
*/
public function testRejectsAnEnumTypeWithIncorrectlyNamedValues()
{ {
$this->assertInvalidEnumValueName( return [
'#value', ['#value', 'SomeEnum has value with invalid name: "#value" (Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "#value" does not.)'],
'SomeEnum has value with invalid name: "#value" (Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "#value" does not.)' ['true', 'SomeEnum: "true" can not be used as an Enum value.'],
); ['false', 'SomeEnum: "false" can not be used as an Enum value.'],
['null', 'SomeEnum: "null" can not be used as an Enum value.'],
$this->assertInvalidEnumValueName('true', 'SomeEnum: "true" can not be used as an Enum value.'); ];
$this->assertInvalidEnumValueName('false', 'SomeEnum: "false" can not be used as an Enum value.');
$this->assertInvalidEnumValueName('null', 'SomeEnum: "null" can not be used as an Enum value.');
} }
public function testDoesNotAllowIsDeprecatedWithoutDeprecationReasonOnEnum() public function testDoesNotAllowIsDeprecatedWithoutDeprecationReasonOnEnum()
@ -1640,16 +1635,16 @@ class ValidationTest extends \PHPUnit_Framework_TestCase
]); ]);
} }
private function assertInvalidEnumValueName($name, $expectedMessage) /**
* @it rejects an Enum type with incorrectly named values
* @dataProvider invalidEnumValueName
*/
public function testRejectsAnEnumTypeWithIncorrectlyNamedValues($name, $expectedMessage)
{ {
$enum = $this->enumValue($name); $enum = $this->enumValue($name);
try { $this->setExpectedException(InvariantViolation::class, $expectedMessage);
$enum->assertValid(); $enum->assertValid();
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals($expectedMessage, $e->getMessage());
}
} }
// DESCRIBE: Type System: Object fields must have output types // DESCRIBE: Type System: Object fields must have output types
@ -1898,15 +1893,8 @@ class ValidationTest extends \PHPUnit_Framework_TestCase
{ {
$schema = $this->schemaWithArgOfType(null); $schema = $this->schemaWithArgOfType(null);
try { $this->setExpectedException(InvariantViolation::class, 'BadObject.badField(badArg): argument type must be Input Type but got: null');
$schema->assertValid(); $schema->assertValid();
$this->fail('Expected exception not thrown');
} catch (InvariantViolation $e) {
$this->assertEquals(
'BadObject.badField(badArg): argument type must be Input Type but got: null',
$e->getMessage()
);
}
} }
/** /**

View File

@ -42,22 +42,20 @@ class ASTFromValueTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(new IntValueNode(['value' => '123']), AST::astFromValue(123.0, Type::int())); $this->assertEquals(new IntValueNode(['value' => '123']), AST::astFromValue(123.0, Type::int()));
$this->assertEquals(new IntValueNode(['value' => '10000']), AST::astFromValue(1e4, Type::int())); $this->assertEquals(new IntValueNode(['value' => '10000']), AST::astFromValue(1e4, Type::int()));
$this->assertEquals(new IntValueNode(['value' => '0']), AST::astFromValue(0e4, Type::int())); $this->assertEquals(new IntValueNode(['value' => '0']), AST::astFromValue(0e4, Type::int()));
}
public function testConvertsIntValuesToASTsCannotRepresentNonInteger()
{
// GraphQL spec does not allow coercing non-integer values to Int to avoid // GraphQL spec does not allow coercing non-integer values to Int to avoid
// accidental data loss. // accidental data loss.
try { $this->setExpectedException(\Exception::class, 'Int cannot represent non-integer value: 123.5');
AST::astFromValue(123.5, Type::int()); AST::astFromValue(123.5, Type::int());
$this->fail('Expected exception not thrown'); }
} catch (\Exception $e) {
$this->assertEquals('Int cannot represent non-integer value: 123.5', $e->getMessage());
}
try { public function testConvertsIntValuesToASTsCannotRepresentNon32bitsInteger()
AST::astFromValue(1e40, Type::int()); // Note: js version will produce 1e+40, both values are valid GraphQL floats {
$this->fail('Expected exception is not thrown'); $this->setExpectedException(\Exception::class, 'Int cannot represent non 32-bit signed integer value: 1.0E+40');
} catch (\Exception $e) { AST::astFromValue(1e40, Type::int()); // Note: js version will produce 1e+40, both values are valid GraphQL floats
$this->assertSame('Int cannot represent non 32-bit signed integer value: 1.0E+40', $e->getMessage());
}
} }
/** /**

View File

@ -10,13 +10,7 @@ class UtilsTest extends \PHPUnit_Framework_TestCase
$object = new \stdClass(); $object = new \stdClass();
$object->requiredKey = 'value'; $object->requiredKey = 'value';
try { $this->setExpectedException(\InvalidArgumentException::class, 'Key requiredKey is expected to be set and not to be null');
Utils::assign($object, [], ['requiredKey']); Utils::assign($object, [], ['requiredKey']);
$this->fail('Expected exception not thrown');
} catch (\InvalidArgumentException $e) {
$this->assertEquals(
"Key requiredKey is expected to be set and not to be null",
$e->getMessage());
}
} }
} }