graphql-php/tests/Executor/VariablesTest.php

993 lines
33 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\Error;
2016-04-09 10:36:53 +03:00
use GraphQL\Executor\Executor;
2015-07-15 20:05:46 +03:00
use GraphQL\Language\Parser;
use GraphQL\Type\Schema;
2015-07-15 20:05:46 +03:00
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\ObjectType;
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
/**
* @describe using inline structs
*/
2015-07-15 20:05:46 +03:00
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());
2016-11-18 19:59:28 +03:00
// properly parses null value to null
$doc = '
{
fieldWithObjectInput(input: {a: null, b: null, c: "C", d: null})
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithObjectInput' => '{"a":null,"b":null,"c":"C","d":null}']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
// properly parses null value in list
$doc = '
{
fieldWithObjectInput(input: {b: ["A",null,"C"], c: "C"})
}
';
$ast = Parser::parse($doc);
$expected = ['data' => ['fieldWithObjectInput' => '{"b":["A",null,"C"],"c":"C"}']];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
// does not use incorrect value
$doc = '
{
fieldWithObjectInput(input: ["foo", "bar", "baz"])
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast)->toArray();
$expected = [
2016-11-19 00:15:40 +03:00
'data' => ['fieldWithObjectInput' => null],
'errors' => [[
'message' => 'Argument "input" has invalid value ["foo", "bar", "baz"].',
'path' => ['fieldWithObjectInput'],
'locations' => [['line' => 3, 'column' => 39]]
2016-11-19 00:15:40 +03:00
]]
];
2016-11-19 00:15:40 +03:00
$this->assertArraySubset($expected, $result);
// properly runs parseLiteral on complex scalar types
$doc = '
{
2016-11-19 00:15:40 +03:00
fieldWithObjectInput(input: {c: "foo", d: "SerializedValue"})
}
';
$ast = Parser::parse($doc);
$this->assertEquals(
2016-11-19 00:15:40 +03:00
['data' => ['fieldWithObjectInput' => '{"c":"foo","d":"DeserializedValue"}']],
Executor::execute($this->schema(), $ast)->toArray()
);
2015-07-15 20:05:46 +03:00
}
/**
* @describe using variables
*/
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, null, $params)->toArray()
2015-07-15 20:05:46 +03:00
);
// uses default value when not provided:
$withDefaultsNode = Parser::parse('
query q($input: TestInputObject = {a: "foo", b: ["bar"], c: "baz"}) {
fieldWithObjectInput(input: $input)
}
');
$result = Executor::execute($this->schema(), $withDefaultsNode)->toArray();
$expected = [
'data' => ['fieldWithObjectInput' => '{"a":"foo","b":["bar"],"c":"baz"}']
];
$this->assertEquals($expected, $result);
// properly parses single value to list:
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, 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, 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]];
$result = Executor::execute($schema, $ast, null, null, $params);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value ' .
'{"a":"foo","b":"bar","c":null}; ' .
'Expected non-nullable type String! not to be null at value.c.',
'locations' => [['line' => 2, 'column' => 17]],
'category' => 'graphql'
]
]
];
$this->assertEquals($expected, $result->toArray());
// errors on incorrect type:
$params = [ 'input' => 'foo bar' ];
$result = Executor::execute($schema, $ast, null, null, $params);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value "foo bar"; ' .
'Expected type TestInputObject to be an object.',
'locations' => [ [ 'line' => 2, 'column' => 17 ] ],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
// errors on omission of nested non-null:
$params = ['input' => ['a' => 'foo', 'b' => 'bar']];
$result = Executor::execute($schema, $ast, null, null, $params);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value {"a":"foo","b":"bar"}; '.
'Field value.c of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 17]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
// errors on deep nested errors and with many errors
$nestedDoc = '
query q($input: TestNestedInputObject) {
fieldWithNestedObjectInput(input: $input)
}
';
$nestedAst = Parser::parse($nestedDoc);
$params = [ 'input' => [ 'na' => [ 'a' => 'foo' ] ] ];
$result = Executor::execute($schema, $nestedAst, null, null, $params);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
'Field value.na.c of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 19]],
'category' => 'graphql',
],
[
'message' =>
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
'Field value.nb of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 19]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
// errors on addition of unknown input field
$params = ['input' => [ 'a' => 'foo', 'b' => 'bar', 'c' => 'baz', 'extra' => 'dog' ]];
$result = Executor::execute($schema, $ast, null, null, $params);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value ' .
'{"a":"foo","b":"bar","c":"baz","extra":"dog"}; ' .
'Field "extra" is not defined by type TestInputObject.',
'locations' => [['line' => 2, 'column' => 17]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
// Describe: Handles nullable scalars
2015-07-15 20:05:46 +03:00
/**
* @it allows nullable inputs to be omitted
*/
2015-07-15 20:05:46 +03:00
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
}
/**
* @it allows nullable inputs to be omitted in a variable
*/
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
}
/**
* @it allows nullable inputs to be omitted in an unlisted variable
*/
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
}
/**
* @it allows nullable inputs to be set to null in a variable
*/
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
}
/**
* @it allows nullable inputs to be set to a value in a variable
*/
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, null, ['value' => 'a'])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows nullable inputs to be set to a value directly
*/
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
}
// Describe: Handles non-nullable scalars
2016-11-19 00:15:40 +03:00
/**
* @it allows non-nullable inputs to be omitted given a default
*/
public function testAllowsNonNullableInputsToBeOmittedGivenADefault()
{
$doc = '
query SetsNonNullable($value: String = "default") {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => ['fieldWithNonNullableStringInput' => '"default"']
];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
}
/**
* @it does not allow non-nullable inputs to be omitted in a variable
*/
2015-07-15 20:05:46 +03:00
public function testDoesntAllowNonNullableInputsToBeOmittedInAVariable()
{
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast);
$expected = [
'errors' => [
[
'message' => 'Variable "$value" of required type "String!" was not provided.',
'locations' => [['line' => 2, 'column' => 31]],
'category' => 'graphql'
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow non-nullable inputs to be set to null in a variable
*/
2015-07-15 20:05:46 +03:00
public function testDoesNotAllowNonNullableInputsToBeSetToNullInAVariable()
{
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast, null, null, ['value' => null]);
$expected = [
'errors' => [
[
'message' =>
'Variable "$value" got invalid value null; ' .
'Expected non-nullable type String! not to be null.',
'locations' => [['line' => 2, 'column' => 31]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows non-nullable inputs to be set to a value in a variable
*/
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, null, ['value' => 'a'])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows non-nullable inputs to be set to a value directly
*/
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
}
/**
2016-11-19 00:15:40 +03:00
* @it reports error for missing non-nullable inputs
*/
2016-11-19 00:15:40 +03:00
public function testReportsErrorForMissingNonNullableInputs()
2015-07-15 20:05:46 +03:00
{
$doc = '
{
fieldWithNonNullableStringInput
}
';
$ast = Parser::parse($doc);
2016-11-19 00:15:40 +03:00
$expected = [
'data' => ['fieldWithNonNullableStringInput' => null],
'errors' => [[
'message' => 'Argument "input" of required type "String!" was not provided.',
'locations' => [ [ 'line' => 3, 'column' => 9 ] ],
'path' => [ 'fieldWithNonNullableStringInput' ],
'category' => 'graphql',
2016-11-19 00:15:40 +03:00
]]
];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
}
/**
* @it reports error for array passed into string input
*/
public function testReportsErrorForArrayPassedIntoStringInput()
{
$doc = '
query SetsNonNullable($value: String!) {
fieldWithNonNullableStringInput(input: $value)
}
';
$ast = Parser::parse($doc);
$variables = ['value' => [1, 2, 3]];
$expected = [
'errors' => [[
'message' =>
'Variable "$value" got invalid value [1,2,3]; Expected type ' .
'String; String cannot represent an array value: [1,2,3]',
'category' => 'graphql',
'locations' => [
['line' => 2, 'column' => 31]
]
]]
];
$result = Executor::execute($this->schema(), $ast, null, null, $variables)->toArray(true);
$this->assertEquals($expected, $result);
}
/**
* @it serializing an array via GraphQLString throws TypeError
*/
public function testSerializingAnArrayViaGraphQLStringThrowsTypeError()
{
$this->setExpectedException(
Error::class,
'String cannot represent non scalar value: [1,2,3]'
);
Type::string()->serialize([1, 2, 3]);
}
2016-11-19 00:15:40 +03:00
/**
* @it reports error for non-provided variables for non-nullable inputs
*/
public function testReportsErrorForNonProvidedVariablesForNonNullableInputs()
{
// Note: this test would typically fail validation before encountering
// this execution error, however for queries which previously validated
// and are being run against a new schema which have introduced a breaking
// change to make a formerly non-required argument required, this asserts
// failure before allowing the underlying code to receive a non-null value.
$doc = '
{
fieldWithNonNullableStringInput(input: $foo)
}
';
$ast = Parser::parse($doc);
$expected = [
'data' => ['fieldWithNonNullableStringInput' => null],
'errors' => [[
'message' =>
'Argument "input" of required type "String!" was provided the ' .
'variable "$foo" which was not provided a runtime value.',
'locations' => [['line' => 3, 'column' => 48]],
'path' => ['fieldWithNonNullableStringInput'],
'category' => 'graphql',
2016-11-19 00:15:40 +03:00
]]
];
$this->assertEquals($expected, Executor::execute($this->schema(), $ast)->toArray());
2015-07-15 20:05:46 +03:00
}
// Describe: Handles lists and nullability
/**
* @it allows lists to be null
*/
2015-07-15 20:05:46 +03:00
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
}
/**
* @it allows lists to contain values
*/
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, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows lists to contain null
*/
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, null, ['input' => ['A',null,'B']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow non-null lists to be null
*/
2015-07-15 20:05:46 +03:00
public function testDoesNotAllowNonNullListsToBeNull()
{
$doc = '
query q($input:[String]!) {
nnList(input: $input)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast, null, null, ['input' => null]);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value null; ' .
'Expected non-nullable type [String]! not to be null.',
'locations' => [['line' => 2, 'column' => 17]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows non-null lists to contain values
*/
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, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows non-null lists to contain null
*/
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, null, ['input' => ['A',null,'B']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows lists of non-nulls to be null
*/
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
}
/**
* @it allows lists of non-nulls to contain values
*/
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, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow lists of non-nulls to contain null
*/
2015-07-15 20:05:46 +03:00
public function testDoesNotAllowListsOfNonNullsToContainNull()
{
$doc = '
query q($input:[String!]) {
listNN(input: $input)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast, null, null, ['input' => ['A', null, 'B']]);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value ["A",null,"B"]; ' .
'Expected non-nullable type String! not to be null at value[1].',
'locations' => [ ['line' => 2, 'column' => 17] ],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow non-null lists of non-nulls to be null
*/
2015-07-15 20:05:46 +03:00
public function testDoesNotAllowNonNullListsOfNonNullsToBeNull()
{
$doc = '
query q($input:[String!]!) {
nnListNN(input: $input)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast, null, null, ['input' => null]);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value null; ' .
'Expected non-nullable type [String!]! not to be null.',
'locations' => [ ['line' => 2, 'column' => 17] ],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it allows non-null lists of non-nulls to contain values
*/
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, null, ['input' => ['A']])->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow non-null lists of non-nulls to contain null
*/
2015-07-15 20:05:46 +03:00
public function testDoesNotAllowNonNullListsOfNonNullsToContainNull()
{
$doc = '
query q($input:[String!]!) {
nnListNN(input: $input)
}
';
$ast = Parser::parse($doc);
$result = Executor::execute($this->schema(), $ast, null, null, ['input' => ['A', null, 'B']]);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" got invalid value ["A",null,"B"]; ' .
'Expected non-nullable type String! not to be null at value[1].',
'locations' => [ ['line' => 2, 'column' => 17] ],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it does not allow invalid types to be used as values
*/
public function testDoesNotAllowInvalidTypesToBeUsedAsValues()
{
$doc = '
query q($input: TestType!) {
fieldWithObjectInput(input: $input)
}
';
$ast = Parser::parse($doc);
$vars = [ 'input' => [ 'list' => [ 'A', 'B' ] ] ];
$result = Executor::execute($this->schema(), $ast, null, null, $vars);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" expected value of type "TestType!" which cannot ' .
'be used as an input type.',
'locations' => [['line' => 2, 'column' => 25]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
}
/**
* @it does not allow unknown types to be used as values
*/
public function testDoesNotAllowUnknownTypesToBeUsedAsValues()
{
$doc = '
query q($input: UnknownType!) {
fieldWithObjectInput(input: $input)
}
';
$ast = Parser::parse($doc);
$vars = ['input' => 'whoknows'];
$result = Executor::execute($this->schema(), $ast, null, null, $vars);
$expected = [
'errors' => [
[
'message' =>
'Variable "$input" expected value of type "UnknownType!" which ' .
'cannot be used as an input type.',
'locations' => [['line' => 2, 'column' => 25]],
'category' => 'graphql',
]
]
];
$this->assertEquals($expected, $result->toArray());
}
// Describe: Execute: Uses argument default values
/**
* @it when no argument provided
*/
public function testWhenNoArgumentProvided()
{
$ast = Parser::parse('{
fieldWithDefaultArgumentValue
}');
$this->assertEquals(
['data' => ['fieldWithDefaultArgumentValue' => '"Hello World"']],
Executor::execute($this->schema(), $ast)->toArray()
);
}
/**
2016-11-19 00:15:40 +03:00
* @it when omitted variable provided
*/
2016-11-19 00:15:40 +03:00
public function testWhenOmittedVariableProvided()
{
$ast = Parser::parse('query optionalVariable($optional: String) {
fieldWithDefaultArgumentValue(input: $optional)
}');
$this->assertEquals(
['data' => ['fieldWithDefaultArgumentValue' => '"Hello World"']],
Executor::execute($this->schema(), $ast)->toArray()
);
}
/**
2016-11-19 00:15:40 +03:00
* @it not when argument cannot be coerced
*/
2016-11-19 00:15:40 +03:00
public function testNotWhenArgumentCannotBeCoerced()
{
$ast = Parser::parse('{
fieldWithDefaultArgumentValue(input: WRONG_TYPE)
}');
2016-11-19 00:15:40 +03:00
$expected = [
'data' => ['fieldWithDefaultArgumentValue' => null],
'errors' => [[
'message' =>
'Argument "input" has invalid value WRONG_TYPE.',
2016-11-19 00:15:40 +03:00
'locations' => [ [ 'line' => 2, 'column' => 50 ] ],
'path' => [ 'fieldWithDefaultArgumentValue' ],
'category' => 'graphql',
2016-11-19 00:15:40 +03:00
]]
];
$this->assertEquals(
2016-11-19 00:15:40 +03:00
$expected,
Executor::execute($this->schema(), $ast)->toArray()
);
}
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
]
]);
$TestNestedInputObject = new InputObjectType([
'name' => 'TestNestedInputObject',
'fields' => [
'na' => [ 'type' => Type::nonNull($TestInputObject) ],
'nb' => [ 'type' => Type::nonNull(Type::string()) ],
],
]);
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
}
],
'fieldWithNestedInputObject' => [
'type' => Type::string(),
'args' => [
'input' => [
'type' => $TestNestedInputObject,
'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(['query' => $TestType]);
2015-07-15 20:05:46 +03:00
return $schema;
}
}