From d0d4cda5bf32ef192974f78e0a9a768b4ef1e98f Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Thu, 6 Dec 2018 16:32:59 +0200 Subject: [PATCH] Enable Flow check on a several test files + Cleanup --- src/error/__tests__/GraphQLError-test.js | 66 +++++++++++-------- src/execution/__tests__/abstract-test.js | 15 ++++- src/language/__tests__/lexer-test.js | 36 +++++----- src/language/__tests__/schema-printer-test.js | 2 +- src/type/__tests__/definition-test.js | 3 +- src/type/__tests__/enumType-test.js | 29 +++++--- src/type/__tests__/introspection-test.js | 1 - src/type/__tests__/predicate-test.js | 26 ++++++-- src/type/__tests__/schema-test.js | 11 +++- .../__tests__/buildASTSchema-test.js | 12 ++-- src/utilities/__tests__/extendSchema-test.js | 4 +- .../__tests__/separateOperations-test.js | 4 +- 12 files changed, 131 insertions(+), 78 deletions(-) diff --git a/src/error/__tests__/GraphQLError-test.js b/src/error/__tests__/GraphQLError-test.js index 9bf8c407f8..3f7e2347dc 100644 --- a/src/error/__tests__/GraphQLError-test.js +++ b/src/error/__tests__/GraphQLError-test.js @@ -33,9 +33,9 @@ describe('GraphQLError', () => { it('has a name, message, and stack trace', () => { const e = new GraphQLError('msg'); - expect(e.name).to.equal('GraphQLError'); + + expect(e).to.include({ name: 'GraphQLError', message: 'msg' }); expect(e.stack).to.be.a('string'); - expect(e.message).to.equal('msg'); }); it('uses the stack of an original error', () => { @@ -48,51 +48,65 @@ describe('GraphQLError', () => { undefined, original, ); - expect(e.name).to.equal('GraphQLError'); - expect(e.stack).to.equal(original.stack); - expect(e.message).to.equal('msg'); - expect(e.originalError).to.equal(original); + + expect(e).to.include({ + name: 'GraphQLError', + message: 'msg', + stack: original.stack, + originalError: original, + }); }); it('creates new stack if original error has no stack', () => { const original = new Error('original'); const e = new GraphQLError('msg', null, null, null, null, original); - expect(e.name).to.equal('GraphQLError'); + + expect(e).to.include({ + name: 'GraphQLError', + message: 'msg', + originalError: original, + }); expect(e.stack).to.be.a('string'); - expect(e.message).to.equal('msg'); - expect(e.originalError).to.equal(original); }); it('converts nodes to positions and locations', () => { const e = new GraphQLError('msg', [fieldNode]); - expect(e.nodes).to.deep.equal([fieldNode]); - expect(e.source).to.equal(source); - expect(e.positions).to.deep.equal([4]); - expect(e.locations).to.deep.equal([{ line: 2, column: 3 }]); + expect(e).to.have.property('source', source); + expect(e).to.deep.include({ + nodes: [fieldNode], + positions: [4], + locations: [{ line: 2, column: 3 }], + }); }); it('converts single node to positions and locations', () => { const e = new GraphQLError('msg', fieldNode); // Non-array value. - expect(e.nodes).to.deep.equal([fieldNode]); - expect(e.source).to.equal(source); - expect(e.positions).to.deep.equal([4]); - expect(e.locations).to.deep.equal([{ line: 2, column: 3 }]); + expect(e).to.have.property('source', source); + expect(e).to.deep.include({ + nodes: [fieldNode], + positions: [4], + locations: [{ line: 2, column: 3 }], + }); }); it('converts node with loc.start === 0 to positions and locations', () => { const e = new GraphQLError('msg', [operationNode]); - expect(e.nodes).to.deep.equal([operationNode]); - expect(e.source).to.equal(source); - expect(e.positions).to.deep.equal([0]); - expect(e.locations).to.deep.equal([{ line: 1, column: 1 }]); + expect(e).to.have.property('source', source); + expect(e).to.deep.include({ + nodes: [operationNode], + positions: [0], + locations: [{ line: 1, column: 1 }], + }); }); it('converts source and positions to locations', () => { const e = new GraphQLError('msg', null, source, [6]); - expect(e.nodes).to.equal(undefined); - expect(e.source).to.equal(source); - expect(e.positions).to.deep.equal([6]); - expect(e.locations).to.deep.equal([{ line: 2, column: 5 }]); + expect(e).to.have.property('source', source); + expect(e).to.deep.include({ + nodes: undefined, + positions: [6], + locations: [{ line: 2, column: 5 }], + }); }); it('serializes to include message', () => { @@ -114,7 +128,7 @@ describe('GraphQLError', () => { 'to', 'field', ]); - expect(e.path).to.deep.equal(['path', 3, 'to', 'field']); + expect(e).to.have.deep.property('path', ['path', 3, 'to', 'field']); expect(JSON.stringify(e)).to.equal( '{"message":"msg","path":["path",3,"to","field"]}', ); diff --git a/src/execution/__tests__/abstract-test.js b/src/execution/__tests__/abstract-test.js index f9cadd8adc..14f922168d 100644 --- a/src/execution/__tests__/abstract-test.js +++ b/src/execution/__tests__/abstract-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow strict */ import { expect } from 'chai'; @@ -21,6 +21,9 @@ import { } from '../../'; class Dog { + name: string; + woofs: boolean; + constructor(name, woofs) { this.name = name; this.woofs = woofs; @@ -28,6 +31,9 @@ class Dog { } class Cat { + name: string; + meows: boolean; + constructor(name, meows) { this.name = name; this.meows = meows; @@ -35,6 +41,8 @@ class Cat { } class Human { + name: string; + constructor(name) { this.name = name; } @@ -383,7 +391,10 @@ describe('Execute: Handles execution of abstract types', () => { const fooInterface = new GraphQLInterfaceType({ name: 'FooInterface', fields: { bar: { type: GraphQLString } }, - resolveType: () => [], + resolveType() { + // $DisableFlowOnNegativeTest + return []; + }, }); const fooObject = new GraphQLObjectType({ diff --git a/src/language/__tests__/lexer-test.js b/src/language/__tests__/lexer-test.js index d7e1fc60ba..53f7e0f585 100644 --- a/src/language/__tests__/lexer-test.js +++ b/src/language/__tests__/lexer-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow strict */ import { inspect as utilInspect } from 'util'; @@ -12,6 +12,7 @@ import { inspect as utilInspect } from 'util'; import { expect } from 'chai'; import { describe, it } from 'mocha'; import dedent from '../../jsutils/dedent'; +import { GraphQLError } from '../../error'; import { Source } from '../source'; import { createLexer, TokenKind } from '../lexer'; @@ -21,20 +22,16 @@ function lexOne(str) { } function expectSyntaxError(text, message, location) { - try { - lexOne(text); - expect.fail('Expected to throw syntax error'); - } catch (error) { - expect(error.message).to.contain(message); - expect(error.locations).to.deep.equal([location]); - } + expect(() => lexOne(text)) + .to.throw('Syntax Error: ' + message) + .with.deep.property('locations', [location]); } describe('Lexer', () => { it('disallows uncommon control characters', () => { expectSyntaxError( '\u0007', - 'Cannot contain the invalid character "\\u0007"', + 'Cannot contain the invalid character "\\u0007".', { line: 1, column: 1 }, ); }); @@ -236,12 +233,12 @@ describe('Lexer', () => { { line: 1, column: 19 }, ); - expectSyntaxError('"multi\nline"', 'Unterminated string', { + expectSyntaxError('"multi\nline"', 'Unterminated string.', { line: 1, column: 7, }); - expectSyntaxError('"multi\rline"', 'Unterminated string', { + expectSyntaxError('"multi\rline"', 'Unterminated string.', { line: 1, column: 7, }); @@ -672,16 +669,13 @@ describe('Lexer', () => { end: 1, value: 'a', }); - let caughtError; - try { - lexer.advance(); - } catch (error) { - caughtError = error; - } - expect(caughtError.message).to.equal( - 'Syntax Error: Invalid number, expected digit but got: "b".', - ); - expect(caughtError.locations).to.deep.equal([{ line: 1, column: 3 }]); + + expect(() => lexer.advance()) + .throw(GraphQLError) + .that.deep.include({ + message: 'Syntax Error: Invalid number, expected digit but got: "b".', + locations: [{ line: 1, column: 3 }], + }); }); it('produces double linked list of tokens, including comments', () => { diff --git a/src/language/__tests__/schema-printer-test.js b/src/language/__tests__/schema-printer-test.js index 85dd5b0fb7..59164c6329 100644 --- a/src/language/__tests__/schema-printer-test.js +++ b/src/language/__tests__/schema-printer-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow strict */ import { expect } from 'chai'; diff --git a/src/type/__tests__/definition-test.js b/src/type/__tests__/definition-test.js index d6fb8fc2e2..1e66430162 100644 --- a/src/type/__tests__/definition-test.js +++ b/src/type/__tests__/definition-test.js @@ -416,8 +416,7 @@ describe('Type System: Example', () => { }); const types = union.getTypes(); - expect(types.length).to.equal(1); - expect(types[0]).to.equal(ObjectType); + expect(types).to.have.members([ObjectType]); }); it('does not mutate passed field definitions', () => { diff --git a/src/type/__tests__/enumType-test.js b/src/type/__tests__/enumType-test.js index 4c035e4094..aacaa03dfe 100644 --- a/src/type/__tests__/enumType-test.js +++ b/src/type/__tests__/enumType-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow */ import { describe, it } from 'mocha'; @@ -350,18 +350,31 @@ describe('Type System: Enum Values', () => { it('presents a getValues() API for complex enums', () => { const values = ComplexEnum.getValues(); - expect(values.length).to.equal(2); - expect(values[0].name).to.equal('ONE'); - expect(values[0].value).to.equal(Complex1); - expect(values[1].name).to.equal('TWO'); - expect(values[1].value).to.equal(Complex2); + expect(values).to.have.deep.ordered.members([ + { + name: 'ONE', + value: Complex1, + description: undefined, + isDeprecated: false, + deprecationReason: undefined, + astNode: undefined, + }, + { + name: 'TWO', + value: Complex2, + description: undefined, + isDeprecated: false, + deprecationReason: undefined, + astNode: undefined, + }, + ]); }); it('presents a getValue() API for complex enums', () => { const oneValue = ComplexEnum.getValue('ONE'); - expect(oneValue.name).to.equal('ONE'); - expect(oneValue.value).to.equal(Complex1); + expect(oneValue).to.include({ name: 'ONE', value: Complex1 }); + // $DisableFlowOnNegativeTest const badUsage = ComplexEnum.getValue(Complex1); expect(badUsage).to.equal(undefined); }); diff --git a/src/type/__tests__/introspection-test.js b/src/type/__tests__/introspection-test.js index 532a19db3e..def914abe8 100644 --- a/src/type/__tests__/introspection-test.js +++ b/src/type/__tests__/introspection-test.js @@ -888,7 +888,6 @@ describe('Introspection', () => { field: { type: GraphQLString, args: { complex: { type: TestInputObject } }, - resolve: (_, { complex }) => JSON.stringify(complex), }, }, }); diff --git a/src/type/__tests__/predicate-test.js b/src/type/__tests__/predicate-test.js index 62c1f3830a..366472caa7 100644 --- a/src/type/__tests__/predicate-test.js +++ b/src/type/__tests__/predicate-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow strict */ import { describe, it } from 'mocha'; @@ -60,16 +60,20 @@ import { getNamedType, } from '../'; -const ObjectType = new GraphQLObjectType({ name: 'Object' }); -const InterfaceType = new GraphQLInterfaceType({ name: 'Interface' }); +const ObjectType = new GraphQLObjectType({ name: 'Object', fields: {} }); +const InterfaceType = new GraphQLInterfaceType({ + name: 'Interface', + fields: {}, +}); const UnionType = new GraphQLUnionType({ name: 'Union', types: [ObjectType] }); const EnumType = new GraphQLEnumType({ name: 'Enum', values: { foo: {} } }); -const InputObjectType = new GraphQLInputObjectType({ name: 'InputObject' }); +const InputObjectType = new GraphQLInputObjectType({ + name: 'InputObject', + fields: {}, +}); const ScalarType = new GraphQLScalarType({ name: 'Scalar', serialize() {}, - parseValue() {}, - parseLiteral() {}, }); describe('Type predicates', () => { @@ -477,6 +481,7 @@ describe('Type predicates', () => { describe('isRequiredArgument', () => { it('returns true for required arguments', () => { const requiredArg = { + name: 'someArg', type: GraphQLNonNull(GraphQLString), }; expect(isRequiredArgument(requiredArg)).to.equal(true); @@ -484,22 +489,26 @@ describe('Type predicates', () => { it('returns false for optional arguments', () => { const optArg1 = { + name: 'someArg', type: GraphQLString, }; expect(isRequiredArgument(optArg1)).to.equal(false); const optArg2 = { + name: 'someArg', type: GraphQLString, defaultValue: null, }; expect(isRequiredArgument(optArg2)).to.equal(false); const optArg3 = { + name: 'someArg', type: GraphQLList(GraphQLNonNull(GraphQLString)), }; expect(isRequiredArgument(optArg3)).to.equal(false); const optArg4 = { + name: 'someArg', type: GraphQLNonNull(GraphQLString), defaultValue: 'default', }; @@ -510,6 +519,7 @@ describe('Type predicates', () => { describe('isRequiredInputField', () => { it('returns true for required input field', () => { const requiredField = { + name: 'someField', type: GraphQLNonNull(GraphQLString), }; expect(isRequiredInputField(requiredField)).to.equal(true); @@ -517,22 +527,26 @@ describe('Type predicates', () => { it('returns false for optional input field', () => { const optField1 = { + name: 'someField', type: GraphQLString, }; expect(isRequiredInputField(optField1)).to.equal(false); const optField2 = { + name: 'someField', type: GraphQLString, defaultValue: null, }; expect(isRequiredInputField(optField2)).to.equal(false); const optField3 = { + name: 'someField', type: GraphQLList(GraphQLNonNull(GraphQLString)), }; expect(isRequiredInputField(optField3)).to.equal(false); const optField4 = { + name: 'someField', type: GraphQLNonNull(GraphQLString), defaultValue: 'default', }; diff --git a/src/type/__tests__/schema-test.js b/src/type/__tests__/schema-test.js index 48363decaa..5d86d8d298 100644 --- a/src/type/__tests__/schema-test.js +++ b/src/type/__tests__/schema-test.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @noflow + * @flow strict */ import { @@ -98,9 +98,13 @@ describe('Type System: Schema', () => { }); it('checks the configuration for mistakes', () => { + // $DisableFlowOnNegativeTest expect(() => new GraphQLSchema(() => null)).to.throw(); + // $DisableFlowOnNegativeTest expect(() => new GraphQLSchema({ types: {} })).to.throw(); + // $DisableFlowOnNegativeTest expect(() => new GraphQLSchema({ directives: {} })).to.throw(); + // $DisableFlowOnNegativeTest expect(() => new GraphQLSchema({ allowedLegacyNames: {} })).to.throw(); }); }); @@ -127,13 +131,18 @@ describe('Type System: Schema', () => { expect(() => { const config = () => null; config.assumeValid = true; + // $DisableFlowOnNegativeTest return new GraphQLSchema(config); }).to.not.throw(); + expect(() => { return new GraphQLSchema({ assumeValid: true, + // $DisableFlowOnNegativeTest types: {}, + // $DisableFlowOnNegativeTest directives: { reduce: () => [] }, + // $DisableFlowOnNegativeTest allowedLegacyNames: {}, }); }).to.not.throw(); diff --git a/src/utilities/__tests__/buildASTSchema-test.js b/src/utilities/__tests__/buildASTSchema-test.js index 9ee0c8f691..937884e0bb 100644 --- a/src/utilities/__tests__/buildASTSchema-test.js +++ b/src/utilities/__tests__/buildASTSchema-test.js @@ -154,7 +154,7 @@ describe('Schema Builder', () => { } `; const schema = buildSchema(sdl); - expect(schema.getDirectives().length).to.equal(3); + expect(schema.getDirectives()).to.have.lengthOf(3); expect(schema.getDirective('skip')).to.equal(GraphQLSkipDirective); expect(schema.getDirective('include')).to.equal(GraphQLIncludeDirective); expect(schema.getDirective('deprecated')).to.equal( @@ -173,7 +173,7 @@ describe('Schema Builder', () => { } `; const schema = buildSchema(sdl); - expect(schema.getDirectives().length).to.equal(3); + expect(schema.getDirectives()).to.have.lengthOf(3); expect(schema.getDirective('skip')).to.not.equal(GraphQLSkipDirective); expect(schema.getDirective('include')).to.not.equal( GraphQLIncludeDirective, @@ -192,7 +192,7 @@ describe('Schema Builder', () => { } `; const schema = buildSchema(sdl); - expect(schema.getDirectives().length).to.equal(4); + expect(schema.getDirectives()).to.have.lengthOf(4); expect(schema.getDirective('skip')).to.not.equal(undefined); expect(schema.getDirective('include')).to.not.equal(undefined); expect(schema.getDirective('deprecated')).to.not.equal(undefined); @@ -358,7 +358,7 @@ describe('Schema Builder', () => { } `); const errors = validateSchema(schema); - expect(errors.length).to.be.above(0); + expect(errors).to.have.lengthOf.above(0); }); it('Specifying Union type using __typename', () => { @@ -765,7 +765,7 @@ describe('Schema Builder', () => { } `); const errors = validateSchema(schema); - expect(errors.length).to.be.above(0); + expect(errors).to.have.lengthOf.above(0); }); it('Accepts legacy names', () => { @@ -776,7 +776,7 @@ describe('Schema Builder', () => { `; const schema = buildSchema(sdl, { allowedLegacyNames: ['__badName'] }); const errors = validateSchema(schema); - expect(errors.length).to.equal(0); + expect(errors).to.have.lengthOf(0); }); it('Rejects invalid SDL', () => { diff --git a/src/utilities/__tests__/extendSchema-test.js b/src/utilities/__tests__/extendSchema-test.js index 06c180613e..f11549fef5 100644 --- a/src/utilities/__tests__/extendSchema-test.js +++ b/src/utilities/__tests__/extendSchema-test.js @@ -301,7 +301,7 @@ describe('extendSchema', () => { `); const errors = validateSchema(extendedSchema); - expect(errors.length).to.be.above(0); + expect(errors).to.have.lengthOf.above(0); expect(printTestSchemaChanges(extendedSchema)).to.equal(dedent` union SomeUnion = Foo | Biz | SomeUnion @@ -922,7 +922,7 @@ describe('extendSchema', () => { `); const errors = validateSchema(extendedSchema); - expect(errors.length).to.be.above(0); + expect(errors).to.have.lengthOf.above(0); expect(printTestSchemaChanges(extendedSchema)).to.equal(dedent` interface SomeInterface { diff --git a/src/utilities/__tests__/separateOperations-test.js b/src/utilities/__tests__/separateOperations-test.js index 22ce89c591..da14048788 100644 --- a/src/utilities/__tests__/separateOperations-test.js +++ b/src/utilities/__tests__/separateOperations-test.js @@ -54,7 +54,7 @@ describe('separateOperations', () => { const separatedASTs = separateOperations(ast); - expect(Object.keys(separatedASTs)).to.deep.equal(['', 'One', 'Two']); + expect(separatedASTs).to.have.all.keys('', 'One', 'Two'); expect(print(separatedASTs[''])).to.equal(dedent` { @@ -136,7 +136,7 @@ describe('separateOperations', () => { const separatedASTs = separateOperations(ast); - expect(Object.keys(separatedASTs)).to.deep.equal(['One', 'Two']); + expect(separatedASTs).to.have.all.keys('One', 'Two'); expect(print(separatedASTs.One)).to.equal(dedent` query One {