From 8817e8e010e4227547dd3bea79f76c7b12f83ad9 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Wed, 22 Aug 2018 18:53:25 +0700 Subject: [PATCH] Throws descriptive error when non-type used instead of interface --- src/Type/Schema.php | 4 +++- src/Type/SchemaValidationContext.php | 21 ++++++++++++--------- tests/Type/ValidationTest.php | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/Type/Schema.php b/src/Type/Schema.php index a2ac20d..cb74d03 100644 --- a/src/Type/Schema.php +++ b/src/Type/Schema.php @@ -297,7 +297,9 @@ class Schema foreach ($this->getTypeMap() as $type) { if ($type instanceof ObjectType) { foreach ($type->getInterfaces() as $interface) { - $this->possibleTypeMap[$interface->name][$type->name] = $type; + if ($interface instanceof InterfaceType) { + $this->possibleTypeMap[$interface->name][$type->name] = $type; + } } } else if ($type instanceof UnionType) { foreach ($type->getTypes() as $innerType) { diff --git a/src/Type/SchemaValidationContext.php b/src/Type/SchemaValidationContext.php index 7a02ff3..d1d587d 100644 --- a/src/Type/SchemaValidationContext.php +++ b/src/Type/SchemaValidationContext.php @@ -278,6 +278,18 @@ class SchemaValidationContext { $implementedTypeNames = []; foreach($object->getInterfaces() as $iface) { + if (! $iface instanceof InterfaceType) { + $this->reportError( + sprintf( + 'Type %s must only implement Interface types, ' . + 'it cannot implement %s.', + $object->name, + Utils::printSafe($iface) + ), + $this->getImplementsInterfaceNode($object, $iface) + ); + continue; + } if (isset($implementedTypeNames[$iface->name])) { $this->reportError( "Type {$object->name} can only implement {$iface->name} once.", @@ -296,15 +308,6 @@ class SchemaValidationContext */ private function validateObjectImplementsInterface(ObjectType $object, $iface) { - if (!$iface instanceof InterfaceType) { - $this->reportError( - "Type {$object->name} must only implement Interface types, " . - "it cannot implement ". Utils::printSafe($iface) . ".", - $this->getImplementsInterfaceNode($object, $iface) - ); - return; - } - $objectFieldMap = $object->getFields(); $ifaceFieldMap = $iface->getFields(); diff --git a/tests/Type/ValidationTest.php b/tests/Type/ValidationTest.php index f5e2176..3481e15 100644 --- a/tests/Type/ValidationTest.php +++ b/tests/Type/ValidationTest.php @@ -974,6 +974,28 @@ class ValidationTest extends TestCase // DESCRIBE: Type System: Objects can only implement unique interfaces + /** + * @it rejects an Object implementing a non-type values + */ + public function testRejectsAnObjectImplementingANonTypeValues() + { + $schema = new Schema([ + 'query' => new ObjectType([ + 'name' => 'BadObject', + 'interfaces' => [null], + 'fields' => ['a' => Type::string()] + ]), + ]); + $expected = [ + 'message' => 'Type BadObject must only implement Interface types, it cannot implement null.' + ]; + + $this->assertContainsValidationMessage( + $schema->validate(), + [$expected] + ); + } + /** * @it rejects an Object implementing a non-Interface type */