mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-11 18:19:23 +03:00
Introspection for april 2016 spec + fixed tests
This commit is contained in:
parent
e7c7924dc0
commit
183a9d72cf
@ -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,130 +255,223 @@ 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 GraphQL’s ' .
|
||||||
|
'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' =>
|
||||||
'kind' => [
|
'The fundamental unit of any GraphQL Schema is the type. There are ' .
|
||||||
'type' => Type::nonNull(self::_typeKind()),
|
'many kinds of types in GraphQL as represented by the `__TypeKind` enum.' .
|
||||||
'resolve' => function (Type $type) {
|
"\n\n".
|
||||||
switch (true) {
|
'Depending on the kind of a type, certain fields describe ' .
|
||||||
case $type instanceof ListOfType:
|
'information about that type. Scalar types provide no information ' .
|
||||||
return TypeKind::LIST_KIND;
|
'beyond a name and description, while Enum types provide their values. ' .
|
||||||
case $type instanceof NonNull:
|
'Object and Interface types provide the fields they describe. Abstract ' .
|
||||||
return TypeKind::NON_NULL;
|
'types, Union and Interface, provide the Object types possible ' .
|
||||||
case $type instanceof ScalarType:
|
'at runtime. List and NonNull types compose other types.',
|
||||||
return TypeKind::SCALAR;
|
'fields' => function() {
|
||||||
case $type instanceof ObjectType:
|
return [
|
||||||
return TypeKind::OBJECT;
|
'kind' => [
|
||||||
case $type instanceof EnumType:
|
'type' => Type::nonNull(self::_typeKind()),
|
||||||
return TypeKind::ENUM;
|
'resolve' => function (Type $type) {
|
||||||
case $type instanceof InputObjectType:
|
switch (true) {
|
||||||
return TypeKind::INPUT_OBJECT;
|
case $type instanceof ListOfType:
|
||||||
case $type instanceof InterfaceType:
|
return TypeKind::LIST_KIND;
|
||||||
return TypeKind::INTERFACE_KIND;
|
case $type instanceof NonNull:
|
||||||
case $type instanceof UnionType:
|
return TypeKind::NON_NULL;
|
||||||
return TypeKind::UNION;
|
case $type instanceof ScalarType:
|
||||||
default:
|
return TypeKind::SCALAR;
|
||||||
throw new \Exception("Unknown kind of type: " . print_r($type, true));
|
case $type instanceof ObjectType:
|
||||||
}
|
return TypeKind::OBJECT;
|
||||||
}
|
case $type instanceof EnumType:
|
||||||
],
|
return TypeKind::ENUM;
|
||||||
'name' => ['type' => Type::string()],
|
case $type instanceof InputObjectType:
|
||||||
'description' => ['type' => Type::string()],
|
return TypeKind::INPUT_OBJECT;
|
||||||
'fields' => [
|
case $type instanceof InterfaceType:
|
||||||
'type' => Type::listOf(Type::nonNull(self::_field())),
|
return TypeKind::INTERFACE_KIND;
|
||||||
'args' => [
|
case $type instanceof UnionType:
|
||||||
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false]
|
return TypeKind::UNION;
|
||||||
],
|
default:
|
||||||
'resolve' => function (Type $type, $args) {
|
throw new \Exception("Unknown kind of type: " . print_r($type, true));
|
||||||
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
|
|
||||||
$fields = $type->getFields();
|
|
||||||
|
|
||||||
if (empty($args['includeDeprecated'])) {
|
|
||||||
$fields = array_filter($fields, function (FieldDefinition $field) {
|
|
||||||
return !$field->deprecationReason;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return array_values($fields);
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'interfaces' => [
|
|
||||||
'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])),
|
|
||||||
'resolve' => function ($type) {
|
|
||||||
if ($type instanceof ObjectType) {
|
|
||||||
return $type->getInterfaces();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'possibleTypes' => [
|
|
||||||
'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])),
|
|
||||||
'resolve' => function ($type) {
|
|
||||||
if ($type instanceof InterfaceType || $type instanceof UnionType) {
|
|
||||||
return $type->getPossibleTypes();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'enumValues' => [
|
|
||||||
'type' => Type::listOf(Type::nonNull(self::_enumValue())),
|
|
||||||
'args' => [
|
|
||||||
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false]
|
|
||||||
],
|
],
|
||||||
'resolve' => function ($type, $args) {
|
'name' => ['type' => Type::string()],
|
||||||
if ($type instanceof EnumType) {
|
'description' => ['type' => Type::string()],
|
||||||
$values = array_values($type->getValues());
|
'fields' => [
|
||||||
|
'type' => Type::listOf(Type::nonNull(self::_field())),
|
||||||
|
'args' => [
|
||||||
|
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false]
|
||||||
|
],
|
||||||
|
'resolve' => function (Type $type, $args) {
|
||||||
|
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
|
||||||
|
$fields = $type->getFields();
|
||||||
|
|
||||||
if (empty($args['includeDeprecated'])) {
|
if (empty($args['includeDeprecated'])) {
|
||||||
$values = array_filter($values, function ($value) {
|
$fields = array_filter($fields, function (FieldDefinition $field) {
|
||||||
return !$value->deprecationReason;
|
return !$field->deprecationReason;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
return array_values($fields);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'interfaces' => [
|
||||||
|
'type' => Type::listOf(Type::nonNull(self::_type())),
|
||||||
|
'resolve' => function ($type) {
|
||||||
|
if ($type instanceof ObjectType) {
|
||||||
|
return $type->getInterfaces();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'possibleTypes' => [
|
||||||
|
'type' => Type::listOf(Type::nonNull([__CLASS__, '_type'])),
|
||||||
|
'resolve' => function ($type, $args, ResolveInfo $info) {
|
||||||
|
if ($type instanceof InterfaceType || $type instanceof UnionType) {
|
||||||
|
return $info->schema->getPossibleTypes($type);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'enumValues' => [
|
||||||
|
'type' => Type::listOf(Type::nonNull(self::_enumValue())),
|
||||||
|
'args' => [
|
||||||
|
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false]
|
||||||
|
],
|
||||||
|
'resolve' => function ($type, $args) {
|
||||||
|
if ($type instanceof EnumType) {
|
||||||
|
$values = array_values($type->getValues());
|
||||||
|
|
||||||
return $values;
|
if (empty($args['includeDeprecated'])) {
|
||||||
|
$values = array_filter($values, function ($value) {
|
||||||
|
return !$value->deprecationReason;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
],
|
||||||
}
|
'inputFields' => [
|
||||||
],
|
'type' => Type::listOf(Type::nonNull(self::_inputValue())),
|
||||||
'inputFields' => [
|
'resolve' => function ($type) {
|
||||||
'type' => Type::listOf(Type::nonNull(self::_inputValue())),
|
if ($type instanceof InputObjectType) {
|
||||||
'resolve' => function ($type) {
|
return array_values($type->getFields());
|
||||||
if ($type instanceof InputObjectType) {
|
}
|
||||||
return array_values($type->getFields());
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
],
|
||||||
}
|
'ofType' => [
|
||||||
],
|
'type' => self::_type(),
|
||||||
'ofType' => [
|
'resolve' => function ($type) {
|
||||||
'type' => [__CLASS__, '_type'],
|
if ($type instanceof WrappingType) {
|
||||||
'resolve' => function($type) {
|
return $type->getWrappedType();
|
||||||
if ($type instanceof WrappingType) {
|
}
|
||||||
return $type->getWrappedType();
|
return null;
|
||||||
}
|
}]
|
||||||
return null;
|
];
|
||||||
}]
|
}
|
||||||
]
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return self::$_map['__Type'];
|
return self::$_map['__Type'];
|
||||||
@ -385,31 +483,36 @@ EOD;
|
|||||||
|
|
||||||
self::$_map['__Field'] = new ObjectType([
|
self::$_map['__Field'] = new ObjectType([
|
||||||
'name' => '__Field',
|
'name' => '__Field',
|
||||||
'fields' => [
|
'description' =>
|
||||||
'name' => ['type' => Type::nonNull(Type::string())],
|
'Object and Interface types are described by a list of Fields, each of ' .
|
||||||
'description' => ['type' => Type::string()],
|
'which has a name, potentially a list of arguments, and a return type.',
|
||||||
'args' => [
|
'fields' => function() {
|
||||||
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
return [
|
||||||
'resolve' => function (FieldDefinition $field) {
|
'name' => ['type' => Type::nonNull(Type::string())],
|
||||||
return empty($field->args) ? [] : $field->args;
|
'description' => ['type' => Type::string()],
|
||||||
}
|
'args' => [
|
||||||
],
|
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
||||||
'type' => [
|
'resolve' => function (FieldDefinition $field) {
|
||||||
'type' => Type::nonNull([__CLASS__, '_type']),
|
return empty($field->args) ? [] : $field->args;
|
||||||
'resolve' => function ($field) {
|
}
|
||||||
return $field->getType();
|
],
|
||||||
}
|
'type' => [
|
||||||
],
|
'type' => Type::nonNull(self::_type()),
|
||||||
'isDeprecated' => [
|
'resolve' => function ($field) {
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
return $field->getType();
|
||||||
'resolve' => function (FieldDefinition $field) {
|
}
|
||||||
return !!$field->deprecationReason;
|
],
|
||||||
}
|
'isDeprecated' => [
|
||||||
],
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'deprecationReason' => [
|
'resolve' => function (FieldDefinition $field) {
|
||||||
'type' => Type::string()
|
return !!$field->deprecationReason;
|
||||||
]
|
}
|
||||||
]
|
],
|
||||||
|
'deprecationReason' => [
|
||||||
|
'type' => Type::string()
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return self::$_map['__Field'];
|
return self::$_map['__Field'];
|
||||||
@ -420,22 +523,30 @@ 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' =>
|
||||||
'name' => ['type' => Type::nonNull(Type::string())],
|
'Arguments provided to Fields or Directives and the input fields of an ' .
|
||||||
'description' => ['type' => Type::string()],
|
'InputObject are represented as Input Values which describe their type ' .
|
||||||
'type' => [
|
'and optionally a default value.',
|
||||||
'type' => Type::nonNull([__CLASS__, '_type']),
|
'fields' => function() {
|
||||||
'resolve' => function($value) {
|
return [
|
||||||
return method_exists($value, 'getType') ? $value->getType() : $value->type;
|
'name' => ['type' => Type::nonNull(Type::string())],
|
||||||
}
|
'description' => ['type' => Type::string()],
|
||||||
],
|
'type' => [
|
||||||
'defaultValue' => [
|
'type' => Type::nonNull(self::_type()),
|
||||||
'type' => Type::string(),
|
'resolve' => function ($value) {
|
||||||
'resolve' => function ($inputValue) {
|
return method_exists($value, 'getType') ? $value->getType() : $value->type;
|
||||||
return $inputValue->defaultValue === null ? null : json_encode($inputValue->defaultValue);
|
}
|
||||||
}
|
],
|
||||||
]
|
'defaultValue' => [
|
||||||
]
|
'type' => Type::string(),
|
||||||
|
'resolve' => function ($inputValue) {
|
||||||
|
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,
|
||||||
|
@ -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([
|
||||||
'name' => 'QueryRoot',
|
'query' => new ObjectType([
|
||||||
'fields' => []
|
'name' => 'QueryRoot',
|
||||||
]));
|
'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 (
|
||||||
@ -117,13 +125,13 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
|
|||||||
'deprecationReason' => NULL,
|
'deprecationReason' => NULL,
|
||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array(
|
array (
|
||||||
'name' => 'subscriptionType',
|
'name' => 'subscriptionType',
|
||||||
'args' =>
|
'args' =>
|
||||||
array(
|
array (
|
||||||
),
|
),
|
||||||
'type' =>
|
'type' =>
|
||||||
array(
|
array (
|
||||||
'kind' => 'OBJECT',
|
'kind' => 'OBJECT',
|
||||||
'name' => '__Type',
|
'name' => '__Type',
|
||||||
'ofType' => NULL,
|
'ofType' => NULL,
|
||||||
@ -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.',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user