Skip to content

Commit

Permalink
tests: Improve type coverage (#2655)
Browse files Browse the repository at this point in the history
Based on #2609
  • Loading branch information
IvanGoncharov committed Jun 15, 2020
1 parent 012f9e2 commit e45fb12
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 93 deletions.
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

0 comments on commit e45fb12

Please sign in to comment.