diff --git a/.eslintrc.yml b/.eslintrc.yml index 5950ac406e1..acbbdbcc40c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -4,6 +4,7 @@ parserOptions: env: es6: true node: true + jest: true plugins: - import diff --git a/.travis.yml b/.travis.yml index 4a51eeaf7c5..99ae2438654 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,11 @@ script: npm run lint; fi - node_version=$(node -v); if [[ ${node_version:1:2} == "13" && $GRAPHQL_VERSION == "14.6" ]]; then - npm run prettier:check; + npm run format:check; fi - npm run compile - npm install graphql@$GRAPHQL_VERSION - npm run testonly:cover -after_success: - - npm run coverage - # Allow Travis tests to run in containers. sudo: false diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000000..fb3873b7905 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,19 @@ +const { resolve } = require('path'); +const CI = !!process.env.CI; + +module.exports = { + transform: { '^.+\\.tsx?$': 'ts-jest' }, + testEnvironment: 'node', + rootDir: process.cwd(), + globals: { + 'ts-jest': { + diagnostics: false, + tsConfig: 'tsconfig.json' + } + }, + restoreMocks: true, + reporters: ['default'], + modulePathIgnorePatterns: ['dist'], + collectCoverage: CI, + collectCoverageFrom: ['src', '!src/test'] +}; diff --git a/package.json b/package.json index 37224cd007d..c831232c60e 100644 --- a/package.json +++ b/package.json @@ -2,31 +2,30 @@ "name": "graphql-tools", "version": "5.0.0-alpha.0", "description": "Useful tools to create and manipulate GraphQL schemas.", - "main": "dist/index.js", + "sideEffects": false, + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts", + "typings": "dist/index.d.ts", + "typescript": { + "definition": "dist/index.d.ts" + }, "files": [ "/dist", "!/dist/test" ], - "sideEffects": false, "scripts": { "clean": "rimraf dist", - "build": "npm run compile", "precompile": "npm run clean", - "compile": "tsc", - "pretest": "npm run clean && npm run compile", - "test": "npm run testonly", + "compile": "rollup -c rollup.config.js", + "test": "jest", "posttest": "npm run lint && npm run prettier:check", "lint": "eslint --ext .js,.ts src", "lint:watch": "esw --watch --cache --ext .js,.ts src", - "watch": "tsc -w", - "testonly": "mocha --reporter spec --full-trace ./dist/test/**.js --require source-map-support/register", - "testonly:cover": "nyc npm run testonly", - "testonly:watch": "mocha -w --reporter spec --full-trace ./dist/test/**.js --require source-map-support/register", - "coverage": "nyc report --reporter=text-lcov | coveralls", + "watch": "npm run compile -- --watch", "prepublishOnly": "npm run compile", - "prettier": "prettier --trailing-comma all --single-quote --write src/**/*.ts", - "prettier:check": "prettier --trailing-comma all --single-quote --check src/**/*.ts" + "format": "prettier --write src/**/*.ts", + "format:check": "prettier --check src/**/*.ts" }, "repository": { "type": "git", @@ -45,9 +44,9 @@ "author": "Jonas Helfer ", "license": "MIT", "bugs": { - "url": "https://github.com/apollostack/graphql-tools/issues" + "url": "https://github.com/apollographql/graphql-tools/issues" }, - "homepage": "https://github.com/apollostack/graphql-tools#readme", + "homepage": "https://github.com/apollographql/graphql-tools#readme", "dependencies": { "apollo-link": "^1.2.13", "apollo-link-http-common": "^0.2.15", @@ -63,13 +62,13 @@ "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0-rc" }, "devDependencies": { - "@types/chai": "4.2.11", + "@rollup/plugin-node-resolve": "7.1.1", "@types/dateformat": "3.0.1", "@types/express": "4.17.3", "@types/extract-files": "3.1.0", "@types/graphql-type-json": "0.3.2", "@types/graphql-upload": "8.0.3", - "@types/mocha": "7.0.2", + "@types/jest": "25.1.4", "@types/node": "13.9.3", "@types/node-fetch": "2.5.5", "@types/uuid": "7.0.2", @@ -77,8 +76,6 @@ "@typescript-eslint/parser": "2.25.0", "babel-eslint": "10.1.0", "body-parser": "1.19.0", - "chai": "4.2.0", - "coveralls": "3.0.11", "dataloader": "2.0.0", "dateformat": "3.0.3", "eslint": "6.8.0", @@ -90,12 +87,18 @@ "graphql-subscriptions": "1.1.0", "graphql-type-json": "0.3.1", "graphql-upload": "10.0.0", - "mocha": "7.1.1", - "nyc": "15.0.0", + "jest": "25.2.4", "prettier": "2.0.2", "rimraf": "3.0.2", - "source-map-support": "0.5.16", + "rollup": "2.3.1", + "rollup-plugin-auto-external": "2.0.0", + "rollup-plugin-typescript2": "0.27.0", + "ts-jest": "25.3.0", "typescript": "3.8.3", "zen-observable-ts": "0.8.20" + }, + "prettier": { + "singleQuote": true, + "trailingComma": "all" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000000..42d4c197d79 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,29 @@ +import autoExternal from 'rollup-plugin-auto-external'; +import resolveNode from '@rollup/plugin-node-resolve'; +import rollupTypescript from 'rollup-plugin-typescript2'; + +const commonOutputOptions = { + preferConst: true, + sourcemap: true +}; + +export default { + input: 'src/index.ts', + plugins: [ + resolveNode(), + autoExternal({ builtins: true, dependencies: true, peerDependencies: true }), + rollupTypescript() + ], + output: [ + { + ...commonOutputOptions, + file: 'dist/index.cjs.js', + format: 'cjs' + }, + { + ...commonOutputOptions, + file: 'dist/index.esm.js', + format: 'esm' + } + ] +}; diff --git a/src/test/testAlternateMergeSchemas.ts b/src/test/alternateMergeSchemas.test.ts similarity index 89% rename from src/test/testAlternateMergeSchemas.ts rename to src/test/alternateMergeSchemas.test.ts index af4fac1a9f1..3144e94160e 100644 --- a/src/test/testAlternateMergeSchemas.ts +++ b/src/test/alternateMergeSchemas.test.ts @@ -11,7 +11,6 @@ import { GraphQLField, } from 'graphql'; import { forAwaitEach } from 'iterall'; -import { expect } from 'chai'; import { transformSchema, @@ -49,7 +48,7 @@ import { subscriptionSchema, subscriptionPubSub, subscriptionPubSubTrigger, -} from './testingSchemas'; +} from './fixtures/schemas'; const linkSchema = ` """ @@ -99,7 +98,7 @@ describe('merge schemas through transforms', () => { let bookingSubschemaConfig: SubschemaConfig; let mergedSchema: GraphQLSchema; - before(async () => { + beforeAll(async () => { bookingSubschemaConfig = await remoteBookingSchema; // namespace and strip schemas @@ -230,7 +229,7 @@ describe('merge schemas through transforms', () => { }); // FIXME fragemnt replacements - it('node should work', async () => { + test('node should work', async () => { const result = await graphql( mergedSchema, ` @@ -266,7 +265,7 @@ describe('merge schemas through transforms', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { booking: { __typename: 'Bookings_Booking', @@ -299,7 +298,7 @@ describe('merge schemas through transforms', () => { }); }); - it('local subscriptions should work even if root fields are renamed', (done) => { + test('local subscriptions should work even if root fields are renamed', (done) => { const originalNotification = { notifications: { text: 'Hello world', @@ -312,12 +311,12 @@ describe('merge schemas through transforms', () => { }; const subscription = parse(` - subscription Subscription { - Subscriptions_notifications { - text + subscription Subscription { + Subscriptions_notifications { + text + } } - } - `); + `); let notificationCnt = 0; subscribe(mergedSchema, subscription) @@ -325,8 +324,8 @@ describe('merge schemas through transforms', () => { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result.data).to.deep.equal(transformedNotification); + expect(result).toHaveProperty('data'); + expect(result.data).toEqual(transformedNotification); if (!notificationCnt++) { return done(); } @@ -344,7 +343,7 @@ describe('merge schemas through transforms', () => { }); describe('transform object fields', () => { - it('should work to add a resolver', async () => { + test('should work to add a resolver', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new TransformObjectFields( ( @@ -396,7 +395,7 @@ describe('transform object fields', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { propertyById: { id: 'p1', @@ -411,7 +410,7 @@ describe('transform object fields', () => { }); describe('default values', () => { - it('should work to add a default value even when renaming root fields', async () => { + test('should work to add a default value even when renaming root fields', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new TransformRootFields( ( @@ -437,7 +436,7 @@ describe('default values', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { renamedJsonTest: { test: 'test', @@ -448,7 +447,7 @@ describe('default values', () => { }); describe('rename fields that implement interface fields', () => { - it('should work', () => { + test('should work', () => { const originalItem = { id: '123', camel: "I'm a camel!", @@ -518,17 +517,17 @@ describe('rename fields that implement interface fields', () => { `; const originalResult = graphqlSync(originalSchema, originalQuery); - expect(originalResult).to.deep.equal({ data: { node: originalItem } }); + expect(originalResult).toEqual({ data: { node: originalItem } }); const newResult = graphqlSync(wrappedSchema, newQuery); - expect(newResult).to.deep.equal({ data: { _node: originalItem } }); + expect(newResult).toEqual({ data: { _node: originalItem } }); }); }); describe('transform object fields', () => { let schema: GraphQLSchema; - before(() => { + beforeAll(() => { const ITEM = { id: '123', // eslint-disable-next-line camelcase @@ -588,7 +587,7 @@ describe('transform object fields', () => { ]); }); - it('renaming should work', async () => { + test('renaming should work', async () => { const result = await graphql( schema, ` @@ -611,7 +610,7 @@ describe('transform object fields', () => { camelCase: "I'm a camel!", }; - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { item: TRANSFORMED_ITEM, items: { @@ -625,7 +624,7 @@ describe('transform object fields', () => { }); }); - it('filtering should work', async () => { + test('filtering should work', async () => { const result = await graphql( schema, ` @@ -659,14 +658,14 @@ describe('transform object fields', () => { expectedResult.errors[0].path = undefined; } - expect(result).to.deep.equal(expectedResult); + expect(result).toEqual(expectedResult); }); }); describe('filter and rename object fields', () => { let transformedPropertySchema: GraphQLSchema; - before(() => { + beforeAll(() => { transformedPropertySchema = filterSchema({ schema: transformSchema(propertySchema, [ new RenameTypes((name: string) => `New_${name}`), @@ -685,10 +684,9 @@ describe('filter and rename object fields', () => { }); }); - it('should filter', () => { + test('should filter', () => { if (graphqlVersion() >= 15) { - expect(printSchema(transformedPropertySchema)).to - .equal(`type New_Property { + expect(printSchema(transformedPropertySchema)).toBe(`type New_Property { new_id: ID! new_name: String! new_location: New_Location @@ -704,8 +702,7 @@ type Query { } `); } else { - expect(printSchema(transformedPropertySchema)).to - .equal(`type New_Location { + expect(printSchema(transformedPropertySchema)).toBe(`type New_Location { name: String! } @@ -723,7 +720,7 @@ type Query { } }); - it('should work', async () => { + test('should work', async () => { const result = await graphql( transformedPropertySchema, ` @@ -780,15 +777,15 @@ type Query { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); }); describe('rename nested object fields with interfaces', () => { - it('should work', () => { + test('should work', () => { const originalNode = { aList: [ { @@ -889,15 +886,15 @@ describe('rename nested object fields with interfaces', () => { const originalResult = graphqlSync(originalSchema, originalQuery); const transformedResult = graphqlSync(transformedSchema, transformedQuery); - expect(originalResult).to.deep.equal({ data: { node: originalNode } }); - expect(transformedResult).to.deep.equal({ + expect(originalResult).toEqual({ data: { node: originalNode } }); + expect(transformedResult).toEqual({ data: { node: transformedNode }, }); }); }); describe('WrapType transform', () => { - it('should work', async () => { + test('should work', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new WrapType('Query', 'Namespace_Query', 'namespace'), ]); @@ -951,15 +948,15 @@ describe('WrapType transform', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); }); describe('schema transformation with extraction of nested fields', () => { - it('should work via ExtendSchema transform', async () => { + test('should work via ExtendSchema transform', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new ExtendSchema({ typeDefs: ` @@ -1031,13 +1028,13 @@ describe('schema transformation with extraction of nested fields', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); - it('should work via HoistField transform', async () => { + test('should work via HoistField transform', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new HoistField('Property', ['location', 'name'], 'locationName'), ]); @@ -1058,7 +1055,7 @@ describe('schema transformation with extraction of nested fields', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { propertyById: { test: 'Helsinki', @@ -1069,7 +1066,7 @@ describe('schema transformation with extraction of nested fields', () => { }); describe('schema transformation with wrapping of object fields', () => { - it('should work via ExtendSchema transform', async () => { + test('should work via ExtendSchema transform', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new ExtendSchema({ typeDefs: ` @@ -1174,14 +1171,14 @@ describe('schema transformation with wrapping of object fields', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); describe('WrapFields transform', () => { - it('should work', async () => { + test('should work', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new WrapFields( 'Property', @@ -1251,13 +1248,13 @@ describe('schema transformation with wrapping of object fields', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); - it('should work, even with multiple fields', async () => { + test('should work, even with multiple fields', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ new WrapFields( 'Property', @@ -1335,8 +1332,8 @@ describe('schema transformation with wrapping of object fields', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); @@ -1346,7 +1343,7 @@ describe('schema transformation with wrapping of object fields', () => { describe('schema transformation with renaming of object fields', () => { let transformedPropertySchema: GraphQLSchema; - before(() => { + beforeAll(() => { transformedPropertySchema = transformSchema(propertySchema, [ new ExtendSchema({ typeDefs: ` @@ -1364,7 +1361,7 @@ describe('schema transformation with renaming of object fields', () => { ]); }); - it('should work, even with aliases, and should preserve errors', async () => { + test('should work, even with aliases, and should preserve errors', async () => { const result = await graphql( transformedPropertySchema, ` @@ -1408,8 +1405,15 @@ describe('schema transformation with renaming of object fields', () => { }; } - expect(result).to.deep.equal(expectedResult); - expect(result.errors[0].extensions).to.deep.equal({ + expect(result.data).toEqual(expectedResult.data); + expect(result.errors).toHaveLength(1); + expect(result.errors[0].locations).toEqual( + expectedResult.errors[0].locations, + ); + expect(result.errors[0].message).toEqual(expectedResult.errors[0].message); + expect(result.errors[0].path).toEqual(expectedResult.errors[0].path); + // expect(result).toEqual(expectedResult); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); @@ -1445,7 +1449,7 @@ describe('interface resolver inheritance', () => { }, }; - it('copies resolvers from interface', async () => { + test('copies resolvers from interface', async () => { const mergedSchema = mergeSchemas({ schemas: [ // pull in an executable schema just so mergeSchema doesn't complain @@ -1458,7 +1462,7 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(mergedSchema, query); - expect(response).to.deep.equal({ + expect(response).toEqual({ data: { user: { id: 'Node:1', @@ -1468,7 +1472,7 @@ describe('interface resolver inheritance', () => { }); }); - it('does not copy resolvers from interface when flag is false', async () => { + test('does not copy resolvers from interface when flag is false', async () => { const mergedSchema = mergeSchemas({ schemas: [ // pull in an executable schema just so mergeSchema doesn't complain @@ -1481,14 +1485,14 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(mergedSchema, query); - expect(response.errors.length).to.equal(1); - expect(response.errors[0].message).to.equal( + expect(response.errors.length).toBe(1); + expect(response.errors[0].message).toBe( 'Cannot return null for non-nullable field User.id.', ); - expect(response.errors[0].path).to.deep.equal(['user', 'id']); + expect(response.errors[0].path).toEqual(['user', 'id']); }); - it('does not copy resolvers from interface when flag is not provided', async () => { + test('does not copy resolvers from interface when flag is not provided', async () => { const mergedSchema = mergeSchemas({ schemas: [ // pull in an executable schema just so mergeSchema doesn't complain @@ -1500,16 +1504,16 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(mergedSchema, query); - expect(response.errors.length).to.equal(1); - expect(response.errors[0].message).to.equal( + expect(response.errors.length).toBe(1); + expect(response.errors[0].message).toBe( 'Cannot return null for non-nullable field User.id.', ); - expect(response.errors[0].path).to.deep.equal(['user', 'id']); + expect(response.errors[0].path).toEqual(['user', 'id']); }); }); describe('mergeSchemas', () => { - it('can merge null root fields', async () => { + test('can merge null root fields', async () => { const schema = makeExecutableSchema({ typeDefs: ` type Query { @@ -1531,11 +1535,11 @@ describe('mergeSchemas', () => { const query = '{ test { field } }'; const response = await graphql(mergedSchema, query); - expect(response.data.test).to.equal(null); - expect(response.errors).to.equal(undefined); + expect(response.data.test).toBe(null); + expect(response.errors).toBeUndefined(); }); - it('can merge default input types', async () => { + test('can merge default input types', async () => { const schema = makeExecutableSchema({ typeDefs: ` input InputWithDefault { @@ -1559,7 +1563,7 @@ describe('mergeSchemas', () => { const response = await graphql(mergedSchema, query); if (graphqlVersion() >= 15) { - expect(printSchema(schema)).to.equal(`input InputWithDefault { + expect(printSchema(schema)).toBe(`input InputWithDefault { field: String = "test" } @@ -1568,12 +1572,12 @@ type Query { } `); } else { - expect(printSchema(schema)).to.equal(printSchema(mergedSchema)); + expect(printSchema(schema)).toBe(printSchema(mergedSchema)); } - expect(response.data?.getInput).to.equal('test'); + expect(response.data?.getInput).toBe('test'); }); - it('can override scalars with new internal values', async () => { + test('can override scalars with new internal values', async () => { const schema = makeExecutableSchema({ typeDefs: ` scalar TestScalar @@ -1610,17 +1614,17 @@ type Query { const query = '{ getTestScalar }'; const response = await graphql(mergedSchema, query); - expect(response.data?.getTestScalar).to.equal('test'); + expect(response.data?.getTestScalar).toBe('test'); }); - it('can override scalars with new internal values when using default input types', async () => { + test('can override scalars with new internal values when using default input types', async () => { const schema = makeExecutableSchema({ typeDefs: ` - scalar TestScalar - type Query { - getTestScalar(input: TestScalar = "test"): TestScalar - } - `, + scalar TestScalar + type Query { + getTestScalar(input: TestScalar = "test"): TestScalar + } + `, resolvers: { TestScalar: new GraphQLScalarType({ name: 'TestScalar', @@ -1650,10 +1654,10 @@ type Query { const query = '{ getTestScalar }'; const response = await graphql(mergedSchema, query); - expect(response.data?.getTestScalar).to.equal('test'); + expect(response.data?.getTestScalar).toBe('test'); }); - it('can use @include directives', async () => { + test('can use @include directives', async () => { const schema = makeExecutableSchema({ typeDefs: ` type WrappingType { @@ -1700,10 +1704,10 @@ type Query { } `; const response = await graphql(mergedSchema, query); - expect(response.data?.get2.subfield).to.equal('test'); + expect(response.data?.get2.subfield).toBe('test'); }); - it('can use functions in subfields', async () => { + test('can use functions in subfields', async () => { const schema = makeExecutableSchema({ typeDefs: ` type WrappingObject { @@ -1728,7 +1732,7 @@ type Query { const query = '{ wrappingObject { functionField } }'; const response = await graphql(mergedSchema, query); - expect(response.data?.wrappingObject.functionField).to.equal(8); + expect(response.data?.wrappingObject.functionField).toBe(8); }); }); @@ -1786,36 +1790,36 @@ describe('onTypeConflict', () => { }); }); - it('by default takes last type', async () => { + test('by default takes last type', async () => { const mergedSchema = mergeSchemas({ schemas: [schema1, schema2], }); const result1 = await graphql(mergedSchema, '{ test2 { fieldC } }'); - expect(result1.data?.test2.fieldC).to.equal('C'); + expect(result1.data?.test2.fieldC).toBe('C'); const result2 = await graphql(mergedSchema, '{ test2 { fieldB } }'); - expect(result2.data).to.equal(undefined); + expect(result2.data).toBeUndefined(); }); - it('can use onTypeConflict to select last type', async () => { + test('can use onTypeConflict to select last type', async () => { const mergedSchema = mergeSchemas({ schemas: [schema1, schema2], onTypeConflict: (_left, right) => right, }); const result1 = await graphql(mergedSchema, '{ test2 { fieldC } }'); - expect(result1.data?.test2.fieldC).to.equal('C'); + expect(result1.data?.test2.fieldC).toBe('C'); const result2 = await graphql(mergedSchema, '{ test2 { fieldB } }'); - expect(result2.data).to.equal(undefined); + expect(result2.data).toBeUndefined(); }); - it('can use onTypeConflict to select first type', async () => { + test('can use onTypeConflict to select first type', async () => { const mergedSchema = mergeSchemas({ schemas: [schema1, schema2], onTypeConflict: (left) => left, }); const result1 = await graphql(mergedSchema, '{ test1 { fieldB } }'); - expect(result1.data?.test1.fieldB).to.equal('B'); + expect(result1.data?.test1.fieldB).toBe('B'); const result2 = await graphql(mergedSchema, '{ test1 { fieldC } }'); - expect(result2.data).to.equal(undefined); + expect(result2.data).toBeUndefined(); }); }); @@ -1883,7 +1887,7 @@ describe('mergeTypes', () => { }); }); - it('can merge types', async () => { + test('can merge types', async () => { const subschemaConfig1: SubschemaConfig = { schema: schema1, merge: { @@ -1943,7 +1947,7 @@ describe('mergeTypes', () => { } `, ); - expect(result1).to.deep.equal({ + expect(result1).toEqual({ data: { rootField1: { test: { diff --git a/src/test/testDataloader.ts b/src/test/dataloader.test.ts similarity index 93% rename from src/test/testDataloader.ts rename to src/test/dataloader.test.ts index 307f79a6f49..0e67723e994 100644 --- a/src/test/testDataloader.ts +++ b/src/test/dataloader.test.ts @@ -1,6 +1,5 @@ import DataLoader from 'dataloader'; import { graphql, GraphQLList } from 'graphql'; -import { expect } from 'chai'; import { delegateToSchema } from '../delegate/index'; import { makeExecutableSchema } from '../generate/index'; @@ -8,7 +7,7 @@ import { mergeSchemas } from '../stitch/index'; import { IGraphQLToolsResolveInfo } from '../Interfaces'; describe('dataloader', () => { - it('should work', async () => { + test('should work', async () => { const taskSchema = makeExecutableSchema({ typeDefs: ` type Task { @@ -82,12 +81,12 @@ describe('dataloader', () => { returnType: new GraphQLList(keys[0].info.returnType), }); - expect(users).to.deep.equal([ - { + expect(users).toContainEqual( + expect.objectContaining({ id: '1', email: '1@tasks.com', - }, - ]); + }), + ); return users; }, @@ -106,7 +105,7 @@ describe('dataloader', () => { const result = await graphql(schema, query, null, { usersLoader }); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { task: { id: '1', diff --git a/src/test/testDelegateToSchema.ts b/src/test/delegateToSchema.test.ts similarity index 91% rename from src/test/testDelegateToSchema.ts rename to src/test/delegateToSchema.test.ts index c94718fdf72..f54366a5ff3 100644 --- a/src/test/testDelegateToSchema.ts +++ b/src/test/delegateToSchema.test.ts @@ -1,5 +1,4 @@ import { GraphQLSchema, graphql } from 'graphql'; -import { expect } from 'chai'; import delegateToSchema from '../delegate/delegateToSchema'; import mergeSchemas from '../stitch/mergeSchemas'; @@ -12,7 +11,7 @@ import { bookingSchema, sampleData, Property, -} from './testingSchemas'; +} from './fixtures/schemas'; function findPropertyByLocationName( properties: { [key: string]: Property }, @@ -86,13 +85,13 @@ describe('stitching', () => { ['standalone', 'info.mergeInfo'].forEach((spec) => { describe(spec, () => { let schema: GraphQLSchema; - before(() => { + beforeAll(() => { schema = mergeSchemas({ schemas: [bookingSchema, propertySchema, proxyTypeDefs], resolvers: proxyResolvers(spec), }); }); - it('should add fragments for deep types', async () => { + test('should add fragments for deep types', async () => { const result = await graphql( schema, COORDINATES_QUERY, @@ -101,7 +100,7 @@ describe('stitching', () => { { bookingId: 'b1' }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { bookingById: { property: { @@ -119,7 +118,7 @@ describe('stitching', () => { }); describe('schema delegation', () => { - it('should work even when there are default fields', async () => { + test('should work even when there are default fields', async () => { const schema = makeExecutableSchema({ typeDefs: ` scalar JSON @@ -158,7 +157,7 @@ describe('schema delegation', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { data: { json: 'test', @@ -167,7 +166,7 @@ describe('schema delegation', () => { }); }); - it('should work even with variables', async () => { + test('should work even with variables', async () => { const innerSchema = makeExecutableSchema({ typeDefs: ` type User { @@ -202,7 +201,7 @@ describe('schema delegation', () => { { show: true }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { user: { id: '123', diff --git a/src/test/testDirectives.ts b/src/test/directives.test.ts similarity index 82% rename from src/test/testDirectives.ts rename to src/test/directives.test.ts index 276aa0b4715..95ea8c34b33 100644 --- a/src/test/testDirectives.ts +++ b/src/test/directives.test.ts @@ -26,7 +26,6 @@ import { isListType, TypeSystemExtensionNode, } from 'graphql'; -import { assert } from 'chai'; import formatDate from 'dateformat'; import { makeExecutableSchema } from '../generate/index'; @@ -156,7 +155,7 @@ ${ `; describe('@directives', () => { - it('are included in the schema AST', () => { + test('are included in the schema AST', () => { const schema = makeExecutableSchema({ typeDefs, resolvers: { @@ -173,13 +172,12 @@ describe('@directives', () => { typeDirectiveNames: Array, fieldDirectiveMap: { [key: string]: Array } = {}, ) { - assert.deepEqual(getDirectiveNames(type), typeDirectiveNames); + expect(getDirectiveNames(type)).toEqual(typeDirectiveNames); Object.keys(fieldDirectiveMap).forEach((key) => { - assert.deepEqual( + expect( getDirectiveNames((type as GraphQLObjectType).getFields()[key]), - fieldDirectiveMap[key], - ); + ).toEqual(fieldDirectiveMap[key]); }); } @@ -198,8 +196,7 @@ describe('@directives', () => { return directives; } - assert.deepEqual( - getDirectiveNames(schema), + expect(getDirectiveNames(schema)).toEqual( graphqlVersion() >= 14 ? ['schemaDirective', 'schemaExtensionDirective'] : ['schemaDirective'], @@ -215,8 +212,7 @@ describe('@directives', () => { }, ); - assert.deepEqual( - getDirectiveNames(schema.getType('Gender')), + expect(getDirectiveNames(schema.getType('Gender'))).toEqual( graphqlVersion() >= 14 ? ['enumTypeDirective', 'enumTypeExtensionDirective'] : ['enumTypeDirective'], @@ -225,7 +221,7 @@ describe('@directives', () => { const nonBinary = (schema.getType( 'Gender', ) as GraphQLEnumType).getValues()[0]; - assert.deepEqual(getDirectiveNames(nonBinary), ['enumValueDirective']); + expect(getDirectiveNames(nonBinary)).toEqual(['enumValueDirective']); checkDirectives( schema.getType('Date') as GraphQLObjectType, @@ -264,10 +260,9 @@ describe('@directives', () => { addPerson: ['mutationMethodDirective'], }, ); - assert.deepEqual( + expect( getDirectiveNames(schema.getMutationType().getFields().addPerson.args[0]), - ['mutationArgumentDirective'], - ); + ).toEqual(['mutationArgumentDirective']); checkDirectives( schema.getType('Person'), @@ -288,7 +283,7 @@ describe('@directives', () => { ); }); - it('works with enum and its resolvers', () => { + test('works with enum and its resolvers', () => { const schema = makeExecutableSchema({ typeDefs: ` enum DateFormat { @@ -312,12 +307,12 @@ describe('@directives', () => { }, }); - assert.exists(schema.getType('DateFormat')); - assert.lengthOf(schema.getDirectives(), 4); - assert.exists(schema.getDirective('date')); + expect(schema.getType('DateFormat')).toBeDefined(); + expect(schema.getDirectives()).toHaveLength(4); + expect(schema.getDirective('date')).toBeDefined(); }); - it('can be implemented with SchemaDirectiveVisitor', () => { + test('can be implemented with SchemaDirectiveVisitor', () => { const visited: Set = new Set(); const schema = makeExecutableSchema({ typeDefs }); @@ -326,23 +321,23 @@ describe('@directives', () => { queryTypeDirective: class extends SchemaDirectiveVisitor { public static description = 'A @directive for query object types'; public visitObject(object: GraphQLObjectType) { - assert.strictEqual(object, schema.getQueryType()); + expect(object).toBe(schema.getQueryType()); visited.add(object); } }, queryTypeExtensionDirective: class extends SchemaDirectiveVisitor { public static description = 'A @directive for query object types'; public visitObject(object: GraphQLObjectType) { - assert.strictEqual(object, schema.getQueryType()); + expect(object).toBe(schema.getQueryType()); visited.add(object); } }, }); - assert.strictEqual(visited.size, 1); + expect(visited.size).toBe(1); }); - it('can visit the schema itself', () => { + test('can visit the schema itself', () => { const visited: Array = []; const schema = makeExecutableSchema({ typeDefs }); SchemaDirectiveVisitor.visitSchemaDirectives(schema, { @@ -357,14 +352,14 @@ describe('@directives', () => { } }, }); - assert.strictEqual(visited.length, graphqlVersion() >= 14 ? 2 : 1); - assert.strictEqual(visited[0], schema); + expect(visited.length).toBe(graphqlVersion() >= 14 ? 2 : 1); + expect(visited[0]).toBe(schema); if (graphqlVersion() >= 14) { - assert.strictEqual(visited[1], schema); + expect(visited[1]).toBe(schema); } }); - it('can visit fields within object types', () => { + test('can visit fields within object types', () => { const schema = makeExecutableSchema({ typeDefs }); let mutationObjectType: GraphQLObjectType; @@ -376,16 +371,16 @@ describe('@directives', () => { mutationTypeDirective: class extends SchemaDirectiveVisitor { public visitObject(object: GraphQLObjectType) { mutationObjectType = object; - assert.strictEqual(this.visitedType, object); - assert.strictEqual(object.name, 'Mutation'); + expect(this.visitedType).toBe(object); + expect(object.name).toBe('Mutation'); } }, mutationTypeExtensionDirective: class extends SchemaDirectiveVisitor { public visitObject(object: GraphQLObjectType) { mutationObjectType = object; - assert.strictEqual(this.visitedType, object); - assert.strictEqual(object.name, 'Mutation'); + expect(this.visitedType).toBe(object); + expect(object.name).toBe('Mutation'); } }, @@ -396,10 +391,10 @@ describe('@directives', () => { objectType: GraphQLObjectType; }, ) { - assert.strictEqual(this.visitedType, field); - assert.strictEqual(field.name, 'addPerson'); - assert.strictEqual(details.objectType, mutationObjectType); - assert.strictEqual(field.args.length, 1); + expect(this.visitedType).toBe(field); + expect(field.name).toBe('addPerson'); + expect(details.objectType).toBe(mutationObjectType); + expect(field.args.length).toBe(1); mutationField = field; } }, @@ -412,26 +407,26 @@ describe('@directives', () => { objectType: GraphQLObjectType; }, ) { - assert.strictEqual(this.visitedType, arg); - assert.strictEqual(arg.name, 'input'); - assert.strictEqual(details.field, mutationField); - assert.strictEqual(details.objectType, mutationObjectType); - assert.strictEqual(details.field.args[0], arg); + expect(this.visitedType).toBe(arg); + expect(arg.name).toBe('input'); + expect(details.field).toBe(mutationField); + expect(details.objectType).toBe(mutationObjectType); + expect(details.field.args[0]).toBe(arg); } }, enumTypeDirective: class extends SchemaDirectiveVisitor { public visitEnum(enumType: GraphQLEnumType) { - assert.strictEqual(this.visitedType, enumType); - assert.strictEqual(enumType.name, 'Gender'); + expect(this.visitedType).toBe(enumType); + expect(enumType.name).toBe('Gender'); enumObjectType = enumType; } }, enumTypeExtensionDirective: class extends SchemaDirectiveVisitor { public visitEnum(enumType: GraphQLEnumType) { - assert.strictEqual(this.visitedType, enumType); - assert.strictEqual(enumType.name, 'Gender'); + expect(this.visitedType).toBe(enumType); + expect(enumType.name).toBe('Gender'); enumObjectType = enumType; } }, @@ -443,26 +438,26 @@ describe('@directives', () => { enumType: GraphQLEnumType; }, ) { - assert.strictEqual(this.visitedType, value); - assert.strictEqual(value.name, 'NONBINARY'); - assert.strictEqual(value.value, 'NONBINARY'); - assert.strictEqual(details.enumType, enumObjectType); + expect(this.visitedType).toBe(value); + expect(value.name).toBe('NONBINARY'); + expect(value.value).toBe('NONBINARY'); + expect(details.enumType).toBe(enumObjectType); } }, inputTypeDirective: class extends SchemaDirectiveVisitor { public visitInputObject(object: GraphQLInputObjectType) { inputObjectType = object; - assert.strictEqual(this.visitedType, object); - assert.strictEqual(object.name, 'PersonInput'); + expect(this.visitedType).toBe(object); + expect(object.name).toBe('PersonInput'); } }, inputTypeExtensionDirective: class extends SchemaDirectiveVisitor { public visitInputObject(object: GraphQLInputObjectType) { inputObjectType = object; - assert.strictEqual(this.visitedType, object); - assert.strictEqual(object.name, 'PersonInput'); + expect(this.visitedType).toBe(object); + expect(object.name).toBe('PersonInput'); } }, @@ -473,15 +468,15 @@ describe('@directives', () => { objectType: GraphQLInputObjectType; }, ) { - assert.strictEqual(this.visitedType, field); - assert.strictEqual(field.name, 'name'); - assert.strictEqual(details.objectType, inputObjectType); + expect(this.visitedType).toBe(field); + expect(field.name).toBe('name'); + expect(details.objectType).toBe(inputObjectType); } }, }); }); - it('can check if a visitor method is implemented', () => { + test('can check if a visitor method is implemented', () => { class Visitor extends SchemaVisitor { // eslint-disable-next-line @typescript-eslint/no-empty-function public notVisitorMethod() {} @@ -491,25 +486,18 @@ describe('@directives', () => { } } - assert.strictEqual( - Visitor.implementsVisitorMethod('notVisitorMethod'), - false, - ); + expect(Visitor.implementsVisitorMethod('notVisitorMethod')).toBe(false); - assert.strictEqual(Visitor.implementsVisitorMethod('visitObject'), true); + expect(Visitor.implementsVisitorMethod('visitObject')).toBe(true); - assert.strictEqual( - Visitor.implementsVisitorMethod('visitInputFieldDefinition'), + expect(Visitor.implementsVisitorMethod('visitInputFieldDefinition')).toBe( false, ); - assert.strictEqual( - Visitor.implementsVisitorMethod('visitBogusType'), - false, - ); + expect(Visitor.implementsVisitorMethod('visitBogusType')).toBe(false); }); - it('can use visitSchema for simple visitor patterns', () => { + test('can use visitSchema for simple visitor patterns', () => { class SimpleVisitor extends SchemaVisitor { public visitCount = 0; public names: Array = []; @@ -527,7 +515,7 @@ describe('@directives', () => { } public visitObject(object: GraphQLObjectType) { - assert.strictEqual(this.schema.getType(object.name), object); + expect(this.schema.getType(object.name)).toBe(object); this.names.push(object.name); } } @@ -535,13 +523,14 @@ describe('@directives', () => { const schema = makeExecutableSchema({ typeDefs }); const visitor = new SimpleVisitor(schema); visitor.visit(); - assert.deepEqual( - visitor.names.sort((a, b) => a.localeCompare(b)), - ['Mutation', 'Person', 'Query'], - ); + expect(visitor.names.sort((a, b) => a.localeCompare(b))).toEqual([ + 'Mutation', + 'Person', + 'Query', + ]); }); - it('can use SchemaDirectiveVisitor as a no-op visitor', () => { + test('can use SchemaDirectiveVisitor as a no-op visitor', () => { const schema = makeExecutableSchema({ typeDefs }); const methodNamesEncountered = Object.create(null); @@ -574,15 +563,16 @@ describe('@directives', () => { unionDirective: EnthusiasticVisitor, }); - assert.deepEqual( + expect( Object.keys(methodNamesEncountered).sort((a, b) => a.localeCompare(b)), + ).toEqual( Object.keys(SchemaVisitor.prototype) .filter((name) => name.startsWith('visit')) .sort((a, b) => a.localeCompare(b)), ); }); - it('can handle declared arguments', () => { + test('can handle declared arguments', () => { const schemaText = ` directive @oyez( times: Int = 5, @@ -618,7 +608,7 @@ describe('@directives', () => { name: string, theSchema: GraphQLSchema, ) { - assert.strictEqual(theSchema, schema); + expect(theSchema).toBe(schema); const prev = schema.getDirective(name); prev.args.some((arg) => { if (arg.name === 'times') { @@ -634,37 +624,36 @@ describe('@directives', () => { public visitObject() { ++this.context.objectCount; - assert.strictEqual(this.args.times, 3); + expect(this.args.times).toBe(3); } public visitFieldDefinition(field: GraphQLField) { ++this.context.fieldCount; if (field.name === 'judge') { - assert.strictEqual(this.args.times, 0); + expect(this.args.times).toBe(0); } else if (field.name === 'marshall') { - assert.strictEqual(this.args.times, 3); + expect(this.args.times).toBe(3); } - assert.strictEqual(this.args.party, 'IMPARTIAL'); + expect(this.args.party).toBe('IMPARTIAL'); } }, }, context, ); - assert.strictEqual(context.objectCount, 1); - assert.strictEqual(context.fieldCount, 2); + expect(context.objectCount).toBe(1); + expect(context.fieldCount).toBe(2); - assert.deepEqual(Object.keys(visitors), ['oyez']); - assert.deepEqual( + expect(Object.keys(visitors)).toEqual(['oyez']); + expect( visitors.oyez.map( (v) => (v.visitedType as GraphQLObjectType | GraphQLField).name, ), - ['Courtroom', 'judge', 'marshall'], - ); + ).toEqual(['Courtroom', 'judge', 'marshall']); }); - it('can be used to implement the @upper example', () => { + test('can be used to implement the @upper example', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @upper on FIELD_DEFINITION @@ -703,13 +692,13 @@ describe('@directives', () => { } `, ).then(({ data }) => { - assert.deepEqual(data, { + expect(data).toEqual({ hello: 'HELLO WORLD', }); }); }); - it('can be used to implement the @date example', () => { + test('can be used to implement the @date example', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @date(format: String) on FIELD_DEFINITION @@ -751,13 +740,13 @@ describe('@directives', () => { } `, ).then(({ data }) => { - assert.deepEqual(data, { + expect(data).toEqual({ today: 'February 26, 2018', }); }); }); - it('can be used to implement the @date by adding an argument', async () => { + test('can be used to implement the @date by adding an argument', async () => { class FormattableDateDirective extends SchemaDirectiveVisitor { public visitFieldDefinition(field: GraphQLField) { const { resolve = defaultFieldResolver } = field; @@ -812,10 +801,10 @@ describe('@directives', () => { const resultNoArg = await graphql(schema, 'query { today }'); if (resultNoArg.errors != null) { - assert.deepEqual(resultNoArg.errors, []); + expect(resultNoArg.errors).toEqual([]); } - assert.deepEqual(resultNoArg.data, { today: 'March 15, 2018' }); + expect(resultNoArg.data).toEqual({ today: 'March 15, 2018' }); const resultWithArg = await graphql( schema, @@ -827,17 +816,17 @@ describe('@directives', () => { ); if (resultWithArg.errors != null) { - assert.deepEqual(resultWithArg.errors, []); + expect(resultWithArg.errors).toEqual([]); } - assert.deepEqual(resultWithArg.data, { today: '15 Mar 2018' }); + expect(resultWithArg.data).toEqual({ today: '15 Mar 2018' }); }); - it('can be used to implement the @intl example', () => { + test('can be used to implement the @intl example', () => { function translate(text: string, path: Array, locale: string) { - assert.strictEqual(text, 'hello'); - assert.deepEqual(path, ['Query', 'greeting']); - assert.strictEqual(locale, 'fr'); + expect(text).toBe('hello'); + expect(path).toEqual(['Query', 'greeting']); + expect(locale).toBe('fr'); return 'bonjour'; } @@ -866,7 +855,7 @@ describe('@directives', () => { const defaultText = await resolve.apply(this, args); // In this example, path would be ["Query", "greeting"]: const path = [details.objectType.name, field.name]; - assert.strictEqual(args[2], context); + expect(args[2]).toBe(context); return translate(defaultText, path, context.locale); }; } @@ -892,13 +881,13 @@ describe('@directives', () => { null, context, ).then(({ data }) => { - assert.deepEqual(data, { + expect(data).toEqual({ greeting: 'bonjour', }); }); }); - it('can be used to implement the @auth example', async () => { + test('can be used to implement the @auth example', async () => { const roles = ['UNKNOWN', 'USER', 'REVIEWER', 'ADMIN']; function getUser(token: string) { @@ -1037,11 +1026,12 @@ describe('@directives', () => { errors: Array; data: any; }) { - assert.strictEqual(errors.length, expectedCount); - assert(errors.every((error) => error.message === 'not authorized')); + expect(errors.length).toBe(expectedCount); + expect( + errors.every((error) => error.message === 'not authorized'), + ).toBeTruthy(); const actualNames = errors.map((error) => error.path.slice(-1)[0]); - assert.deepEqual( - expectedNames.sort((a, b) => a.localeCompare(b)), + expect(expectedNames.sort((a, b) => a.localeCompare(b))).toEqual( actualNames.sort((a, b) => a.localeCompare(b)), ); return data; @@ -1055,15 +1045,15 @@ describe('@directives', () => { execWithRole('ADMIN') .then(checkErrors(0)) .then((data) => { - assert.strictEqual(data.users.length, 1); - assert.strictEqual(data.users[0].banned, true); - assert.strictEqual(data.users[0].canPost, false); - assert.strictEqual(data.users[0].name, 'Ben'); + expect(data.users.length).toBe(1); + expect(data.users[0].banned).toBe(true); + expect(data.users[0].canPost).toBe(false); + expect(data.users[0].name).toBe('Ben'); }), ]); }); - it('can be used to implement the @length example', async () => { + test('can be used to implement the @length example', async () => { class LimitedLengthType extends GraphQLScalarType { constructor(type: GraphQLScalarType, maxLength: number) { super({ @@ -1071,8 +1061,12 @@ describe('@directives', () => { serialize(value: string) { const newValue = type.serialize(value); - assert.strictEqual(typeof newValue.length, 'number'); - assert.isAtMost(newValue.length, maxLength); + expect(typeof newValue.length).toBe('number'); + if (newValue.length > maxLength) { + throw new Error( + `expected ${newValue.length} to be at most ${maxLength}`, + ); + } return newValue; }, @@ -1159,8 +1153,8 @@ describe('@directives', () => { } `, ); - assert.strictEqual(errors.length, 1); - assert.strictEqual(errors[0].message, 'expected 26 to be at most 10'); + expect(errors.length).toBe(1); + expect(errors[0].message).toBe('expected 26 to be at most 10'); const result = await graphql( schema, @@ -1174,17 +1168,17 @@ describe('@directives', () => { ); if (result.errors != null) { - assert.deepEqual(result.errors, []); + expect(result.errors).toEqual([]); } - assert.deepEqual(result.data, { + expect(result.data).toEqual({ createBook: { title: 'safe title', }, }); }); - it('can be used to implement the @uniqueID example', () => { + test('can be used to implement the @uniqueID example', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @uniqueID(name: String, from: [String]) on OBJECT @@ -1265,11 +1259,11 @@ describe('@directives', () => { } `, null, - context, + {}, ).then((result) => { const { data } = result; - assert.deepEqual(data.people, [ + expect(data.people).toEqual([ { uid: '580a207c8e94f03b93a2b01217c3cc218490571a', personID: 1, @@ -1277,7 +1271,7 @@ describe('@directives', () => { }, ]); - assert.deepEqual(data.locations, [ + expect(data.locations).toEqual([ { uid: 'c31b71e6e23a7ae527f94341da333590dd7cba96', locationID: 1, @@ -1287,7 +1281,7 @@ describe('@directives', () => { }); }); - it('automatically updates references to changed types', () => { + test('automatically updates references to changed types', () => { const schema = makeExecutableSchema({ typeDefs, schemaDirectives: { @@ -1304,33 +1298,32 @@ describe('@directives', () => { const Query = schema.getType('Query') as GraphQLObjectType; const peopleType = Query.getFields().people.type; if (isListType(peopleType)) { - assert.strictEqual(peopleType.ofType, schema.getType('Human')); + expect(peopleType.ofType).toBe(schema.getType('Human')); } else { throw new Error('Query.people not a GraphQLList type'); } const Mutation = schema.getType('Mutation') as GraphQLObjectType; const addPersonResultType = Mutation.getFields().addPerson.type; - assert.strictEqual( - addPersonResultType, + expect(addPersonResultType).toBe( schema.getType('Human') as GraphQLOutputType, ); const WhateverUnion = schema.getType('WhateverUnion') as GraphQLUnionType; const found = WhateverUnion.getTypes().some((type) => { if (type.name === 'Human') { - assert.strictEqual(type, schema.getType('Human')); + expect(type).toBe(schema.getType('Human')); return true; } return false; }); - assert.strictEqual(found, true); + expect(found).toBe(true); // Make sure that the Person type was actually removed. - assert.strictEqual(typeof schema.getType('Person'), 'undefined'); + expect(typeof schema.getType('Person')).toBe('undefined'); }); - it('can remove enum values', () => { + test('can remove enum values', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @remove(if: Boolean) on ENUM_VALUE @@ -1357,13 +1350,13 @@ describe('@directives', () => { }); const AgeUnit = schema.getType('AgeUnit') as GraphQLEnumType; - assert.deepEqual( - AgeUnit.getValues().map((value) => value.name), - ['DOG_YEARS', 'PERSON_YEARS'], - ); + expect(AgeUnit.getValues().map((value) => value.name)).toEqual([ + 'DOG_YEARS', + 'PERSON_YEARS', + ]); }); - it('can swap names of GraphQLNamedType objects', () => { + test('can swap names of GraphQLNamedType objects', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @rename(to: String) on OBJECT @@ -1392,13 +1385,12 @@ describe('@directives', () => { }); const Human = schema.getType('Human') as GraphQLObjectType; - assert.strictEqual(Human.name, 'Human'); - assert.strictEqual(Human.getFields().heightInInches.type, GraphQLInt); + expect(Human.name).toBe('Human'); + expect(Human.getFields().heightInInches.type).toBe(GraphQLInt); const Person = schema.getType('Person') as GraphQLObjectType; - assert.strictEqual(Person.name, 'Person'); - assert.strictEqual( - Person.getFields().born.type, + expect(Person.name).toBe('Person'); + expect(Person.getFields().born.type).toBe( schema.getType('Date') as GraphQLScalarType, ); @@ -1406,10 +1398,10 @@ describe('@directives', () => { const peopleType = Query.getFields().people.type as GraphQLList< GraphQLObjectType >; - assert.strictEqual(peopleType.ofType, Human); + expect(peopleType.ofType).toBe(Human); }); - it('does not enforce query directive locations (issue #680)', () => { + test('does not enforce query directive locations (issue #680)', () => { const visited = new Set(); makeExecutableSchema({ typeDefs: ` @@ -1422,25 +1414,25 @@ describe('@directives', () => { schemaDirectives: { hasScope: class extends SchemaDirectiveVisitor { public visitObject(object: GraphQLObjectType) { - assert.strictEqual(object.name, 'Query'); + expect(object.name).toBe('Query'); visited.add(object); } }, }, }); - assert.strictEqual(visited.size, 1); + expect(visited.size).toBe(1); }); - it('allows multiple directives when first replaces type (issue #851)', () => { + test('allows multiple directives when first replaces type (issue #851)', () => { const schema = makeExecutableSchema({ typeDefs: ` - directive @upper on FIELD_DEFINITION - directive @reverse on FIELD_DEFINITION + directive @upper on FIELD_DEFINITION + directive @reverse on FIELD_DEFINITION - type Query { - hello: String @upper @reverse - }`, + type Query { + hello: String @upper @reverse + }`, schemaDirectives: { upper: class extends SchemaDirectiveVisitor { public visitFieldDefinition(field: GraphQLField) { @@ -1488,7 +1480,7 @@ describe('@directives', () => { } `, ).then(({ data }) => { - assert.deepEqual(data, { + expect(data).toEqual({ hello: 'DLROW OLLEH', }); }); diff --git a/src/test/testErrors.ts b/src/test/errors.test.ts similarity index 82% rename from src/test/testErrors.ts rename to src/test/errors.test.ts index c43e77dc3ae..bc041cde543 100644 --- a/src/test/testErrors.ts +++ b/src/test/errors.test.ts @@ -1,4 +1,3 @@ -import { expect, assert } from 'chai'; import { GraphQLError, graphql } from 'graphql'; import { relocatedError } from '../stitch/errors'; @@ -16,7 +15,7 @@ class ErrorWithExtensions extends GraphQLError { describe('Errors', () => { describe('relocatedError', () => { - it('should adjust the path of a GraphqlError', () => { + test('should adjust the path of a GraphqlError', () => { const originalError = new GraphQLError('test', null, null, null, [ 'test', ]); @@ -25,22 +24,22 @@ describe('Errors', () => { 'test', 1, ]); - assert.deepEqual(newError, expectedError); + expect(newError).toEqual(expectedError); }); - it('should also locate a non GraphQLError', () => { + test('should also locate a non GraphQLError', () => { const originalError = new Error('test'); const newError = relocatedError(originalError, null, ['test', 1]); const expectedError = new GraphQLError('test', null, null, null, [ 'test', 1, ]); - assert.deepEqual(newError, expectedError); + expect(newError).toEqual(expectedError); }); }); describe('getErrors', () => { - it('should return all errors including if path is not defined', () => { + test('should return all errors including if path is not defined', () => { const error = { message: 'Test error without path', }; @@ -49,14 +48,14 @@ describe('Errors', () => { [ERROR_SYMBOL]: [error], }; - assert.deepEqual(getErrors(mockErrors, 'responseKey'), [ + expect(getErrors(mockErrors, 'responseKey')).toEqual([ mockErrors[ERROR_SYMBOL][0], ]); }); }); describe('checkResultAndHandleErrors', () => { - it('persists single error', () => { + test('persists single error', () => { const result = { errors: [new GraphQLError('Test error')], }; @@ -68,12 +67,12 @@ describe('Errors', () => { 'responseKey', ); } catch (e) { - assert.equal(e.message, 'Test error'); - assert.isUndefined(e.originalError.errors); + expect(e.message).toEqual('Test error'); + expect(e.originalError.errors).toBeUndefined(); } }); - it('persists single error with extensions', () => { + test('persists single error with extensions', () => { const result = { errors: [new ErrorWithExtensions('Test error', 'UNAUTHENTICATED')], }; @@ -85,13 +84,13 @@ describe('Errors', () => { 'responseKey', ); } catch (e) { - assert.equal(e.message, 'Test error'); - assert.equal(e.extensions && e.extensions.code, 'UNAUTHENTICATED'); - assert.isUndefined(e.originalError.errors); + expect(e.message).toEqual('Test error'); + expect(e.extensions && e.extensions.code).toEqual('UNAUTHENTICATED'); + expect(e.originalError.errors).toBeUndefined(); } }); - it('combines errors and persists the original errors', () => { + test('combines errors and persists the original errors', () => { const result = { errors: [new GraphQLError('Error1'), new GraphQLError('Error2')], }; @@ -103,12 +102,12 @@ describe('Errors', () => { 'responseKey', ); } catch (e) { - assert.equal(e.message, 'Error1\nError2'); - assert.isNotEmpty(e.originalError); - assert.isNotEmpty(e.originalError.errors); - assert.lengthOf(e.originalError.errors, result.errors.length); + expect(e.message).toEqual('Error1\nError2'); + expect(e.originalError).toBeDefined(); + expect(e.originalError.errors).toBeDefined(); + expect(e.originalError.errors).toHaveLength(result.errors.length); result.errors.forEach((error, i) => { - assert.deepEqual(e.originalError.errors[i], error); + expect(e.originalError.errors[i]).toEqual(error); }); } }); @@ -116,7 +115,7 @@ describe('Errors', () => { }); describe('passes along errors for missing fields on list', () => { - it('if non-null', async () => { + test('if non-null', async () => { const typeDefs = ` type Query { getOuter: Outer @@ -147,7 +146,7 @@ describe('passes along errors for missing fields on list', () => { mergedSchema, '{ getOuter { innerList { mandatoryField } } }', ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { getOuter: null, }, @@ -167,7 +166,7 @@ describe('passes along errors for missing fields on list', () => { }); }); - it('even if nullable', async () => { + test('even if nullable', async () => { const typeDefs = ` type Query { getOuter: Outer @@ -198,7 +197,7 @@ describe('passes along errors for missing fields on list', () => { mergedSchema, '{ getOuter { innerList { mandatoryField } } }', ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { getOuter: { innerList: [{ mandatoryField: 'test' }, null], @@ -222,7 +221,7 @@ describe('passes along errors for missing fields on list', () => { }); describe('passes along errors when list field errors', () => { - it('if non-null', async () => { + test('if non-null', async () => { const typeDefs = ` type Query { getOuter: Outer @@ -253,7 +252,7 @@ describe('passes along errors when list field errors', () => { mergedSchema, '{ getOuter { innerList { mandatoryField } } }', ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { getOuter: null, }, @@ -272,7 +271,7 @@ describe('passes along errors when list field errors', () => { }); }); - it('even if nullable', async () => { + test('even if nullable', async () => { const typeDefs = ` type Query { getOuter: Outer @@ -303,7 +302,7 @@ describe('passes along errors when list field errors', () => { mergedSchema, '{ getOuter { innerList { mandatoryField } } }', ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { getOuter: { innerList: [{ mandatoryField: 'test' }, null], diff --git a/src/test/testExtensionExtraction.ts b/src/test/extensionExtraction.test.ts similarity index 64% rename from src/test/testExtensionExtraction.ts rename to src/test/extensionExtraction.test.ts index ae726991f92..eb86d328b1d 100644 --- a/src/test/testExtensionExtraction.ts +++ b/src/test/extensionExtraction.test.ts @@ -1,10 +1,9 @@ -import { expect } from 'chai'; import { parse } from 'graphql'; import { extractExtensionDefinitions } from '../generate/extensionDefinitions'; describe('Extension extraction', () => { - it('extracts extended inputs', () => { + test('extracts extended inputs', () => { const typeDefs = ` input Input { foo: String @@ -18,13 +17,11 @@ describe('Extension extraction', () => { const astDocument = parse(typeDefs); const extensionAst = extractExtensionDefinitions(astDocument); - expect(extensionAst.definitions).to.have.length(1); - expect(extensionAst.definitions[0].kind).to.equal( - 'InputObjectTypeExtension', - ); + expect(extensionAst.definitions).toHaveLength(1); + expect(extensionAst.definitions[0].kind).toBe('InputObjectTypeExtension'); }); - it('extracts extended unions', () => { + test('extracts extended unions', () => { const typeDefs = ` type Person { name: String! @@ -43,11 +40,11 @@ describe('Extension extraction', () => { const astDocument = parse(typeDefs); const extensionAst = extractExtensionDefinitions(astDocument); - expect(extensionAst.definitions).to.have.length(1); - expect(extensionAst.definitions[0].kind).to.equal('UnionTypeExtension'); + expect(extensionAst.definitions).toHaveLength(1); + expect(extensionAst.definitions[0].kind).toBe('UnionTypeExtension'); }); - it('extracts extended enums', () => { + test('extracts extended enums', () => { const typeDefs = ` enum Color { RED @@ -62,7 +59,7 @@ describe('Extension extraction', () => { const astDocument = parse(typeDefs); const extensionAst = extractExtensionDefinitions(astDocument); - expect(extensionAst.definitions).to.have.length(1); - expect(extensionAst.definitions[0].kind).to.equal('EnumTypeExtension'); + expect(extensionAst.definitions).toHaveLength(1); + expect(extensionAst.definitions[0].kind).toBe('EnumTypeExtension'); }); }); diff --git a/src/test/circularSchemaA.ts b/src/test/fixtures/circularSchemaA.ts similarity index 100% rename from src/test/circularSchemaA.ts rename to src/test/fixtures/circularSchemaA.ts diff --git a/src/test/circularSchemaB.ts b/src/test/fixtures/circularSchemaB.ts similarity index 100% rename from src/test/circularSchemaB.ts rename to src/test/fixtures/circularSchemaB.ts diff --git a/src/test/testingSchemas.ts b/src/test/fixtures/schemas.ts similarity index 98% rename from src/test/testingSchemas.ts rename to src/test/fixtures/schemas.ts index e161de0248f..cc31fd1e00a 100644 --- a/src/test/testingSchemas.ts +++ b/src/test/fixtures/schemas.ts @@ -18,10 +18,10 @@ import { } from 'graphql'; import { forAwaitEach } from 'iterall'; -import introspectSchema from '../stitch/introspectSchema'; -import { IResolvers, Fetcher, SubschemaConfig } from '../Interfaces'; -import { makeExecutableSchema } from '../generate/index'; -import { graphqlVersion } from '../utils/index'; +import introspectSchema from '../../stitch/introspectSchema'; +import { IResolvers, Fetcher, SubschemaConfig } from '../../Interfaces'; +import { makeExecutableSchema } from '../../generate/index'; +import { graphqlVersion } from '../../utils/index'; export type Location = { name: string; diff --git a/src/test/testFragmentsAreNotDuplicated.ts b/src/test/fragmentsAreNotDuplicated.test.ts similarity index 87% rename from src/test/testFragmentsAreNotDuplicated.ts rename to src/test/fragmentsAreNotDuplicated.test.ts index 97ff3086fef..2634cf6c7d8 100644 --- a/src/test/testFragmentsAreNotDuplicated.ts +++ b/src/test/fragmentsAreNotDuplicated.test.ts @@ -1,10 +1,9 @@ -import { expect } from 'chai'; import { ExecutionResult, graphql } from 'graphql'; import { addMocksToSchema, makeExecutableSchema, transformSchema } from '..'; describe('Merging schemas', () => { - it('should not throw `There can be only one fragment named "FieldName"` errors', async () => { + test('should not throw `There can be only one fragment named "FieldName"` errors', async () => { const originalSchema = makeExecutableSchema({ typeDefs: rawSchema, }); @@ -81,6 +80,6 @@ const variables = { function assertNoDuplicateFragmentErrors(result: ExecutionResult) { // Run assertion against each array element for better test failure output. if (result.errors != null) { - result.errors.forEach((error) => expect(error.message).to.equal('')); + result.errors.forEach((error) => expect(error.message).toBe('')); } } diff --git a/src/test/testGatsbyTransforms.ts b/src/test/gatsbyTransforms.test.ts similarity index 96% rename from src/test/testGatsbyTransforms.ts rename to src/test/gatsbyTransforms.test.ts index a4d802bc47b..0eac0f4186f 100644 --- a/src/test/testGatsbyTransforms.ts +++ b/src/test/gatsbyTransforms.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { GraphQLObjectType, GraphQLSchema, @@ -79,7 +78,7 @@ class StripNonQueryTransform { } describe('Gatsby transforms', () => { - it('work', async () => { + test('work', async () => { const schema = makeExecutableSchema({ typeDefs: ` directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT | INTERFACE @@ -146,7 +145,7 @@ describe('Gatsby transforms', () => { }), ]); - expect(transformedSchema).to.be.instanceOf(GraphQLSchema); + expect(transformedSchema).toBeInstanceOf(GraphQLSchema); const result = await graphql( transformedSchema, @@ -160,7 +159,7 @@ describe('Gatsby transforms', () => { } `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { countries: { language: { diff --git a/src/test/testLogger.ts b/src/test/logger.test.ts similarity index 84% rename from src/test/testLogger.ts rename to src/test/logger.test.ts index a4c09f0e50c..c7e1c0983e1 100644 --- a/src/test/testLogger.ts +++ b/src/test/logger.test.ts @@ -1,11 +1,10 @@ -import { assert } from 'chai'; import { graphql } from 'graphql'; import { makeExecutableSchema } from '../generate/index'; import { Logger } from '../generate/Logger'; describe('Logger', () => { - it('logs the errors', () => { + test('logs the errors', () => { const shorthand = ` type RootQuery { just_a_field: Int @@ -40,13 +39,13 @@ describe('Logger', () => { const expected0 = 'Error in resolver RootMutation.species\noops!'; const expected1 = 'Error in resolver RootMutation.stuff\noh noes!'; return graphql(jsSchema, testQuery).then(() => { - assert.equal(logger.errors.length, 2); - assert.equal(logger.errors[0].message, expected0); - assert.equal(logger.errors[1].message, expected1); + expect(logger.errors.length).toEqual(2); + expect(logger.errors[0].message).toEqual(expected0); + expect(logger.errors[1].message).toEqual(expected1); }); }); - it('also forwards the errors when you tell it to', () => { + test('also forwards the errors when you tell it to', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -73,11 +72,11 @@ describe('Logger', () => { }); const testQuery = '{ species }'; return graphql(jsSchema, testQuery).then(() => { - assert.equal(loggedErr, logger.errors[0]); + expect(loggedErr).toEqual(logger.errors[0]); }); }); - it('prints the errors when you want it to', () => { + test('prints the errors when you want it to', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -105,12 +104,12 @@ describe('Logger', () => { const testQuery = '{ q: species, p: species(name: "Peter") }'; return graphql(jsSchema, testQuery).then(() => { const allErrors = logger.printAllErrors(); - assert.match(allErrors, /oops/); - assert.match(allErrors, /Peter/); + expect(allErrors).toMatch(/oops/); + expect(allErrors).toMatch(/Peter/); }); }); - it('logs any Promise reject errors', () => { + test('logs any Promise reject errors', () => { const shorthand = ` type RootQuery { just_a_field: Int @@ -147,13 +146,13 @@ describe('Logger', () => { const expected0 = 'Error in resolver RootMutation.species\noops!'; const expected1 = 'Error in resolver RootMutation.stuff\noh noes!'; return graphql(jsSchema, testQuery).then(() => { - assert.equal(logger.errors.length, 2); - assert.equal(logger.errors[0].message, expected0); - assert.equal(logger.errors[1].message, expected1); + expect(logger.errors.length).toEqual(2); + expect(logger.errors[0].message).toEqual(expected0); + expect(logger.errors[1].message).toEqual(expected1); }); }); - it('all Promise rejects will log an Error', () => { + test('all Promise rejects will log an Error', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -183,7 +182,7 @@ describe('Logger', () => { const testQuery = '{ species }'; return graphql(jsSchema, testQuery).then(() => { - assert.equal(loggedErr, logger.errors[0]); + expect(loggedErr).toEqual(logger.errors[0]); }); }); }); diff --git a/src/test/testMakeRemoteExecutableSchema.ts b/src/test/makeRemoteExecutableSchema.test.ts similarity index 78% rename from src/test/testMakeRemoteExecutableSchema.ts rename to src/test/makeRemoteExecutableSchema.test.ts index d263724627f..5c08b2b919b 100644 --- a/src/test/testMakeRemoteExecutableSchema.ts +++ b/src/test/makeRemoteExecutableSchema.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { forAwaitEach } from 'iterall'; import { GraphQLSchema, @@ -15,11 +14,11 @@ import { subscriptionPubSubTrigger, subscriptionPubSub, makeSchemaRemoteFromLink, -} from '../test/testingSchemas'; +} from './fixtures/schemas'; describe('remote queries', () => { let schema: GraphQLSchema; - before(async () => { + beforeAll(async () => { const remoteSubschemaConfig = await makeSchemaRemoteFromLink( propertySchema, ); @@ -29,7 +28,7 @@ describe('remote queries', () => { }); }); - it('should work', async () => { + test('should work', async () => { const query = ` { interfaceTest(kind: ONE) { @@ -56,13 +55,13 @@ describe('remote queries', () => { }; const result = await graphql(schema, query); - expect(result).to.deep.equal(expected); + expect(result).toEqual(expected); }); }); describe('remote subscriptions', () => { let schema: GraphQLSchema; - before(async () => { + beforeAll(async () => { const remoteSubschemaConfig = await makeSchemaRemoteFromLink( subscriptionSchema, ); @@ -72,7 +71,7 @@ describe('remote subscriptions', () => { }); }); - it('should work', (done) => { + test('should work', (done) => { const mockNotification = { notifications: { text: 'Hello world', @@ -93,8 +92,8 @@ describe('remote subscriptions', () => { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result.data).to.deep.equal(mockNotification); + expect(result).toHaveProperty('data'); + expect(result.data).toEqual(mockNotification); if (!notificationCnt++) { done(); } @@ -107,7 +106,7 @@ describe('remote subscriptions', () => { .catch(done); }); - it('should work without triggering multiple times per notification', (done) => { + test('should work without triggering multiple times per notification', (done) => { const mockNotification = { notifications: { text: 'Hello world', @@ -115,20 +114,20 @@ describe('remote subscriptions', () => { }; const subscription = parse(` - subscription Subscription { - notifications { - text + subscription Subscription { + notifications { + text + } } - } - `); + `); let notificationCnt = 0; const sub1 = subscribe(schema, subscription).then((results) => { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result.data).to.deep.equal(mockNotification); + expect(result).toHaveProperty('data'); + expect(result.data).toEqual(mockNotification); notificationCnt++; }, ).catch(done); @@ -138,8 +137,8 @@ describe('remote subscriptions', () => { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result.data).to.deep.equal(mockNotification); + expect(result).toHaveProperty('data'); + expect(result.data).toEqual(mockNotification); }, ).catch(done); }); @@ -154,7 +153,7 @@ describe('remote subscriptions', () => { .catch(done); setTimeout(() => { - expect(notificationCnt).to.eq(2); + expect(notificationCnt).toBe(2); done(); }, 0); }) @@ -173,22 +172,22 @@ describe('respects buildSchema options', () => { scalar CustomScalar `; - it('without comment descriptions', () => { + test('without comment descriptions', () => { const remoteSchema = makeRemoteExecutableSchema({ schema }); const customScalar = remoteSchema.getType('CustomScalar'); - expect(customScalar.description).to.eq(undefined); + expect(customScalar.description).toBeUndefined(); }); - it('with comment descriptions', () => { + test('with comment descriptions', () => { const remoteSchema = makeRemoteExecutableSchema({ schema, buildSchemaOptions: { commentDescriptions: true }, }); const field = remoteSchema.getQueryType().getFields()['custom']; - expect(field.description).to.eq('Field description'); + expect(field.description).toBe('Field description'); const customScalar = remoteSchema.getType('CustomScalar'); - expect(customScalar.description).to.eq('Scalar description'); + expect(customScalar.description).toBe('Scalar description'); }); }); diff --git a/src/test/testMapSchema.ts b/src/test/mapSchema.test.ts similarity index 75% rename from src/test/testMapSchema.ts rename to src/test/mapSchema.test.ts index 6ae1aeb58a9..83eb115d120 100644 --- a/src/test/testMapSchema.ts +++ b/src/test/mapSchema.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { GraphQLObjectType, GraphQLSchema, graphqlSync } from 'graphql'; import { makeExecutableSchema, mapSchema } from '../index'; @@ -6,7 +5,7 @@ import { MapperKind } from '../Interfaces'; import { toConfig } from '../polyfills/index'; describe('mapSchema', () => { - it('does not throw', () => { + test('does not throw', () => { const schema = makeExecutableSchema({ typeDefs: ` type Query { @@ -16,10 +15,10 @@ describe('mapSchema', () => { }); const newSchema = mapSchema(schema, {}); - expect(newSchema).to.be.instanceOf(GraphQLSchema); + expect(newSchema).toBeInstanceOf(GraphQLSchema); }); - it('can add a resolver', () => { + test('can add a resolver', () => { const schema = makeExecutableSchema({ typeDefs: ` type Query { @@ -36,13 +35,13 @@ describe('mapSchema', () => { }, }); - expect(newSchema).to.be.instanceOf(GraphQLSchema); + expect(newSchema).toBeInstanceOf(GraphQLSchema); const result = graphqlSync(newSchema, '{ version }'); - expect(result.data.version).to.equal(1); + expect(result.data.version).toBe(1); }); - it('can change the root query name', () => { + test('can change the root query name', () => { const schema = makeExecutableSchema({ typeDefs: ` type Query { @@ -59,7 +58,7 @@ describe('mapSchema', () => { }, }); - expect(newSchema).to.be.instanceOf(GraphQLSchema); - expect(newSchema.getQueryType().name).to.equal('RootQuery'); + expect(newSchema).toBeInstanceOf(GraphQLSchema); + expect(newSchema.getQueryType().name).toBe('RootQuery'); }); }); diff --git a/src/test/testMergeSchemas.ts b/src/test/mergeSchemas.test.ts similarity index 90% rename from src/test/testMergeSchemas.ts rename to src/test/mergeSchemas.test.ts index f14258446e8..82091231b44 100644 --- a/src/test/testMergeSchemas.ts +++ b/src/test/mergeSchemas.test.ts @@ -1,5 +1,4 @@ import { forAwaitEach } from 'iterall'; -import { expect } from 'chai'; import { graphql, GraphQLSchema, @@ -36,7 +35,7 @@ import { remoteProductSchema, subscriptionPubSub, subscriptionPubSubTrigger, -} from './testingSchemas'; +} from './fixtures/schemas'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const removeLocations = ({ locations, ...rest }: any): any => ({ ...rest }); @@ -339,7 +338,7 @@ testCombinations.forEach((combination) => { let productSchema: GraphQLSchema | SubschemaConfig; let bookingSchema: GraphQLSchema | SubschemaConfig; - before(async () => { + beforeAll(async () => { propertySchema = await combination.property; bookingSchema = await combination.booking; productSchema = await combination.product; @@ -550,7 +549,7 @@ testCombinations.forEach((combination) => { }); describe('basic', () => { - it('works with context', async () => { + test('works with context', async () => { const propertyResult = await graphql( localPropertySchema, ` @@ -577,16 +576,16 @@ testCombinations.forEach((combination) => { }, ); - expect(propertyResult).to.deep.equal({ + expect(propertyResult).toEqual({ data: { contextTest: '"Foo"', }, }); - expect(mergedResult).to.deep.equal(propertyResult); + expect(mergedResult).toEqual(propertyResult); }); - it('works with custom scalars', async () => { + test('works with custom scalars', async () => { const propertyResult = await graphql( localPropertySchema, ` @@ -611,7 +610,7 @@ testCombinations.forEach((combination) => { `, ); - expect(propertyResult).to.deep.equal({ + expect(propertyResult).toEqual({ data: { dateTimeTest: '1987-09-25T12:00:00', test1: { foo: 'bar' }, @@ -619,10 +618,10 @@ testCombinations.forEach((combination) => { test3: '6', }, }); - expect(mergedResult).to.deep.equal(propertyResult); + expect(mergedResult).toEqual(propertyResult); }); - it('works with custom scalars', async () => { + test('works with custom scalars', async () => { const scalarResult = await graphql( scalarSchema, ` @@ -651,7 +650,7 @@ testCombinations.forEach((combination) => { `, ); - expect(scalarResult).to.deep.equal({ + expect(scalarResult).toEqual({ data: { testingScalar: { value: 'test', @@ -663,10 +662,10 @@ testCombinations.forEach((combination) => { ], }, }); - expect(mergedResult).to.deep.equal(scalarResult); + expect(mergedResult).toEqual(scalarResult); }); - it('works with custom enums', async () => { + test('works with custom enums', async () => { const enumResult = await graphql( enumSchema, ` @@ -737,7 +736,7 @@ testCombinations.forEach((combination) => { `, ); - expect(enumResult).to.deep.equal({ + expect(enumResult).toEqual({ data: { color: 'RED', numericEnum: 'TEST', @@ -770,10 +769,10 @@ testCombinations.forEach((combination) => { }, }, }); - expect(mergedResult).to.deep.equal(enumResult); + expect(mergedResult).toEqual(enumResult); }); - it('queries', async () => { + test('queries', async () => { const propertyFragment = ` propertyById(id: "p1") { id @@ -808,7 +807,7 @@ bookingById(id: "b1") { ${bookingFragment} }`, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { ...propertyResult.data, ...bookingResult.data, @@ -817,7 +816,7 @@ bookingById(id: "b1") { }); // Technically mutations are not idempotent, but they are in our test schemas - it('mutations', async () => { + test('mutations', async () => { const mutationFragment = ` mutation Mutation($input: BookingInput!) { addBooking(input: $input) { @@ -856,10 +855,10 @@ bookingById(id: "b1") { }, ); - expect(mergedResult).to.deep.equal(bookingResult); + expect(mergedResult).toEqual(bookingResult); }); - it('local subscriptions working in merged schema', (done) => { + test('local subscriptions working in merged schema', (done) => { const mockNotification = { notifications: { text: 'Hello world', @@ -880,8 +879,8 @@ bookingById(id: "b1") { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result.data).to.deep.equal(mockNotification); + expect(result).toHaveProperty('data'); + expect(result.data).toEqual(mockNotification); if (!notificationCnt++) { done(); } @@ -897,7 +896,7 @@ bookingById(id: "b1") { .catch(done); }); - it('subscription errors are working correctly in merged schema', (done) => { + test('subscription errors are working correctly in merged schema', (done) => { const mockNotification = { notifications: { text: 'Hello world', @@ -940,11 +939,11 @@ bookingById(id: "b1") { forAwaitEach( results as AsyncIterable, (result: ExecutionResult) => { - expect(result).to.have.property('data'); - expect(result).to.have.property('errors'); - expect(result.errors).to.have.lengthOf(1); - expect(result.errors).to.deep.equal(expectedResult.errors); - expect(result.data).to.deep.equal(expectedResult.data); + expect(result).toHaveProperty('data'); + expect(result).toHaveProperty('errors'); + expect(result.errors).toHaveLength(1); + expect(result.errors).toEqual(expectedResult.errors); + expect(result.data).toEqual(expectedResult.data); if (!notificationCnt++) { done(); } @@ -960,7 +959,7 @@ bookingById(id: "b1") { .catch(done); }); - it('links in queries', async () => { + test('links in queries', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1000,7 +999,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { firstProperty: { id: 'p2', @@ -1035,7 +1034,7 @@ bookingById(id: "b1") { }); }); - it('interfaces', async () => { + test('interfaces', async () => { const query = ` query { test1: interfaceTest(kind: ONE) { @@ -1066,7 +1065,7 @@ bookingById(id: "b1") { const propertyResult = await graphql(localPropertySchema, query); const mergedResult = await graphql(mergedSchema, query); - expect(propertyResult).to.deep.equal({ + expect(propertyResult).toEqual({ data: { test1: { __typename: 'TestImpl1', @@ -1083,7 +1082,7 @@ bookingById(id: "b1") { }, }); - expect(mergedResult).to.deep.equal(propertyResult); + expect(mergedResult).toEqual(propertyResult); const delegateQuery = ` query { @@ -1101,7 +1100,7 @@ bookingById(id: "b1") { const mergedDelegate = await graphql(mergedSchema, delegateQuery); - expect(mergedDelegate).to.deep.equal({ + expect(mergedDelegate).toEqual({ data: { withTypeName: { __typename: 'TestImpl1', @@ -1116,7 +1115,7 @@ bookingById(id: "b1") { }); }); - it('unions', async () => { + test('unions', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1135,7 +1134,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { customerById: { name: 'Exampler Customer', @@ -1145,7 +1144,7 @@ bookingById(id: "b1") { }); }); - it('unions with alias', async () => { + test('unions with alias', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1169,7 +1168,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { customerById: { name: 'Exampler Customer', @@ -1180,7 +1179,7 @@ bookingById(id: "b1") { }); }); - it('unions implementing interface', async () => { + test('unions implementing interface', async () => { const query = ` query { test1: unionTest(output: "Interface") { @@ -1211,7 +1210,7 @@ bookingById(id: "b1") { } `; const mergedResult = await graphql(mergedSchema, query); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { test1: { kind: 'ONE', @@ -1225,7 +1224,7 @@ bookingById(id: "b1") { }); }); - it('interfaces spread from top level functions', async () => { + test('interfaces spread from top level functions', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1251,7 +1250,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { first: { id: 'c1', @@ -1265,7 +1264,7 @@ bookingById(id: "b1") { }); }); - it('unions implementing an interface', async () => { + test('unions implementing an interface', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1293,7 +1292,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { customerById: { name: 'Exampler Customer', @@ -1304,7 +1303,7 @@ bookingById(id: "b1") { }); }); - it('input objects with default', async () => { + test('input objects with default', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1315,7 +1314,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { one: 'Foo', two: 'Bar', @@ -1323,7 +1322,7 @@ bookingById(id: "b1") { }); }); - it('deep links', async () => { + test('deep links', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1346,7 +1345,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p2', @@ -1368,7 +1367,7 @@ bookingById(id: "b1") { }); }); - it('link arguments', async () => { + test('link arguments', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1387,7 +1386,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p1', @@ -1405,12 +1404,12 @@ bookingById(id: "b1") { }); }); - it('removes `isTypeOf` checks from proxied schemas', () => { + test('removes `isTypeOf` checks from proxied schemas', () => { const Booking = mergedSchema.getType('Booking') as GraphQLObjectType; - expect(Booking.isTypeOf).to.equal(undefined); + expect(Booking.isTypeOf).toBeUndefined(); }); - it('should merge resolvers when passed an array of resolver objects', async () => { + test('should merge resolvers when passed an array of resolver objects', async () => { const Scalars = { TestScalar: new GraphQLScalarType({ name: 'TestScalar', @@ -1609,12 +1608,12 @@ bookingById(id: "b1") { test3: '6', }, }; - expect(mergedResult).to.deep.equal(expected); + expect(mergedResult).toEqual(expected); }); }); describe('fragments', () => { - it('named', async () => { + test('named', async () => { const propertyFragment = ` fragment PropertyFragment on Property { id @@ -1676,7 +1675,7 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { ...propertyResult.data, ...bookingResult.data, @@ -1684,7 +1683,7 @@ fragment BookingFragment on Booking { }); }); - it('inline', async () => { + test('inline', async () => { const propertyFragment = ` propertyById(id: "p1") { ... on Property { @@ -1724,7 +1723,7 @@ bookingById(id: "b1") { }`, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { ...propertyResult.data, ...bookingResult.data, @@ -1732,7 +1731,7 @@ bookingById(id: "b1") { }); }); - it('containing links', async () => { + test('containing links', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1765,7 +1764,7 @@ bookingById(id: "b1") { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p2', @@ -1787,7 +1786,7 @@ bookingById(id: "b1") { }); }); - it('overlapping selections', async () => { + test('overlapping selections', async () => { const propertyFragment1 = ` fragment PropertyFragment1 on Property { id @@ -1862,7 +1861,7 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { ...propertyResult.data, ...bookingResult.data, @@ -1870,7 +1869,7 @@ fragment BookingFragment on Booking { }); }); - it('containing fragment on outer type', async () => { + test('containing fragment on outer type', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1905,7 +1904,7 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p2', @@ -1927,7 +1926,7 @@ fragment BookingFragment on Booking { }); }); - it('containing links and overlapping fragments on relation', async () => { + test('containing links and overlapping fragments on relation', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -1962,7 +1961,7 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p2', @@ -1984,7 +1983,7 @@ fragment BookingFragment on Booking { }); }); - it('containing links and single fragment on relation', async () => { + test('containing links and single fragment on relation', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -2013,7 +2012,7 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p2', @@ -2037,7 +2036,7 @@ fragment BookingFragment on Booking { }); describe('variables', () => { - it('basic', async () => { + test('basic', async () => { const propertyFragment = ` propertyById(id: $p1) { id @@ -2089,7 +2088,7 @@ fragment BookingFragment on Booking { }, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { ...propertyResult.data, ...bookingResult.data, @@ -2097,7 +2096,7 @@ fragment BookingFragment on Booking { }); }); - it('in link selections', async () => { + test('in link selections', async () => { const mergedResult = await graphql( mergedSchema, ` @@ -2130,7 +2129,7 @@ fragment BookingFragment on Booking { }, ); - expect(mergedResult).to.deep.equal({ + expect(mergedResult).toEqual({ data: { propertyById: { id: 'p1', @@ -2151,7 +2150,7 @@ fragment BookingFragment on Booking { }); describe('aliases', () => { - it('aliases', async () => { + test('aliases', async () => { const result = await graphql( mergedSchema, ` @@ -2177,7 +2176,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { property: { id: 'p1', @@ -2222,7 +2221,7 @@ fragment BookingFragment on Booking { }); }); - it('aliases subschema queries', async () => { + test('aliases subschema queries', async () => { const result = await graphql( mergedSchema, ` @@ -2246,7 +2245,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { customerById: { id: 'c1', @@ -2279,7 +2278,7 @@ fragment BookingFragment on Booking { }); describe('errors', () => { - it('root level', async () => { + test('root level', async () => { const propertyFragment = ` errorTest `; @@ -2315,11 +2314,11 @@ fragment BookingFragment on Booking { ${bookingFragment} }`, ); - expect(mergedResult.data).to.deep.equal({ + expect(mergedResult.data).toEqual({ ...propertyResult.data, ...bookingResult.data, }); - expect(mergedResult.errors.map(removeLocations)).to.deep.equal( + expect(mergedResult.errors.map(removeLocations)).toEqual( propertyResult.errors.map(removeLocations), ); @@ -2333,8 +2332,8 @@ fragment BookingFragment on Booking { `, ); - expect(mergedResult2.data).to.equal(null); - expect(mergedResult2.errors.map(removeLocations)).to.deep.equal([ + expect(mergedResult2.data).toBe(null); + expect(mergedResult2.errors.map(removeLocations)).toEqual([ { message: 'Sample error non-null!', path: ['errorTestNonNull'], @@ -2342,7 +2341,7 @@ fragment BookingFragment on Booking { ]); }); - it('nested errors', async () => { + test('nested errors', async () => { const result = await graphql( mergedSchema, ` @@ -2360,7 +2359,7 @@ fragment BookingFragment on Booking { `, ); - expect(result.data).to.deep.equal({ + expect(result.data).toEqual({ propertyById: { bookings: [ { @@ -2430,26 +2429,26 @@ fragment BookingFragment on Booking { }; } - expect(errorsWithoutLocations).to.deep.equal(expectedErrors); - expect(result.errors[0].extensions).to.deep.equal({ + expect(errorsWithoutLocations).toEqual(expectedErrors); + expect(result.errors[0].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); - expect(result.errors[1].extensions).to.deep.equal({ + expect(result.errors[1].extensions).toEqual({ code: 'SOME_CUSTOM_CODE', }); }); - it( + test( 'should preserve custom error extensions from the original schema, ' + 'when merging schemas', async () => { const propertyQuery = ` - query { - properties(limit: 1) { - error - } + query { + properties(limit: 1) { + error } - `; + } + `; const propertyResult = await graphql( localPropertySchema, @@ -2459,63 +2458,63 @@ fragment BookingFragment on Booking { const mergedResult = await graphql(mergedSchema, propertyQuery); [propertyResult, mergedResult].forEach((result) => { - expect(result.errors).to.not.equal(undefined); - expect(result.errors.length > 0).to.equal(true); + expect(result.errors).toBeDefined(); + expect(result.errors.length > 0).toBe(true); const error = result.errors[0]; - expect(error.extensions).to.not.equal(undefined); - expect(error.extensions.code).to.equal('SOME_CUSTOM_CODE'); + expect(error.extensions).toBeDefined(); + expect(error.extensions.code).toBe('SOME_CUSTOM_CODE'); }); }, ); }); describe('types in schema extensions', () => { - it('should parse descriptions on new types', () => { - expect(mergedSchema.getType('AnotherNewScalar').description).to.equal( + test('should parse descriptions on new types', () => { + expect(mergedSchema.getType('AnotherNewScalar').description).toBe( 'Description of AnotherNewScalar.', ); - expect(mergedSchema.getType('TestingScalar').description).to.equal( + expect(mergedSchema.getType('TestingScalar').description).toBe( 'A type that uses TestScalar.', ); - expect(mergedSchema.getType('Color').description).to.equal( + expect(mergedSchema.getType('Color').description).toBe( 'A type that uses an Enum.', ); - expect(mergedSchema.getType('NumericEnum').description).to.equal( + expect(mergedSchema.getType('NumericEnum').description).toBe( 'A type that uses an Enum with a numeric constant.', ); - expect(mergedSchema.getType('LinkType').description).to.equal( + expect(mergedSchema.getType('LinkType').description).toBe( 'A new type linking the Property type.', ); - expect(mergedSchema.getType('LinkType').description).to.equal( + expect(mergedSchema.getType('LinkType').description).toBe( 'A new type linking the Property type.', ); }); - it('should parse descriptions on new fields', () => { + test('should parse descriptions on new fields', () => { const Query = mergedSchema.getQueryType(); - expect(Query.getFields().linkTest.description).to.equal( + expect(Query.getFields().linkTest.description).toBe( 'A new field on the root query.', ); const Booking = mergedSchema.getType('Booking') as GraphQLObjectType; - expect(Booking.getFields().property.description).to.equal( + expect(Booking.getFields().property.description).toBe( 'The property of the booking.', ); const Property = mergedSchema.getType('Property') as GraphQLObjectType; const bookingsField = Property.getFields().bookings; - expect(bookingsField.description).to.equal('A list of bookings.'); - expect(bookingsField.args[0].description).to.equal( + expect(bookingsField.description).toBe('A list of bookings.'); + expect(bookingsField.args[0].description).toBe( 'The maximum number of bookings to retrieve.', ); }); - it('should allow defining new types in link type', async () => { + test('should allow defining new types in link type', async () => { const result = await graphql( mergedSchema, ` @@ -2530,7 +2529,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { linkTest: { test: 'test', @@ -2544,7 +2543,7 @@ fragment BookingFragment on Booking { }); describe('merge info defined interfaces', () => { - it('inline fragments on existing types in subschema', async () => { + test('inline fragments on existing types in subschema', async () => { const result = await graphql( mergedSchema, ` @@ -2572,7 +2571,7 @@ fragment BookingFragment on Booking { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { property: { id: 'p1', @@ -2587,7 +2586,7 @@ fragment BookingFragment on Booking { }); }); - it('inline fragments on non-compatible sub schema types', async () => { + test('inline fragments on non-compatible sub schema types', async () => { const result = await graphql( mergedSchema, ` @@ -2615,7 +2614,7 @@ fragment BookingFragment on Booking { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { node: { __typename: 'Booking', @@ -2627,7 +2626,7 @@ fragment BookingFragment on Booking { }); }); - it('fragments on non-compatible sub schema types', async () => { + test('fragments on non-compatible sub schema types', async () => { const result = await graphql( mergedSchema, ` @@ -2661,7 +2660,7 @@ fragment BookingFragment on Booking { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { node: { __typename: 'Booking', @@ -2673,7 +2672,7 @@ fragment BookingFragment on Booking { }); }); - it('fragments on interfaces in merged schema', async () => { + test('fragments on interfaces in merged schema', async () => { const result = await graphql( mergedSchema, ` @@ -2701,7 +2700,7 @@ fragment BookingFragment on Booking { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { node: { id: 'b1', @@ -2712,7 +2711,7 @@ fragment BookingFragment on Booking { }); }); - it('multi-interface filter', async () => { + test('multi-interface filter', async () => { const result = await graphql( mergedSchema, ` @@ -2728,7 +2727,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { products: [ { @@ -2746,7 +2745,7 @@ fragment BookingFragment on Booking { }); if (graphqlVersion() >= 13) { - it('interface extensions', async () => { + test('interface extensions', async () => { const result = await graphql( mergedSchema, ` @@ -2762,7 +2761,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { products: [ { @@ -2780,7 +2779,7 @@ fragment BookingFragment on Booking { }); } - it('arbitrary transforms that return interfaces', async () => { + test('arbitrary transforms that return interfaces', async () => { const result = await graphql( mergedSchema, ` @@ -2799,7 +2798,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { nodes: [ { @@ -2841,7 +2840,7 @@ fragment BookingFragment on Booking { }); describe('schema directives', () => { - it('should work with schema directives', async () => { + test('should work with schema directives', async () => { const result = await graphql( mergedSchema, ` @@ -2853,7 +2852,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { propertyById: { someField: 'SOMEFIELD', @@ -2864,7 +2863,7 @@ fragment BookingFragment on Booking { }); describe('regression', () => { - it('should not pass extra arguments to delegates', async () => { + test('should not pass extra arguments to delegates', async () => { const result = await graphql( mergedSchema, ` @@ -2876,7 +2875,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { delegateArgumentTest: { id: 'p1', @@ -2885,16 +2884,16 @@ fragment BookingFragment on Booking { }); }); - it('defaultMergedResolver should work with aliases if parent merged resolver is manually overwritten', async () => { + test('defaultMergedResolver should work with aliases if parent merged resolver is manually overwritten', async () => { // Source: https://github.com/apollographql/graphql-tools/issues/967 const typeDefs = ` - type Query { - book: Book - } - type Book { - category: String! - } - `; + type Query { + book: Book + } + type Book { + category: String! + } + `; let schema = makeExecutableSchema({ typeDefs }); const resolvers = { @@ -2910,12 +2909,12 @@ fragment BookingFragment on Booking { const result = await graphql(schema, '{ book { cat: category } }'); - expect(result.data.book.cat).to.equal('Test'); + expect(result.data.book.cat).toBe('Test'); }); }); describe('deprecation', () => { - it('should retain deprecation information', () => { + test('should retain deprecation information', () => { const typeDefs = ` type Query { book: Book @@ -2943,20 +2942,20 @@ fragment BookingFragment on Booking { }); const deprecatedUsages = findDeprecatedUsages(schema, parse(query)); - expect(deprecatedUsages.length).to.equal(1); + expect(deprecatedUsages.length).toBe(1); expect( deprecatedUsages.find( (error) => error.message.match(/deprecated/g) != null && error.message.match(/yolo/g) != null, ), - ).to.not.equal(undefined); + ).toBeDefined(); }); }); }); describe('scalars without executable schema', () => { - it('can merge and query schema', async () => { + test('can merge and query schema', async () => { const BookSchema = ` type Book { name: String @@ -3004,7 +3003,7 @@ fragment BookingFragment on Booking { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { book: { author: { @@ -3017,7 +3016,7 @@ fragment BookingFragment on Booking { }); describe('new root type name', () => { - it('works', async () => { + test('works', async () => { const bookSchema = makeExecutableSchema({ typeDefs: ` type Query { @@ -3062,7 +3061,7 @@ fragment BookingFragment on Booking { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { book: { name: 'Hello World', diff --git a/src/test/testMocking.ts b/src/test/mocking.test.ts similarity index 79% rename from src/test/testMocking.ts rename to src/test/mocking.test.ts index fab9ece9eaa..e931b032807 100644 --- a/src/test/testMocking.ts +++ b/src/test/mocking.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { graphql, GraphQLResolveInfo, @@ -89,27 +88,29 @@ describe('Mock', () => { }, }; - it('throws an error if you forget to pass schema', () => { - expect(() => addMocksToSchema({})).to.throw('Must provide schema to mock'); + test('throws an error if you forget to pass schema', () => { + expect(() => addMocksToSchema({})).toThrowError( + 'Must provide schema to mock', + ); }); - it('throws an error if the property "schema" on the first argument is not of type GraphQLSchema', () => { + test('throws an error if the property "schema" on the first argument is not of type GraphQLSchema', () => { expect(() => addMocksToSchema({ schema: ({} as unknown) as GraphQLSchema }), - ).to.throw('Value at "schema" must be of type GraphQLSchema'); + ).toThrowError('Value at "schema" must be of type GraphQLSchema'); }); - it('throws an error if second argument is not a Map', () => { + test('throws an error if second argument is not a Map', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); expect(() => addMocksToSchema({ schema: jsSchema, mocks: (['a'] as unknown) as IMocks, }), - ).to.throw('mocks must be of type Object'); + ).toThrowError('mocks must be of type Object'); }); - it('throws an error if mockFunctionMap contains a non-function thingy', () => { + test('throws an error if mockFunctionMap contains a non-function thingy', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Int: 55 }; expect(() => @@ -117,10 +118,10 @@ describe('Mock', () => { schema: jsSchema, mocks: (mockMap as unknown) as IMocks, }), - ).to.throw('mockFunctionMap[Int] must be a function'); + ).toThrowError('mockFunctionMap[Int] must be a function'); }); - it('mocks the default types for you', () => { + test('mocks the default types for you', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = {}; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -132,15 +133,17 @@ describe('Mock', () => { returnID }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnInt']).to.be.within(-1000, 1000); - expect(res.data['returnFloat']).to.be.within(-1000, 1000); - expect(res.data['returnBoolean']).to.be.a('boolean'); - expect(res.data['returnString']).to.be.a('string'); - expect(res.data['returnID']).to.be.a('string'); + expect(res.data['returnInt']).toBeGreaterThanOrEqual(-1000); + expect(res.data['returnInt']).toBeLessThanOrEqual(1000); + expect(res.data['returnFloat']).toBeGreaterThanOrEqual(-1000); + expect(res.data['returnFloat']).toBeLessThanOrEqual(1000); + expect(typeof res.data['returnBoolean']).toBe('boolean'); + expect(typeof res.data['returnString']).toBe('string'); + expect(typeof res.data['returnID']).toBe('string'); }); }); - it('lets you use mockServer for convenience', () => { + test('lets you use mockServer for convenience', () => { const testQuery = `{ returnInt returnFloat @@ -166,19 +169,20 @@ describe('Mock', () => { return mockServer(shorthand, mockMap) .query(testQuery) .then((res: any) => { - expect(res.data.returnInt).to.equal(12345); - expect(res.data.returnFloat).to.be.a('number').within(-1000, 1000); - expect(res.data.returnBoolean).to.be.a('boolean'); - expect(res.data.returnString).to.be.a('string'); - expect(res.data.returnID).to.be.a('string'); + expect(res.data.returnInt).toBe(12345); + expect(res.data.returnFloat).toBeGreaterThanOrEqual(-1000); + expect(res.data.returnFloat).toBeLessThanOrEqual(1000); + expect(typeof res.data.returnBoolean).toBe('boolean'); + expect(typeof res.data.returnString).toBe('string'); + expect(typeof res.data.returnID).toBe('string'); // tests that resolveType is correctly set for unions and interfaces // and that the correct mock function is used - expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321); - expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321); + expect(res.data.returnBirdsAndBees[0].returnInt).toBe(54321); + expect(res.data.returnBirdsAndBees[1].returnInt).toBe(54321); }); }); - it('mockServer is able to preserveResolvers of a prebuilt schema', () => { + test('mockServer is able to preserveResolvers of a prebuilt schema', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { RootQuery: { @@ -206,16 +210,16 @@ describe('Mock', () => { return mockServer(jsSchema, mockMap, true) .query(testQuery) .then((res: any) => { - expect(res.data.returnInt).to.equal(12345); - expect(res.data.returnString).to.equal('someString'); + expect(res.data.returnInt).toBe(12345); + expect(res.data.returnString).toBe('someString'); // tests that resolveType is correctly set for unions and interfaces // and that the correct mock function is used - expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321); - expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321); + expect(res.data.returnBirdsAndBees[0].returnInt).toBe(54321); + expect(res.data.returnBirdsAndBees[1].returnInt).toBe(54321); }); }); - it('lets you use mockServer with prebuilt schema', () => { + test('lets you use mockServer with prebuilt schema', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const testQuery = `{ returnInt @@ -242,19 +246,20 @@ describe('Mock', () => { return mockServer(jsSchema, mockMap) .query(testQuery) .then((res: any) => { - expect(res.data.returnInt).to.equal(12345); - expect(res.data.returnFloat).to.be.a('number').within(-1000, 1000); - expect(res.data.returnBoolean).to.be.a('boolean'); - expect(res.data.returnString).to.be.a('string'); - expect(res.data.returnID).to.be.a('string'); + expect(res.data.returnInt).toBe(12345); + expect(res.data.returnFloat).toBeGreaterThanOrEqual(-1000); + expect(res.data.returnFloat).toBeLessThanOrEqual(1000); + expect(typeof res.data.returnBoolean).toBe('boolean'); + expect(typeof res.data.returnString).toBe('string'); + expect(typeof res.data.returnID).toBe('string'); // tests that resolveType is correctly set for unions and interfaces // and that the correct mock function is used - expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321); - expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321); + expect(res.data.returnBirdsAndBees[0].returnInt).toBe(54321); + expect(res.data.returnBirdsAndBees[1].returnInt).toBe(54321); }); }); - it('does not mask resolveType functions if you tell it not to', () => { + test('does not mask resolveType functions if you tell it not to', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); let spy = 0; const resolvers = { @@ -285,12 +290,12 @@ describe('Mock', () => { }`; return graphql(jsSchema, testQuery).then((_res) => { // the resolveType has been called twice - expect(spy).to.equal(2); + expect(spy).toBe(2); }); }); // TODO test mockServer with precompiled schema - it('can mock Enum', () => { + test('can mock Enum', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = {}; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -298,11 +303,11 @@ describe('Mock', () => { returnEnum }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnEnum']).to.be.oneOf(['A', 'B', 'C']); + expect(['A', 'B', 'C']).toContain(res.data['returnEnum']); }); }); - it('can mock Unions', () => { + test('can mock Unions', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); addResolversToSchema(jsSchema, resolveFunctions); const mockMap = { @@ -328,18 +333,22 @@ describe('Mock', () => { }`; return graphql(jsSchema, testQuery).then((res) => { // XXX this test is expected to fail once every 2^40 times ;-) - expect(res.data['returnBirdsAndBees']).to.deep.include({ - returnInt: 10, - returnString: 'aha', - }); - return expect(res.data['returnBirdsAndBees']).to.deep.include({ - returnInt: 10, - returnEnum: 'A', - }); + expect(res.data['returnBirdsAndBees']).toContainEqual( + expect.objectContaining({ + returnInt: 10, + returnString: 'aha', + }), + ); + return expect(res.data['returnBirdsAndBees']).toContainEqual( + expect.objectContaining({ + returnInt: 10, + returnEnum: 'A', + }), + ); }); }); - it('can mock Interfaces by default', () => { + test('can mock Interfaces by default', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); addResolversToSchema(jsSchema, resolveFunctions); const mockMap = { @@ -368,18 +377,22 @@ describe('Mock', () => { } }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnFlying']).to.deep.include({ - returnInt: 10, - returnString: 'aha', - }); - return expect(res.data['returnFlying']).to.deep.include({ - returnInt: 10, - returnEnum: 'A', - }); + expect(res.data['returnFlying']).toContainEqual( + expect.objectContaining({ + returnInt: 10, + returnString: 'aha', + }), + ); + return expect(res.data['returnFlying']).toContainEqual( + expect.objectContaining({ + returnInt: 10, + returnEnum: 'A', + }), + ); }); }); - it('can support explicit Interface mock', () => { + test('can support explicit Interface mock', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); addResolversToSchema(jsSchema, resolveFunctions); let spy = 0; @@ -415,15 +428,15 @@ describe('Mock', () => { }`; return graphql(jsSchema, testQuery).then((res) => { - expect(spy).to.equal(1); // to make sure that Flying possible types are not randomly selected - expect(res.data['node']).to.include({ + expect(spy).toBe(1); // to make sure that Flying possible types are not randomly selected + expect(res.data['node']).toMatchObject({ id: 'bee:123456', returnInt: 200, }); }); }); - it('can support explicit UnionType mock', () => { + test('can support explicit UnionType mock', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); addResolversToSchema(jsSchema, resolveFunctions); let spy = 0; @@ -460,15 +473,15 @@ describe('Mock', () => { }`; return graphql(jsSchema, testQuery).then((res) => { - expect(spy).to.equal(1); - expect(res.data['node2']).to.include({ + expect(spy).toBe(1); + expect(res.data['node2']).toMatchObject({ id: 'bee:123456', returnEnum: 'A', }); }); }); - it('throws an error when __typename is not returned within an explicit interface mock', () => { + test('throws an error when __typename is not returned within an explicit interface mock', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); addResolversToSchema(jsSchema, resolveFunctions); const mockMap = { @@ -484,18 +497,18 @@ describe('Mock', () => { }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ - node(id:"bee:123456"){ - id, - returnInt - } - }`; + node(id:"bee:123456"){ + id, + returnInt + } + }`; const expected = 'Please return a __typename in "Flying"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).to.equal(expected); + expect(res.errors[0].originalError.message).toBe(expected); }); }); - it('throws an error in resolve if mock type is not defined', () => { + test('throws an error in resolve if mock type is not defined', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = {}; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -504,11 +517,11 @@ describe('Mock', () => { }`; const expected = 'No mock defined for type "MissingMockType"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).to.equal(expected); + expect(res.errors[0].originalError.message).toBe(expected); }); }); - it('throws an error in resolve if mock type is not defined and resolver failed', () => { + test('throws an error in resolve if mock type is not defined and resolver failed', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { MissingMockType: { @@ -529,15 +542,15 @@ describe('Mock', () => { preserveResolvers: true, }); const testQuery = `{ - returnMockError - }`; + returnMockError + }`; const expected = 'No mock defined for type "MissingMockType"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).to.equal(expected); + expect(res.errors[0].originalError.message).toBe(expected); }); }); - it('can preserve scalar resolvers', () => { + test('can preserve scalar resolvers', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { MissingMockType: { @@ -564,12 +577,12 @@ describe('Mock', () => { returnMockError: '10-11-2012', }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); - expect(res.errors).to.equal(undefined); + expect(res.data).toEqual(expected); + expect(res.errors).toBeUndefined(); }); }); - it('can mock an Int', () => { + test('can mock an Int', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Int: () => 55 }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -577,11 +590,11 @@ describe('Mock', () => { returnInt }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnInt']).to.equal(55); + expect(res.data['returnInt']).toBe(55); }); }); - it('can mock a Float', () => { + test('can mock a Float', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Float: () => 55.5 }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -589,10 +602,10 @@ describe('Mock', () => { returnFloat }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnFloat']).to.equal(55.5); + expect(res.data['returnFloat']).toBe(55.5); }); }); - it('can mock a String', () => { + test('can mock a String', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: () => 'a string' }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -600,10 +613,10 @@ describe('Mock', () => { returnString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnString']).to.equal('a string'); + expect(res.data['returnString']).toBe('a string'); }); }); - it('can mock a Boolean', () => { + test('can mock a Boolean', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Boolean: () => true }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -611,10 +624,10 @@ describe('Mock', () => { returnBoolean }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnBoolean']).to.equal(true); + expect(res.data['returnBoolean']).toBe(true); }); }); - it('can mock an ID', () => { + test('can mock an ID', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { ID: () => 'ea5bdc19' }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -622,10 +635,10 @@ describe('Mock', () => { returnID }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnID']).to.equal('ea5bdc19'); + expect(res.data['returnID']).toBe('ea5bdc19'); }); }); - it('nullable type is nullable', () => { + test('nullable type is nullable', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: (): null => null }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -633,10 +646,10 @@ describe('Mock', () => { returnNullableString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnNullableString']).to.equal(null); + expect(res.data['returnNullableString']).toBe(null); }); }); - it('can mock a nonNull type', () => { + test('can mock a nonNull type', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: () => 'nonnull' }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -644,10 +657,10 @@ describe('Mock', () => { returnNonNullString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnNonNullString']).to.equal('nonnull'); + expect(res.data['returnNonNullString']).toBe('nonnull'); }); }); - it('nonNull type is not nullable', () => { + test('nonNull type is not nullable', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: (): null => null }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -655,11 +668,11 @@ describe('Mock', () => { returnNonNullString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.equal(null); - expect(res.errors.length).to.equal(1); + expect(res.data).toBe(null); + expect(res.errors.length).toBe(1); }); }); - it('can mock object types', () => { + test('can mock object types', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: () => 'abc', @@ -673,11 +686,11 @@ describe('Mock', () => { returnObject: { returnInt: 123, returnString: 'abc' }, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('can mock a list of ints', () => { + test('can mock a list of ints', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Int: () => 123 }; addMocksToSchema({ schema: jsSchema, mocks: mockMap }); @@ -688,11 +701,11 @@ describe('Mock', () => { returnListOfInt: [123, 123], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('can mock a list of lists of objects', () => { + test('can mock a list of lists of objects', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { String: () => 'a', @@ -715,11 +728,11 @@ describe('Mock', () => { ], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('does not mask resolvers if you tell it not to', () => { + test('does not mask resolvers if you tell it not to', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -752,11 +765,11 @@ describe('Mock', () => { returnString: 'bar', // c) from resolvers, not masked by mock (and promise) }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock non-leaf types conveniently', () => { + test('lets you mock non-leaf types conveniently', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { Bird: () => ({ @@ -781,11 +794,11 @@ describe('Mock', () => { returnInt: 15, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock and resolve non-leaf types concurrently', () => { + test('lets you mock and resolve non-leaf types concurrently', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { RootQuery: { @@ -824,11 +837,11 @@ describe('Mock', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock and resolve non-leaf types concurrently, support promises', () => { + test('lets you mock and resolve non-leaf types concurrently, support promises', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { RootQuery: { @@ -852,11 +865,11 @@ describe('Mock', () => { preserveResolvers: true, }); const testQuery = `{ - returnObject{ - returnInt - returnString - } - }`; + returnObject{ + returnInt + returnString + } + }`; const expected = { returnObject: { returnInt: 12, // from the resolver, see a) @@ -864,11 +877,11 @@ describe('Mock', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock and resolve non-leaf types concurrently, support defineProperty', () => { + test('lets you mock and resolve non-leaf types concurrently, support defineProperty', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const objProxy = {}; Object.defineProperty( @@ -894,11 +907,11 @@ describe('Mock', () => { preserveResolvers: true, }); const testQuery = `{ - returnObject{ - returnInt - returnString - } - }`; + returnObject{ + returnInt + returnString + } + }`; const expected = { returnObject: { returnInt: 12, // from the resolver, see a) @@ -906,11 +919,11 @@ describe('Mock', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('let you mock with preserving resolvers, also when using logger', () => { + test('let you mock with preserving resolvers, also when using logger', () => { const resolvers = { RootQuery: { returnString: () => 'woot!?', // a) resolve of a string @@ -949,11 +962,11 @@ describe('Mock', () => { returnString: 'woot!?', // from the mock, see a) }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('let you mock with preserving resolvers, also when using connectors', () => { + test('let you mock with preserving resolvers, also when using connectors', () => { const resolvers = { RootQuery: { returnString: () => 'woot!?', // a) resolve of a string @@ -980,12 +993,12 @@ describe('Mock', () => { preserveResolvers: true, }); const testQuery = `{ - returnObject { - returnInt - returnString - } - returnString - }`; + returnObject { + returnInt + returnString + } + returnString + }`; const expected = { returnObject: { returnInt: 123, // from the mock, see b) @@ -994,11 +1007,11 @@ describe('Mock', () => { returnString: 'woot!?', // from the mock, see a) }; return graphql(jsSchema, testQuery, undefined, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('let you mock with preserving resolvers, also when using both connectors and logger', () => { + test('let you mock with preserving resolvers, also when using both connectors and logger', () => { const resolvers = { RootQuery: { returnString: () => 'woot!?', // a) resolve of a string @@ -1026,12 +1039,12 @@ describe('Mock', () => { preserveResolvers: true, }); const testQuery = `{ - returnObject { - returnInt - returnString - } - returnString - }`; + returnObject { + returnInt + returnString + } + returnString + }`; const expected = { returnObject: { returnInt: 123, // from the mock, see b) @@ -1040,11 +1053,11 @@ describe('Mock', () => { returnString: 'woot!?', // from the mock, see a) }; return graphql(jsSchema, testQuery, undefined, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('let you resolve null with mocking and preserving resolvers', () => { + test('let you resolve null with mocking and preserving resolvers', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const resolvers = { RootQuery: { @@ -1075,11 +1088,11 @@ describe('Mock', () => { returnString: null as string, // from the mock, see a) }; return graphql(jsSchema, testQuery, undefined, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock root query fields', () => { + test('lets you mock root query fields', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -1094,11 +1107,11 @@ describe('Mock', () => { returnStringArgument: 'adieu', }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock root mutation fields', () => { + test('lets you mock root mutation fields', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootMutation: () => ({ @@ -1113,11 +1126,11 @@ describe('Mock', () => { returnStringArgument: 'adieu', }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock a list of a certain length', () => { + test('lets you mock a list of a certain length', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ returnListOfInt: () => new MockList(3) }), @@ -1131,11 +1144,11 @@ describe('Mock', () => { returnListOfInt: [12, 12, 12], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you mock a list of a random length', () => { + test('lets you mock a list of a random length', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ returnListOfInt: () => new MockList([10, 20]) }), @@ -1146,12 +1159,13 @@ describe('Mock', () => { returnListOfInt }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['returnListOfInt']).to.have.length.within(10, 20); - expect(res.data['returnListOfInt'][0]).to.equal(12); + expect(res.data['returnListOfInt'].length).toBeGreaterThanOrEqual(10); + expect(res.data['returnListOfInt'].length).toBeLessThanOrEqual(20); + expect(res.data['returnListOfInt'][0]).toBe(12); }); }); - it('lets you mock a list of specific variable length', () => { + test('lets you mock a list of specific variable length', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -1166,12 +1180,12 @@ describe('Mock', () => { l5: returnListOfIntArg(l: 5) }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data['l3'].length).to.equal(3); - expect(res.data['l5'].length).to.equal(5); + expect(res.data['l3'].length).toBe(3); + expect(res.data['l5'].length).toBe(5); }); }); - it('lets you provide a function for your MockList', () => { + test('lets you provide a function for your MockList', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -1187,18 +1201,20 @@ describe('Mock', () => { returnListOfInt: [33, 33], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('throws an error if the second argument to MockList is not a function', () => { + test('throws an error if the second argument to MockList is not a function', () => { expect( () => new MockList(5, ('abc' as unknown) as GraphQLFieldResolver), - ).to.throw('Second argument to MockList must be a function or undefined'); + ).toThrowError( + 'Second argument to MockList must be a function or undefined', + ); }); - it('lets you nest MockList in MockList', () => { + test('lets you nest MockList in MockList', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -1217,11 +1233,11 @@ describe('Mock', () => { ], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('lets you use arguments in nested MockList', () => { + test('lets you use arguments in nested MockList', () => { const jsSchema = buildSchemaFromTypeDefinitions(shorthand); const mockMap = { RootQuery: () => ({ @@ -1241,11 +1257,11 @@ describe('Mock', () => { returnListOfListOfIntArg: [[12], [12]], }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('works for a slightly more elaborate example', () => { + test('works for a slightly more elaborate example', () => { const short = ` type Thread { id: ID! @@ -1291,7 +1307,9 @@ describe('Mock', () => { posts: (_o: any, a: { [key: string]: any }) => new MockList( ITEMS_PER_PAGE * a['num'], - (_oi: any, ai: { [key: string]: any }) => ({ id: ai['num'] }), + (_oi: any, ai: { [key: string]: any }) => ({ + id: ai['num'], + }), ), }), Post: () => ({ @@ -1324,11 +1342,11 @@ describe('Mock', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('works for resolvers returning javascript Dates', () => { + test('works for resolvers returning javascript Dates', () => { const typeDefs = ` scalar Date @@ -1391,11 +1409,11 @@ describe('Mock', () => { date3: '2016-05-04T00:00:00.000Z', }; return graphql(schema, query).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('allows instanceof checks in __resolveType', () => { + test('allows instanceof checks in __resolveType', () => { class Account { public id: string; public username: string; @@ -1470,7 +1488,7 @@ describe('Mock', () => { }, }; return graphql(schema, query).then((res) => { - expect(res).to.deep.equal(expected); + expect(res).toEqual(expected); }); }); diff --git a/src/test/testResolution.ts b/src/test/resolution.test.ts similarity index 83% rename from src/test/testResolution.ts rename to src/test/resolution.test.ts index 74dc8278f94..1b7c88d6859 100644 --- a/src/test/testResolution.ts +++ b/src/test/resolution.test.ts @@ -1,4 +1,3 @@ -import { assert } from 'chai'; import { parse, graphql, subscribe, ExecutionResult } from 'graphql'; import { PubSub } from 'graphql-subscriptions'; import { forAwaitEach } from 'iterall'; @@ -50,7 +49,7 @@ describe('Resolve', () => { return root; }); - it('should run the schema level resolver once in a same query', () => { + test('should run the schema level resolver once in a same query', () => { schemaLevelResolverCalls = 0; const root = 'queryRoot'; return graphql( @@ -63,15 +62,15 @@ describe('Resolve', () => { `, root, ).then(({ data }) => { - assert.deepEqual(data, { + expect(data).toEqual({ printRoot: root, printRootAgain: root, }); - assert.equal(schemaLevelResolverCalls, 1); + expect(schemaLevelResolverCalls).toEqual(1); }); }); - it('should isolate roots from the different operation types', (done) => { + test('should isolate roots from the different operation types', (done) => { schemaLevelResolverCalls = 0; const queryRoot = 'queryRoot'; const mutationRoot = 'mutationRoot'; @@ -106,12 +105,12 @@ describe('Resolve', () => { subsCbkCalls++; try { if (subsCbkCalls === 1) { - assert.equal(schemaLevelResolverCalls, 1); - assert.deepEqual(subsData, { printRoot: subscriptionRoot }); + expect(schemaLevelResolverCalls).toEqual(1); + expect(subsData).toEqual({ printRoot: subscriptionRoot }); return resolveFirst(); } else if (subsCbkCalls === 2) { - assert.equal(schemaLevelResolverCalls, 4); - assert.deepEqual(subsData, { + expect(schemaLevelResolverCalls).toEqual(4); + expect(subsData).toEqual({ printRoot: subscriptionRoot2, }); return done(); @@ -142,8 +141,8 @@ describe('Resolve', () => { ), ) .then(({ data }) => { - assert.equal(schemaLevelResolverCalls, 2); - assert.deepEqual(data, { printRoot: queryRoot }); + expect(schemaLevelResolverCalls).toEqual(2); + expect(data).toEqual({ printRoot: queryRoot }); return graphql( schema, ` @@ -155,8 +154,8 @@ describe('Resolve', () => { ); }) .then(({ data: mutationData }) => { - assert.equal(schemaLevelResolverCalls, 3); - assert.deepEqual(mutationData, { printRoot: mutationRoot }); + expect(schemaLevelResolverCalls).toEqual(3); + expect(mutationData).toEqual({ printRoot: mutationRoot }); return pubsub.publish('printRootChannel', { printRoot: subscriptionRoot2, }); diff --git a/src/test/testSchemaGenerator.ts b/src/test/schemaGenerator.test.ts similarity index 80% rename from src/test/testSchemaGenerator.ts rename to src/test/schemaGenerator.test.ts index 76d033a9ba8..e777a55dfcc 100644 --- a/src/test/testSchemaGenerator.ts +++ b/src/test/schemaGenerator.test.ts @@ -2,7 +2,6 @@ // see https://github.com/apollostack/graphql-tools/issues/26 import { GraphQLJSON } from 'graphql-type-json'; -import { assert, expect } from 'chai'; import { graphql, GraphQLResolveInfo, @@ -24,7 +23,6 @@ import { import { Logger } from '../generate/Logger'; import { makeExecutableSchema, - SchemaError, addErrorLoggingToSchema, addSchemaLevelResolver, attachConnectorsToContext, @@ -44,7 +42,7 @@ import { } from '../Interfaces'; import { visitSchema, graphqlVersion } from '../utils/index'; -import TypeA from './circularSchemaA'; +import TypeA from './fixtures/circularSchemaA'; interface Bird { name: string; @@ -65,9 +63,9 @@ function expectWarning(fn: () => void, warnMatcher?: string) { fn(); if (undefined === warnMatcher) { - expect(warning).to.be.equal(null); + expect(warning).toBe(null); } else { - expect(warning).to.contain(warnMatcher); + expect(warning).toMatch(warnMatcher); } } finally { // eslint-disable-next-line no-console @@ -123,54 +121,56 @@ const testConnectors = { }; describe('generating schema from shorthand', () => { - it('throws an error if no schema is provided', () => { - expect(() => makeExecutableSchema(undefined)).to.throw('undefined'); + test('throws an error if no schema is provided', () => { + expect(() => makeExecutableSchema(undefined)).toThrowError('undefined'); }); - it('throws an error if typeDefinitionNodes are not provided', () => { + test('throws an error if typeDefinitionNodes are not provided', () => { expect(() => makeExecutableSchema({ typeDefs: undefined, resolvers: {} }), - ).to.throw('Must provide typeDefs'); + ).toThrowError('Must provide typeDefs'); }); - it('throws an error if no resolveFunctions are provided', () => { + test('throws an error if no resolveFunctions are provided', () => { expect(() => makeExecutableSchema({ typeDefs: 'blah', resolvers: {} }), - ).to.throw(GraphQLError); + ).toThrowError(GraphQLError); }); - it('throws an error if typeDefinitionNodes is neither string nor array nor schema AST', () => { + test('throws an error if typeDefinitionNodes is neither string nor array nor schema AST', () => { expect(() => makeExecutableSchema({ typeDefs: ({} as unknown) as ITypeDefinitions, resolvers: {}, }), - ).to.throw('typeDefs must be a string, array or schema AST, got object'); + ).toThrowError( + 'typeDefs must be a string, array or schema AST, got object', + ); }); - it('throws an error if typeDefinitionNode array contains not only functions and strings', () => { + test('throws an error if typeDefinitionNode array contains not only functions and strings', () => { expect(() => makeExecutableSchema({ typeDefs: ([17] as unknown) as ITypeDefinitions, resolvers: {}, }), - ).to.throw( + ).toThrowError( 'typeDef array must contain only strings and functions, got number', ); }); - it('throws an error if resolverValidationOptions is not an object', () => { + test('throws an error if resolverValidationOptions is not an object', () => { const options = { typeDefs: 'blah', resolvers: {}, resolverValidationOptions: ('string' as unknown) as IResolverValidationOptions, }; - expect(() => makeExecutableSchema(options)).to.throw( + expect(() => makeExecutableSchema(options)).toThrowError( 'Expected `resolverValidationOptions` to be an object', ); }); - it('can generate a schema', () => { + test('can generate a schema', () => { const shorthand = ` """ A bird species @@ -292,11 +292,11 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, introspectionQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); - it('can generate a schema from an array of types', () => { + test('can generate a schema from an array of types', () => { const typeDefAry = [ ` type Query { @@ -314,10 +314,10 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); + expect(jsSchema.getQueryType().name).toBe('Query'); }); - it('can generate a schema from a parsed type definition', () => { + test('can generate a schema from a parsed type definition', () => { const typeDefSchema = parse(` type Query { foo: String @@ -331,30 +331,30 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefSchema, resolvers: {}, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); + expect(jsSchema.getQueryType().name).toBe('Query'); }); - it('can generate a schema from an array of parsed and none parsed type definitions', () => { + test('can generate a schema from an array of parsed and none parsed type definitions', () => { const typeDefSchema = [ parse(` - type Query { - foo: String - }`), + type Query { + foo: String + }`), ` - schema { - query: Query - } - `, + schema { + query: Query + } + `, ]; const jsSchema = makeExecutableSchema({ typeDefs: typeDefSchema, resolvers: {}, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); + expect(jsSchema.getQueryType().name).toBe('Query'); }); - it('can generate a schema from an array of types with extensions', () => { + test('can generate a schema from an array of types with extensions', () => { const typeDefAry = [ ` type Query { @@ -377,11 +377,12 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); - expect(jsSchema.getQueryType().getFields()).to.have.all.keys('foo', 'bar'); + expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType().getFields().foo).toBeDefined(); + expect(jsSchema.getQueryType().getFields().bar).toBeDefined(); }); - it('can concatenateTypeDefs created by a function inside a closure', () => { + test('can concatenateTypeDefs created by a function inside a closure', () => { const typeA = { typeDefs: () => ['type TypeA { foo: String }'] }; const typeB = { typeDefs: () => ['type TypeB { bar: String }'] }; const typeC = { typeDefs: () => ['type TypeC { foo: String }'] }; @@ -399,13 +400,13 @@ describe('generating schema from shorthand', () => { combinedCandD.typeDefs, ]); - expect(result).to.contain('type TypeA'); - expect(result).to.contain('type TypeB'); - expect(result).to.contain('type TypeC'); - expect(result).to.contain('type TypeD'); + expect(result).toMatch('type TypeA'); + expect(result).toMatch('type TypeB'); + expect(result).toMatch('type TypeC'); + expect(result).toMatch('type TypeD'); }); - it('properly deduplicates the array of type DefinitionNodes', () => { + test('properly deduplicates the array of type DefinitionNodes', () => { const typeDefAry = [ ` type Query { @@ -428,10 +429,10 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); + expect(jsSchema.getQueryType().name).toBe('Query'); }); - it('works with imports, even circular ones', () => { + test('works with imports, even circular ones', () => { const typeDefAry = [ ` type Query { @@ -454,10 +455,10 @@ describe('generating schema from shorthand', () => { TypeB: { a: () => null }, }, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); + expect(jsSchema.getQueryType().name).toBe('Query'); }); - it('can generate a schema with resolvers', () => { + test('can generate a schema with resolvers', () => { const shorthand = ` type BirdSpecies { name: String!, @@ -505,11 +506,11 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); - it('can generate a schema with extensions that can use resolvers', () => { + test('can generate a schema with extensions that can use resolvers', () => { const shorthand = ` type BirdSpecies { name: String!, @@ -568,11 +569,11 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); - it('supports resolveType for unions', () => { + test('supports resolveType for unions', () => { const shorthand = ` union Searchable = Person | Location type Person { @@ -655,11 +656,11 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); - it('can generate a schema with an array of resolvers', () => { + test('can generate a schema with an array of resolvers', () => { const shorthand = ` type BirdSpecies { name: String!, @@ -729,12 +730,12 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); describe('scalar types', () => { - it('supports passing a GraphQLScalarType in resolveFunctions', () => { + test('supports passing a GraphQLScalarType in resolveFunctions', () => { // Here GraphQLJSON is used as an example of non-default GraphQLScalarType const shorthand = ` scalar JSON @@ -754,15 +755,14 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); - expect(jsSchema.getType('JSON')).to.be.an.instanceof(GraphQLScalarType); - expect(jsSchema.getType('JSON')) - .to.have.property('description') - .that.is.a('string'); - expect(jsSchema.getType('JSON')['description']).to.have.length.above(0); + expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getType('JSON')).toBeInstanceOf(GraphQLScalarType); + expect(jsSchema.getType('JSON')).toHaveProperty('description'); + expect(typeof jsSchema.getType('JSON').description).toBe('string'); + expect(jsSchema.getType('JSON')['description'].length).toBeGreaterThan(0); }); - it('supports passing a default scalar type', () => { + test('supports passing a default scalar type', () => { const shorthand = ` type Foo { aField: Boolean @@ -779,11 +779,11 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); - expect(jsSchema.getType('Boolean')).to.equal(GraphQLBoolean); + expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getType('Boolean')).toBe(GraphQLBoolean); }); - it('allow overriding default scalar type fields', () => { + test('allow overriding default scalar type fields', () => { const originalSerialize = GraphQLBoolean.serialize; const shorthand = ` type Foo { @@ -815,7 +815,7 @@ describe('generating schema from shorthand', () => { } `; const result = graphqlSync(jsSchema, testQuery); - expect(result.data.foo.aField).to.equal(false); + expect(result.data.foo.aField).toBe(false); addResolversToSchema({ schema: jsSchema, resolvers: { @@ -826,7 +826,7 @@ describe('generating schema from shorthand', () => { }); }); - it('retains scalars after walking/recreating the schema', () => { + test('retains scalars after walking/recreating the schema', () => { const shorthand = ` scalar Test @@ -864,7 +864,7 @@ describe('generating schema from shorthand', () => { }), Query: { testIn(_: any, { input }: any) { - expect(input).to.contain('scalar:'); + expect(input).toMatch('scalar:'); return input; }, test() { @@ -883,12 +883,9 @@ describe('generating schema from shorthand', () => { }, }, ); - expect(walkedSchema.getType('Test')).to.be.an.instanceof( - GraphQLScalarType, - ); - expect(walkedSchema.getType('Test')) - .to.have.property('description') - .that.equals('Test resolver'); + expect(walkedSchema.getType('Test')).toBeInstanceOf(GraphQLScalarType); + expect(walkedSchema.getType('Test')).toHaveProperty('description'); + expect(walkedSchema.getType('Test').description).toBe('Test resolver'); const testQuery = ` { test @@ -896,29 +893,29 @@ describe('generating schema from shorthand', () => { }`; const resultPromise = graphql(walkedSchema, testQuery); return resultPromise.then((result) => - expect(result.data).to.deep.equal({ + expect(result.data).toEqual({ test: 'scalar:42', testIn: 'scalar:1', }), ); }); - it('should support custom scalar usage on client-side query execution', () => { + test('should support custom scalar usage on client-side query execution', () => { const shorthand = ` - scalar CustomScalar + scalar CustomScalar - type TestType { - testField: String - } + type TestType { + testField: String + } - type RootQuery { - myQuery(t: CustomScalar): TestType - } + type RootQuery { + myQuery(t: CustomScalar): TestType + } - schema { - query: RootQuery - } - `; + schema { + query: RootQuery + } + `; const resolveFunctions = { CustomScalar: new GraphQLScalarType({ @@ -941,21 +938,21 @@ describe('generating schema from shorthand', () => { }; const testQuery = ` - query myQuery($t: CustomScalar) { - myQuery(t: $t) { - testField - } - }`; + query myQuery($t: CustomScalar) { + myQuery(t: $t) { + testField + } + }`; const jsSchema = makeExecutableSchema({ typeDefs: shorthand, resolvers: resolveFunctions, }); const resultPromise = graphql(jsSchema, testQuery); - return resultPromise.then((result) => expect(result.errors).to.not.exist); + return resultPromise.then((result) => expect(result.errors).toBeFalsy()); }); - it('should work with an Odd custom scalar type', () => { + test('should work with an Odd custom scalar type', () => { const oddValue = (value: number) => (value % 2 === 1 ? value : null); const OddType = new GraphQLScalarType({ @@ -1017,12 +1014,12 @@ describe('generating schema from shorthand', () => { `; const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['post'].something, testValue); - assert.equal(result.errors, undefined); + expect(result.data['post'].something).toEqual(testValue); + expect(result.errors).toEqual(undefined); }); }); - it('should work with a Date custom scalar type', () => { + test('should work with a Date custom scalar type', () => { const DateType = new GraphQLScalarType({ name: 'Date', description: 'Date custom scalar type', @@ -1087,14 +1084,14 @@ describe('generating schema from shorthand', () => { `; const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['post'].something, testDate.getTime()); - assert.equal(result.errors, undefined); + expect(result.data['post'].something).toEqual(testDate.getTime()); + expect(result.errors).toEqual(undefined); }); }); }); describe('enum support', () => { - it('supports passing a GraphQLEnumType in resolveFunctions', () => { + test('supports passing a GraphQLEnumType in resolveFunctions', () => { const shorthand = ` enum Color { RED @@ -1128,40 +1125,38 @@ describe('generating schema from shorthand', () => { resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).to.equal('Query'); - expect(jsSchema.getType('Color')).to.be.an.instanceof(GraphQLEnumType); - expect(jsSchema.getType('NumericEnum')).to.be.an.instanceof( - GraphQLEnumType, - ); + expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getType('Color')).toBeInstanceOf(GraphQLEnumType); + expect(jsSchema.getType('NumericEnum')).toBeInstanceOf(GraphQLEnumType); }); - it('supports passing the value for a GraphQLEnumType in resolveFunctions', () => { + test('supports passing the value for a GraphQLEnumType in resolveFunctions', () => { const shorthand = ` - enum Color { - RED - BLUE - } + enum Color { + RED + BLUE + } - enum NumericEnum { - TEST - } + enum NumericEnum { + TEST + } - schema { - query: Query - } + schema { + query: Query + } - type Query { - redColor: Color - blueColor: Color - numericEnum: NumericEnum - } - `; + type Query { + redColor: Color + blueColor: Color + numericEnum: NumericEnum + } + `; const testQuery = `{ - redColor - blueColor - numericEnum - }`; + redColor + blueColor + numericEnum + }`; const resolveFunctions = { Color: { @@ -1191,39 +1186,39 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['redColor'], 'RED'); - assert.equal(result.data['blueColor'], 'BLUE'); - assert.equal(result.data['numericEnum'], 'TEST'); - assert.equal(result.errors, undefined); + expect(result.data['redColor']).toEqual('RED'); + expect(result.data['blueColor']).toEqual('BLUE'); + expect(result.data['numericEnum']).toEqual('TEST'); + expect(result.errors).toEqual(undefined); }); }); - it('supports resolving the value for a GraphQLEnumType in input types', () => { + test('supports resolving the value for a GraphQLEnumType in input types', () => { const shorthand = ` - enum Color { - RED - BLUE - } + enum Color { + RED + BLUE + } - enum NumericEnum { - TEST - } + enum NumericEnum { + TEST + } - schema { - query: Query - } + schema { + query: Query + } - type Query { - colorTest(color: Color): String - numericTest(num: NumericEnum): Int - } - `; + type Query { + colorTest(color: Color): String + numericTest(num: NumericEnum): Int + } + `; const testQuery = `{ - red: colorTest(color: RED) - blue: colorTest(color: BLUE) - num: numericTest(num: TEST) - }`; + red: colorTest(color: RED) + blue: colorTest(color: BLUE) + num: numericTest(num: TEST) + }`; const resolveFunctions = { Color: { @@ -1250,16 +1245,16 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['red'], resolveFunctions.Color.RED); - assert.equal(result.data['blue'], resolveFunctions.Color.BLUE); - assert.equal(result.data['num'], resolveFunctions.NumericEnum.TEST); - assert.equal(result.errors, undefined); + expect(result.data['red']).toEqual(resolveFunctions.Color.RED); + expect(result.data['blue']).toEqual(resolveFunctions.Color.BLUE); + expect(result.data['num']).toEqual(resolveFunctions.NumericEnum.TEST); + expect(result.errors).toEqual(undefined); }); }); }); describe('default value support', () => { - it('supports default field values', () => { + test('supports default field values', () => { const shorthand = ` enum Color { RED @@ -1296,12 +1291,12 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['red'], resolveFunctions.Color.RED); - assert.equal(result.errors, undefined); + expect(result.data['red']).toEqual(resolveFunctions.Color.RED); + expect(result.errors).toEqual(undefined); }); }); - it('supports changing default field values', () => { + test('supports changing default field values', () => { const shorthand = ` enum Color { RED @@ -1347,13 +1342,13 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - assert.equal(result.data['red'], 'override'); - assert.equal(result.errors, undefined); + expect(result.data['red']).toEqual('override'); + expect(result.errors).toEqual(undefined); }); }); }); - it('can set description and deprecation reason', () => { + test('can set description and deprecation reason', () => { const shorthand = ` type BirdSpecies { name: String!, @@ -1414,11 +1409,11 @@ describe('generating schema from shorthand', () => { }); const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => - assert.deepEqual(result, solution as ExecutionResult), + expect(result).toEqual(solution as ExecutionResult), ); }); - it('shows a warning if a field has arguments but no resolver', () => { + test('shows a warning if a field has arguments but no resolver', () => { const short = ` type Query{ bird(id: ID): String @@ -1440,24 +1435,23 @@ describe('generating schema from shorthand', () => { }, 'Resolver missing for "Query.bird"'); }); - it('does not throw an error if `resolverValidationOptions.requireResolversForArgs` is false', () => { + test('does not throw an error if `resolverValidationOptions.requireResolversForArgs` is false', () => { const short = ` - type Query{ - bird(id: ID): String - } - schema { - query: Query - }`; + type Query{ + bird(id: ID): String + } + schema { + query: Query + }`; const rf = { Query: {} }; - assert.doesNotThrow( + expect( makeExecutableSchema.bind(null, { typeDefs: short, resolvers: rf }), - SchemaError, - ); + ).not.toThrow(); }); - it('throws an error if a resolver is not a function', () => { + test('throws an error if a resolver is not a function', () => { const short = ` type Query{ bird(id: ID): String @@ -1473,10 +1467,10 @@ describe('generating schema from shorthand', () => { typeDefs: short, resolvers: rf, }), - ).to.throw('Resolver Query.bird must be object or function'); + ).toThrowError('Resolver Query.bird must be object or function'); }); - it('shows a warning if a field is not scalar, but has no resolver', () => { + test('shows a warning if a field is not scalar, but has no resolver', () => { const short = ` type Bird{ id: ID @@ -1503,31 +1497,30 @@ describe('generating schema from shorthand', () => { }, 'Resolver missing for "Query.bird"'); }); - it('allows non-scalar field to use default resolver if `resolverValidationOptions.requireResolversForNonScalar` = false', () => { + test('allows non-scalar field to use default resolver if `resolverValidationOptions.requireResolversForNonScalar` = false', () => { const short = ` - type Bird{ - id: ID - } - type Query{ - bird: Bird - } - schema { - query: Query - }`; + type Bird{ + id: ID + } + type Query{ + bird: Bird + } + schema { + query: Query + }`; const rf = {}; - assert.doesNotThrow( + expect( makeExecutableSchema.bind(null, { typeDefs: short, resolvers: rf, resolverValidationOptions: { requireResolversForNonScalar: false }, }), - SchemaError, - ); + ).not.toThrow(); }); - it('throws if resolver defined for non-object/interface type', () => { + test('throws if resolver defined for non-object/interface type', () => { const short = ` union Searchable = Person | Location type Person { @@ -1554,7 +1547,9 @@ describe('generating schema from shorthand', () => { expect(() => makeExecutableSchema({ typeDefs: short, resolvers: rf }), - ).to.throw("Searchable was defined in resolvers, but it's not an object"); + ).toThrowError( + "Searchable was defined in resolvers, but it's not an object", + ); expect(() => makeExecutableSchema({ @@ -1564,10 +1559,10 @@ describe('generating schema from shorthand', () => { allowResolversNotInSchema: true, }, }), - ).to.not.throw(); + ).not.toThrowError(); }); - it('throws if resolver defined for non existent type', () => { + test('throws if resolver defined for non existent type', () => { const short = ` type Person { name: String @@ -1589,7 +1584,7 @@ describe('generating schema from shorthand', () => { expect(() => makeExecutableSchema({ typeDefs: short, resolvers: rf }), - ).to.throw('"Searchable" defined in resolvers, but not in schema'); + ).toThrowError('"Searchable" defined in resolvers, but not in schema'); expect(() => makeExecutableSchema({ @@ -1599,10 +1594,10 @@ describe('generating schema from shorthand', () => { allowResolversNotInSchema: true, }, }), - ).to.not.throw(); + ).not.toThrowError(); }); - it('throws if resolver value is invalid', () => { + test('throws if resolver value is invalid', () => { const short = ` type Person { name: String @@ -1622,13 +1617,13 @@ describe('generating schema from shorthand', () => { expect(() => makeExecutableSchema({ typeDefs: short, resolvers: rf }), - ).to.throw( + ).toThrowError( '"Searchable" defined in resolvers, but has invalid value "undefined". A resolver\'s value ' + 'must be of type object or function.', ); }); - it('doesnt let you define resolver field not present in schema', () => { + test('doesnt let you define resolver field not present in schema', () => { const short = ` type Person { name: String @@ -1650,7 +1645,7 @@ describe('generating schema from shorthand', () => { expect(() => makeExecutableSchema({ typeDefs: short, resolvers: rf }), - ).to.throw('RootQuery.name defined in resolvers, but not in schema'); + ).toThrowError('RootQuery.name defined in resolvers, but not in schema'); expect(() => makeExecutableSchema({ @@ -1660,28 +1655,28 @@ describe('generating schema from shorthand', () => { allowResolversNotInSchema: true, }, }), - ).to.not.throw(); + ).not.toThrowError(); }); - it('does not let you define resolver field for enum values not present in schema', () => { + test('does not let you define resolver field for enum values not present in schema', () => { const short = ` - enum Color { - RED - } + enum Color { + RED + } - enum NumericEnum { - TEST - } + enum NumericEnum { + TEST + } - schema { - query: Query - } + schema { + query: Query + } - type Query { - color: Color - numericEnum: NumericEnum - } - `; + type Query { + color: Color + numericEnum: NumericEnum + } + `; const rf = { Color: { @@ -1695,7 +1690,7 @@ describe('generating schema from shorthand', () => { expect(() => makeExecutableSchema({ typeDefs: short, resolvers: rf }), - ).to.throw( + ).toThrowError( 'Color.NO_RESOLVER was defined in resolvers, but enum is not in schema', ); @@ -1707,10 +1702,10 @@ describe('generating schema from shorthand', () => { allowResolversNotInSchema: true, }, }), - ).to.not.throw(); + ).not.toThrowError(); }); - it('throws if conflicting validation options are passed', () => { + test('throws if conflicting validation options are passed', () => { const typeDefs = ` type Bird { id: ID @@ -1726,15 +1721,13 @@ describe('generating schema from shorthand', () => { function assertOptionsError( resolverValidationOptions: IResolverValidationOptions, ) { - assert.throws( - () => - makeExecutableSchema({ - typeDefs, - resolvers, - resolverValidationOptions, - }), - TypeError, - ); + expect(() => + makeExecutableSchema({ + typeDefs, + resolvers, + resolverValidationOptions, + }), + ).toThrow(); } assertOptionsError({ @@ -1752,17 +1745,17 @@ describe('generating schema from shorthand', () => { }); }); - it('throws for any missing field if `resolverValidationOptions.requireResolversForAllFields` = true', () => { + test('throws for any missing field if `resolverValidationOptions.requireResolversForAllFields` = true', () => { const typeDefs = ` - type Bird { - id: ID - } - type Query { - bird: Bird - } - schema { - query: Query - }`; + type Bird { + id: ID + } + type Query { + bird: Bird + } + schema { + query: Query + }`; function assertFieldError(errorMatcher: string, resolvers: IResolvers) { expectWarning(() => { @@ -1789,17 +1782,17 @@ describe('generating schema from shorthand', () => { }); }); - it('does not throw if all fields are satisfied when `resolverValidationOptions.requireResolversForAllFields` = true', () => { + test('does not throw if all fields are satisfied when `resolverValidationOptions.requireResolversForAllFields` = true', () => { const typeDefs = ` - type Bird { - id: ID - } - type Query { - bird: Bird - } - schema { - query: Query - }`; + type Bird { + id: ID + } + type Query { + bird: Bird + } + schema { + query: Query + }`; const resolvers = { Bird: { @@ -1810,16 +1803,16 @@ describe('generating schema from shorthand', () => { }, }; - assert.doesNotThrow(() => + expect(() => makeExecutableSchema({ typeDefs, resolvers, resolverValidationOptions: { requireResolversForAllFields: true }, }), - ); + ).not.toThrow(); }); - it('throws an error if a resolve field cannot be used', (done) => { + test('throws an error if a resolve field cannot be used', (done) => { const shorthand = ` type BirdSpecies { name: String!, @@ -1848,10 +1841,10 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }), - ).to.throw('RootQuery.speciez defined in resolvers, but not in schema'); + ).toThrowError('RootQuery.speciez defined in resolvers, but not in schema'); done(); }); - it('throws an error if a resolve type is not in schema', (done) => { + test('throws an error if a resolve type is not in schema', (done) => { const shorthand = ` type BirdSpecies { name: String!, @@ -1879,13 +1872,13 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }), - ).to.throw('"BootQuery" defined in resolvers, but not in schema'); + ).toThrowError('"BootQuery" defined in resolvers, but not in schema'); done(); }); }); describe('providing useful errors from resolvers', () => { - it('logs an error if a resolver fails', () => { + test('logs an error if a resolver fails', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -1913,12 +1906,12 @@ describe('providing useful errors from resolvers', () => { const testQuery = '{ species }'; const expected = 'Error in resolver RootQuery.species\noops!'; return graphql(jsSchema, testQuery).then((_res) => { - assert.equal(logger.errors.length, 1); - assert.equal(logger.errors[0].message, expected); + expect(logger.errors.length).toEqual(1); + expect(logger.errors[0].message).toEqual(expected); }); }); - it('will throw errors on undefined if you tell it to', () => { + test('will throw errors on undefined if you tell it to', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -1946,13 +1939,13 @@ describe('providing useful errors from resolvers', () => { const expectedErr = /Resolver for "RootQuery.species" returned undefined/; const expectedResData = { species: null as string, stuff: 'stuff' }; return graphql(jsSchema, testQuery).then((res) => { - assert.equal(logger.errors.length, 1); - assert.match(logger.errors[0].message, expectedErr); - assert.deepEqual(res.data, expectedResData); + expect(logger.errors.length).toEqual(1); + expect(logger.errors[0].message).toMatch(expectedErr); + expect(res.data).toEqual(expectedResData); }); }); - it('decorateToCatchUndefined preserves default resolvers', () => { + test('decorateToCatchUndefined preserves default resolvers', () => { const shorthand = ` type Thread { name: String @@ -1988,22 +1981,22 @@ describe('providing useful errors from resolvers', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - assert.deepEqual(res.data, expectedResData); + expect(res.data).toEqual(expectedResData); }); }); - it('decorateToCatchUndefined throws even if default resolvers are preserved', () => { + test('decorateToCatchUndefined throws even if default resolvers are preserved', () => { const shorthand = ` - type Thread { - name: String - } - type RootQuery { - thread(name: String): Thread - } - schema { - query: RootQuery - } - `; + type Thread { + name: String + } + type RootQuery { + thread(name: String): Thread + } + schema { + query: RootQuery + } + `; const resolve = { RootQuery: { thread(_root: any, _args: { [key: string]: any }) { @@ -2018,18 +2011,18 @@ describe('providing useful errors from resolvers', () => { allowUndefinedInResolve: false, }); const testQuery = `{ - thread { - name - } - }`; + thread { + name + } + }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).to.equal( + expect(res.errors[0].originalError.message).toBe( 'Resolver for "Thread.name" returned undefined', ); }); }); - it('will use default resolver when returning function properties ', () => { + test('will use default resolver when returning function properties ', () => { const shorthand = ` type Thread { name: String @@ -2065,11 +2058,11 @@ describe('providing useful errors from resolvers', () => { }, }; return graphql(jsSchema, testQuery).then((res) => { - assert.deepEqual(res.data, expectedResData); + expect(res.data).toEqual(expectedResData); }); }); - it('will not throw errors on undefined by default', () => { + test('will not throw errors on undefined by default', () => { const shorthand = ` type RootQuery { species(name: String): String @@ -2095,34 +2088,31 @@ describe('providing useful errors from resolvers', () => { const testQuery = '{ species, stuff }'; const expectedResData = { species: null as string, stuff: 'stuff' }; return graphql(jsSchema, testQuery).then((res) => { - assert.equal(logger.errors.length, 0); - assert.deepEqual(res.data, expectedResData); + expect(logger.errors.length).toEqual(0); + expect(res.data).toEqual(expectedResData); }); }); }); describe('Add error logging to schema', () => { - it('throws an error if no logger is provided', () => { - assert.throw( - () => addErrorLoggingToSchema(({} as unknown) as GraphQLSchema), - 'Must provide a logger', - ); + test('throws an error if no logger is provided', () => { + expect(() => + addErrorLoggingToSchema(({} as unknown) as GraphQLSchema), + ).toThrow('Must provide a logger'); }); - it('throws an error if logger.log is not a function', () => { - assert.throw( - () => - addErrorLoggingToSchema( - ({} as unknown) as GraphQLSchema, - ({ log: '1' } as unknown) as ILogger, - ), - 'Logger.log must be a function', - ); + test('throws an error if logger.log is not a function', () => { + expect(() => + addErrorLoggingToSchema( + ({} as unknown) as GraphQLSchema, + ({ log: '1' } as unknown) as ILogger, + ), + ).toThrow('Logger.log must be a function'); }); }); describe('Attaching connectors to schema', () => { describe('Schema level resolver', () => { - it('actually runs', () => { + test('actually runs', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2133,11 +2123,11 @@ describe('Attaching connectors to schema', () => { species(name: "strix") }`; return graphql(jsSchema, query).then((res) => { - expect(res.data['species']).to.equal('ROOTstrix'); + expect(res.data['species']).toBe('ROOTstrix'); }); }); - it('can wrap fields that do not have a resolver defined', () => { + test('can wrap fields that do not have a resolver defined', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2148,11 +2138,11 @@ describe('Attaching connectors to schema', () => { stuff }`; return graphql(jsSchema, query).then((res) => { - expect(res.data['stuff']).to.equal('stuff'); + expect(res.data['stuff']).toBe('stuff'); }); }); - it('runs only once per query', () => { + test('runs only once per query', () => { const simpleResolvers = { RootQuery: { usecontext: (_r: any, _a: { [key: string]: any }, ctx: any) => @@ -2190,11 +2180,11 @@ describe('Attaching connectors to schema', () => { stuff: 'stuff', }; return graphql(jsSchema, query).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('runs twice for two queries', () => { + test('runs twice for two queries', () => { const simpleResolvers = { RootQuery: { usecontext: (_r: any, _a: { [key: string]: any }, ctx: any) => @@ -2240,14 +2230,14 @@ describe('Attaching connectors to schema', () => { stuff: 'stuff2', }; return graphql(jsSchema, query).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); return graphql(jsSchema, query).then((res2) => - expect(res2.data).to.deep.equal(expected2), + expect(res2.data).toEqual(expected2), ); }); }); - it('can attach things to context', () => { + test('can attach things to context', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2263,11 +2253,11 @@ describe('Attaching connectors to schema', () => { usecontext: 'ABC', }; return graphql(jsSchema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('can attach with existing static connectors', () => { + test('can attach with existing static connectors', () => { const resolvers = { RootQuery: { testString(_root: any, _args: { [key: string]: any }, ctx: any) { @@ -2305,12 +2295,12 @@ describe('Attaching connectors to schema', () => { }, }, ).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); }); - it('actually attaches the connectors', () => { + test('actually attaches the connectors', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2323,11 +2313,11 @@ describe('Attaching connectors to schema', () => { useTestConnector: 'works', }; return graphql(jsSchema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('actually passes the context to the connector constructor', () => { + test('actually passes the context to the connector constructor', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2340,11 +2330,11 @@ describe('Attaching connectors to schema', () => { useContextConnector: 'YOYO', }; return graphql(jsSchema, query, {}, { str: 'YOYO' }).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('throws error if trying to attach connectors twice', () => { + test('throws error if trying to attach connectors twice', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2352,12 +2342,12 @@ describe('Attaching connectors to schema', () => { attachConnectorsToContext(jsSchema, testConnectors); return expect(() => attachConnectorsToContext(jsSchema, testConnectors), - ).to.throw( + ).toThrowError( 'Connectors already attached to context, cannot attach more than once', ); }); - it('throws error during execution if context is not an object', () => { + test('throws error during execution if context is not an object', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2367,13 +2357,13 @@ describe('Attaching connectors to schema', () => { useTestConnector }`; return graphql(jsSchema, query, {}, 'notObject').then((res) => { - expect(res.errors[0].originalError.message).to.equal( + expect(res.errors[0].originalError.message).toBe( 'Cannot attach connector because context is not an object: string', ); }); }); - it('throws error if trying to attach non-functional connectors', () => { + test('throws error if trying to attach non-functional connectors', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2385,13 +2375,13 @@ describe('Attaching connectors to schema', () => { useTestConnector }`; return graphql(jsSchema, query, undefined, {}).then((res) => { - expect(res.errors[0].originalError.message).to.equal( + expect(res.errors[0].originalError.message).toBe( 'Connector must be a function or an class', ); }); }); - it('does not interfere with schema level resolver', () => { + test('does not interfere with schema level resolver', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2410,59 +2400,59 @@ describe('Attaching connectors to schema', () => { useTestConnector: 'works', }; return graphql(jsSchema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); // TODO test schemaLevelResolve function with wrong arguments }); // TODO test attachConnectors with wrong arguments - it('throws error if no schema is passed', () => { - expect(() => attachConnectorsToContext()).to.throw( + test('throws error if no schema is passed', () => { + expect(() => attachConnectorsToContext()).toThrowError( 'schema must be an instance of GraphQLSchema. ' + 'This error could be caused by installing more than one version of GraphQL-JS', ); }); - it('throws error if schema is not an instance of GraphQLSchema', () => { - expect(() => attachConnectorsToContext({})).to.throw( + test('throws error if schema is not an instance of GraphQLSchema', () => { + expect(() => attachConnectorsToContext({})).toThrowError( 'schema must be an instance of GraphQLSchema. ' + 'This error could be caused by installing more than one version of GraphQL-JS', ); }); - it('throws error if connectors argument is an array', () => { + test('throws error if connectors argument is an array', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, }); - expect(() => attachConnectorsToContext(jsSchema, [1])).to.throw( + expect(() => attachConnectorsToContext(jsSchema, [1])).toThrowError( 'Expected connectors to be of type object, got Array', ); }); - it('throws error if connectors argument is an empty object', () => { + test('throws error if connectors argument is an empty object', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, }); - return expect(() => attachConnectorsToContext(jsSchema, {})).to.throw( + return expect(() => attachConnectorsToContext(jsSchema, {})).toThrowError( 'Expected connectors to not be an empty object', ); }); - it('throws error if connectors argument is not an object', () => { + test('throws error if connectors argument is not an object', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, }); - return expect(() => attachConnectorsToContext(jsSchema, 'a')).to.throw( + return expect(() => attachConnectorsToContext(jsSchema, 'a')).toThrowError( 'Expected connectors to be of type object, got string', ); }); }); describe('Generating a full graphQL schema with resolvers and connectors', () => { - it('outputs a working GraphQL schema', () => { + test('outputs a working GraphQL schema', () => { const schema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2481,21 +2471,21 @@ describe('Generating a full graphQL schema with resolvers and connectors', () => usecontext: 'ABC', }; return graphql(schema, query, {}, { usecontext: 'ABC' }).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); }); describe('chainResolvers', () => { - it('can chain two resolvers', () => { + test('can chain two resolvers', () => { const r1 = (root: number) => root + 1; const r2 = (root: number, { addend }: { addend: number }) => root + addend; const rChained = chainResolvers([r1, r2]); - expect(rChained(0, { addend: 2 }, null, null)).to.equals(3); + expect(rChained(0, { addend: 2 }, null, null)).toBe(3); }); - it('uses default resolver when a resolver is undefined', () => { + test('uses default resolver when a resolver is undefined', () => { const r1 = (_root: any, { name }: { name: string }) => ({ person: { name }, }); @@ -2505,7 +2495,7 @@ describe('chainResolvers', () => { const info: GraphQLResolveInfo = ({ fieldName: 'person', } as unknown) as GraphQLResolveInfo; - expect(rChained(0, { name: 'tony' }, null, info)).to.equals('tony'); + expect(rChained(0, { name: 'tony' }, null, info)).toBe('tony'); }); }); @@ -2598,7 +2588,7 @@ describe('attachDirectiveResolvers on field', () => { }, }; - it('throws error if directiveResolvers argument is an array', () => { + test('throws error if directiveResolvers argument is an array', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2607,10 +2597,12 @@ describe('attachDirectiveResolvers on field', () => { attachDirectiveResolvers(jsSchema, ([ 1, ] as unknown) as IDirectiveResolvers), - ).to.throw('Expected directiveResolvers to be of type object, got Array'); + ).toThrowError( + 'Expected directiveResolvers to be of type object, got Array', + ); }); - it('throws error if directiveResolvers argument is not an object', () => { + test('throws error if directiveResolvers argument is not an object', () => { const jsSchema = makeExecutableSchema({ typeDefs: testSchema, resolvers: testResolvers, @@ -2620,10 +2612,12 @@ describe('attachDirectiveResolvers on field', () => { jsSchema, ('a' as unknown) as IDirectiveResolvers, ), - ).to.throw('Expected directiveResolvers to be of type object, got string'); + ).toThrowError( + 'Expected directiveResolvers to be of type object, got string', + ); }); - it('upper String from resolvers', () => { + test('upper String from resolvers', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2636,11 +2630,11 @@ describe('attachDirectiveResolvers on field', () => { hello: 'GIAU. TRAN MINH', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('using default resolver for object property', () => { + test('using default resolver for object property', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2657,11 +2651,11 @@ describe('attachDirectiveResolvers on field', () => { }, }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('passes in directive arguments to the directive resolver', () => { + test('passes in directive arguments to the directive resolver', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2674,11 +2668,11 @@ describe('attachDirectiveResolvers on field', () => { withDefault: 'some default_value', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('No effect if missing directive resolvers', () => { + test('No effect if missing directive resolvers', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2691,11 +2685,11 @@ describe('attachDirectiveResolvers on field', () => { hello: 'giau. tran minh', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('If resolver return Promise, keep using it', () => { + test('If resolver return Promise, keep using it', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2708,11 +2702,11 @@ describe('attachDirectiveResolvers on field', () => { asyncResolver: 'GIAU. TRAN MINH', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('Multi directives apply with LTR order', () => { + test('Multi directives apply with LTR order', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2725,11 +2719,11 @@ describe('attachDirectiveResolvers on field', () => { multiDirectives: 'giau. tran minh', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); - it('Allow to catch error from next resolver', () => { + test('Allow to catch error from next resolver', () => { const schema = makeExecutableSchema({ typeDefs: testSchemaWithDirectives, resolvers: testResolversDirectives, @@ -2742,13 +2736,13 @@ describe('attachDirectiveResolvers on field', () => { throwError: 'This error for testing', }; return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).to.deep.equal(expected); + expect(res.data).toEqual(expected); }); }); }); describe('can specify lexical parser options', () => { - it("can specify 'noLocation' option", () => { + test("can specify 'noLocation' option", () => { const schema = makeExecutableSchema({ typeDefs: ` type RootQuery { @@ -2764,10 +2758,10 @@ describe('can specify lexical parser options', () => { }, }); - expect(schema.astNode.loc).to.equal(undefined); + expect(schema.astNode.loc).toBeUndefined(); }); - it("can specify 'experimentalFragmentVariables' option", () => { + test("can specify 'experimentalFragmentVariables' option", () => { const typeDefs = ` type Query { version: Int @@ -2788,13 +2782,13 @@ describe('can specify lexical parser options', () => { experimentalFragmentVariables: true, }, }); - }).to.not.throw(); + }).not.toThrowError(); }); // Note that the experimentalFragmentVariables option requires a client side transform // to hoist the parsed variables into queries, see https://github.com/graphql/graphql-js/pull/1141 // and so this really has nothing to do with schema creation or execution. - it("can use 'experimentalFragmentVariables' option", async () => { + test("can use 'experimentalFragmentVariables' option", async () => { const typeDefs = ` type Query { hello(phrase: String): String @@ -2844,12 +2838,12 @@ describe('can specify lexical parser options', () => { const hoistedQuery = hoist(parsedQuery); const result = await execute(jsSchema, hoistedQuery); - expect(result.data).to.deep.equal({ hello: 'hello world' }); + expect(result.data).toEqual({ hello: 'hello world' }); const result2 = await execute(jsSchema, hoistedQuery, null, null, { phrase: 'world again!', }); - expect(result2.data).to.deep.equal({ hello: 'hello world again!' }); + expect(result2.data).toEqual({ hello: 'hello world again!' }); }); }); @@ -2880,7 +2874,7 @@ describe('interfaces', () => { user { id name } }`; - it('throws if there is no interface resolveType resolver', () => { + test('throws if there is no interface resolveType resolver', () => { const resolvers = { Query: queryResolver, }; @@ -2891,15 +2885,14 @@ describe('interfaces', () => { resolverValidationOptions: { requireResolversForResolveType: true }, }); } catch (error) { - assert.equal( - error.message, + expect(error.message).toEqual( 'Type "Node" is missing a "__resolveType" resolver. Pass false into "resolverValidationOptions.requireResolversForResolveType" to disable this error.', ); return; } throw new Error('Should have had an error.'); }); - it('does not throw if there is an interface resolveType resolver', async () => { + test('does not throw if there is an interface resolveType resolver', async () => { const resolvers = { Query: queryResolver, Node: { @@ -2912,9 +2905,9 @@ describe('interfaces', () => { resolverValidationOptions: { requireResolversForResolveType: true }, }); const response = await graphql(schema, query); - assert.isUndefined(response.errors); + expect(response.errors).not.toBeDefined(); }); - it('does not warn if requireResolversForResolveType is disabled and there are missing resolvers', () => { + test('does not warn if requireResolversForResolveType is disabled and there are missing resolvers', () => { const resolvers = { Query: queryResolver, }; @@ -2927,7 +2920,7 @@ describe('interfaces', () => { }); describe('interface resolver inheritance', () => { - it('copies resolvers from the interfaces', async () => { + test('copies resolvers from the interfaces', async () => { const testSchemaWithInterfaceResolvers = ` interface Node { id: ID! @@ -2967,7 +2960,7 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(schema, query); - assert.deepEqual(response, { + expect(response).toEqual({ data: { user: { id: 'Node:1', @@ -2977,7 +2970,7 @@ describe('interface resolver inheritance', () => { }); }); - it('respects interface order and existing resolvers', async () => { + test('respects interface order and existing resolvers', async () => { const testSchemaWithInterfaceResolvers = ` interface Node { id: ID! @@ -3031,7 +3024,7 @@ describe('interface resolver inheritance', () => { }); const query = '{ cyborg { id name } replicant { id name }}'; const response = await graphql(schema, query); - assert.deepEqual(response, { + expect(response).toEqual({ data: { cyborg: { id: 'Node:1', @@ -3080,7 +3073,7 @@ describe('unions', () => { } }`; - it('throws if there is no union resolveType resolver', () => { + test('throws if there is no union resolveType resolver', () => { const resolvers = { Query: queryResolver, }; @@ -3091,15 +3084,14 @@ describe('unions', () => { resolverValidationOptions: { requireResolversForResolveType: true }, }); } catch (error) { - assert.equal( - error.message, + expect(error.message).toEqual( 'Type "Displayable" is missing a "__resolveType" resolver. Pass false into "resolverValidationOptions.requireResolversForResolveType" to disable this error.', ); return; } throw new Error('Should have had an error.'); }); - it('does not throw if there is a resolveType resolver', async () => { + test('does not throw if there is a resolveType resolver', async () => { const resolvers = { Query: queryResolver, Displayable: { @@ -3112,9 +3104,9 @@ describe('unions', () => { resolverValidationOptions: { requireResolversForResolveType: true }, }); const response = await graphql(schema, query); - assert.isUndefined(response.errors); + expect(response.errors).not.toBeDefined(); }); - it('does not warn if requireResolversForResolveType is disabled', () => { + test('does not warn if requireResolversForResolveType is disabled', () => { const resolvers = { Query: queryResolver, }; diff --git a/src/test/testStitchingFromSubschemas.ts b/src/test/stitchingFromSubschemas.test.ts similarity index 90% rename from src/test/testStitchingFromSubschemas.ts rename to src/test/stitchingFromSubschemas.test.ts index df2ddd71885..74c5af510cb 100644 --- a/src/test/testStitchingFromSubschemas.ts +++ b/src/test/stitchingFromSubschemas.test.ts @@ -11,7 +11,6 @@ // The fragment field is still necessary when working with a remote schema // where this is not possible. -import { expect } from 'chai'; import { graphql } from 'graphql'; import { delegateToSchema, mergeSchemas, addMocksToSchema } from '../index'; @@ -119,7 +118,7 @@ const mergedSchema = mergeSchemas({ }); describe('merging without specifying fragments', () => { - it('works', async () => { + test('works', async () => { const query = ` query { userById(id: 5) { @@ -136,9 +135,9 @@ describe('merging without specifying fragments', () => { const result = await graphql(mergedSchema, query); - expect(result.errors).to.equal(undefined); - expect(result.data.userById.chirps[1].id).to.not.equal(null); - expect(result.data.userById.chirps[1].text).to.not.equal(null); - expect(result.data.userById.chirps[1].author.email).to.not.equal(null); + expect(result.errors).toBeUndefined(); + expect(result.data.userById.chirps[1].id).not.toBe(null); + expect(result.data.userById.chirps[1].text).not.toBe(null); + expect(result.data.userById.chirps[1].author.email).not.toBe(null); }); }); diff --git a/src/test/testTransforms.ts b/src/test/transforms.test.ts similarity index 92% rename from src/test/testTransforms.ts rename to src/test/transforms.test.ts index 21d50c3d60a..33ce62197ba 100644 --- a/src/test/testTransforms.ts +++ b/src/test/transforms.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { GraphQLSchema, GraphQLNamedType, @@ -31,7 +30,7 @@ import { } from '../utils/index'; import { addMocksToSchema } from '../mock/index'; -import { propertySchema, bookingSchema } from './testingSchemas'; +import { propertySchema, bookingSchema } from './fixtures/schemas'; describe('transforms', () => { describe('base transform function', () => { @@ -66,7 +65,7 @@ describe('transforms', () => { }, }); - it('should work', async () => { + test('should work', async () => { const schema = transformSchema(scalarSchema, []); const result = await graphql( schema, @@ -84,7 +83,7 @@ describe('transforms', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { testingScalar: { value: 'test', @@ -93,7 +92,7 @@ describe('transforms', () => { }); }); - it('should work when specified as a schema configuration object', async () => { + test('should work when specified as a schema configuration object', async () => { const schema = transformSchema( { schema: scalarSchema, transforms: [] }, [], @@ -114,7 +113,7 @@ describe('transforms', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { testingScalar: { value: 'test', @@ -126,7 +125,7 @@ describe('transforms', () => { describe('rename type', () => { let schema: GraphQLSchema; - before(() => { + beforeAll(() => { const transforms = [ new RenameTypes( (name: string) => @@ -143,7 +142,7 @@ describe('transforms', () => { ]; schema = transformSchema(propertySchema, transforms); }); - it('should work', async () => { + test('should work', async () => { const result = await graphql( schema, ` @@ -171,7 +170,7 @@ describe('transforms', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { dateTimeTest: '1987-09-25T12:00:00', defaultInputTest: 'bar', @@ -187,7 +186,7 @@ describe('transforms', () => { }); describe('rename root type', () => { - it('should work', async () => { + test('should work', async () => { const subschema = makeExecutableSchema({ typeDefs: ` schema { @@ -228,7 +227,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { doSomething: { query: { @@ -239,7 +238,7 @@ describe('transforms', () => { }); }); - it('works with mergeSchemas', async () => { + test('works with mergeSchemas', async () => { const schemaWithCustomRootTypeNames = makeExecutableSchema({ typeDefs: ` schema { @@ -309,7 +308,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { doSomething: { query: { @@ -324,14 +323,14 @@ describe('transforms', () => { describe('namespace', () => { let schema: GraphQLSchema; - before(() => { + beforeAll(() => { const transforms = [ new RenameTypes((name: string) => `_${name}`), new RenameTypes((name: string) => `Property${name}`), ]; schema = transformSchema(propertySchema, transforms); }); - it('should work', async () => { + test('should work', async () => { const result = await graphql( schema, ` @@ -363,7 +362,7 @@ describe('transforms', () => { }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { dateTimeTest: '1987-09-25T12:00:00', defaultInputTest: 'bar', @@ -386,11 +385,11 @@ describe('transforms', () => { describe('filter to schema', () => { let filter: FilterToSchema; - before(() => { + beforeAll(() => { filter = new FilterToSchema(bookingSchema); }); - it('should remove empty selection sets on objects', () => { + test('should remove empty selection sets on objects', () => { const query = parse(` query customerQuery($id: ID!) { customerById(id: $id) { @@ -417,10 +416,10 @@ describe('transforms', () => { } } `); - expect(print(filteredQuery.document)).to.equal(print(expected)); + expect(print(filteredQuery.document)).toBe(print(expected)); }); - it('should also remove variables when removing empty selection sets', () => { + test('should also remove variables when removing empty selection sets', () => { const query = parse(` query customerQuery($id: ID!, $limit: Int) { customerById(id: $id) { @@ -448,21 +447,21 @@ describe('transforms', () => { } } `); - expect(print(filteredQuery.document)).to.equal(print(expected)); + expect(print(filteredQuery.document)).toBe(print(expected)); }); - it('should remove empty selection sets on wrapped objects (non-nullable/lists)', () => { + test('should remove empty selection sets on wrapped objects (non-nullable/lists)', () => { const query = parse(` - query bookingQuery($id: ID!) { - bookingById(id: $id) { - id - propertyId - customer { - favoriteFood + query bookingQuery($id: ID!) { + bookingById(id: $id) { + id + propertyId + customer { + favoriteFood + } } } - } - `); + `); const filteredQuery = filter.transformRequest({ document: query, variables: { @@ -471,20 +470,20 @@ describe('transforms', () => { }); const expected = parse(` - query bookingQuery($id: ID!) { - bookingById(id: $id) { - id - propertyId + query bookingQuery($id: ID!) { + bookingById(id: $id) { + id + propertyId + } } - } - `); - expect(print(filteredQuery.document)).to.equal(print(expected)); + `); + expect(print(filteredQuery.document)).toBe(print(expected)); }); }); describe('filter type', () => { let schema: GraphQLSchema; - before(() => { + beforeAll(() => { const typeNames = ['ID', 'String', 'DateTime', 'Query', 'Booking']; const transforms = [ new FilterTypes( @@ -494,7 +493,7 @@ describe('transforms', () => { schema = transformSchema(bookingSchema, transforms); }); - it('should work normally', async () => { + test('should work normally', async () => { const result = await graphql( schema, ` @@ -509,7 +508,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { bookingById: { endTime: '2016-06-03', @@ -521,7 +520,7 @@ describe('transforms', () => { }); }); - it('should error on removed types', async () => { + test('should error on removed types', async () => { const result = await graphql( schema, ` @@ -538,9 +537,9 @@ describe('transforms', () => { } `, ); - expect(result.errors).to.not.equal(undefined); - expect(result.errors.length).to.equal(1); - expect(result.errors[0].message).to.equal( + expect(result.errors).toBeDefined(); + expect(result.errors.length).toBe(1); + expect(result.errors[0].message).toBe( 'Cannot query field "customer" on type "Booking".', ); }); @@ -550,7 +549,7 @@ describe('transforms', () => { let data: any; let subschema: GraphQLSchema; let schema: GraphQLSchema; - before(() => { + beforeAll(() => { data = { u1: { id: 'u1', @@ -736,7 +735,7 @@ describe('transforms', () => { }); }); - it('wrapping delegation', async () => { + test('wrapping delegation', async () => { const result = await graphql( schema, ` @@ -749,7 +748,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { addressByUser: { streetAddress: 'Windy Shore 21 A 7', @@ -759,7 +758,7 @@ describe('transforms', () => { }); }); - it('extracting delegation', async () => { + test('extracting delegation', async () => { const result = await graphql( schema, ` @@ -795,7 +794,7 @@ describe('transforms', () => { }, }, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { setUserAndAddress: { username: 'new-username', @@ -812,7 +811,7 @@ describe('transforms', () => { let data: any; let subschema: GraphQLSchema; let schema: GraphQLSchema; - before(() => { + beforeAll(() => { data = { u1: { id: 'user1', @@ -919,7 +918,7 @@ describe('transforms', () => { }); }); - it('wrapping delegation, returning selectionSet', async () => { + test('wrapping delegation, returning selectionSet', async () => { const result = await graphql( schema, ` @@ -932,7 +931,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { addressByUser: { streetAddress: 'Windy Shore 21 A 7', @@ -947,7 +946,7 @@ describe('transforms', () => { let data: any; let subschema: GraphQLSchema; let schema: GraphQLSchema; - before(() => { + beforeAll(() => { data = { u1: { id: 'u1', @@ -1089,7 +1088,7 @@ describe('transforms', () => { }); }); - it('wrapping delegation', async () => { + test('wrapping delegation', async () => { const result = await graphql( schema, ` @@ -1102,7 +1101,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { addressByUser: { streetAddress: 'Windy Shore 21 A 7', @@ -1112,7 +1111,7 @@ describe('transforms', () => { }); }); - it('preserves errors from underlying fields', async () => { + test('preserves errors from underlying fields', async () => { const result = await graphql( schema, ` @@ -1129,7 +1128,7 @@ describe('transforms', () => { defaultMergedResolver, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { addressByUser: { errorTest: null, @@ -1150,7 +1149,7 @@ describe('transforms', () => { }); }); - it('preserves errors from the wrapping field', async () => { + test('preserves errors from the wrapping field', async () => { const result = await graphql( schema, ` @@ -1167,7 +1166,7 @@ describe('transforms', () => { defaultMergedResolver, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { errorTest: null, }, @@ -1186,7 +1185,7 @@ describe('transforms', () => { let data: any; let schema: GraphQLSchema; let subschema: GraphQLSchema; - before(() => { + beforeAll(() => { data = { u1: { id: 'u1', @@ -1262,7 +1261,7 @@ describe('transforms', () => { }, }); }); - it('should work', async () => { + test('should work', async () => { const result = await graphql( schema, ` @@ -1275,7 +1274,7 @@ describe('transforms', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { userById: { id: 'u1', @@ -1291,7 +1290,7 @@ describe('replaces field with processed fragment node', () => { let data: any; let schema: GraphQLSchema; let subschema: GraphQLSchema; - before(() => { + beforeAll(() => { data = { u1: { id: 'u1', @@ -1369,7 +1368,7 @@ describe('replaces field with processed fragment node', () => { }, }); }); - it('should work', async () => { + test('should work', async () => { const result = await graphql( schema, ` @@ -1382,7 +1381,7 @@ describe('replaces field with processed fragment node', () => { `, ); - expect(result).to.deep.equal({ + expect(result).toEqual({ data: { userById: { id: 'u1', diff --git a/src/test/testTypeMerging.ts b/src/test/typeMerging.test.ts similarity index 83% rename from src/test/testTypeMerging.ts rename to src/test/typeMerging.test.ts index 594878dcfaa..59ec52e59fe 100644 --- a/src/test/testTypeMerging.ts +++ b/src/test/typeMerging.test.ts @@ -1,7 +1,6 @@ // The below is meant to be an alternative canonical schema stitching example // which relies on type merging. -import { expect } from 'chai'; import { graphql } from 'graphql'; import { mergeSchemas, addMocksToSchema, makeExecutableSchema } from '../index'; @@ -67,7 +66,7 @@ const mergedSchema = mergeSchemas({ }); describe('merging using type merging', () => { - it('works', async () => { + test('works', async () => { const query = ` query { userById(id: 5) { @@ -84,9 +83,9 @@ describe('merging using type merging', () => { const result = await graphql(mergedSchema, query); - expect(result.errors).to.equal(undefined); - expect(result.data.userById.chirps[1].id).to.not.equal(null); - expect(result.data.userById.chirps[1].text).to.not.equal(null); - expect(result.data.userById.chirps[1].author.email).to.not.equal(null); + expect(result.errors).toBeUndefined(); + expect(result.data.userById.chirps[1].id).not.toBe(null); + expect(result.data.userById.chirps[1].text).not.toBe(null); + expect(result.data.userById.chirps[1].author.email).not.toBe(null); }); }); diff --git a/src/test/testUpload.ts b/src/test/upload.test.ts similarity index 96% rename from src/test/testUpload.ts rename to src/test/upload.test.ts index 6ba6c0ce479..7f1e61128e7 100644 --- a/src/test/testUpload.ts +++ b/src/test/upload.test.ts @@ -2,7 +2,6 @@ import { Server } from 'http'; import { AddressInfo } from 'net'; import { Readable } from 'stream'; -import { expect } from 'chai'; import express, { Express } from 'express'; import graphqlHTTP from 'express-graphql'; import { GraphQLUpload, graphqlUploadExpress } from 'graphql-upload'; @@ -56,7 +55,7 @@ function testGraphqlMultipartRequest(query: string, port: number) { } describe('graphql upload', () => { - it('should return a file after uploading one', async () => { + test('should return a file after uploading one', async () => { const remoteSchema = makeExecutableSchema({ typeDefs: ` scalar Upload @@ -126,7 +125,7 @@ describe('graphql upload', () => { `; const res = await testGraphqlMultipartRequest(query, gatewayPort); - expect(await res.json()).to.deep.equal({ + expect(await res.json()).toEqual({ data: { upload: 'abc', }, diff --git a/src/test/testUtils.ts b/src/test/utils.test.ts similarity index 83% rename from src/test/testUtils.ts rename to src/test/utils.test.ts index 27d36a84aac..08aae390363 100644 --- a/src/test/testUtils.ts +++ b/src/test/utils.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import { GraphQLObjectType } from 'graphql'; import { healSchema } from '../utils/index'; @@ -6,7 +5,7 @@ import { toConfig } from '../polyfills/index'; import { makeExecutableSchema } from '../generate/index'; describe('heal', () => { - it('should prune empty types', () => { + test('should prune empty types', () => { const schema = makeExecutableSchema({ typeDefs: ` type WillBeEmptyObject { @@ -29,6 +28,6 @@ describe('heal', () => { healSchema(schema); const healedTypeMap = schema.getTypeMap(); - expect(healedTypeMap).not.to.haveOwnProperty('WillBeEmptyObject'); + expect(healedTypeMap).not.toHaveProperty('WillBeEmptyObject'); }); }); diff --git a/tsconfig.json b/tsconfig.json index 5ac842d3f2b..f93ebb9a6d4 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "lib": ["es7", "esnext.asynciterable", "dom"], "target": "es5", - "module": "commonjs", + "module": "es2015", "moduleResolution": "node", "esModuleInterop": true, "importHelpers": true,