Add support for directives applied on IDL & Schema

This commit is contained in:
Vladimir Razuvaev 2017-09-20 17:43:06 +07:00
parent 39f378ece7
commit 6050af4e67
18 changed files with 246 additions and 77 deletions

View File

@ -9,22 +9,6 @@ use GraphQL\Utils\Utils;
*/ */
class CustomScalarType extends ScalarType class CustomScalarType extends ScalarType
{ {
/**
* @var array
*/
public $config;
/**
* CustomScalarType constructor.
* @param array $config
*/
function __construct(array $config)
{
$this->name = $config['name'];
$this->config = $config;
parent::__construct();
}
/** /**
* @param mixed $value * @param mixed $value
* @return mixed * @return mixed

View File

@ -1,6 +1,8 @@
<?php <?php
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Language\AST\DirectiveDefinitionNode;
/** /**
* Class Directive * Class Directive
* @package GraphQL\Type\Definition * @package GraphQL\Type\Definition
@ -157,6 +159,16 @@ class Directive
*/ */
public $args; public $args;
/**
* @var DirectiveDefinitionNode|null
*/
public $astNode;
/**
* @var array
*/
public $config;
/** /**
* Directive constructor. * Directive constructor.
* @param array $config * @param array $config
@ -166,5 +178,6 @@ class Directive
foreach ($config as $key => $value) { foreach ($config as $key => $value) {
$this->{$key} = $value; $this->{$key} = $value;
} }
$this->config = $config;
} }
} }

View File

@ -2,6 +2,7 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\EnumTypeDefinitionNode;
use GraphQL\Language\AST\EnumValueNode; use GraphQL\Language\AST\EnumValueNode;
use GraphQL\Utils\MixedStore; use GraphQL\Utils\MixedStore;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
@ -12,6 +13,11 @@ use GraphQL\Utils\Utils;
*/ */
class EnumType extends Type implements InputType, OutputType, LeafType class EnumType extends Type implements InputType, OutputType, LeafType
{ {
/**
* @var EnumTypeDefinitionNode|null
*/
public $astNode;
/** /**
* @var EnumValueDefinition[] * @var EnumValueDefinition[]
*/ */
@ -27,11 +33,6 @@ class EnumType extends Type implements InputType, OutputType, LeafType
*/ */
private $nameLookup; private $nameLookup;
/**
* @var array
*/
public $config;
public function __construct($config) public function __construct($config)
{ {
if (!isset($config['name'])) { if (!isset($config['name'])) {
@ -53,6 +54,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType
$this->name = $config['name']; $this->name = $config['name'];
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->config = $config; $this->config = $config;
} }
@ -91,7 +93,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType
/** /**
* @param $name * @param $name
* @return mixed|null * @return EnumValueDefinition|null
*/ */
public function getValue($name) public function getValue($name)
{ {

View File

@ -1,5 +1,6 @@
<?php <?php
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Language\AST\EnumValueDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -28,6 +29,11 @@ class EnumValueDefinition
*/ */
public $description; public $description;
/**
* @var EnumValueDefinitionNode|null
*/
public $astNode;
/** /**
* @var array * @var array
*/ */
@ -39,6 +45,7 @@ class EnumValueDefinition
$this->value = isset($config['value']) ? $config['value'] : null; $this->value = isset($config['value']) ? $config['value'] : null;
$this->deprecationReason = isset($config['deprecationReason']) ? $config['deprecationReason'] : null; $this->deprecationReason = isset($config['deprecationReason']) ? $config['deprecationReason'] : null;
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->config = $config; $this->config = $config;
} }

View File

@ -2,6 +2,8 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Language\AST\InputValueDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
@ -9,7 +11,6 @@ use GraphQL\Utils\Utils;
* Class FieldArgument * Class FieldArgument
* *
* @package GraphQL\Type\Definition * @package GraphQL\Type\Definition
* @todo Rename to ArgumentNode as it is also applicable to directives, not only fields
*/ */
class FieldArgument class FieldArgument
{ {
@ -28,6 +29,11 @@ class FieldArgument
*/ */
public $description; public $description;
/**
* @var InputValueDefinitionNode|null
*/
public $astNode;
/** /**
* @var array * @var array
*/ */
@ -80,6 +86,9 @@ class FieldArgument
case 'description': case 'description':
$this->description = $value; $this->description = $value;
break; break;
case 'astNode':
$this->astNode = $value;
break;
} }
} }
$this->config = $def; $this->config = $def;

View File

@ -1,6 +1,8 @@
<?php <?php
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\FieldDefinitionNode;
use GraphQL\Language\AST\TypeDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -48,6 +50,11 @@ class FieldDefinition
*/ */
public $deprecationReason; public $deprecationReason;
/**
* @var FieldDefinitionNode|null
*/
public $astNode;
/** /**
* Original field definition config * Original field definition config
* *
@ -185,6 +192,7 @@ class FieldDefinition
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->deprecationReason = isset($config['deprecationReason']) ? $config['deprecationReason'] : null; $this->deprecationReason = isset($config['deprecationReason']) ? $config['deprecationReason'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->config = $config; $this->config = $config;

View File

@ -1,5 +1,6 @@
<?php <?php
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Language\AST\InputValueDefinitionNode;
/** /**
* Class InputObjectField * Class InputObjectField
@ -27,6 +28,11 @@ class InputObjectField
*/ */
public $type; public $type;
/**
* @var InputValueDefinitionNode|null
*/
public $astNode;
/** /**
* @var array * @var array
*/ */

View File

@ -2,6 +2,7 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -16,9 +17,9 @@ class InputObjectType extends Type implements InputType
private $fields; private $fields;
/** /**
* @var array * @var InputObjectTypeDefinitionNode|null
*/ */
public $config; public $astNode;
/** /**
* InputObjectType constructor. * InputObjectType constructor.
@ -45,6 +46,7 @@ class InputObjectType extends Type implements InputType
$this->config = $config; $this->config = $config;
$this->name = $config['name']; $this->name = $config['name'];
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
} }

View File

@ -2,6 +2,7 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -16,14 +17,9 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
private $fields; private $fields;
/** /**
* @var mixed|null * @var InterfaceTypeDefinitionNode|null
*/ */
public $description; public $astNode;
/**
* @var array
*/
public $config;
/** /**
* InterfaceType constructor. * InterfaceType constructor.
@ -49,6 +45,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
$this->name = $config['name']; $this->name = $config['name'];
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->config = $config; $this->config = $config;
} }

View File

@ -2,6 +2,8 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\TypeExtensionDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
@ -63,11 +65,14 @@ class ObjectType extends Type implements OutputType, CompositeType
private $interfaceMap; private $interfaceMap;
/** /**
* Keeping reference of config for late bindings and custom app-level metadata * @var ObjectTypeDefinitionNode|null
*
* @var array
*/ */
public $config; public $astNode;
/**
* @var TypeExtensionDefinitionNode[]
*/
public $extensionASTNodes;
/** /**
* @var callable * @var callable
@ -106,6 +111,8 @@ class ObjectType extends Type implements OutputType, CompositeType
$this->name = $config['name']; $this->name = $config['name'];
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->resolveFieldFn = isset($config['resolveField']) ? $config['resolveField'] : null; $this->resolveFieldFn = isset($config['resolveField']) ? $config['resolveField'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->extensionASTNodes = isset($config['extensionASTNodes']) ? $config['extensionASTNodes'] : [];
$this->config = $config; $this->config = $config;
} }

View File

@ -1,6 +1,7 @@
<?php <?php
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -24,13 +25,15 @@ use GraphQL\Utils\Utils;
abstract class ScalarType extends Type implements OutputType, InputType, LeafType abstract class ScalarType extends Type implements OutputType, InputType, LeafType
{ {
/** /**
* ScalarType constructor. * @var ScalarTypeDefinitionNode|null
*/ */
public function __construct() public $astNode;
function __construct(array $config = [])
{ {
if (!isset($this->name)) { $this->name = isset($config['name']) ? $config['name'] : $this->tryInferName();
$this->name = $this->tryInferName(); $this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
} $this->config = $config;
Utils::assertValidName($this->name); Utils::assertValidName($this->name);
} }

View File

@ -2,7 +2,7 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Utils\Utils; use GraphQL\Language\AST\TypeDefinitionNode;
/** /**
* Registry of standard GraphQL types * Registry of standard GraphQL types
@ -202,6 +202,16 @@ abstract class Type implements \JsonSerializable
*/ */
public $description; public $description;
/**
* @var TypeDefinitionNode|null
*/
public $astNode;
/**
* @var array
*/
public $config;
/** /**
* @return null|string * @return null|string
*/ */

View File

@ -2,6 +2,7 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\UnionTypeDefinitionNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
/** /**
@ -10,6 +11,11 @@ use GraphQL\Utils\Utils;
*/ */
class UnionType extends Type implements AbstractType, OutputType, CompositeType class UnionType extends Type implements AbstractType, OutputType, CompositeType
{ {
/**
* @var UnionTypeDefinitionNode
*/
public $astNode;
/** /**
* @var ObjectType[] * @var ObjectType[]
*/ */
@ -20,11 +26,6 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
*/ */
private $possibleTypeNames; private $possibleTypeNames;
/**
* @var array
*/
public $config;
/** /**
* UnionType constructor. * UnionType constructor.
* @param $config * @param $config
@ -51,6 +52,7 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
*/ */
$this->name = $config['name']; $this->name = $config['name'];
$this->description = isset($config['description']) ? $config['description'] : null; $this->description = isset($config['description']) ? $config['description'] : null;
$this->astNode = isset($config['astNode']) ? $config['astNode'] : null;
$this->config = $config; $this->config = $config;
} }

View File

@ -3,6 +3,7 @@ namespace GraphQL\Type;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\GraphQL; use GraphQL\GraphQL;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Type\Definition\FieldArgument; use GraphQL\Type\Definition\FieldArgument;
use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\AbstractType; use GraphQL\Type\Definition\AbstractType;
@ -357,6 +358,14 @@ class Schema
return null; return null;
} }
/**
* @return SchemaDefinitionNode
*/
public function getAstNode()
{
return $this->config->getAstNode();
}
/** /**
* @param $typeName * @param $typeName
* @return Type * @return Type

View File

@ -1,6 +1,7 @@
<?php <?php
namespace GraphQL\Type; namespace GraphQL\Type;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
@ -52,6 +53,11 @@ class SchemaConfig
*/ */
public $typeLoader; public $typeLoader;
/**
* @var SchemaDefinitionNode
*/
public $astNode;
/** /**
* Converts an array of options to instance of SchemaConfig * Converts an array of options to instance of SchemaConfig
* (or just returns empty config when array is not passed). * (or just returns empty config when array is not passed).
@ -132,11 +138,38 @@ class SchemaConfig
); );
$config->setTypeLoader($options['typeLoader']); $config->setTypeLoader($options['typeLoader']);
} }
if (isset($options['astNode'])) {
Utils::invariant(
$options['astNode'] instanceof SchemaDefinitionNode,
'Schema astNode must be an instance of SchemaDefinitionNode but got: %s',
Utils::printSafe($options['typeLoader'])
);
$config->setAstNode($options['astNode']);
}
} }
return $config; return $config;
} }
/**
* @return SchemaDefinitionNode
*/
public function getAstNode()
{
return $this->astNode;
}
/**
* @param SchemaDefinitionNode $astNode
* @return SchemaConfig
*/
public function setAstNode(SchemaDefinitionNode $astNode)
{
$this->astNode = $astNode;
return $this;
}
/** /**
* @api * @api
* @param ObjectType $query * @param ObjectType $query

View File

@ -241,6 +241,7 @@ class BuildSchema
return $this->typeDefNamed($name); return $this->typeDefNamed($name);
}, },
'directives' => $directives, 'directives' => $directives,
'astNode' => $schemaDef,
'types' => function() { 'types' => function() {
$types = []; $types = [];
foreach ($this->nodeMap as $name => $def) { foreach ($this->nodeMap as $name => $def) {
@ -264,6 +265,7 @@ class BuildSchema
return $node->value; return $node->value;
}), }),
'args' => $directiveNode->arguments ? FieldArgument::createMap($this->makeInputValues($directiveNode->arguments)) : null, 'args' => $directiveNode->arguments ? FieldArgument::createMap($this->makeInputValues($directiveNode->arguments)) : null,
'astNode' => $directiveNode
]); ]);
} }
@ -428,7 +430,8 @@ class BuildSchema
}, },
'interfaces' => function() use ($def) { 'interfaces' => function() use ($def) {
return $this->makeImplementedInterfaces($def); return $this->makeImplementedInterfaces($def);
} },
'astNode' => $def
]; ];
} }
@ -444,7 +447,8 @@ class BuildSchema
'type' => $this->produceOutputType($field->type), 'type' => $this->produceOutputType($field->type),
'description' => $this->getDescription($field), 'description' => $this->getDescription($field),
'args' => $this->makeInputValues($field->arguments), 'args' => $this->makeInputValues($field->arguments),
'deprecationReason' => $this->getDeprecationReason($field) 'deprecationReason' => $this->getDeprecationReason($field),
'astNode' => $field
]; ];
} }
); );
@ -472,7 +476,8 @@ class BuildSchema
$config = [ $config = [
'name' => $value->name->value, 'name' => $value->name->value,
'type' => $type, 'type' => $type,
'description' => $this->getDescription($value) 'description' => $this->getDescription($value),
'astNode' => $value
]; ];
if (isset($value->defaultValue)) { if (isset($value->defaultValue)) {
$config['defaultValue'] = AST::valueFromAST($value->defaultValue, $type); $config['defaultValue'] = AST::valueFromAST($value->defaultValue, $type);
@ -491,6 +496,7 @@ class BuildSchema
'fields' => function() use ($def) { 'fields' => function() use ($def) {
return $this->makeFieldDefMap($def); return $this->makeFieldDefMap($def);
}, },
'astNode' => $def,
'resolveType' => function() { 'resolveType' => function() {
$this->cannotExecuteSchema(); $this->cannotExecuteSchema();
} }
@ -502,6 +508,7 @@ class BuildSchema
return [ return [
'name' => $def->name->value, 'name' => $def->name->value,
'description' => $this->getDescription($def), 'description' => $this->getDescription($def),
'astNode' => $def,
'values' => Utils::keyValMap( 'values' => Utils::keyValMap(
$def->values, $def->values,
function($enumValue) { function($enumValue) {
@ -510,7 +517,8 @@ class BuildSchema
function($enumValue) { function($enumValue) {
return [ return [
'description' => $this->getDescription($enumValue), 'description' => $this->getDescription($enumValue),
'deprecationReason' => $this->getDeprecationReason($enumValue) 'deprecationReason' => $this->getDeprecationReason($enumValue),
'astNode' => $enumValue
]; ];
} }
) )
@ -525,6 +533,7 @@ class BuildSchema
'types' => Utils::map($def->types, function($typeNode) { 'types' => Utils::map($def->types, function($typeNode) {
return $this->produceObjectType($typeNode); return $this->produceObjectType($typeNode);
}), }),
'astNode' => $def,
'resolveType' => [$this, 'cannotExecuteSchema'] 'resolveType' => [$this, 'cannotExecuteSchema']
]; ];
} }
@ -534,6 +543,7 @@ class BuildSchema
return [ return [
'name' => $def->name->value, 'name' => $def->name->value,
'description' => $this->getDescription($def), 'description' => $this->getDescription($def),
'astNode' => $def,
'serialize' => function() { 'serialize' => function() {
return false; return false;
}, },
@ -555,7 +565,8 @@ class BuildSchema
return [ return [
'name' => $def->name->value, 'name' => $def->name->value,
'description' => $this->getDescription($def), 'description' => $this->getDescription($def),
'fields' => function() use ($def) { return $this->makeInputValues($def->fields); } 'fields' => function() use ($def) { return $this->makeInputValues($def->fields); },
'astNode' => $def,
]; ];
} }

View File

@ -247,13 +247,14 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
'description' => null, 'description' => null,
'deprecationReason' => 'Just because', 'deprecationReason' => 'Just because',
'value' => 'foo', 'value' => 'foo',
'astNode' => null
], (array) $value); ], (array) $value);
$this->assertEquals(true, $value->isDeprecated()); $this->assertEquals(true, $value->isDeprecated());
} }
/** /**
* @it defines an enum type with a value of `null` * @it defines an enum type with a value of `null` and `undefined`
*/ */
public function testDefinesAnEnumTypeWithAValueOfNullAndUndefined() public function testDefinesAnEnumTypeWithAValueOfNullAndUndefined()
{ {
@ -271,12 +272,14 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
'description' => null, 'description' => null,
'deprecationReason' => null, 'deprecationReason' => null,
'value' => null, 'value' => null,
'astNode' => null,
], ],
[ [
'name' => 'UNDEFINED', 'name' => 'UNDEFINED',
'description' => null, 'description' => null,
'deprecationReason' => null, 'deprecationReason' => null,
'value' => null, 'value' => null,
'astNode' => null,
], ],
]; ];

View File

@ -8,6 +8,9 @@ use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\ObjectTypeDefinitionNode; use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\TypeNode; use GraphQL\Language\AST\TypeNode;
use GraphQL\Language\Parser; use GraphQL\Language\Parser;
use GraphQL\Language\Printer;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Utils\BuildSchema; use GraphQL\Utils\BuildSchema;
use GraphQL\Utils\SchemaPrinter; use GraphQL\Utils\SchemaPrinter;
@ -588,26 +591,19 @@ type Query {
$ast = Parser::parse($body); $ast = Parser::parse($body);
$schema = BuildSchema::buildAST($ast); $schema = BuildSchema::buildAST($ast);
$this->assertEquals($schema->getType('MyEnum')->getValues(), [ /** @var EnumType $myEnum */
new EnumValueDefinition([ $myEnum = $schema->getType('MyEnum');
'name' => 'VALUE',
'description' => '', $value = $myEnum->getValue('VALUE');
'deprecationReason' => null, $this->assertFalse($value->isDeprecated());
'value' => 'VALUE'
]), $oldValue = $myEnum->getValue('OLD_VALUE');
new EnumValueDefinition([ $this->assertTrue($oldValue->isDeprecated());
'name' => 'OLD_VALUE', $this->assertEquals('No longer supported', $oldValue->deprecationReason);
'description' => '',
'deprecationReason' => 'No longer supported', $otherValue = $myEnum->getValue('OTHER_VALUE');
'value' => 'OLD_VALUE' $this->assertTrue($otherValue->isDeprecated());
]), $this->assertEquals('Terrible reasons', $otherValue->deprecationReason);
new EnumValueDefinition([
'name' => 'OTHER_VALUE',
'description' => '',
'deprecationReason' => 'Terrible reasons',
'value' => 'OTHER_VALUE'
])
]);
$rootFields = $schema->getType('Query')->getFields(); $rootFields = $schema->getType('Query')->getFields();
$this->assertEquals($rootFields['field1']->isDeprecated(), true); $this->assertEquals($rootFields['field1']->isDeprecated(), true);
@ -617,6 +613,73 @@ type Query {
$this->assertEquals($rootFields['field2']->deprecationReason, 'Because I said so'); $this->assertEquals($rootFields['field2']->deprecationReason, 'Because I said so');
} }
/**
* @it Correctly assign AST nodes
*/
public function testCorrectlyAssignASTNodes()
{
$schema = BuildSchema::build('
schema {
query: Query
}
type Query {
testField(testArg: TestInput): TestUnion
}
input TestInput {
testInputField: TestEnum
}
enum TestEnum {
TEST_VALUE
}
union TestUnion = TestType
interface TestInterface {
interfaceField: String
}
type TestType implements TestInterface {
interfaceField: String
}
directive @test(arg: Int) on FIELD
');
/** @var ObjectType $query */
$query = $schema->getType('Query');
$testInput = $schema->getType('TestInput');
$testEnum = $schema->getType('TestEnum');
$testUnion = $schema->getType('TestUnion');
$testInterface = $schema->getType('TestInterface');
$testType = $schema->getType('TestType');
$testDirective = $schema->getDirective('test');
$restoredIDL = SchemaPrinter::doPrint(BuildSchema::build(
Printer::doPrint($schema->getAstNode()) . "\n" .
Printer::doPrint($query->astNode) . "\n" .
Printer::doPrint($testInput->astNode) . "\n" .
Printer::doPrint($testEnum->astNode) . "\n" .
Printer::doPrint($testUnion->astNode) . "\n" .
Printer::doPrint($testInterface->astNode) . "\n" .
Printer::doPrint($testType->astNode) . "\n" .
Printer::doPrint($testDirective->astNode)
));
$this->assertEquals($restoredIDL, SchemaPrinter::doPrint($schema));
$testField = $query->getField('testField');
$this->assertEquals('testField(testArg: TestInput): TestUnion', Printer::doPrint($testField->astNode));
$this->assertEquals('testArg: TestInput', Printer::doPrint($testField->args[0]->astNode));
$this->assertEquals('testInputField: TestEnum', Printer::doPrint($testInput->getField('testInputField')->astNode));
$this->assertEquals('TEST_VALUE', Printer::doPrint($testEnum->getValue('TEST_VALUE')->astNode));
$this->assertEquals('interfaceField: String', Printer::doPrint($testInterface->getField('interfaceField')->astNode));
$this->assertEquals('interfaceField: String', Printer::doPrint($testType->getField('interfaceField')->astNode));
$this->assertEquals('arg: Int', Printer::doPrint($testDirective->args[0]->astNode));
}
// Describe: Failures // Describe: Failures
/** /**
@ -973,7 +1036,7 @@ interface Hello {
$this->assertInstanceOf(\Closure::class, $defaultConfig['fields']); $this->assertInstanceOf(\Closure::class, $defaultConfig['fields']);
$this->assertInstanceOf(\Closure::class, $defaultConfig['interfaces']); $this->assertInstanceOf(\Closure::class, $defaultConfig['interfaces']);
$this->assertArrayHasKey('description', $defaultConfig); $this->assertArrayHasKey('description', $defaultConfig);
$this->assertCount(4, $defaultConfig); $this->assertCount(5, $defaultConfig);
$this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']); $this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']);
$this->assertEquals('My description of Query', $schema->getType('Query')->description); $this->assertEquals('My description of Query', $schema->getType('Query')->description);
@ -985,12 +1048,12 @@ interface Hello {
'description' => '', 'description' => '',
'deprecationReason' => '' 'deprecationReason' => ''
]; ];
$this->assertEquals([ $this->assertArraySubset([
'RED' => $enumValue, 'RED' => $enumValue,
'GREEN' => $enumValue, 'GREEN' => $enumValue,
'BLUE' => $enumValue, 'BLUE' => $enumValue,
], $defaultConfig['values']); ], $defaultConfig['values']);
$this->assertCount(3, $defaultConfig); $this->assertCount(4, $defaultConfig); // 3 + astNode
$this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']); $this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']);
$this->assertEquals('My description of Color', $schema->getType('Color')->description); $this->assertEquals('My description of Color', $schema->getType('Color')->description);
@ -1000,7 +1063,7 @@ interface Hello {
$this->assertInstanceOf(\Closure::class, $defaultConfig['fields']); $this->assertInstanceOf(\Closure::class, $defaultConfig['fields']);
$this->assertInstanceOf(\Closure::class, $defaultConfig['resolveType']); $this->assertInstanceOf(\Closure::class, $defaultConfig['resolveType']);
$this->assertArrayHasKey('description', $defaultConfig); $this->assertArrayHasKey('description', $defaultConfig);
$this->assertCount(4, $defaultConfig); $this->assertCount(5, $defaultConfig);
$this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']); $this->assertEquals(array_keys($allNodesMap), ['Query', 'Color', 'Hello']);
$this->assertEquals('My description of Hello', $schema->getType('Hello')->description); $this->assertEquals('My description of Hello', $schema->getType('Hello')->description);
} }