Skip to content

Commit 51e3f14

Browse files
Restore coverage to 100% (#2372)
1 parent f07ec24 commit 51e3f14

File tree

8 files changed

+134
-69
lines changed

8 files changed

+134
-69
lines changed

src/execution/__tests__/variables-test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,18 @@ describe('Execute: Handles inputs', () => {
10171017
};
10181018
}
10191019

1020+
it('return all errors by default', () => {
1021+
const result = getVariableValues(schema, variableDefinitions, inputValue);
1022+
1023+
expect(result).to.deep.equal({
1024+
errors: [
1025+
invalidValueError(0, 0),
1026+
invalidValueError(1, 1),
1027+
invalidValueError(2, 2),
1028+
],
1029+
});
1030+
});
1031+
10201032
it('when maxErrors is equal to number of errors', () => {
10211033
const result = getVariableValues(
10221034
schema,

src/execution/values.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export function getVariableValues(
5050
inputs: { +[variable: string]: mixed, ... },
5151
options?: {| maxErrors?: number |},
5252
): CoercedVariableValues {
53-
const maxErrors = options?.maxErrors;
5453
const errors = [];
54+
const maxErrors = options?.maxErrors;
5555
try {
5656
const coerced = coerceVariableValues(schema, varDefNodes, inputs, error => {
5757
if (maxErrors != null && errors.length >= maxErrors) {

src/subscription/__tests__/mapAsyncIterator-test.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,9 @@ describe('mapAsyncIterator', () => {
273273
} catch (e) {
274274
caughtError = e;
275275
}
276-
expect(caughtError?.message).to.equal('Goodbye');
276+
277+
invariant(caughtError != null);
278+
expect(caughtError.message).to.equal('Goodbye');
277279
});
278280

279281
it('maps over thrown errors if second callback provided', async () => {
@@ -294,8 +296,8 @@ describe('mapAsyncIterator', () => {
294296
});
295297

296298
const result = await doubles.next();
297-
expect(result.value).to.be.instanceof(Error);
298-
expect(result.value?.message).to.equal('Goodbye');
299+
invariant(result.value instanceof Error);
300+
expect(result.value.message).to.equal('Goodbye');
299301
expect(result.done).to.equal(false);
300302

301303
expect(await doubles.next()).to.deep.equal({

src/subscription/__tests__/subscribe-test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import EventEmitter from 'events';
88
import { expect } from 'chai';
99
import { describe, it } from 'mocha';
1010

11+
import invariant from '../../jsutils/invariant';
12+
1113
import { parse } from '../../language/parser';
1214

1315
import { GraphQLError } from '../../error/GraphQLError';
@@ -142,7 +144,8 @@ async function expectPromiseToThrow(promise, message) {
142144
/* istanbul ignore next */
143145
expect.fail('promise should have thrown but did not');
144146
} catch (error) {
145-
expect(error?.message).to.equal(message);
147+
invariant(error instanceof Error);
148+
expect(error.message).to.equal(message);
146149
}
147150
}
148151

src/type/__tests__/validation-test.js

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,88 +13,92 @@ import { buildSchema } from '../../utilities/buildASTSchema';
1313

1414
import { GraphQLSchema } from '../schema';
1515
import { GraphQLString } from '../scalars';
16-
import { GraphQLDirective } from '../directives';
1716
import { validateSchema, assertValidSchema } from '../validate';
17+
import { GraphQLDirective, assertDirective } from '../directives';
1818
import {
1919
type GraphQLNamedType,
2020
type GraphQLInputType,
2121
type GraphQLOutputType,
2222
GraphQLList,
2323
GraphQLNonNull,
24-
GraphQLScalarType,
2524
GraphQLObjectType,
2625
GraphQLInterfaceType,
2726
GraphQLUnionType,
2827
GraphQLEnumType,
2928
GraphQLInputObjectType,
29+
assertScalarType,
30+
assertInterfaceType,
31+
assertObjectType,
32+
assertUnionType,
33+
assertEnumType,
34+
assertInputObjectType,
3035
} from '../definition';
3136

32-
const SomeScalarType = new GraphQLScalarType({ name: 'SomeScalar' });
37+
const SomeSchema = buildSchema(`
38+
scalar SomeScalar
3339
34-
const SomeInterfaceType = new GraphQLInterfaceType({
35-
name: 'SomeInterface',
36-
fields: () => ({ f: { type: SomeObjectType } }),
37-
});
40+
interface SomeInterface { f: SomeObject }
3841
39-
const SomeObjectType = new GraphQLObjectType({
40-
name: 'SomeObject',
41-
fields: () => ({ f: { type: SomeObjectType } }),
42-
interfaces: [SomeInterfaceType],
43-
});
42+
type SomeObject implements SomeInterface { f: SomeObject }
4443
45-
const SomeUnionType = new GraphQLUnionType({
46-
name: 'SomeUnion',
47-
types: [SomeObjectType],
48-
});
44+
union SomeUnion = SomeObject
4945
50-
const SomeEnumType = new GraphQLEnumType({
51-
name: 'SomeEnum',
52-
values: {
53-
ONLY: {},
54-
},
55-
});
46+
enum SomeEnum { ONLY }
5647
57-
const SomeInputObjectType = new GraphQLInputObjectType({
58-
name: 'SomeInputObject',
59-
fields: {
60-
val: { type: GraphQLString, defaultValue: 'hello' },
61-
},
62-
});
48+
input SomeInputObject { val: String = "hello" }
49+
50+
directive @SomeDirective on QUERY
51+
`);
52+
53+
const SomeScalarType = assertScalarType(SomeSchema.getType('SomeScalar'));
54+
const SomeInterfaceType = assertInterfaceType(
55+
SomeSchema.getType('SomeInterface'),
56+
);
57+
const SomeObjectType = assertObjectType(SomeSchema.getType('SomeObject'));
58+
const SomeUnionType = assertUnionType(SomeSchema.getType('SomeUnion'));
59+
const SomeEnumType = assertEnumType(SomeSchema.getType('SomeEnum'));
60+
const SomeInputObjectType = assertInputObjectType(
61+
SomeSchema.getType('SomeInputObject'),
62+
);
63+
64+
const SomeDirective = assertDirective(SomeSchema.getDirective('SomeDirective'));
6365

6466
function withModifiers<T: GraphQLNamedType>(
65-
types: Array<T>,
67+
type: T,
6668
): Array<T | GraphQLList<T> | GraphQLNonNull<T | GraphQLList<T>>> {
6769
return [
68-
...types,
69-
...types.map(type => GraphQLList(type)),
70-
...types.map(type => GraphQLNonNull(type)),
71-
...types.map(type => GraphQLNonNull(GraphQLList(type))),
70+
type,
71+
GraphQLList(type),
72+
GraphQLNonNull(type),
73+
GraphQLNonNull(GraphQLList(type)),
7274
];
7375
}
7476

75-
const outputTypes = withModifiers([
76-
GraphQLString,
77-
SomeScalarType,
78-
SomeEnumType,
79-
SomeObjectType,
80-
SomeUnionType,
81-
SomeInterfaceType,
82-
]);
83-
84-
const notOutputTypes = withModifiers([SomeInputObjectType]);
85-
86-
const inputTypes = withModifiers([
87-
GraphQLString,
88-
SomeScalarType,
89-
SomeEnumType,
90-
SomeInputObjectType,
91-
]);
92-
93-
const notInputTypes = withModifiers([
94-
SomeObjectType,
95-
SomeUnionType,
96-
SomeInterfaceType,
97-
]);
77+
const outputTypes: Array<GraphQLOutputType> = [
78+
...withModifiers(GraphQLString),
79+
...withModifiers(SomeScalarType),
80+
...withModifiers(SomeEnumType),
81+
...withModifiers(SomeObjectType),
82+
...withModifiers(SomeUnionType),
83+
...withModifiers(SomeInterfaceType),
84+
];
85+
86+
const notOutputTypes: Array<GraphQLInputType> = [
87+
...withModifiers(SomeInputObjectType),
88+
];
89+
90+
const inputTypes: Array<GraphQLInputType> = [
91+
...withModifiers(GraphQLString),
92+
...withModifiers(SomeScalarType),
93+
...withModifiers(SomeEnumType),
94+
...withModifiers(SomeInputObjectType),
95+
];
96+
97+
const notInputTypes: Array<GraphQLOutputType> = [
98+
...withModifiers(SomeObjectType),
99+
...withModifiers(SomeUnionType),
100+
...withModifiers(SomeInterfaceType),
101+
];
98102

99103
function schemaWithFieldType(type) {
100104
return new GraphQLSchema({
@@ -380,16 +384,40 @@ describe('Type System: A Schema must have Object root types', () => {
380384
]);
381385
});
382386

387+
it('rejects a Schema whose types are incorrectly typed', () => {
388+
const schema = new GraphQLSchema({
389+
query: SomeObjectType,
390+
// $DisableFlowOnNegativeTest
391+
types: [{ name: 'SomeType' }, SomeDirective],
392+
});
393+
expect(validateSchema(schema)).to.deep.equal([
394+
{
395+
message: 'Expected GraphQL named type but got: { name: "SomeType" }.',
396+
},
397+
{
398+
message: 'Expected GraphQL named type but got: @SomeDirective.',
399+
locations: [{ line: 14, column: 3 }],
400+
},
401+
]);
402+
});
403+
383404
it('rejects a Schema whose directives are incorrectly typed', () => {
384405
const schema = new GraphQLSchema({
385406
query: SomeObjectType,
386407
// $DisableFlowOnNegativeTest
387-
directives: ['SomeDirective'],
408+
directives: [null, 'SomeDirective', SomeScalarType],
388409
});
389410
expect(validateSchema(schema)).to.deep.equal([
411+
{
412+
message: 'Expected directive but got: null.',
413+
},
390414
{
391415
message: 'Expected directive but got: "SomeDirective".',
392416
},
417+
{
418+
message: 'Expected directive but got: SomeScalar.',
419+
locations: [{ line: 2, column: 3 }],
420+
},
393421
]);
394422
});
395423
});

src/type/validate.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ function validateTypes(context: SchemaValidationContext): void {
204204
if (!isNamedType(type)) {
205205
context.reportError(
206206
`Expected GraphQL named type but got: ${inspect(type)}.`,
207-
type?.astNode,
207+
type.astNode,
208208
);
209209
continue;
210210
}
@@ -354,7 +354,7 @@ function validateTypeImplementsInterface(
354354
`Interface field ${iface.name}.${fieldName} expects type ` +
355355
`${inspect(ifaceField.type)} but ${type.name}.${fieldName} ` +
356356
`is type ${inspect(typeField.type)}.`,
357-
[ifaceField.astNode?.type, typeField.astNode?.type],
357+
[ifaceField.astNode.type, typeField.astNode.type],
358358
);
359359
}
360360

@@ -381,7 +381,7 @@ function validateTypeImplementsInterface(
381381
`expects type ${inspect(ifaceArg.type)} but ` +
382382
`${type.name}.${fieldName}(${argName}:) is type ` +
383383
`${inspect(typeArg.type)}.`,
384-
[ifaceArg.astNode?.type, typeArg.astNode?.type],
384+
[ifaceArg.astNode.type, typeArg.astNode.type],
385385
);
386386
}
387387

src/utilities/__tests__/findDeprecatedUsages-test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ describe('findDeprecatedUsages', () => {
3030
expect(errors.length).to.equal(0);
3131
});
3232

33+
it('should ignore unknown stuff', () => {
34+
const errors = findDeprecatedUsages(
35+
schema,
36+
parse(`
37+
{
38+
unknownField(unknownArg: UNKNOWN_VALUE)
39+
normalField(enumArg: UNKNOWN_VALUE)
40+
}
41+
`),
42+
);
43+
44+
expect(errors.length).to.equal(0);
45+
});
46+
3347
it('should report usage of deprecated fields', () => {
3448
const errors = findDeprecatedUsages(
3549
schema,

src/utilities/__tests__/getOperationAST-test.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,31 +32,37 @@ describe('getOperationAST', () => {
3232
const doc = parse(`
3333
{ field }
3434
mutation Test { field }
35-
subscription TestSub { field }`);
35+
subscription TestSub { field }
36+
`);
3637
expect(getOperationAST(doc)).to.equal(null);
3738
});
3839

3940
it('Does not get ambiguous named operation', () => {
4041
const doc = parse(`
4142
query TestQ { field }
4243
mutation TestM { field }
43-
subscription TestS { field }`);
44+
subscription TestS { field }
45+
`);
4446
expect(getOperationAST(doc)).to.equal(null);
4547
});
4648

4749
it('Does not get misnamed operation', () => {
4850
const doc = parse(`
51+
{ field }
52+
4953
query TestQ { field }
5054
mutation TestM { field }
51-
subscription TestS { field }`);
55+
subscription TestS { field }
56+
`);
5257
expect(getOperationAST(doc, 'Unknown')).to.equal(null);
5358
});
5459

5560
it('Gets named operation', () => {
5661
const doc = parse(`
5762
query TestQ { field }
5863
mutation TestM { field }
59-
subscription TestS { field }`);
64+
subscription TestS { field }
65+
`);
6066
expect(getOperationAST(doc, 'TestQ')).to.equal(doc.definitions[0]);
6167
expect(getOperationAST(doc, 'TestM')).to.equal(doc.definitions[1]);
6268
expect(getOperationAST(doc, 'TestS')).to.equal(doc.definitions[2]);

0 commit comments

Comments
 (0)