Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(SchemaComposer): add helper methods
getOrCreateTC()
, `getOrCrea…
…teITC()`, `getOrCreateETC()`, fix flowtype autocompletion
- Loading branch information
Showing
2 changed files
with
162 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,170 @@ | ||
/* @flow strict */ | ||
|
||
import { SchemaComposer } from '../'; | ||
import { TypeComposer } from '../TypeComposer'; | ||
import { InputTypeComposer } from '../InputTypeComposer'; | ||
import { EnumTypeComposer } from '../EnumTypeComposer'; | ||
|
||
describe('Storage [Class]', () => { | ||
describe('SchemaComposer', () => { | ||
it('should implements `add` method', () => { | ||
const storage = new SchemaComposer(); | ||
const someTC = storage.TypeComposer.create({ name: 'validType' }); | ||
storage.add(someTC); | ||
expect(storage.get('validType')).toBe(someTC); | ||
const sc = new SchemaComposer(); | ||
const SomeTC = sc.TypeComposer.create({ name: 'validType' }); | ||
sc.add(SomeTC); | ||
expect(sc.get('validType')).toBe(SomeTC); | ||
}); | ||
|
||
it('should implements `get` method', () => { | ||
const storage = new SchemaComposer(); | ||
const someTC = storage.TypeComposer.create({ name: 'validType' }); | ||
storage.add(someTC); | ||
expect(storage.get('validType')).toBe(someTC); | ||
const sc = new SchemaComposer(); | ||
const SomeTC = sc.TypeComposer.create({ name: 'validType' }); | ||
sc.add(SomeTC); | ||
expect(sc.get('validType')).toBe(SomeTC); | ||
}); | ||
|
||
it('should implements `has` method`', () => { | ||
const storage = new SchemaComposer(); | ||
const someTC = storage.TypeComposer.create({ name: 'validType' }); | ||
storage.add(someTC); | ||
expect(storage.has('validType')).toBe(true); | ||
expect(storage.has('unexistedType')).toBe(false); | ||
const sc = new SchemaComposer(); | ||
const SomeTC = sc.TypeComposer.create({ name: 'validType' }); | ||
sc.add(SomeTC); | ||
expect(sc.has('validType')).toBe(true); | ||
expect(sc.has('unexistedType')).toBe(false); | ||
}); | ||
|
||
describe('getOrCreateTC()', () => { | ||
it('should create TC if not exists', () => { | ||
const sc = new SchemaComposer(); | ||
const UserTC = sc.getOrCreateTC('User'); | ||
expect(UserTC).toBeInstanceOf(TypeComposer); | ||
expect(sc.has('User')).toBeTruthy(); | ||
expect(sc.hasInstance('User', TypeComposer)).toBeTruthy(); | ||
expect(sc.getTC('User')).toBe(UserTC); | ||
}); | ||
|
||
it('should create TC if not exists with onCreate', () => { | ||
const sc = new SchemaComposer(); | ||
const UserTC = sc.getOrCreateTC('User', tc => { | ||
tc.setDescription('User model'); | ||
}); | ||
expect(UserTC.getDescription()).toBe('User model'); | ||
}); | ||
|
||
it('should return already created TC without onCreate', () => { | ||
const sc = new SchemaComposer(); | ||
const UserTC = sc.getOrCreateTC('User', tc => { | ||
tc.setDescription('User model'); | ||
}); | ||
const UserTC2 = sc.getOrCreateTC('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(); | ||
const UserITC = sc.getOrCreateITC('UserInput'); | ||
expect(UserITC).toBeInstanceOf(InputTypeComposer); | ||
expect(sc.has('UserInput')).toBeTruthy(); | ||
expect(sc.hasInstance('UserInput', InputTypeComposer)).toBeTruthy(); | ||
expect(sc.getITC('UserInput')).toBe(UserITC); | ||
}); | ||
|
||
it('should create ITC if not exists with onCreate', () => { | ||
const sc = new 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(); | ||
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('getOrCreateETC()', () => { | ||
it('should create ETC if not exists', () => { | ||
const sc = new SchemaComposer(); | ||
const UserETC = sc.getOrCreateETC('UserEnum'); | ||
expect(UserETC).toBeInstanceOf(EnumTypeComposer); | ||
expect(sc.has('UserEnum')).toBeTruthy(); | ||
expect(sc.hasInstance('UserEnum', EnumTypeComposer)).toBeTruthy(); | ||
expect(sc.getETC('UserEnum')).toBe(UserETC); | ||
}); | ||
|
||
it('should create ETC if not exists with onCreate', () => { | ||
const sc = new 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(); | ||
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('buildSchema()', () => { | ||
it('should throw error, if root fields not defined', () => { | ||
const storage = new SchemaComposer(); | ||
storage.clear(); | ||
const sc = new SchemaComposer(); | ||
sc.clear(); | ||
|
||
expect(() => { | ||
storage.buildSchema(); | ||
sc.buildSchema(); | ||
}).toThrowError(); | ||
}); | ||
}); | ||
|
||
describe('removeEmptyTypes()', () => { | ||
it('should remove fields with Types which have no fields', () => { | ||
const storage = new SchemaComposer(); | ||
const typeWithoutFieldsTC = storage.getOrCreateTC('Stub'); | ||
typeWithoutFieldsTC.setFields({}); | ||
const sc = new SchemaComposer(); | ||
const TypeWithoutFieldsTC = sc.getOrCreateTC('Stub'); | ||
TypeWithoutFieldsTC.setFields({}); | ||
|
||
const viewerTC = storage.getOrCreateTC('Viewer'); | ||
viewerTC.setFields({ | ||
const ViewerTC = sc.getOrCreateTC('Viewer'); | ||
ViewerTC.setFields({ | ||
name: 'String', | ||
stub: typeWithoutFieldsTC, | ||
stub: TypeWithoutFieldsTC, | ||
}); | ||
|
||
/* eslint-disable */ | ||
const oldConsoleLog = console.log; | ||
global.console.log = jest.fn(); | ||
|
||
storage.removeEmptyTypes(viewerTC); | ||
sc.removeEmptyTypes(ViewerTC); | ||
|
||
expect(console.log).lastCalledWith( | ||
"GQC: 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); | ||
expect(ViewerTC.hasField('stub')).toBe(false); | ||
}); | ||
|
||
it('should not produce Maximum call stack size exceeded', () => { | ||
const storage = new SchemaComposer(); | ||
const userTC = storage.getOrCreateTC('User'); | ||
userTC.setField('friend', userTC); | ||
const sc = new SchemaComposer(); | ||
const UserTC = sc.getOrCreateTC('User'); | ||
UserTC.setField('friend', UserTC); | ||
|
||
storage.removeEmptyTypes(userTC); | ||
sc.removeEmptyTypes(UserTC); | ||
}); | ||
}); | ||
}); |