diff --git a/resources/mocha-bootload.js b/resources/mocha-bootload.js index f7e0b73281..9aad5746c8 100644 --- a/resources/mocha-bootload.js +++ b/resources/mocha-bootload.js @@ -6,8 +6,6 @@ */ var chai = require('chai'); -chai.use(require('chai-json-equal')); -chai.use(require('chai-spies-next')); chai.use(require('chai-subset')); process.on('unhandledRejection', function (error) { diff --git a/src/execution/__tests__/abstract-promise-test.js b/src/execution/__tests__/abstract-promise-test.js index c8c123726a..6fb6c7e84d 100644 --- a/src/execution/__tests__/abstract-promise-test.js +++ b/src/execution/__tests__/abstract-promise-test.js @@ -332,7 +332,7 @@ describe('Execute: Handles execution of abstract types with promises', () => { const result = await graphql(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { @@ -428,7 +428,7 @@ describe('Execute: Handles execution of abstract types with promises', () => { const result = await graphql(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { @@ -513,7 +513,7 @@ describe('Execute: Handles execution of abstract types with promises', () => { const result = await graphql(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { @@ -585,7 +585,7 @@ describe('Execute: Handles execution of abstract types with promises', () => { const result = await graphql(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [null, null], }, diff --git a/src/execution/__tests__/abstract-test.js b/src/execution/__tests__/abstract-test.js index 3320eb36a6..9a5d9a8a77 100644 --- a/src/execution/__tests__/abstract-test.js +++ b/src/execution/__tests__/abstract-test.js @@ -8,7 +8,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; import { - graphql, + graphqlSync, GraphQLSchema, GraphQLObjectType, GraphQLInterfaceType, @@ -39,7 +39,7 @@ class Human { } describe('Execute: Handles execution of abstract types', () => { - it('isTypeOf used to resolve runtime type for Interface', async () => { + it('isTypeOf used to resolve runtime type for Interface', () => { const PetType = new GraphQLInterfaceType({ name: 'Pet', fields: { @@ -94,7 +94,7 @@ describe('Execute: Handles execution of abstract types', () => { } }`; - const result = await graphql(schema, query); + const result = graphqlSync(schema, query); expect(result).to.deep.equal({ data: { @@ -112,7 +112,7 @@ describe('Execute: Handles execution of abstract types', () => { }); }); - it('isTypeOf used to resolve runtime type for Union', async () => { + it('isTypeOf used to resolve runtime type for Union', () => { const DogType = new GraphQLObjectType({ name: 'Dog', isTypeOf: obj => obj instanceof Dog, @@ -163,7 +163,7 @@ describe('Execute: Handles execution of abstract types', () => { } }`; - const result = await graphql(schema, query); + const result = graphqlSync(schema, query); expect(result).to.deep.equal({ data: { @@ -181,7 +181,7 @@ describe('Execute: Handles execution of abstract types', () => { }); }); - it('resolveType on Interface yields useful error', async () => { + it('resolveType on Interface yields useful error', () => { const PetType = new GraphQLInterfaceType({ name: 'Pet', resolveType(obj) { @@ -252,9 +252,9 @@ describe('Execute: Handles execution of abstract types', () => { } }`; - const result = await graphql(schema, query); + const result = graphqlSync(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { @@ -279,7 +279,7 @@ describe('Execute: Handles execution of abstract types', () => { }); }); - it('resolveType on Union yields useful error', async () => { + it('resolveType on Union yields useful error', () => { const HumanType = new GraphQLObjectType({ name: 'Human', fields: { @@ -346,9 +346,9 @@ describe('Execute: Handles execution of abstract types', () => { } }`; - const result = await graphql(schema, query); + const result = graphqlSync(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { @@ -373,7 +373,7 @@ describe('Execute: Handles execution of abstract types', () => { }); }); - it('resolveType allows resolving with type name', async () => { + it('resolveType allows resolving with type name', () => { const PetType = new GraphQLInterfaceType({ name: 'Pet', resolveType(obj) { @@ -429,9 +429,9 @@ describe('Execute: Handles execution of abstract types', () => { } }`; - const result = await graphql(schema, query); + const result = graphqlSync(schema, query); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { pets: [ { diff --git a/src/execution/__tests__/directives-test.js b/src/execution/__tests__/directives-test.js index ea6a0b5a98..c150fb23db 100644 --- a/src/execution/__tests__/directives-test.js +++ b/src/execution/__tests__/directives-test.js @@ -30,248 +30,277 @@ const data = { }, }; -async function executeTestQuery(doc) { - return await execute(schema, parse(doc), data); +function executeTestQuery(doc) { + return execute(schema, parse(doc), data); } describe('Execute: handles directives', () => { describe('works without directives', () => { - it('basic query works', async () => { - expect(await executeTestQuery('{ a, b }')).to.deep.equal({ + it('basic query works', () => { + const result = executeTestQuery('{ a, b }'); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); }); describe('works on scalars', () => { - it('if true includes scalar', async () => { - return expect( - await executeTestQuery('{ a, b @include(if: true) }'), - ).to.deep.equal({ + it('if true includes scalar', () => { + const result = executeTestQuery('{ a, b @include(if: true) }'); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('if false omits on scalar', async () => { - return expect( - await executeTestQuery('{ a, b @include(if: false) }'), - ).to.deep.equal({ + it('if false omits on scalar', () => { + const result = executeTestQuery('{ a, b @include(if: false) }'); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); - it('unless false includes scalar', async () => { - return expect( - await executeTestQuery('{ a, b @skip(if: false) }'), - ).to.deep.equal({ + it('unless false includes scalar', () => { + const result = executeTestQuery('{ a, b @skip(if: false) }'); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless true omits scalar', async () => { - return expect( - await executeTestQuery('{ a, b @skip(if: true) }'), - ).to.deep.equal({ + it('unless true omits scalar', () => { + const result = executeTestQuery('{ a, b @skip(if: true) }'); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); }); describe('works on fragment spreads', () => { - it('if false omits fragment spread', async () => { - const q = ` - query Q { + it('if false omits fragment spread', () => { + const result = executeTestQuery(` + query { a ...Frag @include(if: false) } fragment Frag on TestType { b } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); - it('if true includes fragment spread', async () => { - const q = ` - query Q { + it('if true includes fragment spread', () => { + const result = executeTestQuery(` + query { a ...Frag @include(if: true) } fragment Frag on TestType { b } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless false includes fragment spread', async () => { - const q = ` - query Q { + it('unless false includes fragment spread', () => { + const result = executeTestQuery(` + query { a ...Frag @skip(if: false) } fragment Frag on TestType { b } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless true omits fragment spread', async () => { - const q = ` - query Q { + it('unless true omits fragment spread', () => { + const result = executeTestQuery(` + query { a ...Frag @skip(if: true) } fragment Frag on TestType { b } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); }); describe('works on inline fragment', () => { - it('if false omits inline fragment', async () => { - const q = ` - query Q { + it('if false omits inline fragment', () => { + const result = executeTestQuery(` + query { a ... on TestType @include(if: false) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); - it('if true includes inline fragment', async () => { - const q = ` - query Q { + it('if true includes inline fragment', () => { + const result = executeTestQuery(` + query { a ... on TestType @include(if: true) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless false includes inline fragment', async () => { - const q = ` - query Q { + it('unless false includes inline fragment', () => { + const result = executeTestQuery(` + query { a ... on TestType @skip(if: false) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless true includes inline fragment', async () => { - const q = ` - query Q { + it('unless true includes inline fragment', () => { + const result = executeTestQuery(` + query { a ... on TestType @skip(if: true) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); }); describe('works on anonymous inline fragment', () => { - it('if false omits anonymous inline fragment', async () => { - const q = ` - query Q { + it('if false omits anonymous inline fragment', () => { + const result = executeTestQuery(` + query { a ... @include(if: false) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); - it('if true includes anonymous inline fragment', async () => { - const q = ` - query Q { + it('if true includes anonymous inline fragment', () => { + const result = executeTestQuery(` + query { a ... @include(if: true) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless false includes anonymous inline fragment', async () => { - const q = ` + it('unless false includes anonymous inline fragment', () => { + const result = executeTestQuery(` query Q { a ... @skip(if: false) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('unless true includes anonymous inline fragment', async () => { - const q = ` - query Q { + it('unless true includes anonymous inline fragment', () => { + const result = executeTestQuery(` + query { a ... @skip(if: true) { b } } - `; - return expect(await executeTestQuery(q)).to.deep.equal({ + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); }); describe('works with skip and include directives', () => { - it('include and no skip', async () => { - return expect( - await executeTestQuery('{ a, b @include(if: true) @skip(if: false) }'), - ).to.deep.equal({ + it('include and no skip', () => { + const result = executeTestQuery(` + { + a + b @include(if: true) @skip(if: false) + } + `); + + expect(result).to.deep.equal({ data: { a: 'a', b: 'b' }, }); }); - it('include and skip', async () => { - return expect( - await executeTestQuery('{ a, b @include(if: true) @skip(if: true) }'), - ).to.deep.equal({ + it('include and skip', () => { + const result = executeTestQuery(` + { + a + b @include(if: true) @skip(if: true) + } + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); - it('no include or skip', async () => { - return expect( - await executeTestQuery('{ a, b @include(if: false) @skip(if: false) }'), - ).to.deep.equal({ + it('no include or skip', () => { + const result = executeTestQuery(` + { + a + b @include(if: false) @skip(if: false) + } + `); + + expect(result).to.deep.equal({ data: { a: 'a' }, }); }); diff --git a/src/execution/__tests__/executor-test.js b/src/execution/__tests__/executor-test.js index 656d9fe9ea..d3178d6891 100644 --- a/src/execution/__tests__/executor-test.js +++ b/src/execution/__tests__/executor-test.js @@ -67,7 +67,7 @@ describe('Execute: Handles basic execution tasks', () => { rootValue: data, }); - expect(result).to.jsonEqual({ + expect(result).to.deep.equal({ data: { a: 'rootValue' }, }); }); @@ -1110,6 +1110,6 @@ describe('Execute: Handles basic execution tasks', () => { customResolver, ); - expect(result).to.jsonEqual({ data: { foo: 'foo' } }); + expect(result).to.deep.equal({ data: { foo: 'foo' } }); }); }); diff --git a/src/execution/__tests__/schema-test.js b/src/execution/__tests__/schema-test.js index f16477f266..76d2999818 100644 --- a/src/execution/__tests__/schema-test.js +++ b/src/execution/__tests__/schema-test.js @@ -22,7 +22,7 @@ import { } from '../../type'; describe('Execute: Handles execution with a complex schema', () => { - it('executes using a schema', async () => { + it('executes using a schema', () => { const BlogImage = new GraphQLObjectType({ name: 'Image', fields: { @@ -151,7 +151,7 @@ describe('Execute: Handles execution with a complex schema', () => { // Note: this is intentionally not validating to ensure appropriate // behavior occurs when executing an invalid query. - return expect(await execute(BlogSchema, parse(request))).to.deep.equal({ + return expect(execute(BlogSchema, parse(request))).to.deep.equal({ data: { feed: [ { diff --git a/src/execution/__tests__/union-interface-test.js b/src/execution/__tests__/union-interface-test.js index 93f3a7eb2f..b518fd6521 100644 --- a/src/execution/__tests__/union-interface-test.js +++ b/src/execution/__tests__/union-interface-test.js @@ -104,7 +104,7 @@ const liz = new Person('Liz'); const john = new Person('John', [garfield, odie], [liz, odie]); describe('Execute: Union and intersection types', () => { - it('can introspect on union and intersection types', async () => { + it('can introspect on union and intersection types', () => { const ast = parse(` { Named: __type(name: "Named") { @@ -128,7 +128,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast)).to.deep.equal({ + return expect(execute(schema, ast)).to.deep.equal({ data: { Named: { kind: 'INTERFACE', @@ -152,7 +152,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('executes using union types', async () => { + it('executes using union types', () => { // NOTE: This is an *invalid* query, but it should be an *executable* query. const ast = parse(` { @@ -167,7 +167,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast, john)).to.deep.equal({ + return expect(execute(schema, ast, john)).to.deep.equal({ data: { __typename: 'Person', name: 'John', @@ -179,7 +179,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('executes union types with inline fragments', async () => { + it('executes union types with inline fragments', () => { // This is the valid version of the query in the above test. const ast = parse(` { @@ -199,7 +199,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast, john)).to.deep.equal({ + return expect(execute(schema, ast, john)).to.deep.equal({ data: { __typename: 'Person', name: 'John', @@ -211,7 +211,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('executes using interface types', async () => { + it('executes using interface types', () => { // NOTE: This is an *invalid* query, but it should be an *executable* query. const ast = parse(` { @@ -226,7 +226,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast, john)).to.deep.equal({ + return expect(execute(schema, ast, john)).to.deep.equal({ data: { __typename: 'Person', name: 'John', @@ -238,7 +238,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('executes union types with inline fragments', async () => { + it('executes union types with inline fragments', () => { // This is the valid version of the query in the above test. const ast = parse(` { @@ -257,7 +257,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast, john)).to.deep.equal({ + return expect(execute(schema, ast, john)).to.deep.equal({ data: { __typename: 'Person', name: 'John', @@ -269,7 +269,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('allows fragment conditions to be abstract types', async () => { + it('allows fragment conditions to be abstract types', () => { const ast = parse(` { __typename @@ -302,7 +302,7 @@ describe('Execute: Union and intersection types', () => { } `); - return expect(await execute(schema, ast, john)).to.deep.equal({ + return expect(execute(schema, ast, john)).to.deep.equal({ data: { __typename: 'Person', name: 'John', @@ -318,7 +318,7 @@ describe('Execute: Union and intersection types', () => { }); }); - it('gets execution info in resolver', async () => { + it('gets execution info in resolver', () => { let encounteredContext; let encounteredSchema; let encounteredRootValue; @@ -355,7 +355,7 @@ describe('Execute: Union and intersection types', () => { const ast = parse('{ name, friends { name } }'); - expect(await execute(schema2, ast, john2, context)).to.deep.equal({ + expect(execute(schema2, ast, john2, context)).to.deep.equal({ data: { name: 'John', friends: [{ name: 'Liz' }] }, }); diff --git a/src/type/__tests__/enumType-test.js b/src/type/__tests__/enumType-test.js index e97d0ff2aa..075dce39e5 100644 --- a/src/type/__tests__/enumType-test.js +++ b/src/type/__tests__/enumType-test.js @@ -8,201 +8,202 @@ import { describe, it } from 'mocha'; import { expect } from 'chai'; import { - graphql, + graphqlSync, GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLInt, GraphQLString, GraphQLBoolean, - getIntrospectionQuery, + introspectionFromSchema, } from '../../'; -describe('Type System: Enum Values', () => { - const ColorType = new GraphQLEnumType({ - name: 'Color', - values: { - RED: { value: 0 }, - GREEN: { value: 1 }, - BLUE: { value: 2 }, - }, - }); +const ColorType = new GraphQLEnumType({ + name: 'Color', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); - const Complex1 = { someRandomFunction: () => {} }; - const Complex2 = { someRandomValue: 123 }; +const Complex1 = { someRandomFunction: () => {} }; +const Complex2 = { someRandomValue: 123 }; - const ComplexEnum = new GraphQLEnumType({ - name: 'Complex', - values: { - ONE: { value: Complex1 }, - TWO: { value: Complex2 }, - }, - }); +const ComplexEnum = new GraphQLEnumType({ + name: 'Complex', + values: { + ONE: { value: Complex1 }, + TWO: { value: Complex2 }, + }, +}); - const QueryType = new GraphQLObjectType({ - name: 'Query', - fields: { - colorEnum: { - type: ColorType, - args: { - fromEnum: { type: ColorType }, - fromInt: { type: GraphQLInt }, - fromString: { type: GraphQLString }, - }, - resolve(value, { fromEnum, fromInt, fromString }) { - return fromInt !== undefined - ? fromInt - : fromString !== undefined ? fromString : fromEnum; - }, +const QueryType = new GraphQLObjectType({ + name: 'Query', + fields: { + colorEnum: { + type: ColorType, + args: { + fromEnum: { type: ColorType }, + fromInt: { type: GraphQLInt }, + fromString: { type: GraphQLString }, }, - colorInt: { - type: GraphQLInt, - args: { - fromEnum: { type: ColorType }, - fromInt: { type: GraphQLInt }, - }, - resolve(value, { fromEnum, fromInt }) { - return fromInt !== undefined ? fromInt : fromEnum; - }, + resolve(value, { fromEnum, fromInt, fromString }) { + return fromInt !== undefined + ? fromInt + : fromString !== undefined ? fromString : fromEnum; }, - complexEnum: { - type: ComplexEnum, - args: { - fromEnum: { - type: ComplexEnum, - // Note: defaultValue is provided an *internal* representation for - // Enums, rather than the string name. - defaultValue: Complex1, - }, - provideGoodValue: { type: GraphQLBoolean }, - provideBadValue: { type: GraphQLBoolean }, - }, - resolve(value, { fromEnum, provideGoodValue, provideBadValue }) { - if (provideGoodValue) { - // Note: this is one of the references of the internal values which - // ComplexEnum allows. - return Complex2; - } - if (provideBadValue) { - // Note: similar shape, but not the same *reference* - // as Complex2 above. Enum internal values require === equality. - return { someRandomValue: 123 }; - } - return fromEnum; + }, + colorInt: { + type: GraphQLInt, + args: { + fromEnum: { type: ColorType }, + fromInt: { type: GraphQLInt }, + }, + resolve(value, { fromEnum, fromInt }) { + return fromInt !== undefined ? fromInt : fromEnum; + }, + }, + complexEnum: { + type: ComplexEnum, + args: { + fromEnum: { + type: ComplexEnum, + // Note: defaultValue is provided an *internal* representation for + // Enums, rather than the string name. + defaultValue: Complex1, }, + provideGoodValue: { type: GraphQLBoolean }, + provideBadValue: { type: GraphQLBoolean }, + }, + resolve(value, { fromEnum, provideGoodValue, provideBadValue }) { + if (provideGoodValue) { + // Note: this is one of the references of the internal values which + // ComplexEnum allows. + return Complex2; + } + if (provideBadValue) { + // Note: similar shape, but not the same *reference* + // as Complex2 above. Enum internal values require === equality. + return { someRandomValue: 123 }; + } + return fromEnum; }, }, - }); + }, +}); - const MutationType = new GraphQLObjectType({ - name: 'Mutation', - fields: { - favoriteEnum: { - type: ColorType, - args: { color: { type: ColorType } }, - resolve(value, { color }) { - return color; - }, +const MutationType = new GraphQLObjectType({ + name: 'Mutation', + fields: { + favoriteEnum: { + type: ColorType, + args: { color: { type: ColorType } }, + resolve(value, { color }) { + return color; }, }, - }); + }, +}); - const SubscriptionType = new GraphQLObjectType({ - name: 'Subscription', - fields: { - subscribeToEnum: { - type: ColorType, - args: { color: { type: ColorType } }, - resolve(value, { color }) { - return color; - }, +const SubscriptionType = new GraphQLObjectType({ + name: 'Subscription', + fields: { + subscribeToEnum: { + type: ColorType, + args: { color: { type: ColorType } }, + resolve(value, { color }) { + return color; }, }, - }); + }, +}); - const schema = new GraphQLSchema({ - query: QueryType, - mutation: MutationType, - subscription: SubscriptionType, - }); +const schema = new GraphQLSchema({ + query: QueryType, + mutation: MutationType, + subscription: SubscriptionType, +}); - it('accepts enum literals as input', async () => { - expect(await graphql(schema, '{ colorInt(fromEnum: GREEN) }')).to.jsonEqual( - { - data: { - colorInt: 1, - }, - }, - ); +function executeQuery(source, variableValues) { + return graphqlSync({ schema, source, variableValues }); +} + +describe('Type System: Enum Values', () => { + it('accepts enum literals as input', () => { + const result = executeQuery('{ colorInt(fromEnum: GREEN) }'); + + expect(result).to.deep.equal({ + data: { colorInt: 1 }, + }); }); - it('enum may be output type', async () => { - expect(await graphql(schema, '{ colorEnum(fromInt: 1) }')).to.jsonEqual({ - data: { - colorEnum: 'GREEN', - }, + it('enum may be output type', () => { + const result = executeQuery('{ colorEnum(fromInt: 1) }'); + + expect(result).to.deep.equal({ + data: { colorEnum: 'GREEN' }, }); }); - it('enum may be both input and output type', async () => { - expect( - await graphql(schema, '{ colorEnum(fromEnum: GREEN) }'), - ).to.jsonEqual({ - data: { - colorEnum: 'GREEN', - }, + it('enum may be both input and output type', () => { + const result = executeQuery('{ colorEnum(fromEnum: GREEN) }'); + + expect(result).to.deep.equal({ + data: { colorEnum: 'GREEN' }, }); }); - it('does not accept string literals', async () => { - expect( - await graphql(schema, '{ colorEnum(fromEnum: "GREEN") }'), - ).to.jsonEqual({ + it('does not accept string literals', () => { + const result = executeQuery('{ colorEnum(fromEnum: "GREEN") }'); + + expect(result).to.deep.equal({ errors: [ { message: 'Expected type Color, found "GREEN"; Did you mean the enum value GREEN?', locations: [{ line: 1, column: 23 }], + path: undefined, }, ], }); }); - it('does not accept values not in the enum', async () => { - expect( - await graphql(schema, '{ colorEnum(fromEnum: GREENISH) }'), - ).to.jsonEqual({ + it('does not accept values not in the enum', () => { + const result = executeQuery('{ colorEnum(fromEnum: GREENISH) }'); + + expect(result).to.deep.equal({ errors: [ { message: 'Expected type Color, found GREENISH; Did you mean the enum value GREEN?', locations: [{ line: 1, column: 23 }], + path: undefined, }, ], }); }); - it('does not accept values with incorrect casing', async () => { - expect( - await graphql(schema, '{ colorEnum(fromEnum: green) }'), - ).to.jsonEqual({ + it('does not accept values with incorrect casing', () => { + const result = executeQuery('{ colorEnum(fromEnum: green) }'); + + expect(result).to.deep.equal({ errors: [ { message: 'Expected type Color, found green; Did you mean the enum value GREEN?', locations: [{ line: 1, column: 23 }], + path: undefined, }, ], }); }); - it('does not accept incorrect internal value', async () => { - expect( - await graphql(schema, '{ colorEnum(fromString: "GREEN") }'), - ).to.containSubset({ - data: { - colorEnum: null, - }, + it('does not accept incorrect internal value', () => { + const result = executeQuery('{ colorEnum(fromString: "GREEN") }'); + + expect(result).to.deep.equal({ + data: { colorEnum: null }, errors: [ { message: 'Expected a value of type "Color" but received: GREEN', @@ -213,152 +214,121 @@ describe('Type System: Enum Values', () => { }); }); - it('does not accept internal value in place of enum literal', async () => { - expect(await graphql(schema, '{ colorEnum(fromEnum: 1) }')).to.jsonEqual({ + it('does not accept internal value in place of enum literal', () => { + const result = executeQuery('{ colorEnum(fromEnum: 1) }'); + + expect(result).to.deep.equal({ errors: [ { message: 'Expected type Color, found 1.', locations: [{ line: 1, column: 23 }], + path: undefined, }, ], }); }); - it('does not accept enum literal in place of int', async () => { - expect(await graphql(schema, '{ colorEnum(fromInt: GREEN) }')).to.jsonEqual( - { - errors: [ - { - message: 'Expected type Int, found GREEN.', - locations: [{ line: 1, column: 22 }], - }, - ], - }, - ); + it('does not accept enum literal in place of int', () => { + const result = executeQuery('{ colorEnum(fromInt: GREEN) }'); + + expect(result).to.deep.equal({ + errors: [ + { + message: 'Expected type Int, found GREEN.', + locations: [{ line: 1, column: 22 }], + path: undefined, + }, + ], + }); }); - it('accepts JSON string as enum variable', async () => { - expect( - await graphql( - schema, - 'query test($color: Color!) { colorEnum(fromEnum: $color) }', - null, - null, - { color: 'BLUE' }, - ), - ).to.jsonEqual({ - data: { - colorEnum: 'BLUE', - }, + it('accepts JSON string as enum variable', () => { + const doc = 'query ($color: Color!) { colorEnum(fromEnum: $color) }'; + const result = executeQuery(doc, { color: 'BLUE' }); + + expect(result).to.deep.equal({ + data: { colorEnum: 'BLUE' }, }); }); - it('accepts enum literals as input arguments to mutations', async () => { - expect( - await graphql( - schema, - 'mutation x($color: Color!) { favoriteEnum(color: $color) }', - null, - null, - { color: 'GREEN' }, - ), - ).to.jsonEqual({ - data: { - favoriteEnum: 'GREEN', - }, + it('accepts enum literals as input arguments to mutations', () => { + const doc = 'mutation ($color: Color!) { favoriteEnum(color: $color) }'; + const result = executeQuery(doc, { color: 'GREEN' }); + + expect(result).to.deep.equal({ + data: { favoriteEnum: 'GREEN' }, }); }); - it('accepts enum literals as input arguments to subscriptions', async () => { - expect( - await graphql( - schema, - 'subscription x($color: Color!) { subscribeToEnum(color: $color) }', - null, - null, - { color: 'GREEN' }, - ), - ).to.jsonEqual({ - data: { - subscribeToEnum: 'GREEN', - }, + it('accepts enum literals as input arguments to subscriptions', () => { + const doc = + 'subscription ($color: Color!) { subscribeToEnum(color: $color) }'; + const result = executeQuery(doc, { color: 'GREEN' }); + + expect(result).to.deep.equal({ + data: { subscribeToEnum: 'GREEN' }, }); }); - it('does not accept internal value as enum variable', async () => { - expect( - await graphql( - schema, - 'query test($color: Color!) { colorEnum(fromEnum: $color) }', - null, - null, - { color: 2 }, - ), - ).to.jsonEqual({ + it('does not accept internal value as enum variable', () => { + const doc = 'query ($color: Color!) { colorEnum(fromEnum: $color) }'; + const result = executeQuery(doc, { color: 2 }); + + expect(result).to.deep.equal({ errors: [ { message: 'Variable "$color" got invalid value 2; Expected type Color.', - locations: [{ line: 1, column: 12 }], + locations: [{ line: 1, column: 8 }], + path: undefined, }, ], }); }); - it('does not accept string variables as enum input', async () => { - expect( - await graphql( - schema, - 'query test($color: String!) { colorEnum(fromEnum: $color) }', - null, - null, - { color: 'BLUE' }, - ), - ).to.jsonEqual({ + it('does not accept string variables as enum input', () => { + const doc = 'query ($color: String!) { colorEnum(fromEnum: $color) }'; + const result = executeQuery(doc, { color: 'BLUE' }); + + expect(result).to.deep.equal({ errors: [ { message: 'Variable "$color" of type "String!" used in position ' + 'expecting type "Color".', - locations: [{ line: 1, column: 12 }, { line: 1, column: 51 }], + locations: [{ line: 1, column: 8 }, { line: 1, column: 47 }], + path: undefined, }, ], }); }); - it('does not accept internal value variable as enum input', async () => { - expect( - await graphql( - schema, - 'query test($color: Int!) { colorEnum(fromEnum: $color) }', - null, - null, - { color: 2 }, - ), - ).to.jsonEqual({ + it('does not accept internal value variable as enum input', () => { + const doc = 'query ($color: Int!) { colorEnum(fromEnum: $color) }'; + const result = executeQuery(doc, { color: 2 }); + + expect(result).to.deep.equal({ errors: [ { message: 'Variable "$color" of type "Int!" used in position ' + 'expecting type "Color".', - locations: [{ line: 1, column: 12 }, { line: 1, column: 48 }], + locations: [{ line: 1, column: 8 }, { line: 1, column: 44 }], + path: undefined, }, ], }); }); - it('enum value may have an internal value of 0', async () => { - expect( - await graphql( - schema, - ` - { - colorEnum(fromEnum: RED) - colorInt(fromEnum: RED) - } - `, - ), - ).to.jsonEqual({ + it('enum value may have an internal value of 0', () => { + const result = executeQuery(` + { + colorEnum(fromEnum: RED) + colorInt(fromEnum: RED) + } + `); + + expect(result).to.deep.equal({ data: { colorEnum: 'RED', colorInt: 0, @@ -366,18 +336,15 @@ describe('Type System: Enum Values', () => { }); }); - it('enum inputs may be nullable', async () => { - expect( - await graphql( - schema, - ` - { - colorEnum - colorInt - } - `, - ), - ).to.jsonEqual({ + it('enum inputs may be nullable', () => { + const result = executeQuery(` + { + colorEnum + colorInt + } + `); + + expect(result).to.deep.equal({ data: { colorEnum: null, colorInt: null, @@ -403,20 +370,17 @@ describe('Type System: Enum Values', () => { expect(badUsage).to.equal(undefined); }); - it('may be internally represented with complex values', async () => { - expect( - await graphql( - schema, - ` - { - first: complexEnum - second: complexEnum(fromEnum: TWO) - good: complexEnum(provideGoodValue: true) - bad: complexEnum(provideBadValue: true) - } - `, - ), - ).to.containSubset({ + it('may be internally represented with complex values', () => { + const result = executeQuery(` + { + first: complexEnum + second: complexEnum(fromEnum: TWO) + good: complexEnum(provideGoodValue: true) + bad: complexEnum(provideBadValue: true) + } + `); + + expect(result).to.deep.equal({ data: { first: 'ONE', second: 'TWO', @@ -427,14 +391,14 @@ describe('Type System: Enum Values', () => { { message: 'Expected a value of type "Complex" but received: [object Object]', - locations: [{ line: 6, column: 13 }], + locations: [{ line: 6, column: 9 }], + path: ['bad'], }, ], }); }); - it('can be introspected without error', async () => { - const result = await graphql(schema, getIntrospectionQuery()); - expect(result).to.not.have.property('errors'); + it('can be introspected without error', () => { + expect(() => introspectionFromSchema(schema)).to.not.throw(); }); }); diff --git a/src/utilities/__tests__/buildClientSchema-test.js b/src/utilities/__tests__/buildClientSchema-test.js index 6a93a96646..c25b060ec1 100644 --- a/src/utilities/__tests__/buildClientSchema-test.js +++ b/src/utilities/__tests__/buildClientSchema-test.js @@ -8,9 +8,9 @@ import { describe, it } from 'mocha'; import { expect } from 'chai'; import { buildClientSchema } from '../buildClientSchema'; -import { getIntrospectionQuery } from '../introspectionQuery'; +import { introspectionFromSchema } from '../introspectionFromSchema'; import { - graphql, + graphqlSync, GraphQLSchema, GraphQLScalarType, GraphQLObjectType, @@ -34,21 +34,15 @@ import { GraphQLDirective } from '../../type/directives'; // by using "buildClientSchema". If the client then runs the introspection // query against the client-side schema, it should get a result identical to // what was returned by the server. -async function testSchema(serverSchema) { - const initialIntrospection = await graphql( - serverSchema, - getIntrospectionQuery(), - ); - const clientSchema = buildClientSchema(initialIntrospection.data); - const secondIntrospection = await graphql( - clientSchema, - getIntrospectionQuery(), - ); +function testSchema(serverSchema) { + const initialIntrospection = introspectionFromSchema(serverSchema); + const clientSchema = buildClientSchema(initialIntrospection); + const secondIntrospection = introspectionFromSchema(clientSchema); expect(secondIntrospection).to.deep.equal(initialIntrospection); } describe('Type System: build schema from introspection', () => { - it('builds a simple schema', async () => { + it('builds a simple schema', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Simple', @@ -62,10 +56,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a simple schema with all operation types', async () => { + it('builds a simple schema with all operation types', () => { const queryType = new GraphQLObjectType({ name: 'QueryType', description: 'This is a simple query type', @@ -108,10 +102,10 @@ describe('Type System: build schema from introspection', () => { subscription: subscriptionType, }); - await testSchema(schema); + testSchema(schema); }); - it('uses built-in scalars when possible', async () => { + it('uses built-in scalars when possible', () => { const customScalar = new GraphQLScalarType({ name: 'CustomScalar', serialize: () => null, @@ -130,10 +124,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); - const introspection = await graphql(schema, getIntrospectionQuery()); - const clientSchema = buildClientSchema(introspection.data); + const introspection = introspectionFromSchema(schema); + const clientSchema = buildClientSchema(introspection); // Built-ins are used expect(clientSchema.getType('Int')).to.equal(GraphQLInt); @@ -146,7 +140,7 @@ describe('Type System: build schema from introspection', () => { expect(clientSchema.getType('CustomScalar')).not.to.equal(customScalar); }); - it('builds a schema with a recursive type reference', async () => { + it('builds a schema with a recursive type reference', () => { const recurType = new GraphQLObjectType({ name: 'Recur', fields: () => ({ @@ -157,10 +151,10 @@ describe('Type System: build schema from introspection', () => { query: recurType, }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with a circular type reference', async () => { + it('builds a schema with a circular type reference', () => { const dogType = new GraphQLObjectType({ name: 'Dog', fields: () => ({ @@ -183,10 +177,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with an interface', async () => { + it('builds a schema with an interface', () => { const friendlyType = new GraphQLInterfaceType({ name: 'Friendly', fields: () => ({ @@ -220,10 +214,10 @@ describe('Type System: build schema from introspection', () => { types: [dogType, humanType], }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with an implicit interface', async () => { + it('builds a schema with an implicit interface', () => { const friendlyType = new GraphQLInterfaceType({ name: 'Friendly', fields: () => ({ @@ -249,10 +243,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with a union', async () => { + it('builds a schema with a union', () => { const dogType = new GraphQLObjectType({ name: 'Dog', fields: () => ({ @@ -278,10 +272,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with complex field values', async () => { + it('builds a schema with complex field values', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'ComplexFields', @@ -301,10 +295,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with field arguments', async () => { + it('builds a schema with field arguments', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'ArgFields', @@ -337,10 +331,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with default value on custom scalar field', async () => { + it('builds a schema with default value on custom scalar field', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'ArgFields', @@ -361,10 +355,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with an enum', async () => { + it('builds a schema with an enum', () => { const foodEnum = new GraphQLEnumType({ name: 'Food', description: 'Varieties of food stuffs', @@ -409,10 +403,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); - const introspection = await graphql(schema, getIntrospectionQuery()); - const clientSchema = buildClientSchema(introspection.data); + const introspection = introspectionFromSchema(schema); + const clientSchema = buildClientSchema(introspection); const clientFoodEnum = clientSchema.getType('Food'); // It's also an Enum type on the client. @@ -464,7 +458,7 @@ describe('Type System: build schema from introspection', () => { ]); }); - it('builds a schema with an input object', async () => { + it('builds a schema with an input object', () => { const addressType = new GraphQLInputObjectType({ name: 'Address', description: 'An input address', @@ -502,10 +496,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with field arguments with default values', async () => { + it('builds a schema with field arguments with default values', () => { const geoType = new GraphQLInputObjectType({ name: 'Geo', fields: { @@ -566,10 +560,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with custom directives', async () => { + it('builds a schema with custom directives', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Simple', @@ -590,10 +584,10 @@ describe('Type System: build schema from introspection', () => { ], }); - await testSchema(schema); + testSchema(schema); }); - it('builds a schema with legacy directives', async () => { + it('builds a schema with legacy directives', () => { const oldIntrospection = { __schema: { // Minimum required schema. @@ -662,11 +656,8 @@ describe('Type System: build schema from introspection', () => { }; const clientSchema = buildClientSchema(oldIntrospection); - const secondIntrospection = await graphql( - clientSchema, - getIntrospectionQuery(), - ); - expect(secondIntrospection.data).to.containSubset(newIntrospection); + const secondIntrospection = introspectionFromSchema(clientSchema); + expect(secondIntrospection).to.containSubset(newIntrospection); }); it('builds a schema with legacy names', () => { @@ -697,7 +688,7 @@ describe('Type System: build schema from introspection', () => { expect(schema.__allowedLegacyNames).to.deep.equal(['__badName']); }); - it('builds a schema aware of deprecation', async () => { + it('builds a schema aware of deprecation', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Simple', @@ -730,10 +721,10 @@ describe('Type System: build schema from introspection', () => { }), }); - await testSchema(schema); + testSchema(schema); }); - it('can use client schema for limited execution', async () => { + it('can use client schema for limited execution', () => { const customScalar = new GraphQLScalarType({ name: 'CustomScalar', serialize: () => null, @@ -754,10 +745,10 @@ describe('Type System: build schema from introspection', () => { }), }); - const introspection = await graphql(schema, getIntrospectionQuery()); - const clientSchema = buildClientSchema(introspection.data); + const introspection = introspectionFromSchema(schema); + const clientSchema = buildClientSchema(introspection); - const result = await graphql( + const result = graphqlSync( clientSchema, 'query Limited($v: CustomScalar) { foo(custom1: 123, custom2: $v) }', { foo: 'bar', unused: 'value' }, @@ -829,7 +820,7 @@ describe('Type System: build schema from introspection', () => { }); describe('very deep decorators are not supported', () => { - it('fails on very deep (> 7 levels) lists', async () => { + it('fails on very deep (> 7 levels) lists', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Query', @@ -851,13 +842,13 @@ describe('Type System: build schema from introspection', () => { }), }); - const introspection = await graphql(schema, getIntrospectionQuery()); - expect(() => buildClientSchema(introspection.data)).to.throw( + const introspection = introspectionFromSchema(schema); + expect(() => buildClientSchema(introspection)).to.throw( 'Decorated type deeper than introspection query.', ); }); - it('fails on a very deep (> 7 levels) non-null', async () => { + it('fails on a very deep (> 7 levels) non-null', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Query', @@ -881,13 +872,13 @@ describe('Type System: build schema from introspection', () => { }), }); - const introspection = await graphql(schema, getIntrospectionQuery()); - expect(() => buildClientSchema(introspection.data)).to.throw( + const introspection = introspectionFromSchema(schema); + expect(() => buildClientSchema(introspection)).to.throw( 'Decorated type deeper than introspection query.', ); }); - it('succeeds on deep (<= 7 levels) types', async () => { + it('succeeds on deep (<= 7 levels) types', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Query', @@ -910,8 +901,8 @@ describe('Type System: build schema from introspection', () => { }), }); - const introspection = await graphql(schema, getIntrospectionQuery()); - buildClientSchema(introspection.data); + const introspection = introspectionFromSchema(schema); + buildClientSchema(introspection); }); }); }); diff --git a/yarn.lock b/yarn.lock index 0b9a5a91b9..cc743684d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -886,14 +886,6 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chai-json-equal@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/chai-json-equal/-/chai-json-equal-0.0.1.tgz#338fcbbdaec63349379c7c4278c8a28da3b141a1" - -chai-spies-next@0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/chai-spies-next/-/chai-spies-next-0.9.3.tgz#672a84f68824af152ea1cbdda5a96f1a066302b9" - chai-subset@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/chai-subset/-/chai-subset-1.6.0.tgz#a5d0ca14e329a79596ed70058b6646bd6988cfe9"