Introspection for april 2016 spec + fixed tests

This commit is contained in:
vladar 2016-05-01 03:04:16 +06:00
parent e7c7924dc0
commit 183a9d72cf
2 changed files with 448 additions and 207 deletions

View File

@ -2,6 +2,7 @@
namespace GraphQL\Type; namespace GraphQL\Type;
use GraphQL\Language\Printer;
use GraphQL\Schema; use GraphQL\Schema;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
@ -16,6 +17,7 @@ use GraphQL\Type\Definition\ScalarType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Definition\UnionType;
use GraphQL\Type\Definition\WrappingType; use GraphQL\Type\Definition\WrappingType;
use GraphQL\Utils\AST;
class TypeKind { class TypeKind {
const SCALAR = 0; const SCALAR = 0;
@ -42,18 +44,17 @@ class Introspection
__schema { __schema {
queryType { name } queryType { name }
mutationType { name } mutationType { name }
subscriptionType { name }
types { types {
...FullType ...FullType
} }
directives { directives {
name name
description description
locations
args { args {
...InputValue ...InputValue
} }
onOperation
onFragment
onField
} }
} }
} }
@ -62,7 +63,7 @@ class Introspection
kind kind
name name
description description
fields { fields(includeDeprecated: true) {
name name
description description
args { args {
@ -80,7 +81,7 @@ class Introspection
interfaces { interfaces {
...TypeRef ...TypeRef
} }
enumValues { enumValues(includeDeprecated: true) {
name name
description description
isDeprecated isDeprecated
@ -120,17 +121,17 @@ EOD;
__schema { __schema {
queryType { name } queryType { name }
mutationType { name } mutationType { name }
subscriptionType { name }
types { types {
...FullType ...FullType
} }
directives { directives {
name name
locations
args { args {
...InputValue ...InputValue
} }
onOperation
onFragment
onField
} }
} }
} }
@ -138,8 +139,10 @@ EOD;
fragment FullType on __Type { fragment FullType on __Type {
kind kind
name name
fields {
fields(includeDeprecated: true) {
name name
args { args {
...InputValue ...InputValue
} }
@ -155,8 +158,9 @@ EOD;
interfaces { interfaces {
...TypeRef ...TypeRef
} }
enumValues { enumValues(includeDeprecated: true) {
name name
isDeprecated isDeprecated
deprecationReason deprecationReason
} }
@ -167,6 +171,7 @@ EOD;
fragment InputValue on __InputValue { fragment InputValue on __InputValue {
name name
type { ...TypeRef } type { ...TypeRef }
defaultValue defaultValue
} }
@ -250,28 +255,120 @@ EOD;
if (!isset(self::$_map['__Directive'])) { if (!isset(self::$_map['__Directive'])) {
self::$_map['__Directive'] = new ObjectType([ self::$_map['__Directive'] = new ObjectType([
'name' => '__Directive', 'name' => '__Directive',
'description' => 'A Directive provides a way to describe alternate runtime execution and ' .
'type validation behavior in a GraphQL document.' .
'\n\nIn some cases, you need to provide options to alter GraphQLs ' .
'execution behavior in ways field arguments will not suffice, such as ' .
'conditionally including or skipping a field. Directives provide this by ' .
'describing additional information to the executor.',
'fields' => [ 'fields' => [
'name' => ['type' => Type::nonNull(Type::string())], 'name' => ['type' => Type::nonNull(Type::string())],
'description' => ['type' => Type::string()], 'description' => ['type' => Type::string()],
'locations' => [
'type' => Type::nonNull(Type::listOf(Type::nonNull(
self::_directiveLocation()
)))
],
'args' => [ 'args' => [
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))), 'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
'resolve' => function(Directive $directive) {return $directive->args ?: [];} 'resolve' => function (Directive $directive) {
return $directive->args ?: [];
}
], ],
'onOperation' => ['type' => Type::nonNull(Type::boolean())],
'onFragment' => ['type' => Type::nonNull(Type::boolean())], // NOTE: the following three fields are deprecated and are no longer part
'onField' => ['type' => Type::nonNull(Type::boolean())] // of the GraphQL specification.
'onOperation' => [
'deprecationReason' => 'Use `locations`.',
'type' => Type::nonNull(Type::boolean()),
'resolve' => function($d) {
return in_array(Directive::$directiveLocations['QUERY'], $d['locations']) ||
in_array(Directive::$directiveLocations['MUTATION'], $d['locations']) ||
in_array(Directive::$directiveLocations['SUBSCRIPTION'], $d['locations']);
}
],
'onFragment' => [
'deprecationReason' => 'Use `locations`.',
'type' => Type::nonNull(Type::boolean()),
'resolve' => function($d) {
return in_array(Directive::$directiveLocations['FRAGMENT_SPREAD'], $d['locations']) ||
in_array(Directive::$directiveLocations['INLINE_FRAGMENT'], $d['locations']) ||
in_array(Directive::$directiveLocations['FRAGMENT_DEFINITION'], $d['locations']);
}
],
'onField' => [
'deprecationReason' => 'Use `locations`.',
'type' => Type::nonNull(Type::boolean()),
'resolve' => function($d) {
return in_array(Directive::$directiveLocations['FIELD'], $d['locations']);
}
]
] ]
]); ]);
} }
return self::$_map['__Directive']; return self::$_map['__Directive'];
} }
public static function _directiveLocation()
{
if (!isset(self::$_map['__DirectiveLocation'])) {
self::$_map['__DirectiveLocation'] = new EnumType([
'name' => '__DirectiveLocation',
'description' =>
'A Directive can be adjacent to many parts of the GraphQL language, a ' .
'__DirectiveLocation describes one such possible adjacencies.',
'values' => [
'QUERY' => [
'value' => Directive::$directiveLocations['QUERY'],
'description' => 'Location adjacent to a query operation.'
],
'MUTATION' => [
'value' => Directive::$directiveLocations['MUTATION'],
'description' => 'Location adjacent to a mutation operation.'
],
'SUBSCRIPTION' => [
'value' => Directive::$directiveLocations['SUBSCRIPTION'],
'description' => 'Location adjacent to a subscription operation.'
],
'FIELD' => [
'value' => Directive::$directiveLocations['FIELD'],
'description' => 'Location adjacent to a field.'
],
'FRAGMENT_DEFINITION' => [
'value' => Directive::$directiveLocations['FRAGMENT_DEFINITION'],
'description' => 'Location adjacent to a fragment definition.'
],
'FRAGMENT_SPREAD' => [
'value' => Directive::$directiveLocations['FRAGMENT_SPREAD'],
'description' => 'Location adjacent to a fragment spread.'
],
'INLINE_FRAGMENT' => [
'value' => Directive::$directiveLocations['INLINE_FRAGMENT'],
'description' => 'Location adjacent to an inline fragment.'
],
]
]);
}
return self::$_map['__DirectiveLocation'];
}
public static function _type() public static function _type()
{ {
if (!isset(self::$_map['__Type'])) { if (!isset(self::$_map['__Type'])) {
self::$_map['__Type'] = new ObjectType([ self::$_map['__Type'] = new ObjectType([
'name' => '__Type', 'name' => '__Type',
'fields' => [ 'description' =>
'The fundamental unit of any GraphQL Schema is the type. There are ' .
'many kinds of types in GraphQL as represented by the `__TypeKind` enum.' .
"\n\n".
'Depending on the kind of a type, certain fields describe ' .
'information about that type. Scalar types provide no information ' .
'beyond a name and description, while Enum types provide their values. ' .
'Object and Interface types provide the fields they describe. Abstract ' .
'types, Union and Interface, provide the Object types possible ' .
'at runtime. List and NonNull types compose other types.',
'fields' => function() {
return [
'kind' => [ 'kind' => [
'type' => Type::nonNull(self::_typeKind()), 'type' => Type::nonNull(self::_typeKind()),
'resolve' => function (Type $type) { 'resolve' => function (Type $type) {
@ -319,7 +416,7 @@ EOD;
} }
], ],
'interfaces' => [ 'interfaces' => [
'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])), 'type' => Type::listOf(Type::nonNull(self::_type())),
'resolve' => function ($type) { 'resolve' => function ($type) {
if ($type instanceof ObjectType) { if ($type instanceof ObjectType) {
return $type->getInterfaces(); return $type->getInterfaces();
@ -329,9 +426,9 @@ EOD;
], ],
'possibleTypes' => [ 'possibleTypes' => [
'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])), 'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])),
'resolve' => function ($type) { 'resolve' => function ($type, $args, ResolveInfo $info) {
if ($type instanceof InterfaceType || $type instanceof UnionType) { if ($type instanceof InterfaceType || $type instanceof UnionType) {
return $type->getPossibleTypes(); return $info->schema->getPossibleTypes($type);
} }
return null; return null;
} }
@ -366,14 +463,15 @@ EOD;
} }
], ],
'ofType' => [ 'ofType' => [
'type' => [__CLASS__, '_type'], 'type' => self::_type(),
'resolve' => function ($type) { 'resolve' => function ($type) {
if ($type instanceof WrappingType) { if ($type instanceof WrappingType) {
return $type->getWrappedType(); return $type->getWrappedType();
} }
return null; return null;
}] }]
] ];
}
]); ]);
} }
return self::$_map['__Type']; return self::$_map['__Type'];
@ -385,7 +483,11 @@ EOD;
self::$_map['__Field'] = new ObjectType([ self::$_map['__Field'] = new ObjectType([
'name' => '__Field', 'name' => '__Field',
'fields' => [ 'description' =>
'Object and Interface types are described by a list of Fields, each of ' .
'which has a name, potentially a list of arguments, and a return type.',
'fields' => function() {
return [
'name' => ['type' => Type::nonNull(Type::string())], 'name' => ['type' => Type::nonNull(Type::string())],
'description' => ['type' => Type::string()], 'description' => ['type' => Type::string()],
'args' => [ 'args' => [
@ -395,7 +497,7 @@ EOD;
} }
], ],
'type' => [ 'type' => [
'type' => Type::nonNull([__CLASS__, '_type']), 'type' => Type::nonNull(self::_type()),
'resolve' => function ($field) { 'resolve' => function ($field) {
return $field->getType(); return $field->getType();
} }
@ -409,7 +511,8 @@ EOD;
'deprecationReason' => [ 'deprecationReason' => [
'type' => Type::string() 'type' => Type::string()
] ]
] ];
}
]); ]);
} }
return self::$_map['__Field']; return self::$_map['__Field'];
@ -420,11 +523,16 @@ EOD;
if (!isset(self::$_map['__InputValue'])) { if (!isset(self::$_map['__InputValue'])) {
self::$_map['__InputValue'] = new ObjectType([ self::$_map['__InputValue'] = new ObjectType([
'name' => '__InputValue', 'name' => '__InputValue',
'fields' => [ 'description' =>
'Arguments provided to Fields or Directives and the input fields of an ' .
'InputObject are represented as Input Values which describe their type ' .
'and optionally a default value.',
'fields' => function() {
return [
'name' => ['type' => Type::nonNull(Type::string())], 'name' => ['type' => Type::nonNull(Type::string())],
'description' => ['type' => Type::string()], 'description' => ['type' => Type::string()],
'type' => [ 'type' => [
'type' => Type::nonNull([__CLASS__, '_type']), 'type' => Type::nonNull(self::_type()),
'resolve' => function ($value) { 'resolve' => function ($value) {
return method_exists($value, 'getType') ? $value->getType() : $value->type; return method_exists($value, 'getType') ? $value->getType() : $value->type;
} }
@ -432,10 +540,13 @@ EOD;
'defaultValue' => [ 'defaultValue' => [
'type' => Type::string(), 'type' => Type::string(),
'resolve' => function ($inputValue) { 'resolve' => function ($inputValue) {
return $inputValue->defaultValue === null ? null : json_encode($inputValue->defaultValue); return $inputValue->defaultValue === null
? null
: Printer::doPrint(AST::astFromValue($inputValue->defaultValue, $inputValue->getType()));
} }
] ]
] ];
}
]); ]);
} }
return self::$_map['__InputValue']; return self::$_map['__InputValue'];
@ -446,6 +557,10 @@ EOD;
if (!isset(self::$_map['__EnumValue'])) { if (!isset(self::$_map['__EnumValue'])) {
self::$_map['__EnumValue'] = new ObjectType([ self::$_map['__EnumValue'] = new ObjectType([
'name' => '__EnumValue', 'name' => '__EnumValue',
'description' =>
'One possible value for a given Enum. Enum values are unique values, not ' .
'a placeholder for a string or numeric value. However an Enum value is ' .
'returned in a JSON response as a string.',
'fields' => [ 'fields' => [
'name' => ['type' => Type::nonNull(Type::string())], 'name' => ['type' => Type::nonNull(Type::string())],
'description' => ['type' => Type::string()], 'description' => ['type' => Type::string()],
@ -469,7 +584,7 @@ EOD;
if (!isset(self::$_map['__TypeKind'])) { if (!isset(self::$_map['__TypeKind'])) {
self::$_map['__TypeKind'] = new EnumType([ self::$_map['__TypeKind'] = new EnumType([
'name' => '__TypeKind', 'name' => '__TypeKind',
'description' => 'An enum describing what kind of type a given __Type is', 'description' => 'An enum describing what kind of type a given __Type is.',
'values' => [ 'values' => [
'SCALAR' => [ 'SCALAR' => [
'value' => TypeKind::SCALAR, 'value' => TypeKind::SCALAR,

View File

@ -14,12 +14,19 @@ use GraphQL\Validator\Rules\ProvidedNonNullArguments;
class IntrospectionTest extends \PHPUnit_Framework_TestCase class IntrospectionTest extends \PHPUnit_Framework_TestCase
{ {
// Describe: Introspection
/**
* @it executes an introspection query
*/
function testExecutesAnIntrospectionQuery() function testExecutesAnIntrospectionQuery()
{ {
$emptySchema = new Schema(new ObjectType([ $emptySchema = new Schema([
'query' => new ObjectType([
'name' => 'QueryRoot', 'name' => 'QueryRoot',
'fields' => [] 'fields' => []
])); ])
]);
$request = Introspection::getIntrospectionQuery(false); $request = Introspection::getIntrospectionQuery(false);
$expected = array ( $expected = array (
@ -28,6 +35,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'__schema' => '__schema' =>
array ( array (
'mutationType' => NULL, 'mutationType' => NULL,
'subscriptionType' => NULL,
'queryType' => 'queryType' =>
array ( array (
'name' => 'QueryRoot', 'name' => 'QueryRoot',
@ -44,7 +52,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
), ),
'enumValues' => NULL, 'enumValues' => NULL,
'possibleTypes' => NULL, 'possibleTypes' => NULL,
'fields' => [] 'fields' => Array ()
), ),
1 => 1 =>
array ( array (
@ -817,6 +825,35 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'deprecationReason' => NULL, 'deprecationReason' => NULL,
), ),
2 => 2 =>
array (
'name' => 'locations',
'args' =>
array (
),
'type' =>
array (
'kind' => 'NON_NULL',
'name' => NULL,
'ofType' =>
array (
'kind' => 'LIST',
'name' => NULL,
'ofType' =>
array (
'kind' => 'NON_NULL',
'name' => NULL,
'ofType' =>
array (
'kind' => 'ENUM',
'name' => '__DirectiveLocation',
),
),
),
),
'isDeprecated' => false,
'deprecationReason' => NULL,
),
3 =>
array ( array (
'name' => 'args', 'name' => 'args',
'args' => 'args' =>
@ -845,7 +882,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'isDeprecated' => false, 'isDeprecated' => false,
'deprecationReason' => NULL, 'deprecationReason' => NULL,
), ),
3 => 4 =>
array ( array (
'name' => 'onOperation', 'name' => 'onOperation',
'args' => 'args' =>
@ -862,10 +899,10 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'ofType' => NULL, 'ofType' => NULL,
), ),
), ),
'isDeprecated' => false, 'isDeprecated' => true,
'deprecationReason' => NULL, 'deprecationReason' => 'Use `locations`.',
), ),
4 => 5 =>
array ( array (
'name' => 'onFragment', 'name' => 'onFragment',
'args' => 'args' =>
@ -882,10 +919,10 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'ofType' => NULL, 'ofType' => NULL,
), ),
), ),
'isDeprecated' => false, 'isDeprecated' => true,
'deprecationReason' => NULL, 'deprecationReason' => 'Use `locations`.',
), ),
5 => 6 =>
array ( array (
'name' => 'onField', 'name' => 'onField',
'args' => 'args' =>
@ -902,8 +939,8 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'ofType' => NULL, 'ofType' => NULL,
), ),
), ),
'isDeprecated' => false, 'isDeprecated' => true,
'deprecationReason' => NULL, 'deprecationReason' => 'Use `locations`.',
), ),
), ),
'inputFields' => NULL, 'inputFields' => NULL,
@ -913,39 +950,99 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'enumValues' => NULL, 'enumValues' => NULL,
'possibleTypes' => NULL, 'possibleTypes' => NULL,
), ),
10 => [ 10 =>
array (
'kind' => 'ENUM',
'name' => '__DirectiveLocation',
'fields' => NULL,
'inputFields' => NULL,
'interfaces' => NULL,
'enumValues' =>
array (
0 =>
array (
'name' => 'QUERY',
'isDeprecated' => false,
'deprecationReason' => null
),
1 =>
array (
'name' => 'MUTATION',
'isDeprecated' => false,
'deprecationReason' => null
),
2 =>
array (
'name' => 'SUBSCRIPTION',
'isDeprecated' => false,
'deprecationReason' => null
),
3 =>
array (
'name' => 'FIELD',
'isDeprecated' => false,
'deprecationReason' => null
),
4 =>
array (
'name' => 'FRAGMENT_DEFINITION',
'isDeprecated' => false,
'deprecationReason' => null
),
5 =>
array (
'name' => 'FRAGMENT_SPREAD',
'isDeprecated' => false,
'deprecationReason' => null
),
6 =>
array (
'name' => 'INLINE_FRAGMENT',
'isDeprecated' => false,
'deprecationReason' => null
),
),
'possibleTypes' => NULL,
),
11 => array (
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'name' => 'ID', 'name' => 'ID',
'fields' => null, 'fields' => NULL,
'inputFields' => null, 'inputFields' => NULL,
'interfaces' => null, 'interfaces' => NULL,
'enumValues' => null, 'enumValues' => NULL,
'possibleTypes' => null 'possibleTypes' => NULL,
], ),
11 => [ 12 => array (
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'name' => 'Float', 'name' => 'Float',
'fields' => null, 'fields' => NULL,
'inputFields' => null, 'inputFields' => NULL,
'interfaces' => null, 'interfaces' => NULL,
'enumValues' => null, 'enumValues' => NULL,
'possibleTypes' => null 'possibleTypes' => NULL,
], ),
12 => [ 13 => array (
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'name' => 'Int', 'name' => 'Int',
'fields' => null, 'fields' => NULL,
'inputFields' => null, 'inputFields' => NULL,
'interfaces' => null, 'interfaces' => NULL,
'enumValues' => null, 'enumValues' => NULL,
'possibleTypes' => null 'possibleTypes' => NULL,
], )
), ),
'directives' => 'directives' =>
array ( array (
0 => 0 =>
array ( array (
'name' => 'include', 'name' => 'include',
'locations' =>
array (
0 => 'FIELD',
1 => 'FRAGMENT_SPREAD',
2 => 'INLINE_FRAGMENT',
),
'args' => 'args' =>
array ( array (
0 => 0 =>
@ -965,13 +1062,16 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
), ),
), ),
), ),
'onOperation' => false,
'onFragment' => true,
'onField' => true,
), ),
1 => 1 =>
array ( array (
'name' => 'skip', 'name' => 'skip',
'locations' =>
array (
0 => 'FIELD',
1 => 'FRAGMENT_SPREAD',
2 => 'INLINE_FRAGMENT',
),
'args' => 'args' =>
array ( array (
0 => 0 =>
@ -991,20 +1091,23 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
), ),
), ),
), ),
'onOperation' => false,
'onFragment' => true,
'onField' => true,
),
), ),
), ),
), ),
)
); );
$actual = GraphQL::execute($emptySchema, $request); $actual = GraphQL::execute($emptySchema, $request);
// print_r($actual);
// exit;
$this->assertEquals($expected, $actual); $this->assertEquals($expected, $actual);
} }
/**
* @it introspects on input object
*/
function testIntrospectsOnInputObject() function testIntrospectsOnInputObject()
{ {
$TestInputObject = new InputObjectType([ $TestInputObject = new InputObjectType([
@ -1028,7 +1131,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__schema { __schema {
@ -1088,6 +1191,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertContains($expectedFragment, $result); $this->assertContains($expectedFragment, $result);
} }
/**
* @it supports the __type root field
*/
public function testSupportsThe__typeRootField() public function testSupportsThe__typeRootField()
{ {
@ -1100,7 +1206,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type(name: "TestType") { __type(name: "TestType") {
@ -1118,6 +1224,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it identifies deprecated fields
*/
public function testIdentifiesDeprecatedFields() public function testIdentifiesDeprecatedFields()
{ {
@ -1134,7 +1243,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type(name: "TestType") { __type(name: "TestType") {
@ -1170,6 +1279,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it respects the includeDeprecated parameter for fields
*/
public function testRespectsTheIncludeDeprecatedParameterForFields() public function testRespectsTheIncludeDeprecatedParameterForFields()
{ {
$TestType = new ObjectType([ $TestType = new ObjectType([
@ -1185,7 +1297,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type(name: "TestType") { __type(name: "TestType") {
@ -1232,6 +1344,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it identifies deprecated enum values
*/
public function testIdentifiesDeprecatedEnumValues() public function testIdentifiesDeprecatedEnumValues()
{ {
$TestEnum = new EnumType([ $TestEnum = new EnumType([
@ -1252,7 +1367,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type(name: "TestEnum") { __type(name: "TestEnum") {
@ -1293,6 +1408,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it respects the includeDeprecated parameter for enum values
*/
public function testRespectsTheIncludeDeprecatedParameterForEnumValues() public function testRespectsTheIncludeDeprecatedParameterForEnumValues()
{ {
$TestEnum = new EnumType([ $TestEnum = new EnumType([
@ -1313,7 +1431,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type(name: "TestEnum") { __type(name: "TestEnum") {
@ -1353,9 +1471,11 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it fails as expected on the __type root field without an arg
*/
public function testFailsAsExpectedOnThe__typeRootFieldWithoutAnArg() public function testFailsAsExpectedOnThe__typeRootFieldWithoutAnArg()
{ {
$TestType = new ObjectType([ $TestType = new ObjectType([
'name' => 'TestType', 'name' => 'TestType',
'fields' => [ 'fields' => [
@ -1365,7 +1485,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
] ]
]); ]);
$schema = new Schema($TestType); $schema = new Schema(['query' => $TestType]);
$request = ' $request = '
{ {
__type { __type {
@ -1384,6 +1504,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it exposes descriptions on types and fields
*/
public function testExposesDescriptionsOnTypesAndFields() public function testExposesDescriptionsOnTypesAndFields()
{ {
$QueryRoot = new ObjectType([ $QueryRoot = new ObjectType([
@ -1391,7 +1514,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'fields' => [] 'fields' => []
]); ]);
$schema = new Schema($QueryRoot); $schema = new Schema(['query' => $QueryRoot]);
$request = ' $request = '
{ {
schemaType: __type(name: "__Schema") { schemaType: __type(name: "__Schema") {
@ -1441,6 +1564,9 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, GraphQL::execute($schema, $request)); $this->assertEquals($expected, GraphQL::execute($schema, $request));
} }
/**
* @it exposes descriptions on enums
*/
public function testExposesDescriptionsOnEnums() public function testExposesDescriptionsOnEnums()
{ {
$QueryRoot = new ObjectType([ $QueryRoot = new ObjectType([
@ -1448,7 +1574,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'fields' => [] 'fields' => []
]); ]);
$schema = new Schema($QueryRoot); $schema = new Schema(['query' => $QueryRoot]);
$request = ' $request = '
{ {
typeKindType: __type(name: "__TypeKind") { typeKindType: __type(name: "__TypeKind") {
@ -1465,7 +1591,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
'data' => [ 'data' => [
'typeKindType' => [ 'typeKindType' => [
'name' => '__TypeKind', 'name' => '__TypeKind',
'description' => 'An enum describing what kind of type a given __Type is', 'description' => 'An enum describing what kind of type a given __Type is.',
'enumValues' => [ 'enumValues' => [
[ [
'description' => 'Indicates this type is a scalar.', 'description' => 'Indicates this type is a scalar.',