diff --git a/src/Type/Schema.php b/src/Type/Schema.php index dfdebb5..b4ec795 100644 --- a/src/Type/Schema.php +++ b/src/Type/Schema.php @@ -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; } diff --git a/tests/StarWarsIntrospectionTest.php b/tests/StarWarsIntrospectionTest.php index 530c760..2569027 100644 --- a/tests/StarWarsIntrospectionTest.php +++ b/tests/StarWarsIntrospectionTest.php @@ -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'], ] ] ]; diff --git a/tests/Type/DefinitionTest.php b/tests/Type/DefinitionTest.php index 86439e1..f0f3fe3 100644 --- a/tests/Type/DefinitionTest.php +++ b/tests/Type/DefinitionTest.php @@ -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')); + } +} diff --git a/tests/Type/IntrospectionTest.php b/tests/Type/IntrospectionTest.php index 54a00d7..532028b 100644 --- a/tests/Type/IntrospectionTest.php +++ b/tests/Type/IntrospectionTest.php @@ -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 (