diff --git a/src/test/testDirectives.ts b/src/test/testDirectives.ts index 6cb76719cda..3a190e91c57 100644 --- a/src/test/testDirectives.ts +++ b/src/test/testDirectives.ts @@ -24,6 +24,7 @@ import { GraphQLList, GraphQLUnionType, GraphQLInt, + GraphQLOutputType, } from 'graphql'; import formatDate = require('dateformat'); @@ -202,24 +203,19 @@ describe('@directives', () => { it('can be implemented with SchemaDirectiveVisitor', () => { const visited: Set = new Set; const schema = makeExecutableSchema({ typeDefs }); - let visitCount = 0; SchemaDirectiveVisitor.visitSchemaDirectives(schema, { // The directive subclass can be defined anonymously inline! queryTypeDirective: class extends SchemaDirectiveVisitor { public static description = 'A @directive for query object types'; public visitObject(object: GraphQLObjectType) { + assert.strictEqual(object, schema.getQueryType()); visited.add(object); - visitCount++; } }, }); assert.strictEqual(visited.size, 1); - assert.strictEqual(visitCount, 1); - visited.forEach(object => { - assert.strictEqual(object, schema.getType('Query')); - }); }); it('can visit the schema itself', () => { @@ -1081,14 +1077,12 @@ describe('@directives', () => { }); it('automatically updates references to changed types', () => { - let HumanType: GraphQLObjectType = null; - const schema = makeExecutableSchema({ typeDefs, schemaDirectives: { objectTypeDirective: class extends SchemaDirectiveVisitor { public visitObject(object: GraphQLObjectType) { - return HumanType = Object.create(object, { + return Object.create(object, { name: { value: 'Human' } }); } @@ -1099,19 +1093,19 @@ describe('@directives', () => { const Query = schema.getType('Query') as GraphQLObjectType; const peopleType = Query.getFields().people.type; if (peopleType instanceof GraphQLList) { - assert.strictEqual(peopleType.ofType, HumanType); + assert.strictEqual(peopleType.ofType, schema.getType('Human')); } else { throw new Error('Query.people not a GraphQLList type'); } const Mutation = schema.getType('Mutation') as GraphQLObjectType; const addPersonResultType = Mutation.getFields().addPerson.type; - assert.strictEqual(addPersonResultType, HumanType); + assert.strictEqual(addPersonResultType, schema.getType('Human') as GraphQLOutputType); const WhateverUnion = schema.getType('WhateverUnion') as GraphQLUnionType; const found = WhateverUnion.getTypes().some(type => { if (type.name === 'Human') { - assert.strictEqual(type, HumanType); + assert.strictEqual(type, schema.getType('Human')); return true; } }); @@ -1209,7 +1203,7 @@ describe('@directives', () => { it('does not enforce query directive locations (issue #680)', () => { const visited = new Set(); - const schema = makeExecutableSchema({ + makeExecutableSchema({ typeDefs: ` directive @hasScope(scope: [String]) on QUERY | FIELD | OBJECT @@ -1228,9 +1222,6 @@ describe('@directives', () => { }); assert.strictEqual(visited.size, 1); - visited.forEach(object => { - assert.strictEqual(schema.getType('Query'), object); - }); }); it('allows multiple directives when first replaces type (issue #851)', () => { diff --git a/src/utils/visitSchema.ts b/src/utils/visitSchema.ts index 4e3e5393eed..8f8668a2e28 100644 --- a/src/utils/visitSchema.ts +++ b/src/utils/visitSchema.ts @@ -225,9 +225,12 @@ export function visitSchema( // during the traversal, so implementors don't have to worry about that. healSchema(schema); - // Return a cloned version of the schema as a workaround for constructor - // initiliazation not currently healed, e.g. the stored implementation map. - return cloneSchema(schema); + // Reconstruct the schema to reinitialize private variables + // e.g. the stored implementation map. + Object.assign(schema, cloneSchema(schema)); + + // Return schema for convenience, even though schema parameter has all updated types. + return schema; }