Skip to content

Commit

Permalink
Throws descriptive error when non-type used instead of interface (#1282)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov authored and leebyron committed Mar 9, 2018
1 parent fb27b92 commit 1fbd7ec
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
16 changes: 16 additions & 0 deletions src/type/__tests__/validation-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,22 @@ describe('Type System: Object fields must have output types', () => {
});

describe('Type System: Objects can only implement unique interfaces', () => {
it('rejects an Object implementing a non-type values', () => {
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'BadObject',
interfaces: [undefined],
}),
});

expect(validateSchema(schema)).to.containSubset([
{
message:
'Type BadObject must only implement Interface types, it cannot implement undefined.',
},
]);
});

it('rejects an Object implementing a non-Interface type', () => {
const schema = buildSchema(`
type Query {
Expand Down
12 changes: 7 additions & 5 deletions src/type/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,13 @@ export class GraphQLSchema {
const type = this._typeMap[typeName];
if (isObjectType(type)) {
type.getInterfaces().forEach(iface => {
const impls = this._implementations[iface.name];
if (impls) {
impls.push(type);
} else {
this._implementations[iface.name] = [type];
if (isInterfaceType(iface)) {
const impls = this._implementations[iface.name];
if (impls) {
impls.push(type);
} else {
this._implementations[iface.name] = [type];
}
}
});
}
Expand Down
18 changes: 9 additions & 9 deletions src/type/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,15 @@ function validateObjectInterfaces(
): void {
const implementedTypeNames = Object.create(null);
object.getInterfaces().forEach(iface => {
if (!isInterfaceType(iface)) {
context.reportError(
`Type ${String(object)} must only implement Interface types, ` +
`it cannot implement ${String(iface)}.`,
getImplementsInterfaceNode(object, iface),
);
return;
}

if (implementedTypeNames[iface.name]) {
context.reportError(
`Type ${object.name} can only implement ${iface.name} once.`,
Expand All @@ -360,15 +369,6 @@ function validateObjectImplementsInterface(
object: GraphQLObjectType,
iface: GraphQLInterfaceType,
): void {
if (!isInterfaceType(iface)) {
context.reportError(
`Type ${String(object)} must only implement Interface types, ` +
`it cannot implement ${String(iface)}.`,
getImplementsInterfaceNode(object, iface),
);
return;
}

const objectFieldMap = object.getFields();
const ifaceFieldMap = iface.getFields();

Expand Down

0 comments on commit 1fbd7ec

Please sign in to comment.