Throws descriptive error when non-type used instead of interface

This commit is contained in:
Vladimir Razuvaev 2018-08-22 18:53:25 +07:00
parent ea6a21a13b
commit 8817e8e010
3 changed files with 37 additions and 10 deletions

View File

@ -297,8 +297,10 @@ class Schema
foreach ($this->getTypeMap() as $type) { foreach ($this->getTypeMap() as $type) {
if ($type instanceof ObjectType) { if ($type instanceof ObjectType) {
foreach ($type->getInterfaces() as $interface) { foreach ($type->getInterfaces() as $interface) {
if ($interface instanceof InterfaceType) {
$this->possibleTypeMap[$interface->name][$type->name] = $type; $this->possibleTypeMap[$interface->name][$type->name] = $type;
} }
}
} else if ($type instanceof UnionType) { } else if ($type instanceof UnionType) {
foreach ($type->getTypes() as $innerType) { foreach ($type->getTypes() as $innerType) {
$this->possibleTypeMap[$type->name][$innerType->name] = $innerType; $this->possibleTypeMap[$type->name][$innerType->name] = $innerType;

View File

@ -278,6 +278,18 @@ class SchemaValidationContext
{ {
$implementedTypeNames = []; $implementedTypeNames = [];
foreach($object->getInterfaces() as $iface) { 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])) { if (isset($implementedTypeNames[$iface->name])) {
$this->reportError( $this->reportError(
"Type {$object->name} can only implement {$iface->name} once.", "Type {$object->name} can only implement {$iface->name} once.",
@ -296,15 +308,6 @@ class SchemaValidationContext
*/ */
private function validateObjectImplementsInterface(ObjectType $object, $iface) 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(); $objectFieldMap = $object->getFields();
$ifaceFieldMap = $iface->getFields(); $ifaceFieldMap = $iface->getFields();

View File

@ -974,6 +974,28 @@ class ValidationTest extends TestCase
// DESCRIBE: Type System: Objects can only implement unique interfaces // 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 * @it rejects an Object implementing a non-Interface type
*/ */