Skip to content

Commit

Permalink
Restore coverage to 100% (#2372)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov authored Jan 20, 2020
1 parent f07ec24 commit 51e3f14
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 69 deletions.
12 changes: 12 additions & 0 deletions src/execution/__tests__/variables-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,18 @@ describe('Execute: Handles inputs', () => {
};
}

it('return all errors by default', () => {
const result = getVariableValues(schema, variableDefinitions, inputValue);

expect(result).to.deep.equal({
errors: [
invalidValueError(0, 0),
invalidValueError(1, 1),
invalidValueError(2, 2),
],
});
});

it('when maxErrors is equal to number of errors', () => {
const result = getVariableValues(
schema,
Expand Down
2 changes: 1 addition & 1 deletion src/execution/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export function getVariableValues(
inputs: { +[variable: string]: mixed, ... },
options?: {| maxErrors?: number |},
): CoercedVariableValues {
const maxErrors = options?.maxErrors;
const errors = [];
const maxErrors = options?.maxErrors;
try {
const coerced = coerceVariableValues(schema, varDefNodes, inputs, error => {
if (maxErrors != null && errors.length >= maxErrors) {
Expand Down
8 changes: 5 additions & 3 deletions src/subscription/__tests__/mapAsyncIterator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ describe('mapAsyncIterator', () => {
} catch (e) {
caughtError = e;
}
expect(caughtError?.message).to.equal('Goodbye');

invariant(caughtError != null);
expect(caughtError.message).to.equal('Goodbye');
});

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

const result = await doubles.next();
expect(result.value).to.be.instanceof(Error);
expect(result.value?.message).to.equal('Goodbye');
invariant(result.value instanceof Error);
expect(result.value.message).to.equal('Goodbye');
expect(result.done).to.equal(false);

expect(await doubles.next()).to.deep.equal({
Expand Down
5 changes: 4 additions & 1 deletion src/subscription/__tests__/subscribe-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import EventEmitter from 'events';
import { expect } from 'chai';
import { describe, it } from 'mocha';

import invariant from '../../jsutils/invariant';

import { parse } from '../../language/parser';

import { GraphQLError } from '../../error/GraphQLError';
Expand Down Expand Up @@ -142,7 +144,8 @@ async function expectPromiseToThrow(promise, message) {
/* istanbul ignore next */
expect.fail('promise should have thrown but did not');
} catch (error) {
expect(error?.message).to.equal(message);
invariant(error instanceof Error);
expect(error.message).to.equal(message);
}
}

Expand Down
142 changes: 85 additions & 57 deletions src/type/__tests__/validation-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,88 +13,92 @@ import { buildSchema } from '../../utilities/buildASTSchema';

import { GraphQLSchema } from '../schema';
import { GraphQLString } from '../scalars';
import { GraphQLDirective } from '../directives';
import { validateSchema, assertValidSchema } from '../validate';
import { GraphQLDirective, assertDirective } from '../directives';
import {
type GraphQLNamedType,
type GraphQLInputType,
type GraphQLOutputType,
GraphQLList,
GraphQLNonNull,
GraphQLScalarType,
GraphQLObjectType,
GraphQLInterfaceType,
GraphQLUnionType,
GraphQLEnumType,
GraphQLInputObjectType,
assertScalarType,
assertInterfaceType,
assertObjectType,
assertUnionType,
assertEnumType,
assertInputObjectType,
} from '../definition';

const SomeScalarType = new GraphQLScalarType({ name: 'SomeScalar' });
const SomeSchema = buildSchema(`
scalar SomeScalar
const SomeInterfaceType = new GraphQLInterfaceType({
name: 'SomeInterface',
fields: () => ({ f: { type: SomeObjectType } }),
});
interface SomeInterface { f: SomeObject }
const SomeObjectType = new GraphQLObjectType({
name: 'SomeObject',
fields: () => ({ f: { type: SomeObjectType } }),
interfaces: [SomeInterfaceType],
});
type SomeObject implements SomeInterface { f: SomeObject }
const SomeUnionType = new GraphQLUnionType({
name: 'SomeUnion',
types: [SomeObjectType],
});
union SomeUnion = SomeObject
const SomeEnumType = new GraphQLEnumType({
name: 'SomeEnum',
values: {
ONLY: {},
},
});
enum SomeEnum { ONLY }
const SomeInputObjectType = new GraphQLInputObjectType({
name: 'SomeInputObject',
fields: {
val: { type: GraphQLString, defaultValue: 'hello' },
},
});
input SomeInputObject { val: String = "hello" }
directive @SomeDirective on QUERY
`);

const SomeScalarType = assertScalarType(SomeSchema.getType('SomeScalar'));
const SomeInterfaceType = assertInterfaceType(
SomeSchema.getType('SomeInterface'),
);
const SomeObjectType = assertObjectType(SomeSchema.getType('SomeObject'));
const SomeUnionType = assertUnionType(SomeSchema.getType('SomeUnion'));
const SomeEnumType = assertEnumType(SomeSchema.getType('SomeEnum'));
const SomeInputObjectType = assertInputObjectType(
SomeSchema.getType('SomeInputObject'),
);

const SomeDirective = assertDirective(SomeSchema.getDirective('SomeDirective'));

function withModifiers<T: GraphQLNamedType>(
types: Array<T>,
type: T,
): Array<T | GraphQLList<T> | GraphQLNonNull<T | GraphQLList<T>>> {
return [
...types,
...types.map(type => GraphQLList(type)),
...types.map(type => GraphQLNonNull(type)),
...types.map(type => GraphQLNonNull(GraphQLList(type))),
type,
GraphQLList(type),
GraphQLNonNull(type),
GraphQLNonNull(GraphQLList(type)),
];
}

const outputTypes = withModifiers([
GraphQLString,
SomeScalarType,
SomeEnumType,
SomeObjectType,
SomeUnionType,
SomeInterfaceType,
]);

const notOutputTypes = withModifiers([SomeInputObjectType]);

const inputTypes = withModifiers([
GraphQLString,
SomeScalarType,
SomeEnumType,
SomeInputObjectType,
]);

const notInputTypes = withModifiers([
SomeObjectType,
SomeUnionType,
SomeInterfaceType,
]);
const outputTypes: Array<GraphQLOutputType> = [
...withModifiers(GraphQLString),
...withModifiers(SomeScalarType),
...withModifiers(SomeEnumType),
...withModifiers(SomeObjectType),
...withModifiers(SomeUnionType),
...withModifiers(SomeInterfaceType),
];

const notOutputTypes: Array<GraphQLInputType> = [
...withModifiers(SomeInputObjectType),
];

const inputTypes: Array<GraphQLInputType> = [
...withModifiers(GraphQLString),
...withModifiers(SomeScalarType),
...withModifiers(SomeEnumType),
...withModifiers(SomeInputObjectType),
];

const notInputTypes: Array<GraphQLOutputType> = [
...withModifiers(SomeObjectType),
...withModifiers(SomeUnionType),
...withModifiers(SomeInterfaceType),
];

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

it('rejects a Schema whose types are incorrectly typed', () => {
const schema = new GraphQLSchema({
query: SomeObjectType,
// $DisableFlowOnNegativeTest
types: [{ name: 'SomeType' }, SomeDirective],
});
expect(validateSchema(schema)).to.deep.equal([
{
message: 'Expected GraphQL named type but got: { name: "SomeType" }.',
},
{
message: 'Expected GraphQL named type but got: @SomeDirective.',
locations: [{ line: 14, column: 3 }],
},
]);
});

it('rejects a Schema whose directives are incorrectly typed', () => {
const schema = new GraphQLSchema({
query: SomeObjectType,
// $DisableFlowOnNegativeTest
directives: ['SomeDirective'],
directives: [null, 'SomeDirective', SomeScalarType],
});
expect(validateSchema(schema)).to.deep.equal([
{
message: 'Expected directive but got: null.',
},
{
message: 'Expected directive but got: "SomeDirective".',
},
{
message: 'Expected directive but got: SomeScalar.',
locations: [{ line: 2, column: 3 }],
},
]);
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/type/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function validateTypes(context: SchemaValidationContext): void {
if (!isNamedType(type)) {
context.reportError(
`Expected GraphQL named type but got: ${inspect(type)}.`,
type?.astNode,
type.astNode,
);
continue;
}
Expand Down Expand Up @@ -354,7 +354,7 @@ function validateTypeImplementsInterface(
`Interface field ${iface.name}.${fieldName} expects type ` +
`${inspect(ifaceField.type)} but ${type.name}.${fieldName} ` +
`is type ${inspect(typeField.type)}.`,
[ifaceField.astNode?.type, typeField.astNode?.type],
[ifaceField.astNode.type, typeField.astNode.type],
);
}

Expand All @@ -381,7 +381,7 @@ function validateTypeImplementsInterface(
`expects type ${inspect(ifaceArg.type)} but ` +
`${type.name}.${fieldName}(${argName}:) is type ` +
`${inspect(typeArg.type)}.`,
[ifaceArg.astNode?.type, typeArg.astNode?.type],
[ifaceArg.astNode.type, typeArg.astNode.type],
);
}

Expand Down
14 changes: 14 additions & 0 deletions src/utilities/__tests__/findDeprecatedUsages-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ describe('findDeprecatedUsages', () => {
expect(errors.length).to.equal(0);
});

it('should ignore unknown stuff', () => {
const errors = findDeprecatedUsages(
schema,
parse(`
{
unknownField(unknownArg: UNKNOWN_VALUE)
normalField(enumArg: UNKNOWN_VALUE)
}
`),
);

expect(errors.length).to.equal(0);
});

it('should report usage of deprecated fields', () => {
const errors = findDeprecatedUsages(
schema,
Expand Down
14 changes: 10 additions & 4 deletions src/utilities/__tests__/getOperationAST-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,37 @@ describe('getOperationAST', () => {
const doc = parse(`
{ field }
mutation Test { field }
subscription TestSub { field }`);
subscription TestSub { field }
`);
expect(getOperationAST(doc)).to.equal(null);
});

it('Does not get ambiguous named operation', () => {
const doc = parse(`
query TestQ { field }
mutation TestM { field }
subscription TestS { field }`);
subscription TestS { field }
`);
expect(getOperationAST(doc)).to.equal(null);
});

it('Does not get misnamed operation', () => {
const doc = parse(`
{ field }
query TestQ { field }
mutation TestM { field }
subscription TestS { field }`);
subscription TestS { field }
`);
expect(getOperationAST(doc, 'Unknown')).to.equal(null);
});

it('Gets named operation', () => {
const doc = parse(`
query TestQ { field }
mutation TestM { field }
subscription TestS { field }`);
subscription TestS { field }
`);
expect(getOperationAST(doc, 'TestQ')).to.equal(doc.definitions[0]);
expect(getOperationAST(doc, 'TestM')).to.equal(doc.definitions[1]);
expect(getOperationAST(doc, 'TestS')).to.equal(doc.definitions[2]);
Expand Down

0 comments on commit 51e3f14

Please sign in to comment.