Files
30-seconds-of-code/node_modules/graphql-compose/lib/__tests__/SchemaComposer-test.js
2019-08-20 15:52:05 +02:00

1116 lines
42 KiB
JavaScript

"use strict";
var _SchemaComposer = require("../SchemaComposer");
var _ObjectTypeComposer = require("../ObjectTypeComposer");
var _InputTypeComposer = require("../InputTypeComposer");
var _ScalarTypeComposer = require("../ScalarTypeComposer");
var _EnumTypeComposer = require("../EnumTypeComposer");
var _InterfaceTypeComposer = require("../InterfaceTypeComposer");
var _UnionTypeComposer = require("../UnionTypeComposer");
var _graphql = require("../graphql");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
describe('SchemaComposer', () => {
it('should implements `add` method', () => {
const sc = new _SchemaComposer.SchemaComposer();
const SomeTC = sc.createObjectTC({
name: 'validType'
});
sc.add(SomeTC);
expect(sc.get('validType')).toBe(SomeTC);
});
it('should implements `get` method', () => {
const sc = new _SchemaComposer.SchemaComposer();
const SomeTC = sc.createObjectTC({
name: 'validType'
});
sc.add(SomeTC);
expect(sc.get('validType')).toBe(SomeTC);
});
it('should implements `has` method`', () => {
const sc = new _SchemaComposer.SchemaComposer();
const SomeTC = sc.createObjectTC({
name: 'validType'
});
sc.add(SomeTC);
expect(sc.has('validType')).toBe(true);
expect(sc.has('unexistedType')).toBe(false);
});
describe('getOrCreateOTC()', () => {
it('should create TC if not exists', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserTC = sc.getOrCreateOTC('User');
expect(UserTC).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.has('User')).toBeTruthy();
expect(sc.hasInstance('User', _ObjectTypeComposer.ObjectTypeComposer)).toBeTruthy();
expect(sc.getOTC('User')).toBe(UserTC);
});
it('should create TC if not exists with onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserTC = sc.getOrCreateOTC('User', tc => {
tc.setDescription('User model');
});
expect(UserTC.getDescription()).toBe('User model');
});
it('should return already created TC without onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserTC = sc.getOrCreateOTC('User', tc => {
tc.setDescription('User model');
});
const UserTC2 = sc.getOrCreateOTC('User', tc => {
tc.setDescription('updated description');
});
expect(UserTC).toBe(UserTC2);
expect(UserTC.getDescription()).toBe('User model');
});
});
describe('getOrCreateITC()', () => {
it('should create ITC if not exists', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserITC = sc.getOrCreateITC('UserInput');
expect(UserITC).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(sc.has('UserInput')).toBeTruthy();
expect(sc.hasInstance('UserInput', _InputTypeComposer.InputTypeComposer)).toBeTruthy();
expect(sc.getITC('UserInput')).toBe(UserITC);
});
it('should create ITC if not exists with onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserITC = sc.getOrCreateITC('UserInput', tc => {
tc.setDescription('User input');
});
expect(UserITC.getDescription()).toBe('User input');
});
it('should return already created ITC without onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserITC = sc.getOrCreateITC('UserInput', tc => {
tc.setDescription('User input');
});
const UserITC2 = sc.getOrCreateITC('UserInput', tc => {
tc.setDescription('updated description');
});
expect(UserITC).toBe(UserITC2);
expect(UserITC.getDescription()).toBe('User input');
});
});
describe('getOrCreateSTC()', () => {
it('should create STC if not exists', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UIntSTC = sc.getOrCreateSTC('UInt');
expect(UIntSTC).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
expect(sc.has('UInt')).toBeTruthy();
expect(sc.hasInstance('UInt', _ScalarTypeComposer.ScalarTypeComposer)).toBeTruthy();
expect(sc.getSTC('UInt')).toBe(UIntSTC);
});
it('should create UTC if not exists with onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UIntTC = sc.getOrCreateSTC('Uint', tc => {
tc.setDescription('Unsigned int');
});
expect(UIntTC.getDescription()).toBe('Unsigned int');
});
it('should return already created STC without onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UIntTC = sc.getOrCreateSTC('UInt', tc => {
tc.setDescription('Positive int');
});
const UIntTC2 = sc.getOrCreateSTC('UInt', tc => {
tc.setDescription('updated description');
});
expect(UIntTC).toBe(UIntTC2);
expect(UIntTC.getDescription()).toBe('Positive int');
});
});
describe('getOrCreateETC()', () => {
it('should create ETC if not exists', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserETC = sc.getOrCreateETC('UserEnum');
expect(UserETC).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
expect(sc.has('UserEnum')).toBeTruthy();
expect(sc.hasInstance('UserEnum', _EnumTypeComposer.EnumTypeComposer)).toBeTruthy();
expect(sc.getETC('UserEnum')).toBe(UserETC);
});
it('should create ETC if not exists with onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserETC = sc.getOrCreateETC('UserEnum', tc => {
tc.setDescription('User enum');
});
expect(UserETC.getDescription()).toBe('User enum');
});
it('should return already created ETC without onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserETC = sc.getOrCreateETC('UserEnum', tc => {
tc.setDescription('User enum');
});
const UserETC2 = sc.getOrCreateETC('UserEnum', tc => {
tc.setDescription('updated description');
});
expect(UserETC).toBe(UserETC2);
expect(UserETC.getDescription()).toBe('User enum');
});
});
describe('getOrCreateIFTC()', () => {
it('should create IFTC if not exists', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserIFTC = sc.getOrCreateIFTC('UserInterface');
expect(UserIFTC).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
expect(sc.has('UserInterface')).toBeTruthy();
expect(sc.hasInstance('UserInterface', _InterfaceTypeComposer.InterfaceTypeComposer)).toBeTruthy();
expect(sc.getIFTC('UserInterface')).toBe(UserIFTC);
});
it('should create IFTC if not exists with onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserIFTC = sc.getOrCreateIFTC('UserInterface', tc => {
tc.setDescription('User interface');
});
expect(UserIFTC.getDescription()).toBe('User interface');
});
it('should return already created IFTC without onCreate', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserIFTC = sc.getOrCreateIFTC('UserInterface', tc => {
tc.setDescription('User interface');
});
const UserIFTC2 = sc.getOrCreateIFTC('UserInterface', tc => {
tc.setDescription('updated description');
});
expect(UserIFTC).toBe(UserIFTC2);
expect(UserIFTC.getDescription()).toBe('User interface');
});
});
describe('buildSchema()', () => {
it('should throw error, if root fields not defined', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.clear();
expect(() => {
sc.buildSchema();
}).toThrowError();
});
it('should accept additional types', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.Query.addFields({
time: 'Int'
});
const me1 = sc.createObjectTC('type Me1 { a: Int }').getType();
const me2 = sc.createObjectTC('type Me2 { a: Int }').getType();
const schema = sc.buildSchema({
types: [me1, me1, me2]
});
expect(schema._typeMap.Me1).toEqual(me1);
expect(schema._typeMap.Me2).toEqual(me2);
});
it('should provide proper Schema when provided only Query',
/*#__PURE__*/
_asyncToGenerator(function* () {
const sc = new _SchemaComposer.SchemaComposer();
sc.Query.addFields({
num: 'Int'
});
const schema = sc.buildSchema();
expect((yield (0, _graphql.graphql)({
schema,
source: `
query {
num
}
`
}))).toEqual({
data: {
num: null
}
});
}));
it('should throw error if only Mutation provided',
/*#__PURE__*/
_asyncToGenerator(function* () {
const sc = new _SchemaComposer.SchemaComposer();
sc.Mutation.addFields({
num: 'Int'
});
expect(() => {
sc.buildSchema();
}).toThrow('Must be initialized Query type');
}));
});
describe('removeEmptyTypes()', () => {
it('should remove fields with Types which have no fields', () => {
const sc = new _SchemaComposer.SchemaComposer();
const TypeWithoutFieldsTC = sc.getOrCreateOTC('Stub');
TypeWithoutFieldsTC.setFields({});
const ViewerTC = sc.getOrCreateOTC('Viewer');
ViewerTC.setFields({
name: 'String',
stub: TypeWithoutFieldsTC
});
/* eslint-disable */
const oldConsoleLog = console.log;
global.console.log = jest.fn();
sc.removeEmptyTypes(ViewerTC);
expect(console.log).lastCalledWith("graphql-compose: Delete field 'Viewer.stub' with type 'Stub', cause it does not have fields.");
global.console.log = oldConsoleLog;
/* eslint-enable */
expect(ViewerTC.hasField('stub')).toBe(false);
});
it('should not produce Maximum call stack size exceeded', () => {
const sc = new _SchemaComposer.SchemaComposer();
const UserTC = sc.getOrCreateOTC('User');
UserTC.setField('friend', UserTC);
sc.removeEmptyTypes(UserTC);
});
});
describe('root type getters', () => {
it('Query', () => {
const sc = new _SchemaComposer.SchemaComposer();
expect(sc.Query).toBe(sc.Query);
expect(sc.Query.getTypeName()).toBe('Query');
});
it('Mutation', () => {
const sc = new _SchemaComposer.SchemaComposer();
expect(sc.Mutation).toBe(sc.Mutation);
expect(sc.Mutation.getTypeName()).toBe('Mutation');
});
it('Subscription', () => {
const sc = new _SchemaComposer.SchemaComposer();
expect(sc.Subscription).toBe(sc.Subscription);
expect(sc.Subscription.getTypeName()).toBe('Subscription');
});
});
describe('SchemaMustHaveType', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createObjectTC(`type Me { name: String }`);
sc.addSchemaMustHaveType(tc);
expect(sc._schemaMustHaveTypes).toContain(tc);
sc.clear();
expect(sc._schemaMustHaveTypes).not.toContain(tc);
sc.addSchemaMustHaveType(tc);
sc.Query.addFields({
time: 'String'
});
const schema = sc.buildSchema();
expect(schema._typeMap.Me).toEqual(tc.getType());
});
describe('getOTC', () => {
it('should return ObjectTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`
type Author {
name: String
}
`);
expect(sc.getOTC('Author')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
});
it('should return GraphQLObjectType as ObjectTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.add(new _graphql.GraphQLObjectType({
name: 'Author',
fields: {
name: {
type: _graphql.GraphQLString
}
}
}));
expect(sc.getOTC('Author')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
});
it('should throw error for incorrect type', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createInputTC(`
input Author {
name: String
}
`);
expect(() => sc.getOTC('Author')).toThrowError('Cannot find ObjectTypeComposer with name Author');
});
});
describe('getITC', () => {
it('should return InputTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createInputTC(`
input Author {
name: String
}
`);
expect(sc.getITC('Author')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
});
it('should return GraphQLInputObjectType as InputTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.add(new _graphql.GraphQLInputObjectType({
name: 'Author',
fields: {
name: {
type: _graphql.GraphQLString
}
}
}));
expect(sc.getITC('Author')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
});
it('should throw error for incorrect type', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`
type Author {
name: String
}
`);
expect(() => sc.getITC('Author')).toThrowError('Cannot find InputTypeComposer with name Author');
});
});
describe('getSTC', () => {
it('should return ScalarTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createScalarTC(`scalar UInt`);
expect(sc.getSTC('UInt')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
it('should return GraphQLScalarType as ScalarTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.add(new _graphql.GraphQLScalarType({
name: 'SomeInt',
serialize: () => {}
}));
expect(sc.getSTC('SomeInt')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
it('should throw error for incorrect type', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`
type Sort {
name: String
}
`);
expect(() => sc.getSTC('Sort')).toThrowError('Cannot find ScalarTypeComposer with name Sort');
});
});
describe('getETC', () => {
it('should return EnumTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createEnumTC(`
enum Sort {
ASC DESC
}
`);
expect(sc.getETC('Sort')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
});
it('should return GraphQLEnumType as EnumTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.add(new _graphql.GraphQLEnumType({
name: 'Sort',
values: {
ASC: {
value: 'ASC'
}
}
}));
expect(sc.getETC('Sort')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
});
it('should throw error for incorrect type', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`
type Sort {
name: String
}
`);
expect(() => sc.getETC('Sort')).toThrowError('Cannot find EnumTypeComposer with name Sort');
});
});
describe('getIFTC', () => {
it('should return InterfaceTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createInterfaceTC(`
interface IFace {
name: String
}
`);
expect(sc.getIFTC('IFace')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should return GraphQLInterfaceType as InterfaceTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.add(new _graphql.GraphQLInterfaceType({
name: 'IFace',
fields: {
name: {
type: _graphql.GraphQLString
}
}
}));
expect(sc.getIFTC('IFace')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should throw error for incorrect type', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`
type IFace {
name: String
}
`);
expect(() => sc.getIFTC('IFace')).toThrowError('Cannot find InterfaceTypeComposer with name IFace');
});
});
describe('getAnyTC()', () => {
it('should return ObjectTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createObjectTC(`type Object1 { name: String }`);
expect(sc.getAnyTC('Object1')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
sc.add(new _graphql.GraphQLObjectType({
name: 'Object2',
fields: () => ({})
}));
expect(sc.getAnyTC('Object2')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
});
it('should return InputTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createInputTC(`input Input1 { name: String }`);
expect(sc.getAnyTC('Input1')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
sc.add(new _graphql.GraphQLInputObjectType({
name: 'Input2',
fields: () => ({})
}));
expect(sc.getAnyTC('Input2')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
});
it('should return ScalarTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createScalarTC(`scalar Scalar1`);
expect(sc.getAnyTC('Scalar1')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
sc.add(new _graphql.GraphQLScalarType({
name: 'Scalar2',
serialize: () => {}
}));
expect(sc.getAnyTC('Scalar2')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
it('should return EnumTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createEnumTC(`enum Enum1 { A B }`);
expect(sc.getAnyTC('Enum1')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
sc.add(new _graphql.GraphQLEnumType({
name: 'Enum2',
values: {}
}));
expect(sc.getAnyTC('Enum2')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
});
it('should return InterfaceTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createInterfaceTC(`interface Iface1 { f1: Int }`);
expect(sc.getAnyTC('Iface1')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
sc.add(new _graphql.GraphQLInterfaceType({
name: 'Iface2',
fields: () => ({})
}));
expect(sc.getAnyTC('Iface2')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should return UnionTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const a = sc.createObjectTC(`type A { f: Int }`);
sc.createUnionTC(`union Union1 = A`);
expect(sc.getAnyTC('Union1')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
sc.add(new _graphql.GraphQLUnionType({
name: 'Union2',
types: [a.getType()]
}));
expect(sc.getAnyTC('Union2')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
});
it('should unwrap graphql List and NonNull', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.getAnyTC(new _graphql.GraphQLNonNull(new _graphql.GraphQLList(_graphql.GraphQLString)));
expect(tc).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
});
describe('add()', () => {
it('should add ObjectTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = _ObjectTypeComposer.ObjectTypeComposer.createTemp('User');
const typeName = sc.add(tc);
expect(typeName).toBe('User');
expect(sc.get('User')).toBe(tc);
expect(sc.getOTC('User')).toBe(tc);
sc.add(`type Object { a: Int }`);
expect(sc.get('Object')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
});
it('should add InputTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const itc = _InputTypeComposer.InputTypeComposer.createTemp('UserInput');
const typeName = sc.add(itc);
expect(typeName).toBe('UserInput');
expect(sc.get('UserInput')).toBe(itc);
expect(sc.getITC('UserInput')).toBe(itc);
sc.add(`input Object { a: Int }`);
expect(sc.get('Object')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
});
it('should add ScalarTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const stc = _ScalarTypeComposer.ScalarTypeComposer.createTemp('UserScalar');
const typeName = sc.add(stc);
expect(typeName).toBe('UserScalar');
expect(sc.get('UserScalar')).toBe(stc);
expect(sc.getSTC('UserScalar')).toBe(stc);
sc.add(`scalar Object`);
expect(sc.get('Object')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
it('should add EnumTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const etc = _EnumTypeComposer.EnumTypeComposer.createTemp('UserEnum');
const typeName = sc.add(etc);
expect(typeName).toBe('UserEnum');
expect(sc.get('UserEnum')).toBe(etc);
expect(sc.getETC('UserEnum')).toBe(etc);
sc.add(`enum Object { A }`);
expect(sc.get('Object')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
});
it('should add GraphQLObjectType', () => {
const sc = new _SchemaComposer.SchemaComposer();
const t = new _graphql.GraphQLObjectType({
name: 'NativeType',
fields: () => {}
});
const typeName = sc.add(t);
expect(typeName).toBe('NativeType');
expect(sc.get('NativeType')).toBe(t);
});
it('should add InterfaceTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const iftc = _InterfaceTypeComposer.InterfaceTypeComposer.createTemp('UserInterface');
const typeName = sc.add(iftc);
expect(typeName).toBe('UserInterface');
expect(sc.get('UserInterface')).toBe(iftc);
expect(sc.getIFTC('UserInterface')).toBe(iftc);
sc.add(`interface Object { a: Int }`);
expect(sc.get('Object')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should add UnionTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const utc = _UnionTypeComposer.UnionTypeComposer.createTemp('UserUnion');
const typeName = sc.add(utc);
expect(typeName).toBe('UserUnion');
expect(sc.get('UserUnion')).toBe(utc);
expect(sc.getUTC('UserUnion')).toBe(utc);
sc.add(`type A { f: Int }`);
sc.add(`union Object = A`);
expect(sc.get('Object')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
});
});
describe('addAsComposer()', () => {
it('should add ObjectTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addAsComposer(`type Object1 { name: String }`);
sc.addAsComposer(_ObjectTypeComposer.ObjectTypeComposer.createTemp(`type Object2 { name: String }`));
sc.addAsComposer(new _graphql.GraphQLObjectType({
name: 'Object3',
fields: () => ({})
}));
expect(sc.get('Object1')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
});
it('should return InputTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addAsComposer(`input Object1 { name: String }`);
sc.addAsComposer(_InputTypeComposer.InputTypeComposer.createTemp(`input Object2 { name: String }`));
sc.addAsComposer(new _graphql.GraphQLInputObjectType({
name: 'Object3',
fields: () => ({})
}));
expect(sc.get('Object1')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
});
it('should return ScalarTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addAsComposer(`scalar Object1`);
sc.addAsComposer(_ScalarTypeComposer.ScalarTypeComposer.createTemp(`scalar Object2`));
sc.addAsComposer(new _graphql.GraphQLScalarType({
name: 'Object3',
serialize: () => ({})
}));
expect(sc.get('Object1')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
});
it('should return EnumTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addAsComposer(`enum Object1 { A B }`);
sc.addAsComposer(_EnumTypeComposer.EnumTypeComposer.createTemp(`enum Object2 { A B }`));
sc.addAsComposer(new _graphql.GraphQLEnumType({
name: 'Object3',
values: {}
}));
expect(sc.get('Object1')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
});
it('should return InterfaceTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addAsComposer(`interface Object1 { a: Int }`);
sc.addAsComposer(_InterfaceTypeComposer.InterfaceTypeComposer.createTemp(`interface Object2 { a: Int }`));
sc.addAsComposer(new _graphql.GraphQLInterfaceType({
name: 'Object3',
fields: () => ({})
}));
expect(sc.get('Object1')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should return UnionTypeComposer', () => {
const sc = new _SchemaComposer.SchemaComposer();
const a = sc.createObjectTC(`type A { f: Int }`);
sc.addAsComposer(`union Object1 = A`);
sc.addAsComposer(_UnionTypeComposer.UnionTypeComposer.createTemp(`union Object2 = A`));
sc.addAsComposer(new _graphql.GraphQLUnionType({
name: 'Object3',
types: [a.getType()]
}));
expect(sc.get('Object1')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
expect(sc.get('Object2')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
expect(sc.get('Object3')).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
});
});
describe('addTypeDefs', () => {
it('should parse types from SDL', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
type Author {
name: String
some(arg: Int): String
}
input AuthorInput {
name: String
}
scalar MyInt
enum Sort {
ASC
DESC
}
interface PersonI {
name: String
}
`);
expect(sc.get('Author')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.get('AuthorInput')).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(sc.get('MyInt')).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
expect(sc.get('Sort')).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
expect(sc.get('PersonI')).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
});
it('should parse cross referenced types from SDL', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
type Author {
posts: [Post]
}
type Post {
author: Author
}
`);
expect(sc.get('Author')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.get('Post')).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer); // Post type should be the same instance
const Post = sc.getOTC('Post').getType();
const PostInAuthor = sc.getOTC('Author').getFieldTC('posts').getType();
expect(Post).toBe(PostInAuthor); // Author type should be the same instance
const Author = sc.getOTC('Author').getType();
const AuthorInPost = sc.getOTC('Post').getFieldTC('author').getType();
expect(Author).toBe(AuthorInPost);
});
it('should replace existed types', () => {
// This behavior maybe changed in future.
// Need to gather more use cases and problems.
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
type Author {
name: String
some(arg: Int): String
}
`);
expect(sc.getOTC('Author').hasFieldArg('some', 'arg')).toBeTruthy();
sc.addTypeDefs(`
type Author {
name: String
}
`);
expect(sc.getOTC('Author').hasFieldArg('some', 'arg')).toBeFalsy();
});
it('should merge Root types', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.Query.addFields({
field1: 'Int'
});
sc.Mutation.addFields({
field2: 'Int'
});
sc.Subscription.addFields({
field3: 'Int'
});
sc.addTypeDefs(`
type Query {
field4: Int
}
type Mutation {
field5: Int
}
type Subscription {
field6: Int
}
`);
expect(sc.Query.getFieldNames()).toEqual(['field1', 'field4']);
expect(sc.Mutation.getFieldNames()).toEqual(['field2', 'field5']);
expect(sc.Subscription.getFieldNames()).toEqual(['field3', 'field6']);
});
});
describe('addResolveMethods', () => {
it('should add resolve methods to fields in graphql-tools way',
/*#__PURE__*/
_asyncToGenerator(function* () {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
schema {
query: Query
}
type Post {
id: Int!
title: String
votes: Int
}
type Query {
posts: [Post]
}
`);
sc.addResolveMethods({
Query: {
posts: () => [{
id: 1,
title: 'Post title'
}]
},
Post: {
votes: () => 10
}
});
const schema = sc.buildSchema();
expect((yield (0, _graphql.graphql)(schema, '{ posts { id title votes } }'))).toEqual({
data: {
posts: [{
id: 1,
title: 'Post title',
votes: 10
}]
}
});
}));
it('should add scalar types', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
scalar Date
`);
sc.addResolveMethods({
Date: new _graphql.GraphQLScalarType({
name: 'Date',
serialize(value) {
return new Date(value).toISOString().slice(0, 10);
}
})
});
expect(sc.get('Date')).toBeInstanceOf(_graphql.GraphQLScalarType);
expect(Array.from(sc.types.keys())).toContain('Date');
});
it('should add scalar types as configs', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
scalar Date
`);
sc.addResolveMethods({
Date: {
name: 'Date',
serialize(value) {
return new Date(value).toISOString().slice(0, 10);
}
}
});
expect(sc.get('Date')).toBeInstanceOf(_graphql.GraphQLScalarType);
expect(Array.from(sc.types.keys())).toContain('Date');
});
});
describe('createTC helper methods', () => {
it('createObjectTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createObjectTC(`type A { f: Int }`);
expect(tc).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(tc.hasField('f')).toBeTruthy();
const tc2 = sc.createObjectTC(`type B { f: Int }`);
expect(tc2).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(tc2.hasField('f')).toBeTruthy();
});
it('createInputTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createInputTC(`input A { f: Int }`);
expect(tc).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(tc.hasField('f')).toBeTruthy();
});
it('createScalarTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createScalarTC(`scalar ABC`);
expect(tc).toBeInstanceOf(_ScalarTypeComposer.ScalarTypeComposer);
expect(tc.getTypeName()).toBe('ABC');
});
it('createEnumTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createEnumTC(`enum A { AAA BBB }`);
expect(tc).toBeInstanceOf(_EnumTypeComposer.EnumTypeComposer);
expect(tc.hasField('AAA')).toBeTruthy();
});
it('createInterfaceTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createInterfaceTC(`interface A { f: Int }`);
expect(tc).toBeInstanceOf(_InterfaceTypeComposer.InterfaceTypeComposer);
expect(tc.hasField('f')).toBeTruthy();
});
it('createUnionTC()', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.addTypeDefs(`
type AA { a: Int }
type BB { b: Int }
`);
const tc = sc.createUnionTC(`union A = AA | BB`);
expect(tc).toBeInstanceOf(_UnionTypeComposer.UnionTypeComposer);
expect(tc.hasType('AA')).toBeTruthy();
});
});
describe('works with directives', () => {
const d1 = new _graphql.GraphQLDirective({
name: 'myDirective1',
locations: [_graphql.DirectiveLocation.INPUT_FIELD_DEFINITION],
args: {
value: {
type: _graphql.GraphQLString
}
}
});
const d2 = new _graphql.GraphQLDirective({
name: 'myDirective2',
locations: [_graphql.DirectiveLocation.INPUT_FIELD_DEFINITION],
args: {
value: {
type: _graphql.GraphQLString
}
}
});
function removeDefaultDirectives(sc) {
_SchemaComposer.BUILT_IN_DIRECTIVES.forEach(d => sc.removeDirective(d));
}
it('has default directives', () => {
const sc = new _SchemaComposer.SchemaComposer();
expect(sc.hasDirective('@skip')).toBeTruthy();
expect(sc.hasDirective('@include')).toBeTruthy();
expect(sc.hasDirective('@deprecated')).toBeTruthy();
expect(sc.hasDirective('@default')).toBeTruthy();
expect(sc.getDirectives()).toHaveLength(4);
});
it('addDirective()', () => {
const sc = new _SchemaComposer.SchemaComposer();
removeDefaultDirectives(sc);
sc.addDirective(d1);
expect(sc.getDirectives()).toHaveLength(1);
sc.addDirective(d1);
expect(sc.getDirectives()).toHaveLength(1);
sc.addDirective(d2);
expect(sc.getDirectives()).toHaveLength(2);
});
it('removeDirective()', () => {
const sc = new _SchemaComposer.SchemaComposer();
removeDefaultDirectives(sc);
sc.addDirective(d1);
sc.addDirective(d2);
expect(sc.getDirectives()).toHaveLength(2);
sc.removeDirective(d1);
expect(sc.getDirectives()).toHaveLength(1);
sc.removeDirective(d1);
expect(sc.getDirectives()).toHaveLength(1);
sc.removeDirective(d2);
expect(sc.getDirectives()).toHaveLength(0);
});
it('addTypeDefs() should add directives', () => {
const sc = new _SchemaComposer.SchemaComposer();
removeDefaultDirectives(sc);
expect(sc.getDirectives()).toHaveLength(0);
sc.addTypeDefs(`
directive @customDirective(level: Int!) on FIELD
`);
expect(sc.getDirectives()).toHaveLength(1);
expect(sc.getDirectives()[0]).toBeInstanceOf(_graphql.GraphQLDirective);
});
it('clear() should clear directives and restore defaults', () => {
const sc = new _SchemaComposer.SchemaComposer();
removeDefaultDirectives(sc);
sc.addDirective(d1);
expect(sc.getDirectives()).toHaveLength(1);
expect(sc.has('String')).toBeTruthy();
sc.clear();
expect(sc.has('String')).toBeTruthy();
expect(sc.has('Int')).toBeTruthy();
expect(sc.hasDirective('@skip')).toBe(true);
expect(sc.hasDirective('@include')).toBe(true);
expect(sc.hasDirective('@deprecated')).toBe(true);
expect(sc.hasDirective('@default')).toBe(true);
expect(sc.getDirectives()).toHaveLength(4);
});
it('hasDirective()', () => {
const sc = new _SchemaComposer.SchemaComposer();
removeDefaultDirectives(sc);
sc.addDirective(d1);
expect(sc.hasDirective(d1)).toBeTruthy();
expect(sc.hasDirective('@myDirective1')).toBeTruthy();
expect(sc.hasDirective('myDirective1')).toBeTruthy();
expect(sc.hasDirective(d2)).toBeFalsy();
expect(sc.hasDirective('myDirective2')).toBeFalsy();
});
});
describe('createTC()', () => {
it('should Create ObjectTC', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createTC(`type MyType { a: Int }`);
expect(tc).toBeInstanceOf(_ObjectTypeComposer.ObjectTypeComposer);
expect(sc.has('MyType')).toBeTruthy(); // schoul return the same type composer instance
expect(sc.get('MyType')).toBe(tc);
expect(sc.createTC(`type MyType { a: Int }`)).toBe(tc);
});
it('should Create InputObjectTC', () => {
const sc = new _SchemaComposer.SchemaComposer();
const tc = sc.createTC(`input MyTypeInput { a: Int }`);
expect(tc).toBeInstanceOf(_InputTypeComposer.InputTypeComposer);
expect(sc.has('MyTypeInput')).toBeTruthy(); // schoul return the same type composer instance
expect(sc.get('MyTypeInput')).toBe(tc);
expect(sc.createTC(`input MyTypeInput { a: Int }`)).toBe(tc);
});
});
describe('merge()', () => {
it('should load types from GraphQLSchema and merge with existed types', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.Query.addFields({
existedInQuery: 'String'
});
sc.Mutation.addFields({
existedInMutation: 'String'
});
sc.Subscription.addFields({
existedInSubscription: 'String'
});
sc.createTC(`type User { age: Int }`);
const schema = new _graphql.GraphQLSchema({
query: new _graphql.GraphQLObjectType({
name: 'MyQuery',
fields: {
user: {
type: new _graphql.GraphQLObjectType({
name: 'User',
interfaces: [new _graphql.GraphQLInterfaceType({
name: 'IUser',
fields: {
name: {
type: _graphql.GraphQLString
}
}
})],
fields: {
name: {
type: _graphql.GraphQLString
}
}
})
}
}
}),
mutation: new _graphql.GraphQLObjectType({
name: 'MyMutation',
fields: {
write: {
type: _graphql.GraphQLString
}
}
}),
subscription: new _graphql.GraphQLObjectType({
name: 'MySubscription',
fields: {
subscribe: {
type: _graphql.GraphQLString
}
}
})
});
sc.merge(schema); // imported schema should extend Query, Mutation and Subscription
expect(sc.Query.getFieldNames()).toEqual(['existedInQuery', 'user']);
expect(sc.Mutation.getFieldNames()).toEqual(['existedInMutation', 'write']);
expect(sc.Subscription.getFieldNames()).toEqual(['existedInSubscription', 'subscribe']); // should merge object types
expect(sc.getOTC('User').getFieldNames()).toEqual(['age', 'name']); // should import interfaces
expect(sc.getIFTC('IUser').getFieldNames()).toEqual(['name']);
});
it('should load types from another SchemaComposer and merge with existed types', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.Query.addFields({
existedInQuery: 'String'
});
sc.Mutation.addFields({
existedInMutation: 'String'
});
sc.Subscription.addFields({
existedInSubscription: 'String'
});
sc.createTC(`type User { age: Int }`);
const sc2 = new _SchemaComposer.SchemaComposer();
sc2.createInterfaceTC(`interface IUser { name: String }`);
sc2.Query.addFields({
user: sc2.createObjectTC(`type User implements IUser { name: String }`)
});
sc2.Mutation.addFields({
write: 'String'
});
sc2.Subscription.addFields({
subscribe: 'String'
});
sc.merge(sc2); // imported schema should extend Query, Mutation and Subscription
expect(sc.Query.getFieldNames()).toEqual(['existedInQuery', 'user']);
expect(sc.Mutation.getFieldNames()).toEqual(['existedInMutation', 'write']);
expect(sc.Subscription.getFieldNames()).toEqual(['existedInSubscription', 'subscribe']); // should merge object types
expect(sc.getOTC('User').getFieldNames()).toEqual(['age', 'name']); // should import interfaces
expect(sc.getIFTC('IUser').getFieldNames()).toEqual(['name']);
});
it('should throw an error on merging different kind of types with the same name', () => {
const sc = new _SchemaComposer.SchemaComposer();
sc.createTC(`type User { name: String }`);
const sc2 = new _SchemaComposer.SchemaComposer();
sc2.createTC(`input User { name: String }`);
expect(() => {
sc.merge(sc2);
}).toThrow(/Cannot merge InputTypeComposer.*with ObjectType/);
});
});
});