graphql-php/tests/Executor/NonNullTest.php

263 lines
6.9 KiB
PHP
Raw Normal View History

2015-07-15 20:05:46 +03:00
<?php
namespace GraphQL\Executor;
use GraphQL\Error;
use GraphQL\FormattedError;
use GraphQL\Language\Parser;
use GraphQL\Language\SourceLocation;
use GraphQL\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
class NonNullTest extends \PHPUnit_Framework_TestCase
{
/** @var Error */
public $syncError;
public $nonNullSyncError;
public $throwingData;
public $nullingData;
public $schema;
public function setUp()
{
$this->syncError = new Error('sync');
$this->nonNullSyncError = new Error('nonNullSync');
$this->throwingData = [
'sync' => function () {
throw $this->syncError;
},
'nonNullSync' => function () {
throw $this->nonNullSyncError;
},
'nest' => function () {
return $this->throwingData;
},
'nonNullNest' => function () {
return $this->throwingData;
},
];
$this->nullingData = [
'sync' => function () {
return null;
},
'nonNullSync' => function () {
return null;
},
'nest' => function () {
return $this->nullingData;
},
'nonNullNest' => function () {
return $this->nullingData;
},
];
$dataType = new ObjectType([
'name' => 'DataType',
'fields' => [
'sync' => ['type' => Type::string()],
'nonNullSync' => ['type' => Type::nonNull(Type::string())],
'nest' => ['type' => function () use (&$dataType) {
return $dataType;
}],
'nonNullNest' => ['type' => function () use (&$dataType) {
return Type::nonNull($dataType);
}]
]
]);
$this->schema = new Schema($dataType);
}
// Execute: handles non-nullable types
public function testNullsANullableFieldThatThrowsSynchronously()
{
$doc = '
query Q {
sync
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'sync' => null,
],
'errors' => [
new FormattedError(
$this->syncError->message,
[new SourceLocation(3, 9)]
)
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->throwingData, $ast, 'Q', []));
}
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsSynchronously()
{
// nulls a synchronously returned object that contains a non-nullable field that throws synchronously
$doc = '
query Q {
nest {
nonNullSync,
}
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'nest' => null
],
'errors' => [
new FormattedError($this->nonNullSyncError->message, [new SourceLocation(4, 11)])
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->throwingData, $ast, 'Q', []));
}
public function testNullsAComplexTreeOfNullableFieldsThatThrow()
{
$doc = '
query Q {
nest {
sync
nest {
sync
}
}
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'nest' => [
'sync' => null,
'nest' => [
'sync' => null,
]
]
],
'errors' => [
new FormattedError($this->syncError->message, [new SourceLocation(4, 11)]),
new FormattedError($this->syncError->message, [new SourceLocation(6, 13)]),
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->throwingData, $ast, 'Q', []));
}
public function testNullsANullableFieldThatSynchronouslyReturnsNull()
{
$doc = '
query Q {
sync
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'sync' => null,
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->nullingData, $ast, 'Q', []));
}
public function test4()
{
// nulls a synchronously returned object that contains a non-nullable field that returns null synchronously
$doc = '
query Q {
nest {
nonNullSync,
}
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'nest' => null
],
'errors' => [
new FormattedError('Cannot return null for non-nullable type.', [new SourceLocation(4, 11)])
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->nullingData, $ast, 'Q', []));
}
public function test5()
{
// nulls a complex tree of nullable fields that return null
$doc = '
query Q {
nest {
sync
nest {
sync
nest {
sync
}
}
}
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'nest' => [
'sync' => null,
'nest' => [
'sync' => null,
'nest' => [
'sync' => null
]
],
],
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->nullingData, $ast, 'Q', []));
}
public function testNullsTheTopLevelIfSyncNonNullableFieldThrows()
{
$doc = '
query Q { nonNullSync }
';
$expected = [
'data' => null,
'errors' => [
new FormattedError($this->nonNullSyncError->message, [new SourceLocation(2, 17)])
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->throwingData, Parser::parse($doc)));
}
public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
{
// nulls the top level if sync non-nullable field returns null
$doc = '
query Q { nonNullSync }
';
$expected = [
'data' => null,
'errors' => [
new FormattedError('Cannot return null for non-nullable type.', [new SourceLocation(2, 17)]),
]
];
$this->assertEquals($expected, Executor::execute($this->schema, $this->nullingData, Parser::parse($doc)));
}
}