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) {
if ($type instanceof ObjectType) {
foreach ($type->getInterfaces() as $interface) {
if ($interface instanceof InterfaceType) {
$this->possibleTypeMap[$interface->name][$type->name] = $type;
}
}
} else if ($type instanceof UnionType) {
foreach ($type->getTypes() as $innerType) {
$this->possibleTypeMap[$type->name][$innerType->name] = $innerType;

View File

@ -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();

View File

@ -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
*/