Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: Improve type coverage #2655

Merged
merged 1 commit into from Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/__testUtils__/__tests__/genFuzzStrings-test.js
Expand Up @@ -5,7 +5,10 @@ import { describe, it } from 'mocha';

import genFuzzStrings from '../genFuzzStrings';

function expectFuzzStrings(options) {
function expectFuzzStrings(options: {|
allowedChars: Array<string>,
maxLength: number,
|}) {
return expect(Array.from(genFuzzStrings(options)));
}

Expand Down
88 changes: 45 additions & 43 deletions src/__tests__/starWarsData.js
@@ -1,5 +1,35 @@
// @flow strict

/**
* These are types which correspond to the schema.
* They represent the shape of the data visited during field resolution.
*/
export type Character = {
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
...
};

export type Human = {|
type: 'Human',
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
homePlanet?: string,
|};

export type Droid = {|
type: 'Droid',
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
primaryFunction: string,
|};

/**
* This defines a basic set of data for our Star Wars Schema.
*
Expand All @@ -8,7 +38,7 @@
* JSON objects in a more complex demo.
*/

const luke = {
const luke: Human = {
type: 'Human',
id: '1000',
name: 'Luke Skywalker',
Expand All @@ -17,7 +47,7 @@ const luke = {
homePlanet: 'Tatooine',
};

const vader = {
const vader: Human = {
type: 'Human',
id: '1001',
name: 'Darth Vader',
Expand All @@ -26,15 +56,15 @@ const vader = {
homePlanet: 'Tatooine',
};

const han = {
const han: Human = {
type: 'Human',
id: '1002',
name: 'Han Solo',
friends: ['1000', '1003', '2001'],
appearsIn: [4, 5, 6],
};

const leia = {
const leia: Human = {
type: 'Human',
id: '1003',
name: 'Leia Organa',
Expand All @@ -43,23 +73,23 @@ const leia = {
homePlanet: 'Alderaan',
};

const tarkin = {
const tarkin: Human = {
type: 'Human',
id: '1004',
name: 'Wilhuff Tarkin',
friends: ['1001'],
appearsIn: [4],
};

const humanData = {
const humanData: {| [id: string]: Human |} = {
'1000': luke,
'1001': vader,
'1002': han,
'1003': leia,
'1004': tarkin,
};

const threepio = {
const threepio: Droid = {
type: 'Droid',
id: '2000',
name: 'C-3PO',
Expand All @@ -68,7 +98,7 @@ const threepio = {
primaryFunction: 'Protocol',
};

const artoo = {
const artoo: Droid = {
type: 'Droid',
id: '2001',
name: 'R2-D2',
Expand All @@ -77,53 +107,25 @@ const artoo = {
primaryFunction: 'Astromech',
};

const droidData = {
const droidData: {| [id: string]: Droid |} = {
'2000': threepio,
'2001': artoo,
};

/**
* These are Flow types which correspond to the schema.
* They represent the shape of the data visited during field resolution.
*/
export type Character = {
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
...
};

export type Human = {|
type: 'Human',
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
homePlanet: string,
|};

export type Droid = {|
type: 'Droid',
id: string,
name: string,
friends: Array<string>,
appearsIn: Array<number>,
primaryFunction: string,
|};

/**
* Helper function to get a character by ID.
*/
function getCharacter(id) {
function getCharacter(id: string): Promise<Character | null> {
// Returning a promise just to illustrate that GraphQL.js supports it.
return Promise.resolve(humanData[id] ?? droidData[id]);
}

/**
* Allows us to query for a character's friends.
*/
export function getFriends(character: Character): Array<Promise<Character>> {
export function getFriends(
character: Character,
): Array<Promise<Character | null>> {
// Notice that GraphQL accepts Arrays of Promises.
return character.friends.map((id) => getCharacter(id));
}
Expand All @@ -143,13 +145,13 @@ export function getHero(episode: number): Character {
/**
* Allows us to query for the human with the given id.
*/
export function getHuman(id: string): Human {
export function getHuman(id: string): Human | null {
return humanData[id];
}

/**
* Allows us to query for the droid with the given id.
*/
export function getDroid(id: string): Droid {
export function getDroid(id: string): Droid | null {
return droidData[id];
}
2 changes: 1 addition & 1 deletion src/__tests__/starWarsIntrospection-test.js
Expand Up @@ -7,7 +7,7 @@ import { graphqlSync } from '../graphql';

import { StarWarsSchema } from './starWarsSchema';

function queryStarWars(source) {
function queryStarWars(source: string) {
const result = graphqlSync({ schema: StarWarsSchema, source });
expect(Object.keys(result)).to.deep.equal(['data']);
return result.data;
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/starWarsValidation-test.js
Expand Up @@ -13,7 +13,7 @@ import { StarWarsSchema } from './starWarsSchema';
/**
* Helper function to test a query and the expected response.
*/
function validationErrors(query) {
function validationErrors(query: string) {
const source = new Source(query, 'StarWars.graphql');
const ast = parse(source);
return validate(StarWarsSchema, ast);
Expand Down
6 changes: 3 additions & 3 deletions src/execution/__tests__/abstract-promise-test.js
Expand Up @@ -20,7 +20,7 @@ class Dog {
name: string;
woofs: boolean;

constructor(name, woofs) {
constructor(name: string, woofs: boolean) {
this.name = name;
this.woofs = woofs;
}
Expand All @@ -30,7 +30,7 @@ class Cat {
name: string;
meows: boolean;

constructor(name, meows) {
constructor(name: string, meows: boolean) {
this.name = name;
this.meows = meows;
}
Expand All @@ -39,7 +39,7 @@ class Cat {
class Human {
name: string;

constructor(name) {
constructor(name: string) {
this.name = name;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/execution/__tests__/abstract-test.js
Expand Up @@ -20,7 +20,7 @@ class Dog {
name: string;
woofs: boolean;

constructor(name, woofs) {
constructor(name: string, woofs: boolean) {
this.name = name;
this.woofs = woofs;
}
Expand All @@ -30,7 +30,7 @@ class Cat {
name: string;
meows: boolean;

constructor(name, meows) {
constructor(name: string, meows: boolean) {
this.name = name;
this.meows = meows;
}
Expand All @@ -39,7 +39,7 @@ class Cat {
class Human {
name: string;

constructor(name) {
constructor(name: string) {
this.name = name;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/execution/__tests__/directives-test.js
Expand Up @@ -30,7 +30,7 @@ const rootValue = {
},
};

function executeTestQuery(query) {
function executeTestQuery(query: string) {
const document = parse(query);
return execute({ schema, document, rootValue });
}
Expand Down
39 changes: 23 additions & 16 deletions src/execution/__tests__/executor-test.js
Expand Up @@ -103,7 +103,7 @@ describe('Execute: Handles basic execution tasks', () => {
e: () => 'Egg',
f: 'Fish',
// Called only by DataType::pic static resolver
pic: (size) => 'Pic of size: ' + size,
pic: (size: number) => 'Pic of size: ' + size,
deep: () => deepData,
promise: promiseData,
};
Expand Down Expand Up @@ -1006,15 +1006,15 @@ describe('Execute: Handles basic execution tasks', () => {
class Special {
value: string;

constructor(value) {
constructor(value: string) {
this.value = value;
}
}

class NotSpecial {
value: string;

constructor(value) {
constructor(value: string) {
this.value = value;
}
}
Expand Down Expand Up @@ -1131,12 +1131,15 @@ describe('Execute: Handles basic execution tasks', () => {
});
const document = parse('{ foo }');

function fieldResolver(_source, _args, _context, info) {
// For the purposes of test, just return the name of the field!
return info.fieldName;
}
const result = execute({
schema,
document,
fieldResolver(_source, _args, _context, info) {
// For the purposes of test, just return the name of the field!
return info.fieldName;
},
});

const result = execute({ schema, document, fieldResolver });
expect(result).to.deep.equal({ data: { foo: 'foo' } });
});

Expand Down Expand Up @@ -1168,16 +1171,20 @@ describe('Execute: Handles basic execution tasks', () => {
types: [fooObject],
});

let possibleTypes;
function typeResolver(_source, _context, info, abstractType) {
// Resolver should be able to figure out all possible types on its own
possibleTypes = info.schema.getPossibleTypes(abstractType);
const rootValue = { foo: { bar: 'bar' } };

return 'FooObject';
}
let possibleTypes;
const result = execute({
schema,
document,
rootValue,
typeResolver(_source, _context, info, abstractType) {
// Resolver should be able to figure out all possible types on its own
possibleTypes = info.schema.getPossibleTypes(abstractType);

const rootValue = { foo: { bar: 'bar' } };
const result = execute({ schema, document, rootValue, typeResolver });
return 'FooObject';
},
});

expect(result).to.deep.equal({ data: { foo: { bar: 'bar' } } });
expect(possibleTypes).to.deep.equal([fooObject]);
Expand Down
5 changes: 3 additions & 2 deletions src/execution/__tests__/lists-test.js
Expand Up @@ -11,6 +11,7 @@ import {
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
type GraphQLOutputType,
} from '../../type/definition';

import { execute } from '../execute';
Expand All @@ -27,7 +28,7 @@ const rejected = Promise.reject.bind(Promise);
* contains a rejection, testData should be a function that returns that
* rejection so as not to trigger the "unhandled rejection" error watcher.
*/
function check(testType, testData, expected) {
function check(testType: GraphQLOutputType, testData: mixed, expected: mixed) {
return async () => {
const data = { test: testData };

Expand Down Expand Up @@ -71,7 +72,7 @@ describe('Execute: Accepts any iterable as list value', () => {
}),
);

function getArgs(...args) {
function getArgs(...args: Array<string>) {
return args;
}

Expand Down