diff --git a/src/__testUtils__/expectJSON.ts b/src/__testUtils__/expectJSON.ts new file mode 100644 index 0000000000..04a2bdb20b --- /dev/null +++ b/src/__testUtils__/expectJSON.ts @@ -0,0 +1,40 @@ +import { expect } from 'chai'; + +import { mapValue } from '../jsutils/mapValue'; +import { isObjectLike } from '../jsutils/isObjectLike'; + +/** + * Deeply transforms an arbitrary value to a JSON-safe value by calling toJSON + * on any nested value which defines it. + */ +function toJSONDeep(value: unknown): unknown { + if (!isObjectLike(value)) { + return value; + } + + if (typeof value.toJSON === 'function') { + return value.toJSON(); + } + + if (Array.isArray(value)) { + return value.map(toJSONDeep); + } + + return mapValue(value, toJSONDeep); +} + +export function expectJSON(value: unknown) { + return expect(toJSONDeep(value)); +} + +export function expectToThrowJSON(fn: () => unknown) { + function mapException(): unknown { + try { + return fn(); + } catch (error) { + throw toJSONDeep(error); + } + } + + return expect(mapException).to.throw(); +} diff --git a/src/__tests__/starWarsQuery-test.ts b/src/__tests__/starWarsQuery-test.ts index 73f583fcf7..d442806892 100644 --- a/src/__tests__/starWarsQuery-test.ts +++ b/src/__tests__/starWarsQuery-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../__testUtils__/expectJSON'; + import { graphql } from '../graphql'; import { StarWarsSchema as schema } from './starWarsSchema'; @@ -393,7 +395,7 @@ describe('Star Wars Query Tests', () => { `; const result = await graphql({ schema, source }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { hero: { name: 'R2-D2', @@ -424,7 +426,7 @@ describe('Star Wars Query Tests', () => { `; const result = await graphql({ schema, source }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { hero: { name: 'R2-D2', @@ -475,7 +477,7 @@ describe('Star Wars Query Tests', () => { `; const result = await graphql({ schema, source }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { mainHero: { name: 'R2-D2', diff --git a/src/error/GraphQLError.ts b/src/error/GraphQLError.ts index a3a7992526..2bea7d4103 100644 --- a/src/error/GraphQLError.ts +++ b/src/error/GraphQLError.ts @@ -240,7 +240,7 @@ export class GraphQLError extends Error { } get [Symbol.toStringTag](): string { - return 'Object'; + return 'GraphQLError'; } } diff --git a/src/execution/__tests__/abstract-test.ts b/src/execution/__tests__/abstract-test.ts index 0dd097f527..18b8586794 100644 --- a/src/execution/__tests__/abstract-test.ts +++ b/src/execution/__tests__/abstract-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { parse } from '../../language/parser'; import { GraphQLSchema } from '../../type/schema'; @@ -204,7 +206,7 @@ describe('Execute: Handles execution of abstract types', () => { } `; - expect(await executeQuery({ schema, query })).to.deep.equal({ + expectJSON(await executeQuery({ schema, query })).to.deep.equal({ data: { pets: [null, null], }, @@ -358,7 +360,7 @@ describe('Execute: Handles execution of abstract types', () => { } `; - expect(await executeQuery({ schema, query })).to.deep.equal({ + expectJSON(await executeQuery({ schema, query })).to.deep.equal({ data: { pets: [null, null], }, @@ -539,7 +541,7 @@ describe('Execute: Handles execution of abstract types', () => { const result = executeSync({ schema, document, rootValue }); return { toEqual(message: string) { - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { pet: null }, errors: [ { diff --git a/src/execution/__tests__/executor-test.ts b/src/execution/__tests__/executor-test.ts index 330f719d58..f5e55b9ef8 100644 --- a/src/execution/__tests__/executor-test.ts +++ b/src/execution/__tests__/executor-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { inspect } from '../../jsutils/inspect'; import { invariant } from '../../jsutils/invariant'; @@ -497,7 +499,7 @@ describe('Execute: Handles basic execution tasks', () => { }; const result = await execute({ schema, document, rootValue }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { sync: 'sync', syncError: null, @@ -611,7 +613,7 @@ describe('Execute: Handles basic execution tasks', () => { const result = await execute({ schema, document }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { foods: null }, errors: [ { @@ -670,7 +672,7 @@ describe('Execute: Handles basic execution tasks', () => { `); const result = executeSync({ schema, document }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { nullableA: { aliasedA: null, @@ -752,7 +754,7 @@ describe('Execute: Handles basic execution tasks', () => { const rootValue = { a: 'b' }; const result = executeSync({ schema, document, rootValue }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [{ message: 'Must provide an operation.' }], }); }); @@ -772,7 +774,7 @@ describe('Execute: Handles basic execution tasks', () => { `); const result = executeSync({ schema, document }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -798,7 +800,7 @@ describe('Execute: Handles basic execution tasks', () => { const operationName = 'UnknownExample'; const result = executeSync({ schema, document, operationName }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [{ message: 'Unknown operation named "UnknownExample".' }], }); }); @@ -816,7 +818,7 @@ describe('Execute: Handles basic execution tasks', () => { const operationName = ''; const result = executeSync({ schema, document, operationName }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [{ message: 'Unknown operation named "".' }], }); }); @@ -1074,7 +1076,7 @@ describe('Execute: Handles basic execution tasks', () => { }; const result = executeSync({ schema, document, rootValue }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { specials: [{ value: 'foo' }, null], }, @@ -1118,7 +1120,7 @@ describe('Execute: Handles basic execution tasks', () => { }); const result = executeSync({ schema, document: parse('{ customScalar }') }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { customScalar: null }, errors: [ { diff --git a/src/execution/__tests__/lists-test.ts b/src/execution/__tests__/lists-test.ts index 53314ecba8..45ca7f5d76 100644 --- a/src/execution/__tests__/lists-test.ts +++ b/src/execution/__tests__/lists-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { parse } from '../../language/parser'; import { buildSchema } from '../../utilities/buildASTSchema'; @@ -50,7 +52,7 @@ describe('Execute: Accepts any iterable as list value', () => { it('Does not accept (Iterable) String-literal as a List value', () => { const listField = 'Singular'; - expect(complete({ listField })).to.deep.equal({ + expectJSON(complete({ listField })).to.deep.equal({ data: { listField: null }, errors: [ { @@ -129,11 +131,11 @@ describe('Execute: Handles list nullability', () => { expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({ data: { listField: [1, null, 2] }, }); - expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({ data: { listField: null }, errors, }); - expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ data: null, errors, }); @@ -152,14 +154,14 @@ describe('Execute: Handles list nullability', () => { expect(await complete({ listField, as: '[Int]' })).to.deep.equal({ data: { listField: null }, }); - expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({ data: null, errors, }); expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({ data: { listField: null }, }); - expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ data: null, errors, }); @@ -175,19 +177,19 @@ describe('Execute: Handles list nullability', () => { }, ]; - expect(await complete({ listField, as: '[Int]' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int]' })).to.deep.equal({ data: { listField: [1, null, 2] }, errors, }); - expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({ data: { listField: [1, null, 2] }, errors, }); - expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({ data: { listField: null }, errors, }); - expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ data: null, errors, }); @@ -203,19 +205,19 @@ describe('Execute: Handles list nullability', () => { }, ]; - expect(await complete({ listField, as: '[Int]' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int]' })).to.deep.equal({ data: { listField: null }, errors, }); - expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({ data: null, errors, }); - expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({ data: { listField: null }, errors, }); - expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ + expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({ data: null, errors, }); diff --git a/src/execution/__tests__/mutations-test.ts b/src/execution/__tests__/mutations-test.ts index f15977cc46..4d11b11b68 100644 --- a/src/execution/__tests__/mutations-test.ts +++ b/src/execution/__tests__/mutations-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick'; import { parse } from '../../language/parser'; @@ -167,7 +169,7 @@ describe('Execute: Handles mutation execution ordering', () => { const rootValue = new Root(6); const result = await execute({ schema, document, rootValue }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { first: { theNumber: 1 }, second: { theNumber: 2 }, diff --git a/src/execution/__tests__/nonnull-test.ts b/src/execution/__tests__/nonnull-test.ts index 223c552c33..4fb4589051 100644 --- a/src/execution/__tests__/nonnull-test.ts +++ b/src/execution/__tests__/nonnull-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { parse } from '../../language/parser'; import { GraphQLSchema } from '../../type/schema'; @@ -130,7 +132,7 @@ async function executeSyncAndAsync(query: string, rootValue: unknown) { rootValue, }); - expect(asyncResult).to.deep.equal(patchData(syncResult)); + expectJSON(asyncResult).to.deep.equal(patchData(syncResult)); return syncResult; } @@ -151,7 +153,7 @@ describe('Execute: handles non-nullable types', () => { it('that throws', async () => { const result = await executeSyncAndAsync(query, throwingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { sync: null }, errors: [ { @@ -175,7 +177,7 @@ describe('Execute: handles non-nullable types', () => { it('that returns null', async () => { const result = await executeSyncAndAsync(query, nullingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { syncNest: null }, errors: [ { @@ -190,7 +192,7 @@ describe('Execute: handles non-nullable types', () => { it('that throws', async () => { const result = await executeSyncAndAsync(query, throwingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { syncNest: null }, errors: [ { @@ -242,7 +244,7 @@ describe('Execute: handles non-nullable types', () => { it('that throws', async () => { const result = await executeQuery(query, throwingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data, errors: [ { @@ -368,7 +370,7 @@ describe('Execute: handles non-nullable types', () => { it('that returns null', async () => { const result = await executeQuery(query, nullingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data, errors: [ { @@ -429,7 +431,7 @@ describe('Execute: handles non-nullable types', () => { it('that throws', async () => { const result = await executeQuery(query, throwingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data, errors: [ { @@ -494,7 +496,7 @@ describe('Execute: handles non-nullable types', () => { it('that returns null', async () => { const result = await executeSyncAndAsync(query, nullingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: null, errors: [ { @@ -509,7 +511,7 @@ describe('Execute: handles non-nullable types', () => { it('that throws', async () => { const result = await executeSyncAndAsync(query, throwingData); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: null, errors: [ { @@ -609,7 +611,7 @@ describe('Execute: handles non-nullable types', () => { `), }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { withNonNullArg: null, }, @@ -636,7 +638,7 @@ describe('Execute: handles non-nullable types', () => { `), }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { withNonNullArg: null, }, @@ -666,7 +668,7 @@ describe('Execute: handles non-nullable types', () => { }, }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { withNonNullArg: null, }, @@ -694,7 +696,7 @@ describe('Execute: handles non-nullable types', () => { }, }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { withNonNullArg: null, }, diff --git a/src/execution/__tests__/sync-test.ts b/src/execution/__tests__/sync-test.ts index 184a259b69..c270c4d900 100644 --- a/src/execution/__tests__/sync-test.ts +++ b/src/execution/__tests__/sync-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { parse } from '../../language/parser'; import { validate } from '../../validation/validate'; @@ -52,7 +54,7 @@ describe('Execute: synchronously when possible', () => { document: parse(doc), rootValue: 'rootValue', }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [{ message: 'Must provide an operation.' }], }); }); @@ -120,7 +122,7 @@ describe('Execute: synchronously when possible', () => { schema: badSchema, source: '{ __typename }', }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [{ message: 'Query root type must be provided.' }], }); }); @@ -131,7 +133,7 @@ describe('Execute: synchronously when possible', () => { schema, source: doc, }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: 'Syntax Error: Expected Name, found "{".', diff --git a/src/execution/__tests__/variables-test.ts b/src/execution/__tests__/variables-test.ts index ebf7d0b169..df89ab24c0 100644 --- a/src/execution/__tests__/variables-test.ts +++ b/src/execution/__tests__/variables-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { inspect } from '../../jsutils/inspect'; import { invariant } from '../../jsutils/invariant'; @@ -196,7 +198,7 @@ describe('Execute: Handles inputs', () => { } `); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { fieldWithObjectInput: null, }, @@ -369,7 +371,7 @@ describe('Execute: Handles inputs', () => { const params = { input: { a: 'foo', b: 'bar', c: null } }; const result = executeQuery(doc, params); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -383,7 +385,7 @@ describe('Execute: Handles inputs', () => { it('errors on incorrect type', () => { const result = executeQuery(doc, { input: 'foo bar' }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -397,7 +399,7 @@ describe('Execute: Handles inputs', () => { it('errors on omission of nested non-null', () => { const result = executeQuery(doc, { input: { a: 'foo', b: 'bar' } }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -416,7 +418,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(nestedDoc, { input: { na: { a: 'foo' } } }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -438,7 +440,7 @@ describe('Execute: Handles inputs', () => { }; const result = executeQuery(doc, params); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -613,7 +615,7 @@ describe('Execute: Handles inputs', () => { } `); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -632,7 +634,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { value: null }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -675,7 +677,7 @@ describe('Execute: Handles inputs', () => { it('reports error for missing non-nullable inputs', () => { const result = executeQuery('{ fieldWithNonNullableStringInput }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { fieldWithNonNullableStringInput: null, }, @@ -698,7 +700,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { value: [1, 2, 3] }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -723,7 +725,7 @@ describe('Execute: Handles inputs', () => { } `); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { fieldWithNonNullableStringInput: null, }, @@ -781,7 +783,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: null }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -844,7 +846,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: ['A', null, 'B'] }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -863,7 +865,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: null }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -893,7 +895,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: ['A', null, 'B'] }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -912,7 +914,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: { list: ['A', 'B'] } }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -931,7 +933,7 @@ describe('Execute: Handles inputs', () => { `; const result = executeQuery(doc, { input: 'WhoKnows' }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -975,7 +977,7 @@ describe('Execute: Handles inputs', () => { } `); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { fieldWithDefaultArgumentValue: null, }, @@ -1029,7 +1031,7 @@ describe('Execute: Handles inputs', () => { it('return all errors by default', () => { const result = getVariableValues(schema, variableDefinitions, inputValue); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ invalidValueError(0, 0), invalidValueError(1, 1), @@ -1046,7 +1048,7 @@ describe('Execute: Handles inputs', () => { { maxErrors: 3 }, ); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ invalidValueError(0, 0), invalidValueError(1, 1), @@ -1063,7 +1065,7 @@ describe('Execute: Handles inputs', () => { { maxErrors: 2 }, ); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ invalidValueError(0, 0), invalidValueError(1, 1), diff --git a/src/language/__tests__/lexer-test.ts b/src/language/__tests__/lexer-test.ts index 8e26212a77..173d7176cb 100644 --- a/src/language/__tests__/lexer-test.ts +++ b/src/language/__tests__/lexer-test.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; import { dedent } from '../../__testUtils__/dedent'; +import { expectToThrowJSON } from '../../__testUtils__/expectJSON'; import { inspect } from '../../jsutils/inspect'; @@ -24,7 +25,7 @@ function lexSecond(str: string) { } function expectSyntaxError(text: string) { - return expect(() => lexSecond(text)).to.throw(); + return expectToThrowJSON(() => lexSecond(text)); } describe('Lexer', () => { diff --git a/src/language/__tests__/parser-test.ts b/src/language/__tests__/parser-test.ts index 8cbfe16c95..767d3d1be6 100644 --- a/src/language/__tests__/parser-test.ts +++ b/src/language/__tests__/parser-test.ts @@ -3,6 +3,7 @@ import { describe, it } from 'mocha'; import { dedent } from '../../__testUtils__/dedent'; import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery'; +import { expectJSON, expectToThrowJSON } from '../../__testUtils__/expectJSON'; import { inspect } from '../../jsutils/inspect'; @@ -11,10 +12,8 @@ import { Source } from '../source'; import { TokenKind } from '../tokenKind'; import { parse, parseValue, parseConstValue, parseType } from '../parser'; -import { toJSONDeep } from './toJSONDeep'; - function expectSyntaxError(text: string) { - return expect(() => parse(text)).to.throw(); + return expectToThrowJSON(() => parse(text)); } describe('Parser', () => { @@ -235,7 +234,7 @@ describe('Parser', () => { } `); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.DOCUMENT, loc: { start: 0, end: 40 }, definitions: [ @@ -325,7 +324,7 @@ describe('Parser', () => { } `); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.DOCUMENT, loc: { start: 0, end: 29 }, definitions: [ @@ -420,7 +419,7 @@ describe('Parser', () => { describe('parseValue', () => { it('parses null value', () => { const result = parseValue('null'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.NULL, loc: { start: 0, end: 4 }, }); @@ -428,7 +427,7 @@ describe('Parser', () => { it('parses list values', () => { const result = parseValue('[123 "abc"]'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.LIST, loc: { start: 0, end: 11 }, values: [ @@ -449,7 +448,7 @@ describe('Parser', () => { it('parses block strings', () => { const result = parseValue('["""long""" "short"]'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.LIST, loc: { start: 0, end: 20 }, values: [ @@ -471,7 +470,7 @@ describe('Parser', () => { it('allows variables', () => { const result = parseValue('{ field: $var }'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.OBJECT, loc: { start: 0, end: 15 }, fields: [ @@ -519,7 +518,7 @@ describe('Parser', () => { describe('parseConstValue', () => { it('parses values', () => { const result = parseConstValue('[123 "abc"]'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.LIST, loc: { start: 0, end: 11 }, values: [ @@ -561,7 +560,7 @@ describe('Parser', () => { describe('parseType', () => { it('parses well known types', () => { const result = parseType('String'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.NAMED_TYPE, loc: { start: 0, end: 6 }, name: { @@ -574,7 +573,7 @@ describe('Parser', () => { it('parses custom types', () => { const result = parseType('MyType'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.NAMED_TYPE, loc: { start: 0, end: 6 }, name: { @@ -587,7 +586,7 @@ describe('Parser', () => { it('parses list types', () => { const result = parseType('[MyType]'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.LIST_TYPE, loc: { start: 0, end: 8 }, type: { @@ -604,7 +603,7 @@ describe('Parser', () => { it('parses non-null types', () => { const result = parseType('MyType!'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.NON_NULL_TYPE, loc: { start: 0, end: 7 }, type: { @@ -621,7 +620,7 @@ describe('Parser', () => { it('parses nested types', () => { const result = parseType('[MyType!]'); - expect(toJSONDeep(result)).to.deep.equal({ + expectJSON(result).to.deep.equal({ kind: Kind.LIST_TYPE, loc: { start: 0, end: 9 }, type: { diff --git a/src/language/__tests__/schema-parser-test.ts b/src/language/__tests__/schema-parser-test.ts index 3ad3b9497c..46fed5fbc6 100644 --- a/src/language/__tests__/schema-parser-test.ts +++ b/src/language/__tests__/schema-parser-test.ts @@ -3,13 +3,12 @@ import { describe, it } from 'mocha'; import { dedent } from '../../__testUtils__/dedent'; import { kitchenSinkSDL } from '../../__testUtils__/kitchenSinkSDL'; +import { expectJSON, expectToThrowJSON } from '../../__testUtils__/expectJSON'; import { parse } from '../parser'; -import { toJSONDeep } from './toJSONDeep'; - function expectSyntaxError(text: string) { - return expect(() => parse(text)).to.throw(); + return expectToThrowJSON(() => parse(text)); } function typeNode(name: unknown, loc: unknown) { @@ -84,7 +83,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -115,15 +114,12 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.nested.property( - 'definitions[0].description', - { - kind: 'StringValue', - value: 'Description', - block: false, - loc: { start: 0, end: 13 }, - }, - ); + expectJSON(doc).to.deep.nested.property('definitions[0].description', { + kind: 'StringValue', + value: 'Description', + block: false, + loc: { start: 0, end: 13 }, + }); }); it('parses type with description multi-line string', () => { @@ -137,15 +133,12 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.nested.property( - 'definitions[0].description', - { - kind: 'StringValue', - value: 'Description', - block: true, - loc: { start: 0, end: 19 }, - }, - ); + expectJSON(doc).to.deep.nested.property('definitions[0].description', { + kind: 'StringValue', + value: 'Description', + block: true, + loc: { start: 0, end: 19 }, + }); }); it('parses schema with description string', () => { @@ -156,15 +149,12 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.nested.property( - 'definitions[0].description', - { - kind: 'StringValue', - value: 'Description', - block: false, - loc: { start: 0, end: 13 }, - }, - ); + expectJSON(doc).to.deep.nested.property('definitions[0].description', { + kind: 'StringValue', + value: 'Description', + block: false, + loc: { start: 0, end: 13 }, + }); }); it('Description followed by something other than type system definition throws', () => { @@ -181,7 +171,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -206,7 +196,7 @@ describe('Schema Parser', () => { it('Object extension without fields', () => { const doc = parse('extend type Hello implements Greeting'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -224,7 +214,7 @@ describe('Schema Parser', () => { it('Interface extension without fields', () => { const doc = parse('extend interface Hello implements Greeting'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -247,7 +237,7 @@ describe('Schema Parser', () => { extend type Hello implements SecondGreeting `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -309,7 +299,7 @@ describe('Schema Parser', () => { extend interface Hello implements SecondGreeting `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -383,7 +373,7 @@ describe('Schema Parser', () => { mutation: Mutation }`; const doc = parse(body); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -407,7 +397,7 @@ describe('Schema Parser', () => { it('Schema extension with only directives', () => { const body = 'extend schema @directive'; const doc = parse(body); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -449,7 +439,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -478,7 +468,7 @@ describe('Schema Parser', () => { it('Simple interface inheriting interface', () => { const doc = parse('interface Hello implements World { field: String }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -504,7 +494,7 @@ describe('Schema Parser', () => { it('Simple type inheriting interface', () => { const doc = parse('type Hello implements World { field: String }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -530,7 +520,7 @@ describe('Schema Parser', () => { it('Simple type inheriting multiple interfaces', () => { const doc = parse('type Hello implements Wo & rld { field: String }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -558,7 +548,7 @@ describe('Schema Parser', () => { it('Simple interface inheriting multiple interfaces', () => { const doc = parse('interface Hello implements Wo & rld { field: String }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -587,7 +577,7 @@ describe('Schema Parser', () => { it('Simple type inheriting multiple interfaces with leading ampersand', () => { const doc = parse('type Hello implements & Wo & rld { field: String }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -617,7 +607,7 @@ describe('Schema Parser', () => { const doc = parse( 'interface Hello implements & Wo & rld { field: String }', ); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -646,7 +636,7 @@ describe('Schema Parser', () => { it('Single value enum', () => { const doc = parse('enum Hello { WORLD }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -665,7 +655,7 @@ describe('Schema Parser', () => { it('Double value enum', () => { const doc = parse('enum Hello { WO, RLD }'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -691,7 +681,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -721,7 +711,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -759,7 +749,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -801,7 +791,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -843,7 +833,7 @@ describe('Schema Parser', () => { } `); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -883,7 +873,7 @@ describe('Schema Parser', () => { it('Simple union', () => { const doc = parse('union Hello = World'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -902,7 +892,7 @@ describe('Schema Parser', () => { it('Union with two types', () => { const doc = parse('union Hello = Wo | Rld'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -924,7 +914,7 @@ describe('Schema Parser', () => { it('Union with two types and leading pipe', () => { const doc = parse('union Hello = | Wo | Rld'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -974,7 +964,7 @@ describe('Schema Parser', () => { it('Scalar', () => { const doc = parse('scalar Hello'); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -995,7 +985,7 @@ input Hello { world: String }`); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -1033,7 +1023,7 @@ input Hello { const body = 'directive @foo on OBJECT | INTERFACE'; const doc = parse(body); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { @@ -1069,7 +1059,7 @@ input Hello { const body = 'directive @foo repeatable on OBJECT | INTERFACE'; const doc = parse(body); - expect(toJSONDeep(doc)).to.deep.equal({ + expectJSON(doc).to.deep.equal({ kind: 'Document', definitions: [ { diff --git a/src/language/__tests__/toJSONDeep.ts b/src/language/__tests__/toJSONDeep.ts deleted file mode 100644 index a82606252a..0000000000 --- a/src/language/__tests__/toJSONDeep.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { mapValue } from '../../jsutils/mapValue'; -import { isObjectLike } from '../../jsutils/isObjectLike'; - -/** - * Deeply transforms an arbitrary value to a JSON-safe value by calling toJSON - * on any nested value which defines it. - */ -export function toJSONDeep(value: unknown): unknown { - if (!isObjectLike(value)) { - return value; - } - - if (typeof value.toJSON === 'function') { - return value.toJSON(); - } - - if (Array.isArray(value)) { - return value.map(toJSONDeep); - } - - return mapValue(value, toJSONDeep); -} diff --git a/src/subscription/__tests__/subscribe-test.ts b/src/subscription/__tests__/subscribe-test.ts index 85d6400a3d..004429630e 100644 --- a/src/subscription/__tests__/subscribe-test.ts +++ b/src/subscription/__tests__/subscribe-test.ts @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick'; import { invariant } from '../../jsutils/invariant'; @@ -347,7 +348,7 @@ describe('Subscription Initialization Phase', () => { const document = parse('subscription { unknownField }'); const result = await subscribe({ schema, document }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: 'The subscription field "unknownField" is not defined.', @@ -423,24 +424,24 @@ describe('Subscription Initialization Phase', () => { ], }; - expect( + expectJSON( // Returning an error await subscribeWithFn(() => new Error('test error')), ).to.deep.equal(expectedResult); - expect( + expectJSON( // Throwing an error await subscribeWithFn(() => { throw new Error('test error'); }), ).to.deep.equal(expectedResult); - expect( + expectJSON( // Resolving to an error await subscribeWithFn(() => Promise.resolve(new Error('test error'))), ).to.deep.equal(expectedResult); - expect( + expectJSON( // Rejecting with an error await subscribeWithFn(() => Promise.reject(new Error('test error'))), ).to.deep.equal(expectedResult); @@ -470,7 +471,7 @@ describe('Subscription Initialization Phase', () => { // If we receive variables that cannot be coerced correctly, subscribe() will // resolve to an ExecutionResult that contains an informative error description. const result = await subscribe({ schema, document, variableValues }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -892,7 +893,7 @@ describe('Subscription Publish Phase', () => { }); // An error in execution is presented as such. - expect(await subscription.next()).to.deep.equal({ + expectJSON(await subscription.next()).to.deep.equal({ done: false, value: { data: { newMessage: null }, @@ -908,7 +909,7 @@ describe('Subscription Publish Phase', () => { // However that does not close the response event stream. // Subsequent events are still executed. - expect(await subscription.next()).to.deep.equal({ + expectJSON(await subscription.next()).to.deep.equal({ done: false, value: { data: { newMessage: 'Bonjour' }, diff --git a/src/type/__tests__/enumType-test.ts b/src/type/__tests__/enumType-test.ts index c3cf23cd1c..301eb13857 100644 --- a/src/type/__tests__/enumType-test.ts +++ b/src/type/__tests__/enumType-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { graphqlSync } from '../../graphql'; import { introspectionFromSchema } from '../../utilities/introspectionFromSchema'; @@ -147,7 +149,7 @@ describe('Type System: Enum Values', () => { it('does not accept string literals', () => { const result = executeQuery('{ colorEnum(fromEnum: "GREEN") }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -161,7 +163,7 @@ describe('Type System: Enum Values', () => { it('does not accept values not in the enum', () => { const result = executeQuery('{ colorEnum(fromEnum: GREENISH) }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -175,7 +177,7 @@ describe('Type System: Enum Values', () => { it('does not accept values with incorrect casing', () => { const result = executeQuery('{ colorEnum(fromEnum: green) }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -189,7 +191,7 @@ describe('Type System: Enum Values', () => { it('does not accept incorrect internal value', () => { const result = executeQuery('{ colorEnum(fromString: "GREEN") }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { colorEnum: null }, errors: [ { @@ -204,7 +206,7 @@ describe('Type System: Enum Values', () => { it('does not accept internal value in place of enum literal', () => { const result = executeQuery('{ colorEnum(fromEnum: 1) }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: 'Enum "Color" cannot represent non-enum value: 1.', @@ -217,7 +219,7 @@ describe('Type System: Enum Values', () => { it('does not accept enum literal in place of int', () => { const result = executeQuery('{ colorEnum(fromInt: GREEN) }'); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: 'Int cannot represent non-integer value: GREEN', @@ -259,7 +261,7 @@ describe('Type System: Enum Values', () => { const doc = 'query ($color: Color!) { colorEnum(fromEnum: $color) }'; const result = executeQuery(doc, { color: 2 }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -274,7 +276,7 @@ describe('Type System: Enum Values', () => { const doc = 'query ($color: String!) { colorEnum(fromEnum: $color) }'; const result = executeQuery(doc, { color: 'BLUE' }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -292,7 +294,7 @@ describe('Type System: Enum Values', () => { const doc = 'query ($color: Int!) { colorEnum(fromEnum: $color) }'; const result = executeQuery(doc, { color: 2 }); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ errors: [ { message: @@ -379,7 +381,7 @@ describe('Type System: Enum Values', () => { } `); - expect(result).to.deep.equal({ + expectJSON(result).to.deep.equal({ data: { first: 'ONE', second: 'TWO', diff --git a/src/type/__tests__/introspection-test.ts b/src/type/__tests__/introspection-test.ts index 4d5f1398d1..0851769d4e 100644 --- a/src/type/__tests__/introspection-test.ts +++ b/src/type/__tests__/introspection-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { buildSchema } from '../../utilities/buildASTSchema'; import { getIntrospectionQuery } from '../../utilities/getIntrospectionQuery'; @@ -1522,7 +1524,7 @@ describe('Introspection', () => { } `; - expect(graphqlSync({ schema, source })).to.deep.equal({ + expectJSON(graphqlSync({ schema, source })).to.deep.equal({ errors: [ { message: diff --git a/src/type/__tests__/validation-test.ts b/src/type/__tests__/validation-test.ts index b36021055b..016ff8a7a6 100644 --- a/src/type/__tests__/validation-test.ts +++ b/src/type/__tests__/validation-test.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; import { dedent } from '../../__testUtils__/dedent'; +import { expectJSON } from '../../__testUtils__/expectJSON'; import { inspect } from '../../jsutils/inspect'; @@ -121,7 +122,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); const schemaWithDef = buildSchema(` schema { @@ -132,7 +133,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([]); + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([]); }); it('accepts a Schema whose query and mutation types are object types', () => { @@ -145,7 +146,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); const schemaWithDef = buildSchema(` schema { @@ -161,7 +162,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([]); + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([]); }); it('accepts a Schema whose query and subscription types are object types', () => { @@ -174,7 +175,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); const schemaWithDef = buildSchema(` schema { @@ -190,7 +191,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([]); + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([]); }); it('rejects a Schema without a query type', () => { @@ -199,7 +200,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Query root type must be provided.', }, @@ -214,7 +215,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([ + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([ { message: 'Query root type must be provided.', locations: [{ line: 2, column: 7 }], @@ -228,7 +229,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Query root type must be Object type, it cannot be Query.', locations: [{ line: 2, column: 7 }], @@ -244,7 +245,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([ + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([ { message: 'Query root type must be Object type, it cannot be SomeInputObject.', @@ -263,7 +264,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Mutation root type must be Object type if provided, it cannot be Mutation.', @@ -285,7 +286,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([ + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([ { message: 'Mutation root type must be Object type if provided, it cannot be SomeInputObject.', @@ -304,7 +305,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Subscription root type must be Object type if provided, it cannot be Subscription.', @@ -326,7 +327,7 @@ describe('Type System: A Schema must have Object root types', () => { test: String } `); - expect(validateSchema(schemaWithDef)).to.deep.equal([ + expectJSON(validateSchema(schemaWithDef)).to.deep.equal([ { message: 'Subscription root type must be Object type if provided, it cannot be SomeInputObject.', @@ -369,7 +370,7 @@ describe('Type System: A Schema must have Object root types', () => { `), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Query root type must be Object type, it cannot be SomeInputObject.', @@ -394,7 +395,7 @@ describe('Type System: A Schema must have Object root types', () => { // @ts-expect-error types: [{ name: 'SomeType' }, SomeDirective], }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Expected GraphQL named type but got: { name: "SomeType" }.', }, @@ -411,7 +412,7 @@ describe('Type System: A Schema must have Object root types', () => { // @ts-expect-error directives: [null, 'SomeDirective', SomeScalarType], }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Expected directive but got: null.', }, @@ -437,7 +438,7 @@ describe('Type System: Objects must have fields', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Object type with missing fields', () => { @@ -448,7 +449,7 @@ describe('Type System: Objects must have fields', () => { type IncompleteObject `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type IncompleteObject must define one or more fields.', locations: [{ line: 6, column: 7 }], @@ -461,7 +462,7 @@ describe('Type System: Objects must have fields', () => { fields: {}, }), ); - expect(validateSchema(manualSchema)).to.deep.equal([ + expectJSON(validateSchema(manualSchema)).to.deep.equal([ { message: 'Type IncompleteObject must define one or more fields.', }, @@ -475,7 +476,7 @@ describe('Type System: Objects must have fields', () => { }, }), ); - expect(validateSchema(manualSchema2)).to.deep.equal([ + expectJSON(validateSchema(manualSchema2)).to.deep.equal([ { message: 'Type IncompleteObject must define one or more fields.', }, @@ -489,7 +490,7 @@ describe('Type System: Objects must have fields', () => { fields: { 'bad-name-with-dashes': { type: GraphQLString } }, }), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "bad-name-with-dashes" does not.', @@ -513,7 +514,7 @@ describe('Type System: Fields args must be properly named', () => { }, }), ); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects field arg with invalid names', () => { @@ -531,7 +532,7 @@ describe('Type System: Fields args must be properly named', () => { }), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "bad-name-with-dashes" does not.', @@ -559,7 +560,7 @@ describe('Type System: Union types must be valid', () => { | TypeA | TypeB `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects a Union type with empty types', () => { @@ -580,7 +581,7 @@ describe('Type System: Union types must be valid', () => { `), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Union type BadUnion must define one or more member types.', locations: [ @@ -611,7 +612,7 @@ describe('Type System: Union types must be valid', () => { | TypeA `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Union type BadUnion can only include type TypeA once.', locations: [ @@ -623,7 +624,7 @@ describe('Type System: Union types must be valid', () => { schema = extendSchema(schema, parse('extend union BadUnion = TypeB')); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Union type BadUnion can only include type TypeA once.', locations: [ @@ -663,7 +664,7 @@ describe('Type System: Union types must be valid', () => { schema = extendSchema(schema, parse('extend union BadUnion = Int')); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Union type BadUnion can only include Object types, it cannot include String.', @@ -692,7 +693,7 @@ describe('Type System: Union types must be valid', () => { types: [memberType], }); const badSchema = schemaWithFieldType(badUnion); - expect(validateSchema(badSchema)).to.deep.equal([ + expectJSON(validateSchema(badSchema)).to.deep.equal([ { message: 'Union type BadUnion can only include Object types, ' + @@ -714,7 +715,7 @@ describe('Type System: Input Objects must have fields', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Input Object type with missing fields', () => { @@ -735,7 +736,7 @@ describe('Type System: Input Objects must have fields', () => { `), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Input Object type SomeInputObject must define one or more fields.', @@ -766,7 +767,7 @@ describe('Type System: Input Objects must have fields', () => { } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Input Object with non-breakable circular reference', () => { @@ -780,7 +781,7 @@ describe('Type System: Input Objects must have fields', () => { } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Cannot reference Input Object "SomeInputObject" within itself through a series of non-null fields: "nonNullSelf".', @@ -808,7 +809,7 @@ describe('Type System: Input Objects must have fields', () => { } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Cannot reference Input Object "SomeInputObject" within itself through a series of non-null fields: "startLoop.nextInLoop.closeLoop".', @@ -842,7 +843,7 @@ describe('Type System: Input Objects must have fields', () => { } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Cannot reference Input Object "SomeInputObject" within itself through a series of non-null fields: "startLoop.closeLoop".', @@ -885,7 +886,7 @@ describe('Type System: Input Objects must have fields', () => { goodInputObject: SomeInputObject } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of SomeInputObject.badObject must be Input Type but got: SomeObject.', @@ -911,7 +912,7 @@ describe('Type System: Input Objects must have fields', () => { anotherOptionalField: String! = "" @deprecated } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Required input field SomeInputObject.badField cannot be deprecated.', @@ -943,7 +944,7 @@ describe('Type System: Enum types must be well defined', () => { `), ); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Enum type SomeEnum must define one or more values.', locations: [ @@ -965,7 +966,7 @@ describe('Type System: Enum types must be well defined', () => { } const schema1 = schemaWithEnum({ '#value': {} }); - expect(validateSchema(schema1)).to.deep.equal([ + expectJSON(validateSchema(schema1)).to.deep.equal([ { message: 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "#value" does not.', @@ -973,7 +974,7 @@ describe('Type System: Enum types must be well defined', () => { ]); const schema2 = schemaWithEnum({ '1value': {} }); - expect(validateSchema(schema2)).to.deep.equal([ + expectJSON(validateSchema(schema2)).to.deep.equal([ { message: 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "1value" does not.', @@ -981,7 +982,7 @@ describe('Type System: Enum types must be well defined', () => { ]); const schema3 = schemaWithEnum({ 'KEBAB-CASE': {} }); - expect(validateSchema(schema3)).to.deep.equal([ + expectJSON(validateSchema(schema3)).to.deep.equal([ { message: 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "KEBAB-CASE" does not.', @@ -989,17 +990,17 @@ describe('Type System: Enum types must be well defined', () => { ]); const schema4 = schemaWithEnum({ true: {} }); - expect(validateSchema(schema4)).to.deep.equal([ + expectJSON(validateSchema(schema4)).to.deep.equal([ { message: 'Enum type SomeEnum cannot include value: true.' }, ]); const schema5 = schemaWithEnum({ false: {} }); - expect(validateSchema(schema5)).to.deep.equal([ + expectJSON(validateSchema(schema5)).to.deep.equal([ { message: 'Enum type SomeEnum cannot include value: false.' }, ]); const schema6 = schemaWithEnum({ null: {} }); - expect(validateSchema(schema6)).to.deep.equal([ + expectJSON(validateSchema(schema6)).to.deep.equal([ { message: 'Enum type SomeEnum cannot include value: null.' }, ]); }); @@ -1031,14 +1032,14 @@ describe('Type System: Object fields must have output types', () => { const typeName = inspect(type); it(`accepts an output type as an Object field type: ${typeName}`, () => { const schema = schemaWithObjectField({ type }); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); } it('rejects an empty Object field type', () => { // @ts-expect-error (type field must not be undefined) const schema = schemaWithObjectField({ type: undefined }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadObject.badField must be Output Type but got: undefined.', @@ -1051,7 +1052,7 @@ describe('Type System: Object fields must have output types', () => { it(`rejects a non-output type as an Object field type: ${typeStr}`, () => { // @ts-expect-error const schema = schemaWithObjectField({ type }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: `The type of BadObject.badField must be Output Type but got: ${typeStr}.`, }, @@ -1062,7 +1063,7 @@ describe('Type System: Object fields must have output types', () => { it('rejects a non-type value as an Object field type', () => { // @ts-expect-error const schema = schemaWithObjectField({ type: Number }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadObject.badField must be Output Type but got: [function Number].', @@ -1083,7 +1084,7 @@ describe('Type System: Object fields must have output types', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of Query.field must be Output Type but got: [SomeInputObject].', @@ -1104,7 +1105,7 @@ describe('Type System: Objects can only implement unique interfaces', () => { }), }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type BadObject must only implement Interface types, it cannot implement undefined.', @@ -1126,7 +1127,7 @@ describe('Type System: Objects can only implement unique interfaces', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type BadObject must only implement Interface types, it cannot implement SomeInputObject.', @@ -1149,7 +1150,7 @@ describe('Type System: Objects can only implement unique interfaces', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type AnotherObject can only implement AnotherInterface once.', locations: [ @@ -1178,7 +1179,7 @@ describe('Type System: Objects can only implement unique interfaces', () => { schema, parse('extend type AnotherObject implements AnotherInterface'), ); - expect(validateSchema(extendedSchema)).to.deep.equal([ + expectJSON(validateSchema(extendedSchema)).to.deep.equal([ { message: 'Type AnotherObject can only implement AnotherInterface once.', locations: [ @@ -1217,7 +1218,7 @@ describe('Type System: Interface extensions should be valid', () => { } `), ); - expect(validateSchema(extendedSchema)).to.deep.equal([ + expectJSON(validateSchema(extendedSchema)).to.deep.equal([ { message: 'Interface field AnotherInterface.newField expected but AnotherObject does not provide it.', @@ -1256,7 +1257,7 @@ describe('Type System: Interface extensions should be valid', () => { } `), ); - expect(validateSchema(extendedSchema)).to.deep.equal([ + expectJSON(validateSchema(extendedSchema)).to.deep.equal([ { message: 'Interface field argument AnotherInterface.newField(test:) expected but AnotherObject.newField does not provide it.', @@ -1307,7 +1308,7 @@ describe('Type System: Interface extensions should be valid', () => { } `), ); - expect(validateSchema(extendedSchema)).to.deep.equal([ + expectJSON(validateSchema(extendedSchema)).to.deep.equal([ { message: 'Interface field AnotherInterface.newInterfaceField expects type NewInterface but AnotherObject.newInterfaceField is type MismatchingInterface.', @@ -1352,14 +1353,14 @@ describe('Type System: Interface fields must have output types', () => { const typeName = inspect(type); it(`accepts an output type as an Interface field type: ${typeName}`, () => { const schema = schemaWithInterfaceField({ type }); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); } it('rejects an empty Interface field type', () => { // @ts-expect-error (type field must not be undefined) const schema = schemaWithInterfaceField({ type: undefined }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadImplementing.badField must be Output Type but got: undefined.', @@ -1376,7 +1377,7 @@ describe('Type System: Interface fields must have output types', () => { it(`rejects a non-output type as an Interface field type: ${typeStr}`, () => { // @ts-expect-error const schema = schemaWithInterfaceField({ type }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: `The type of BadImplementing.badField must be Output Type but got: ${typeStr}.`, }, @@ -1390,7 +1391,7 @@ describe('Type System: Interface fields must have output types', () => { it('rejects a non-type value as an Interface field type', () => { // @ts-expect-error const schema = schemaWithInterfaceField({ type: Number }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadImplementing.badField must be Output Type but got: [function Number].', @@ -1423,7 +1424,7 @@ describe('Type System: Interface fields must have output types', () => { field: SomeInputObject } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of SomeInterface.field must be Output Type but got: SomeInputObject.', @@ -1447,7 +1448,7 @@ describe('Type System: Interface fields must have output types', () => { foo: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); }); @@ -1488,14 +1489,14 @@ describe('Type System: Arguments must have input types', () => { const typeName = inspect(type); it(`accepts an input type as a field arg type: ${typeName}`, () => { const schema = schemaWithArg({ type }); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); } it('rejects an empty field arg type', () => { // @ts-expect-error (type field must not be undefined) const schema = schemaWithArg({ type: undefined }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of @BadDirective(badArg:) must be Input Type but got: undefined.', @@ -1512,7 +1513,7 @@ describe('Type System: Arguments must have input types', () => { it(`rejects a non-input type as a field arg type: ${typeStr}`, () => { // @ts-expect-error const schema = schemaWithArg({ type }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: `The type of @BadDirective(badArg:) must be Input Type but got: ${typeStr}.`, }, @@ -1526,7 +1527,7 @@ describe('Type System: Arguments must have input types', () => { it('rejects a non-type value as a field arg type', () => { // @ts-expect-error const schema = schemaWithArg({ type: Number }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of @BadDirective(badArg:) must be Input Type but got: [function Number].', @@ -1557,7 +1558,7 @@ describe('Type System: Arguments must have input types', () => { ): String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Required argument @BadDirective(badArg:) cannot be deprecated.', @@ -1586,7 +1587,7 @@ describe('Type System: Arguments must have input types', () => { foo: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of Query.test(arg:) must be Input Type but got: SomeObject.', @@ -1626,14 +1627,14 @@ describe('Type System: Input Object fields must have input types', () => { const typeName = inspect(type); it(`accepts an input type as an input field type: ${typeName}`, () => { const schema = schemaWithInputField({ type }); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); } it('rejects an empty input field type', () => { // @ts-expect-error (type field must not be undefined) const schema = schemaWithInputField({ type: undefined }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadInputObject.badField must be Input Type but got: undefined.', @@ -1646,7 +1647,7 @@ describe('Type System: Input Object fields must have input types', () => { it(`rejects a non-input type as an input field type: ${typeStr}`, () => { // @ts-expect-error const schema = schemaWithInputField({ type }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: `The type of BadInputObject.badField must be Input Type but got: ${typeStr}.`, }, @@ -1657,7 +1658,7 @@ describe('Type System: Input Object fields must have input types', () => { it('rejects a non-type value as an input field type', () => { // @ts-expect-error const schema = schemaWithInputField({ type: Number }); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of BadInputObject.badField must be Input Type but got: [function Number].', @@ -1682,7 +1683,7 @@ describe('Type System: Input Object fields must have input types', () => { bar: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'The type of SomeInputObject.foo must be Input Type but got: SomeObject.', @@ -1707,7 +1708,7 @@ describe('Objects must adhere to Interface they implement', () => { field(input: String): String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Object which implements an Interface along with more fields', () => { @@ -1725,7 +1726,7 @@ describe('Objects must adhere to Interface they implement', () => { anotherField: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Object which implements an Interface field along with additional optional arguments', () => { @@ -1742,7 +1743,7 @@ describe('Objects must adhere to Interface they implement', () => { field(input: String, anotherInput: String): String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Object missing an Interface field', () => { @@ -1759,7 +1760,7 @@ describe('Objects must adhere to Interface they implement', () => { anotherField: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expected but AnotherObject does not provide it.', @@ -1785,7 +1786,7 @@ describe('Objects must adhere to Interface they implement', () => { field(input: String): Int } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type String but AnotherObject.field is type Int.', @@ -1814,7 +1815,7 @@ describe('Objects must adhere to Interface they implement', () => { field: B } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type A but AnotherObject.field is type B.', @@ -1840,7 +1841,7 @@ describe('Objects must adhere to Interface they implement', () => { field: AnotherObject } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Object with a subtyped Interface field (union)', () => { @@ -1863,7 +1864,7 @@ describe('Objects must adhere to Interface they implement', () => { field: SomeObject } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Object missing an Interface argument', () => { @@ -1880,7 +1881,7 @@ describe('Objects must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field argument AnotherInterface.field(input:) expected but AnotherObject.field does not provide it.', @@ -1906,7 +1907,7 @@ describe('Objects must adhere to Interface they implement', () => { field(input: Int): String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field argument AnotherInterface.field(input:) expects type String but AnotherObject.field(input:) is type Int.', @@ -1932,7 +1933,7 @@ describe('Objects must adhere to Interface they implement', () => { field(input: Int): Int } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type String but AnotherObject.field is type Int.', @@ -1971,7 +1972,7 @@ describe('Objects must adhere to Interface they implement', () => { ): String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Object field AnotherObject.field includes required argument requiredArg that is missing from the Interface field AnotherInterface.field.', @@ -1997,7 +1998,7 @@ describe('Objects must adhere to Interface they implement', () => { field: [String]! } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Object with a non-list Interface field list type', () => { @@ -2014,7 +2015,7 @@ describe('Objects must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type [String] but AnotherObject.field is type String.', @@ -2040,7 +2041,7 @@ describe('Objects must adhere to Interface they implement', () => { field: [String] } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type String but AnotherObject.field is type [String].', @@ -2066,7 +2067,7 @@ describe('Objects must adhere to Interface they implement', () => { field: String! } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Object with a superset nullable Interface field type', () => { @@ -2083,7 +2084,7 @@ describe('Objects must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field AnotherInterface.field expects type String! but AnotherObject.field is type String.', @@ -2113,7 +2114,7 @@ describe('Objects must adhere to Interface they implement', () => { field: String! } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type AnotherObject must implement SuperInterface because it is implemented by AnotherInterface.', @@ -2141,7 +2142,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field(input: String): String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Interface which implements an Interface along with more fields', () => { @@ -2159,7 +2160,7 @@ describe('Interfaces must adhere to Interface they implement', () => { anotherField: String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Interface which implements an Interface field along with additional optional arguments', () => { @@ -2176,7 +2177,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field(input: String, anotherInput: String): String } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Interface missing an Interface field', () => { @@ -2193,7 +2194,7 @@ describe('Interfaces must adhere to Interface they implement', () => { anotherField: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expected but ChildInterface does not provide it.', @@ -2219,7 +2220,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field(input: String): Int } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type String but ChildInterface.field is type Int.', @@ -2248,7 +2249,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: B } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type A but ChildInterface.field is type B.', @@ -2274,7 +2275,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: ChildInterface } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('accepts an Interface with a subtyped Interface field (union)', () => { @@ -2297,7 +2298,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: SomeObject } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Interface implementing a non-Interface type', () => { @@ -2314,7 +2315,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type BadInterface must only implement Interface types, it cannot implement SomeInputObject.', @@ -2337,7 +2338,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field argument ParentInterface.field(input:) expected but ChildInterface.field does not provide it.', @@ -2363,7 +2364,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field(input: Int): String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field argument ParentInterface.field(input:) expects type String but ChildInterface.field(input:) is type Int.', @@ -2389,7 +2390,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field(input: Int): Int } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type String but ChildInterface.field is type Int.', @@ -2428,7 +2429,7 @@ describe('Interfaces must adhere to Interface they implement', () => { ): String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Object field ChildInterface.field includes required argument requiredArg that is missing from the Interface field ParentInterface.field.', @@ -2454,7 +2455,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: [String]! } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Interface with a non-list Interface field list type', () => { @@ -2471,7 +2472,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type [String] but ChildInterface.field is type String.', @@ -2497,7 +2498,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: [String] } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type String but ChildInterface.field is type [String].', @@ -2523,7 +2524,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String! } `); - expect(validateSchema(schema)).to.deep.equal([]); + expectJSON(validateSchema(schema)).to.deep.equal([]); }); it('rejects an Interface with a superset nullable Interface field type', () => { @@ -2540,7 +2541,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Interface field ParentInterface.field expects type String! but ChildInterface.field is type String.', @@ -2570,7 +2571,7 @@ describe('Interfaces must adhere to Interface they implement', () => { field: String! } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type ChildInterface must implement SuperInterface because it is implemented by ParentInterface.', @@ -2593,7 +2594,7 @@ describe('Interfaces must adhere to Interface they implement', () => { } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type FooInterface cannot implement itself because it would create a circular reference.', @@ -2617,7 +2618,7 @@ describe('Interfaces must adhere to Interface they implement', () => { } `); - expect(validateSchema(schema)).to.deep.equal([ + expectJSON(validateSchema(schema)).to.deep.equal([ { message: 'Type FooInterface cannot implement BarInterface because it would create a circular reference.', diff --git a/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts b/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts index 1f3cbab8e0..e14b0f3558 100644 --- a/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts +++ b/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts @@ -1,11 +1,17 @@ +import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { inspect } from '../../jsutils/inspect'; +import { parse } from '../../language/parser'; + import { GraphQLSchema } from '../../type/schema'; import { GraphQLString } from '../../type/scalars'; import { GraphQLScalarType, GraphQLObjectType } from '../../type/definition'; +import { validate } from '../validate'; import { ValuesOfCorrectTypeRule } from '../rules/ValuesOfCorrectTypeRule'; import { @@ -962,12 +968,10 @@ describe('Validate: Values of correct type', () => { }), }); - const expectedErrors = expectErrorsWithSchema( - schema, - '{ invalidArg(arg: 123) }', - ); + const doc = parse('{ invalidArg(arg: 123) }'); + const errors = validate(schema, doc, [ValuesOfCorrectTypeRule]); - expectedErrors.to.deep.equal([ + expectJSON(errors).to.deep.equal([ { message: 'Expected value of type "Invalid", found 123; Invalid scalar is always invalid: 123', @@ -975,8 +979,8 @@ describe('Validate: Values of correct type', () => { }, ]); - expectedErrors.to.have.nested.property( - '[0].originalError.message', + expect(errors[0]).to.have.nested.property( + 'originalError.message', 'Invalid scalar is always invalid: 123', ); }); diff --git a/src/validation/__tests__/harness.ts b/src/validation/__tests__/harness.ts index 139827af11..304cde6762 100644 --- a/src/validation/__tests__/harness.ts +++ b/src/validation/__tests__/harness.ts @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { expectJSON } from '../../__testUtils__/expectJSON'; import type { Maybe } from '../../jsutils/Maybe'; @@ -122,7 +122,7 @@ export function expectValidationErrorsWithSchema( ): any { const doc = parse(queryStr); const errors = validate(schema, doc, [rule]); - return expect(errors); + return expectJSON(errors); } export function expectValidationErrors( @@ -139,5 +139,5 @@ export function expectSDLValidationErrors( ): any { const doc = parse(sdlStr); const errors = validateSDL(doc, schema, [rule]); - return expect(errors); + return expectJSON(errors); } diff --git a/src/validation/__tests__/validation-test.ts b/src/validation/__tests__/validation-test.ts index af8508912f..65a8561376 100644 --- a/src/validation/__tests__/validation-test.ts +++ b/src/validation/__tests__/validation-test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import { expectJSON } from '../../__testUtils__/expectJSON'; + import { GraphQLError } from '../../error/GraphQLError'; import type { DirectiveNode } from '../../language/ast'; @@ -37,7 +39,7 @@ describe('Validate: Supports full validation', () => { `); const errors = validate(testSchema, doc); - expect(errors).to.deep.equal([]); + expectJSON(errors).to.deep.equal([]); }); it('detects unknown fields', () => { @@ -48,7 +50,7 @@ describe('Validate: Supports full validation', () => { `); const errors = validate(testSchema, doc); - expect(errors).to.deep.equal([ + expectJSON(errors).to.deep.equal([ { locations: [{ line: 3, column: 9 }], message: 'Cannot query field "unknown" on type "QueryRoot".', @@ -114,7 +116,7 @@ describe('Validate: Supports full validation', () => { } const errors = validate(schema, doc, [customRule]); - expect(errors).to.deep.equal([ + expectJSON(errors).to.deep.equal([ { message: 'Reporting directive: @custom', locations: [{ line: 3, column: 14 }], @@ -146,7 +148,7 @@ describe('Validate: Limit maximum number of validation errors', () => { it('when maxErrors is equal to number of errors', () => { const errors = validateDocument({ maxErrors: 3 }); - expect(errors).to.be.deep.equal([ + expectJSON(errors).to.be.deep.equal([ invalidFieldError('firstUnknownField'), invalidFieldError('secondUnknownField'), invalidFieldError('thirdUnknownField'), @@ -155,7 +157,7 @@ describe('Validate: Limit maximum number of validation errors', () => { it('when maxErrors is less than number of errors', () => { const errors = validateDocument({ maxErrors: 2 }); - expect(errors).to.be.deep.equal([ + expectJSON(errors).to.be.deep.equal([ invalidFieldError('firstUnknownField'), invalidFieldError('secondUnknownField'), {