Skip to content

Commit b8c3d0d

Browse files
committed
Ensure unreferenced types that implement reference interfaces are detected
1 parent 8317a11 commit b8c3d0d

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

src/utilities/__tests__/buildASTSchema.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,40 @@ type Mutation {
253253
var output = cycleOutput(body, 'HelloScalars', 'Mutation');
254254
expect(output).to.equal(body);
255255
});
256+
257+
it('Unreferenced type implementing referenced interface', () => {
258+
var body = `
259+
type Concrete implements Iface {
260+
key: String
261+
}
262+
263+
interface Iface {
264+
key: String
265+
}
266+
267+
type Query {
268+
iface: Iface
269+
}
270+
`;
271+
var output = cycleOutput(body, 'Query');
272+
expect(output).to.equal(body);
273+
});
274+
275+
it('Unreferenced type implementing referenced union', () => {
276+
var body = `
277+
type Concrete {
278+
key: String
279+
}
280+
281+
type Query {
282+
union: Union
283+
}
284+
285+
union Union = Concrete
286+
`;
287+
var output = cycleOutput(body, 'Query');
288+
expect(output).to.equal(body);
289+
});
256290
});
257291

258292
describe('Schema Parser Failures', () => {

src/utilities/buildASTSchema.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ export function buildASTSchema(
136136
throw new Error('Nothing constructed for ' + typeName);
137137
}
138138
innerTypeMap[typeName] = innerTypeDef;
139+
if (astMap[typeName].kind === INTERFACE_DEFINITION) {
140+
// Now that we've created and cached our interface, ensure
141+
// we create all implementations to point to it.
142+
makeInterfaceImplementations(astMap[typeName]);
143+
}
139144
return buildWrappedType(innerTypeDef, typeAST);
140145
};
141146
}
@@ -211,6 +216,16 @@ export function buildASTSchema(
211216
return def.interfaces.map(inter => produceTypeDef(inter));
212217
}
213218

219+
function makeInterfaceImplementations(inter: InterfaceDefinition) {
220+
var interName = inter.name.value;
221+
var types = ast.definitions.filter(def => def.kind === TYPE_DEFINITION);
222+
var implementingTypes = types.filter(def => {
223+
var names = def.interfaces.map(namedType => namedType.name.value);
224+
return names.indexOf(interName) !== -1;
225+
});
226+
implementingTypes.forEach(produceTypeDef);
227+
}
228+
214229
function makeInputValues(values: Array<InputValueDefinition>) {
215230
return keyValMap(
216231
values,

0 commit comments

Comments
 (0)