graphql-php/tests/Executor/VariablesTest.php

599 lines
20 KiB
PHP
Raw Normal View History

2015-07-15 20:05:46 +03:00
<?php
2016-04-09 10:36:53 +03:00
namespace GraphQL\Tests\Executor;
2015-07-15 20:05:46 +03:00
require_once __DIR__ . '/TestClasses.php';
use GraphQL\Error;
2016-04-09 10:36:53 +03:00
use GraphQL\Executor\Executor;
2015-07-15 20:05:46 +03:00
use GraphQL\FormattedError;
use GraphQL\Language\Parser;
use GraphQL\Language\SourceLocation;
use GraphQL\Schema;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ScalarType;
2015-07-15 20:05:46 +03:00
use GraphQL\Type\Definition\Type;
class VariablesTest extends \PHPUnit_Framework_TestCase
2015-07-15 20:05:46 +03:00
{
// Execute: Handles inputs
2015-07-15 20:05:46 +03:00
// Handles objects and nullability
public function testUsingInlineStructs()
{
// executes with complex input:
$doc = '
{
fieldWithObjectInput(input: {a: "foo", b: ["bar"], c: "baz"})
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => [
'fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}'
]
];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
// properly parses single value to list:
2015-07-15 20:05:46 +03:00
$doc = '
{
fieldWithObjectInput(input: {a: "foo", b: "bar", c: "baz"})
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
}
public function testDoesNotUseIncorrectValue()
{
$doc = '
{
fieldWithObjectInput(input: ["foo", "bar", "baz"])
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast)->toArray();
$expected = [
'data' => ['fieldWithObjectInput' => null]
];
$this->assertEquals($expected, $result);
2015-07-15 20:05:46 +03:00
}
public function testUsingVariables()
{
// executes with complex input:
$doc = '
query q($input:TestInputObject) {
fieldWithObjectInput(input: $input)
}
';
$ast = Parser::parse($doc);
$params = ['input' => ['a' => 'foo', 'b' => ['bar'], 'c' => 'baz']];
$schema = $this->schema();
$this->assertEquals(
['data' => ['fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}']],
Executor::execute($schema, $ast, null, $params)->toArray()
2015-07-15 20:05:46 +03:00
);
// uses default value when not provided:
$withDefaultsAST = Parser::parse('
query q($input: TestInputObject = {a: "foo", b: ["bar"], c: "baz"}) {
fieldWithObjectInput(input: $input)
}
');
$result = Executor::execute($this->schema(), $withDefaultsAST)->toArray();
$expected = [
'data' => ['fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}']
];
$this->assertEquals($expected, $result);
// properly parses single value to array:
2015-07-15 20:05:46 +03:00
$params = ['input' => ['a' => 'foo', 'b' => 'bar', 'c' => 'baz']];
$this->assertEquals(
['data' => ['fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}']],
Executor::execute($schema, $ast, null, $params)->toArray()
2015-07-15 20:05:46 +03:00
);
// executes with complex scalar input:
$params = [ 'input' => [ 'c' => 'foo', 'd' => 'SerializedValue' ] ];
$result = Executor::execute($schema, $ast, null, $params)->toArray();
2015-07-15 20:05:46 +03:00
$expected = [
'data' => [
'fieldWithObjectInput' => '{"c":"foo","d":"DeserializedValue"}'
]
2015-07-15 20:05:46 +03:00
];
$this->assertEquals($expected, $result);
// errors on null for nested non-null:
$params = ['input' => ['a' => 'foo', 'b' => 'bar', 'c' => null]];
$expected = FormattedError::create(
'Variable $input expected value of type ' .
'TestInputObject but got: ' .
'{"a":"foo","b":"bar","c":null}.',
[new SourceLocation(2, 17)]
);
2015-07-15 20:05:46 +03:00
try {
Executor::execute($schema, $ast, null, $params);
$this->fail('Expected exception not thrown');
} catch (Error $err) {
$this->assertEquals($expected, Error::formatError($err));
}
// errors on incorrect type:
$params = [ 'input' => 'foo bar' ];
try {
Executor::execute($schema, $ast, null, $params);
$this->fail('Expected exception not thrown');
} catch (Error $error) {
$expected = FormattedError::create(
'Variable $input expected value of type TestInputObject but got: "foo bar".',
[new SourceLocation(2, 17)]
);
$this->assertEquals($expected, Error::formatError($error));
}
2015-07-15 20:05:46 +03:00
// errors on omission of nested non-null:
$params = ['input' => ['a' => 'foo', 'b' => 'bar']];
try {
Executor::execute($schema, $ast, null, $params);
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$expected = FormattedError::create(
'Variable $input expected value of type ' .
'TestInputObject but got: {"a":"foo","b":"bar"}.',
[new SourceLocation(2, 17)]
);
$this->assertEquals($expected, Error::formatError($e));
}
// errors on addition of unknown input field
$params = ['input' => [ 'a' => 'foo', 'b' => 'bar', 'c' => 'baz', 'd' => 'dog' ]];
try {
Executor::execute($schema, $ast, null, $params);
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$expected = FormattedError::create(
'Variable $input expected value of type TestInputObject but ' .
'got: {"a":"foo","b":"bar","c":"baz","d":"dog"}.',
[new SourceLocation(2, 17)]
);
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
// Handles nullable scalars
public function testAllowsNullableInputsToBeOmitted()
{
$doc = '
{
fieldWithNullableStringInput
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => ['fieldWithNullableStringInput' => null]
2015-07-15 20:05:46 +03:00
];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNullableInputsToBeOmittedInAVariable()
{
$doc = '
query SetsNullable($value: String) {
fieldWithNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNullableStringInput' => null]];
2015-07-15 20:05:46 +03:00
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNullableInputsToBeOmittedInAnUnlistedVariable()
{
$doc = '
query SetsNullable {
fieldWithNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNullableStringInput' => null]];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNullableInputsToBeSetToNullInAVariable()
{
$doc = '
query SetsNullable($value: String) {
fieldWithNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNullableStringInput' => null]];
2015-07-15 20:05:46 +03:00
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['value' => null])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNullableInputsToBeSetToAValueInAVariable()
{
$doc = '
query SetsNullable($value: String) {
fieldWithNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNullableStringInput' => '"a"']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['value' => 'a'])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNullableInputsToBeSetToAValueDirectly()
{
$doc = '
{
fieldWithNullableStringInput(input: "a")
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNullableStringInput' => '"a"']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
// Handles non-nullable scalars
public function testDoesntAllowNonNullableInputsToBeOmittedInAVariable()
{
// does not allow non-nullable inputs to be omitted in a variable
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
try {
Executor::execute($this->schema(), $ast);
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$expected = FormattedError::create(
'Variable $value expected value of type String! but got: null.',
[new SourceLocation(2, 31)]
);
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function testDoesNotAllowNonNullableInputsToBeSetToNullInAVariable()
{
// does not allow non-nullable inputs to be set to null in a variable
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
try {
Executor::execute($this->schema(), $ast, null, ['value' => null]);
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$expected = FormattedError::create(
'Variable $value expected value of type String! but got: null.',
[new SourceLocation(2, 31)]
);
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function testAllowsNonNullableInputsToBeSetToAValueInAVariable()
{
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNonNullableStringInput' => '"a"']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['value' => 'a'])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNonNullableInputsToBeSetToAValueDirectly()
{
$doc = '
{
fieldWithNonNullableStringInput(input: "a")
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNonNullableStringInput' => '"a"']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
public function testPassesAlongNullForNonNullableInputsIfExplcitlySetInTheQuery()
{
$doc = '
{
fieldWithNonNullableStringInput
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithNonNullableStringInput' => null]];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
// Handles lists and nullability
public function testAllowsListsToBeNull()
{
$doc = '
query q($input:[String]) {
list(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['list' => null]];
2015-07-15 20:05:46 +03:00
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => null])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsListsToContainValues()
{
$doc = '
query q($input:[String]) {
list(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['list' => '["A"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsListsToContainNull()
{
$doc = '
query q($input:[String]) {
list(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['list' => '["A",null,"B"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => ['A',null,'B']])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testDoesNotAllowNonNullListsToBeNull()
{
$doc = '
query q($input:[String]!) {
nnList(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = FormattedError::create(
'Variable $input expected value of type [String]! but got: null.',
[new SourceLocation(2, 17)]
);
2015-07-15 20:05:46 +03:00
try {
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => null])->toArray());
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function testAllowsNonNullListsToContainValues()
{
$doc = '
query q($input:[String]!) {
nnList(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['nnList' => '["A"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => 'A'])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsNonNullListsToContainNull()
{
$doc = '
query q($input:[String]!) {
nnList(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['nnList' => '["A",null,"B"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => ['A',null,'B']])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsListsOfNonNullsToBeNull()
{
$doc = '
query q($input:[String!]) {
listNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['listNN' => null]];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => null])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testAllowsListsOfNonNullsToContainValues()
{
$doc = '
query q($input:[String!]) {
listNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['listNN' => '["A"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => 'A'])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testDoesNotAllowListsOfNonNullsToContainNull()
{
$doc = '
query q($input:[String!]) {
listNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = FormattedError::create(
'Variable $input expected value of type [String!] but got: ["A",null,"B"].',
[new SourceLocation(2, 17)]
);
try {
Executor::execute($this->schema(), $ast, null, ['input' => ['A', null, 'B']]);
$this->fail('Expected exception not thrown');
} catch (Error $e) {
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function testDoesNotAllowNonNullListsOfNonNullsToBeNull()
{
$doc = '
query q($input:[String!]!) {
nnListNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = FormattedError::create(
'Variable $input expected value of type [String!]! but got: null.',
[new SourceLocation(2, 17)]
);
try {
Executor::execute($this->schema(), $ast, null, ['input' => null]);
} catch (Error $e) {
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function testAllowsNonNullListsOfNonNullsToContainValues()
{
$doc = '
query q($input:[String!]!) {
nnListNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['nnListNN' => '["A"]']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
public function testDoesNotAllowNonNullListsOfNonNullsToContainNull()
{
$doc = '
query q($input:[String!]!) {
nnListNN(input: $input)
}
';
$ast = Parser::parse($doc);
$expected = FormattedError::create(
'Variable $input expected value of type [String!]! but got: ["A",null,"B"].',
[new SourceLocation(2, 17)]
);
try {
Executor::execute($this->schema(), $ast, null, ['input' => ['A', null, 'B']]);
} catch (Error $e) {
$this->assertEquals($expected, Error::formatError($e));
}
2015-07-15 20:05:46 +03:00
}
public function schema()
{
$ComplexScalarType = ComplexScalar::create();
2015-07-15 20:05:46 +03:00
$TestInputObject = new InputObjectType([
'name' => 'TestInputObject',
'fields' => [
'a' => ['type' => Type::string()],
'b' => ['type' => Type::listOf(Type::string())],
'c' => ['type' => Type::nonNull(Type::string())],
'd' => ['type' => $ComplexScalarType],
2015-07-15 20:05:46 +03:00
]
]);
$TestType = new ObjectType([
'name' => 'TestType',
'fields' => [
'fieldWithObjectInput' => [
'type' => Type::string(),
'args' => ['input' => ['type' => $TestInputObject]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'fieldWithNullableStringInput' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::string()]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'fieldWithNonNullableStringInput' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::nonNull(Type::string())]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
}
],
'fieldWithDefaultArgumentValue' => [
'type' => Type::string(),
'args' => [ 'input' => [ 'type' => Type::string(), 'defaultValue' => 'Hello World' ]],
'resolve' => function($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'list' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::listOf(Type::string())]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'nnList' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::nonNull(Type::listOf(Type::string()))]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'listNN' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::listOf(Type::nonNull(Type::string()))]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
'nnListNN' => [
'type' => Type::string(),
'args' => ['input' => ['type' => Type::nonNull(Type::listOf(Type::nonNull(Type::string())))]],
'resolve' => function ($_, $args) {
return isset($args['input']) ? json_encode($args['input']) : null;
2015-07-15 20:05:46 +03:00
}
],
]
]);
$schema = new Schema($TestType);
return $schema;
}
}