From b8c3d0de7debccf8d77ded335e4b569bfb2cec8a Mon Sep 17 00:00:00 2001 From: dschafer Date: Wed, 5 Aug 2015 22:58:12 -0700 Subject: [PATCH 1/2] Ensure unreferenced types that implement reference interfaces are detected --- src/utilities/__tests__/buildASTSchema.js | 34 +++++++++++++++++++++++ src/utilities/buildASTSchema.js | 15 ++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/utilities/__tests__/buildASTSchema.js b/src/utilities/__tests__/buildASTSchema.js index 6de1556e7e..79c35cbcb1 100644 --- a/src/utilities/__tests__/buildASTSchema.js +++ b/src/utilities/__tests__/buildASTSchema.js @@ -253,6 +253,40 @@ type Mutation { var output = cycleOutput(body, 'HelloScalars', 'Mutation'); expect(output).to.equal(body); }); + + it('Unreferenced type implementing referenced interface', () => { + var body = ` +type Concrete implements Iface { + key: String +} + +interface Iface { + key: String +} + +type Query { + iface: Iface +} +`; + var output = cycleOutput(body, 'Query'); + expect(output).to.equal(body); + }); + + it('Unreferenced type implementing referenced union', () => { + var body = ` +type Concrete { + key: String +} + +type Query { + union: Union +} + +union Union = Concrete +`; + var output = cycleOutput(body, 'Query'); + expect(output).to.equal(body); + }); }); describe('Schema Parser Failures', () => { diff --git a/src/utilities/buildASTSchema.js b/src/utilities/buildASTSchema.js index 433151d941..e3c00e1b19 100644 --- a/src/utilities/buildASTSchema.js +++ b/src/utilities/buildASTSchema.js @@ -136,6 +136,11 @@ export function buildASTSchema( throw new Error('Nothing constructed for ' + typeName); } innerTypeMap[typeName] = innerTypeDef; + if (astMap[typeName].kind === INTERFACE_DEFINITION) { + // Now that we've created and cached our interface, ensure + // we create all implementations to point to it. + makeInterfaceImplementations(astMap[typeName]); + } return buildWrappedType(innerTypeDef, typeAST); }; } @@ -211,6 +216,16 @@ export function buildASTSchema( return def.interfaces.map(inter => produceTypeDef(inter)); } + function makeInterfaceImplementations(inter: InterfaceDefinition) { + var interName = inter.name.value; + var types = ast.definitions.filter(def => def.kind === TYPE_DEFINITION); + var implementingTypes = types.filter(def => { + var names = def.interfaces.map(namedType => namedType.name.value); + return names.indexOf(interName) !== -1; + }); + implementingTypes.forEach(produceTypeDef); + } + function makeInputValues(values: Array) { return keyValMap( values, From b3109219399c3912776d06413f21f131b60f88b1 Mon Sep 17 00:00:00 2001 From: dschafer Date: Thu, 6 Aug 2015 10:25:14 -0700 Subject: [PATCH 2/2] Iterate through all types, not just from query --- src/utilities/buildASTSchema.js | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/utilities/buildASTSchema.js b/src/utilities/buildASTSchema.js index e3c00e1b19..dfe64e713d 100644 --- a/src/utilities/buildASTSchema.js +++ b/src/utilities/buildASTSchema.js @@ -136,22 +136,18 @@ export function buildASTSchema( throw new Error('Nothing constructed for ' + typeName); } innerTypeMap[typeName] = innerTypeDef; - if (astMap[typeName].kind === INTERFACE_DEFINITION) { - // Now that we've created and cached our interface, ensure - // we create all implementations to point to it. - makeInterfaceImplementations(astMap[typeName]); - } return buildWrappedType(innerTypeDef, typeAST); }; } - var produceTypeDef = getTypeDefProducer(ast); if (isNullish(astMap[queryTypeName])) { throw new Error(`Type ${queryTypeName} not found in document`); } + ast.definitions.forEach(produceTypeDef); + var queryType = produceTypeDef(astMap[queryTypeName]); var schema; if (isNullish(mutationTypeName)) { @@ -216,16 +212,6 @@ export function buildASTSchema( return def.interfaces.map(inter => produceTypeDef(inter)); } - function makeInterfaceImplementations(inter: InterfaceDefinition) { - var interName = inter.name.value; - var types = ast.definitions.filter(def => def.kind === TYPE_DEFINITION); - var implementingTypes = types.filter(def => { - var names = def.interfaces.map(namedType => namedType.name.value); - return names.indexOf(interName) !== -1; - }); - implementingTypes.forEach(produceTypeDef); - } - function makeInputValues(values: Array) { return keyValMap( values,