Files
2017-11-25 23:06:42 -08:00

318 lines
7.9 KiB
JavaScript

import { stripIndent } from 'common-tags';
import {
parse,
isType,
GraphQLID,
GraphQLString,
GraphQLInt,
GraphQLList,
GraphQLNonNull
} from 'graphql';
import {
generateSource
} from '../../src/typescript/codeGeneration';
import { loadSchema } from '../../src/loading';
const starWarsSchema = loadSchema(require.resolve('../fixtures/starwars/schema.json'));
const miscSchema = loadSchema(require.resolve('../fixtures/misc/schema.json'));
import CodeGenerator from '../../src/utilities/CodeGenerator';
import { compileToLegacyIR } from '../../src/compiler/legacyIR';
describe('TypeScript code generation', function() {
let generator;
let compileFromSource;
let addFragment;
function setup(schema) {
const context = {
schema: schema,
operations: {},
fragments: {},
typesUsed: {}
}
generator = new CodeGenerator(context);
compileFromSource = (source) => {
const document = parse(source);
const context = compileToLegacyIR(schema, document, {
mergeInFieldsFromFragmentSpreads: true,
addTypename: true
});
generator.context = context;
return context;
};
addFragment = (fragment) => {
generator.context.fragments[fragment.fragmentName] = fragment;
};
return { generator, compileFromSource, addFragment };
}
describe('#generateSource()', function() {
test(`should generate simple query operations`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroName {
hero {
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate simple query operations including input variables`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroName($episode: Episode) {
hero(episode: $episode) {
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate simple nested query operations including input variables`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroAndFriendsNames($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate simple nested with required elements in lists`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query StarshipCoords {
starship {
coordinates
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate fragmented query operations`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroAndFriendsNames {
hero {
name
...heroFriends
}
}
fragment heroFriends on Character {
friends {
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate query operations with inline fragments`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroAndDetails {
hero {
name
...HeroDetails
}
}
fragment HeroDetails on Character {
... on Droid {
primaryFunction
}
... on Human {
height
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate mutation operations with complex input types`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
mutation ReviewMovie($episode: Episode, $review: ReviewInput) {
createReview(episode: $episode, review: $review) {
stars
commentary
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test(`should generate correct list with custom fragment`, function() {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
fragment Friend on Character {
name
}
query HeroAndFriendsNames($episode: Episode) {
hero(episode: $episode) {
name
friends {
...Friend
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should handle single line comments', () => {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
commentTest {
singleLine
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should handle multi-line comments', () => {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
commentTest {
multiLine
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should handle comments in enums', () => {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
commentTest {
enumCommentTest
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should handle interfaces at root', () => {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
interfaceTest {
prop
... on ImplA {
propA
}
... on ImplB {
propB
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should handle unions at root', () => {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
unionTest {
... on PartialA {
prop
}
... on PartialB {
prop
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should have __typename value matching fragment type on generic type', () => {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query HeroName {
hero {
...HeroWithName
}
}
fragment HeroWithName on Character {
__typename
name
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should have __typename value matching fragment type on specific type', () => {
const { compileFromSource } = setup(starWarsSchema);
const context = compileFromSource(`
query DroidName {
droid {
...DroidWithName
}
}
fragment DroidWithName on Droid {
__typename
name
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
});
});