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

Flow to Typescript #191

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ const packageJSON = require('./package.json');
process.env.TZ = 'UTC';

module.exports = {
verbose: true,
name: packageJSON.name,
displayName: packageJSON.name,
globals: {
'ts-jest': {
disableSourceMapSupport: true,
},
},
verbose: true,
transform: {
'\\.[jt]sx?$': 'babel-jest',
'^.+\\.tsx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
testURL: 'http://localhost',
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
testMatch: ['**/*.(spec|test).js'],
testMatch: ['**/*.(spec|test).ts'],
collectCoverage: true,
coverageDirectory: './coverage/',
};
94 changes: 94 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"postinstall": "npm run download && npm run build",
"start": "node lib/server",
"watch": "babel scripts/watch.js | node",
"test": "npm run lint && npm run check && npm run test:only",
"test": "npm run lint && npm run test:only",
"test:only": "jest",
"lint": "eslint src handler",
"lint:fix": "eslint --fix src handler",
Expand All @@ -56,6 +56,7 @@
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@types/graphql-relay": "^0.6.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.3",
Expand All @@ -77,6 +78,8 @@
"jest": "^26.6.3",
"netlify-lambda": "^1.6.3",
"prettier": "^1.18.2",
"sane": "^4.1.0"
"sane": "^4.1.0",
"ts-jest": "^26.4.4",
"typescript": "^4.1.2"
}
}
File renamed without changes.
File renamed without changes.
15 changes: 11 additions & 4 deletions src/api/local.js → src/api/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@
* @flow strict
*/

import swapiData from '../../cache/data';
import swapiData from '../../cache/data.json';

/**
* Given a URL of an object in the SWAPI, return the data
* from our local cache.
*/
// casting json file to a Record with Index.
const typedSwapiData = swapiData as typeof swapiData & { [key: string]: any }
export async function getFromLocalUrl(
url: string,
): Promise<{ [key: string]: any }> {
const text = swapiData[url];
url: unknown,
): Promise<Record<string, any>> {

if (!(typeof url === 'string')) {
throw new Error('Url provided is not a string');
}

const text = typedSwapiData[url];
if (!text) {
throw new Error(`No entry in local cache for ${url}`);
}
Expand Down
36 changes: 36 additions & 0 deletions src/schema/__tests__/apiHelper.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/

import {
getObjectFromUrl,
getObjectsByType,
getObjectFromTypeAndId,
} from '../apiHelper';

describe('API Helper', () => {
it('Gets a person', async () => {
const luke = await getObjectFromUrl('https://swapi.dev/api/people/1/');
expect(luke.name).toBe('Luke Skywalker');
const threePO = await getObjectFromUrl('https://swapi.dev/api/people/2/');
expect(threePO.name).toBe('C-3PO');
});

it('Gets all pages at once', async () => {
const { objects, totalCount } = await getObjectsByType('people');
expect(objects.length).toBe(82);
expect(totalCount).toBe(82);
expect(objects[0].name).toBe('Luke Skywalker');
});

it('Gets a person by ID', async () => {
const luke = await getObjectFromTypeAndId('people', 1);
expect(luke.name).toBe('Luke Skywalker');
const threePO = await getObjectFromTypeAndId('people', 2);
expect(threePO.name).toBe('C-3PO');
});
});
120 changes: 120 additions & 0 deletions src/schema/__tests__/film.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/

import { swapi } from './swapi';

function getDocument(query: string): string {
return `${query}
fragment AllFilmProperties on Film {
director
episodeID
openingCrawl
producers
releaseDate
title
characterConnection(first:1) { edges { node { name } } }
planetConnection(first:1) { edges { node { name } } }
speciesConnection(first:1) { edges { node { name } } }
starshipConnection(first:1) { edges { node { name } } }
vehicleConnection(first:1) { edges { node { name } } }
}
`;
}

describe('Film type', () => {
it('Gets an object by SWAPI ID', async () => {
const query = '{ film(filmID: 1) { title } }';
const result = await swapi(query);
expect(result.data?.film.title).toBe('A New Hope');
});

it('Gets a different object by SWAPI ID', async () => {
const query = '{ film(filmID: 2) { title } }';
const result = await swapi(query);
expect(result.data?.film.title).toBe('The Empire Strikes Back');
});

it('Gets an object by global ID', async () => {
const query = '{ film(filmID: 1) { id, title } }';
const result = await swapi(query);
const nextQuery = `{ film(id: "${result.data?.film.id}") { id, title } }`;
const nextResult = await swapi(nextQuery);
expect(result.data?.film.title).toBe('A New Hope');
expect(nextResult.data?.film.title).toBe('A New Hope');
expect(result.data?.film.id).toBe(nextResult.data?.film.id);
});

it('Gets an object by global ID with node', async () => {
const query = '{ film(filmID: 1) { id, title } }';
const result = await swapi(query);
const nextQuery = `{
node(id: "${result.data?.film.id}") {
... on Film {
id
title
}
}
}`;
const nextResult = await swapi(nextQuery);
expect(result.data?.film.title).toBe('A New Hope');
expect(nextResult.data?.node.title).toBe('A New Hope');
expect(result.data?.film.id).toBe(nextResult.data?.node.id);
});

it('Gets all properties', async () => {
const query = getDocument(
`{
film(filmID: 1) {
...AllFilmProperties
}
}`,
);
const result = await swapi(query);
const expected = {
title: 'A New Hope',
episodeID: 4,
openingCrawl:
"It is a period of civil war.\r\nRebel spaceships, striking\r\nfrom a hidden base, have won\r\ntheir first victory against\r\nthe evil Galactic Empire.\r\n\r\nDuring the battle, Rebel\r\nspies managed to steal secret\r\nplans to the Empire's\r\nultimate weapon, the DEATH\r\nSTAR, an armored space\r\nstation with enough power\r\nto destroy an entire planet.\r\n\r\nPursued by the Empire's\r\nsinister agents, Princess\r\nLeia races home aboard her\r\nstarship, custodian of the\r\nstolen plans that can save her\r\npeople and restore\r\nfreedom to the galaxy....",
director: 'George Lucas',
producers: ['Gary Kurtz', 'Rick McCallum'],
releaseDate: '1977-05-25',
speciesConnection: { edges: [{ node: { name: 'Human' } }] },
starshipConnection: { edges: [{ node: { name: 'CR90 corvette' } }] },
vehicleConnection: { edges: [{ node: { name: 'Sand Crawler' } }] },
characterConnection: { edges: [{ node: { name: 'Luke Skywalker' } }] },
planetConnection: { edges: [{ node: { name: 'Tatooine' } }] },
};
expect(result.data?.film).toMatchObject(expected);
});

it('All objects query', async () => {
const query = getDocument(
'{ allFilms { edges { cursor, node { ...AllFilmProperties } } } }',
);
const result = await swapi(query);
expect(result.data?.allFilms.edges.length).toBe(6);
});

it('Pagination query', async () => {
const query = `{
allFilms(first: 2) { edges { cursor, node { title } } }
}`;
const result = await swapi(query);
expect(
result.data?.allFilms.edges.map((e: any) => e.node.title),
).toMatchObject(['A New Hope', 'The Empire Strikes Back']);
const nextCursor = result.data?.allFilms.edges[1].cursor;
const nextQuery = `{ allFilms(first: 2, after:"${nextCursor}") {
edges { cursor, node { title } } }
}`;
const nextResult = await swapi(nextQuery);
expect(
nextResult.data?.allFilms.edges.map((e: any) => e.node.title),
).toMatchObject(['Return of the Jedi', 'The Phantom Menace']);
});
});
Loading