Ability to override internal types (using types option of Schema class) #174

This commit is contained in:
Vladimir Razuvaev 2017-09-22 23:08:51 +07:00
parent d46ad09108
commit f7248dec76
4 changed files with 68 additions and 35 deletions

View File

@ -110,7 +110,6 @@ class Schema
);
$this->config = $config;
$this->resolvedTypes = Type::getInternalTypes() + Introspection::getTypes();
$this->resolvedTypes[$config->query->name] = $config->query;
if ($config->mutation) {
@ -119,6 +118,20 @@ class Schema
if ($config->subscription) {
$this->resolvedTypes[$config->subscription->name] = $config->subscription;
}
if (is_array($this->config->types)) {
foreach ($this->resolveAdditionalTypes() as $type) {
if (isset($this->resolvedTypes[$type->name])) {
Utils::invariant(
$type === $this->resolvedTypes[$type->name],
"Schema must contain unique named types but contains multiple types named \"$type\" ".
"(see http://webonyx.github.io/graphql-php/type-system/#type-registry)."
);
}
$this->resolvedTypes[$type->name] = $type;
}
}
$this->resolvedTypes += Type::getInternalTypes() + Introspection::getTypes();
if (!$this->config->typeLoader) {
// Perform full scan of the schema
$this->getTypeMap();
@ -209,8 +222,11 @@ class Schema
foreach ($this->resolvedTypes as $type) {
$typeMap = TypeInfo::extractTypes($type, $typeMap);
}
foreach ($this->resolveAdditionalTypes() as $type) {
$typeMap = TypeInfo::extractTypes($type, $typeMap);
// When types are set as array they are resolved in constructor
if (is_callable($this->config->types)) {
foreach ($this->resolveAdditionalTypes() as $type) {
$typeMap = TypeInfo::extractTypes($type, $typeMap);
}
}
return $typeMap;
}

View File

@ -26,8 +26,13 @@ class StarWarsIntrospectionTest extends \PHPUnit_Framework_TestCase
$expected = [
'__schema' => [
'types' => [
['name' => 'ID'],
['name' => 'Query'],
['name' => 'Episode'],
['name' => 'Character'],
['name' => 'String'],
['name' => 'Human'],
['name' => 'Droid'],
['name' => 'ID'],
['name' => 'Float'],
['name' => 'Int'],
['name' => 'Boolean'],
@ -39,11 +44,6 @@ class StarWarsIntrospectionTest extends \PHPUnit_Framework_TestCase
['name' => '__EnumValue'],
['name' => '__Directive'],
['name' => '__DirectiveLocation'],
['name' => 'Query'],
['name' => 'Episode'],
['name' => 'Character'],
['name' => 'Human'],
['name' => 'Droid'],
]
]
];

View File

@ -3,6 +3,7 @@ namespace GraphQL\Tests\Type;
require_once __DIR__ . '/TestClasses.php';
use GraphQL\Type\Definition\CustomScalarType;
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InputObjectType;
@ -713,5 +714,21 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
$otherCustom = new OtherCustom();
$this->assertEquals('OtherCustom', $otherCustom->name);
}
}
public function testAllowsOverridingInternalTypes()
{
$idType = new CustomScalarType([
'name' => 'ID',
'serialize' => function() {},
'parseValue' => function() {},
'parseLiteral' => function() {}
]);
$schema = new Schema([
'query' => new ObjectType(['name' => 'Query', 'fields' => []]),
'types' => [$idType]
]);
$this->assertSame($idType, $schema->getType('ID'));
}
}

View File

@ -42,9 +42,32 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
),
'types' =>
array (
array (
'kind' => 'OBJECT',
'name' => 'QueryRoot',
'inputFields' => NULL,
'interfaces' =>
array (
),
'enumValues' => NULL,
'possibleTypes' => NULL,
'fields' => array (
array (
'name' => 'a',
'args' => array(),
'type' => array(
'kind' => 'SCALAR',
'name' => 'String',
'ofType' => null
),
'isDeprecated' => false,
'deprecationReason' => null,
)
)
),
array (
'kind' => 'SCALAR',
'name' => 'ID',
'name' => 'String',
'fields' => NULL,
'inputFields' => NULL,
'interfaces' => NULL,
@ -53,7 +76,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
),
array (
'kind' => 'SCALAR',
'name' => 'String',
'name' => 'ID',
'fields' => NULL,
'inputFields' => NULL,
'interfaces' => NULL,
@ -975,29 +998,6 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase
),
'possibleTypes' => NULL,
),
array (
'kind' => 'OBJECT',
'name' => 'QueryRoot',
'inputFields' => NULL,
'interfaces' =>
array (
),
'enumValues' => NULL,
'possibleTypes' => NULL,
'fields' => array (
array (
'name' => 'a',
'args' => array(),
'type' => array(
'kind' => 'SCALAR',
'name' => 'String',
'ofType' => null
),
'isDeprecated' => false,
'deprecationReason' => null,
)
)
),
),
'directives' =>
array (