Skip to content

Commit

Permalink
fix(TypeStorage): add getTC(), getITC(), getETC() methods, bett…
Browse files Browse the repository at this point in the history
…er typechecks
  • Loading branch information
nodkz committed Feb 14, 2018
1 parent b559186 commit f7b0a19
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 33 deletions.
75 changes: 53 additions & 22 deletions src/TypeStorage.js
@@ -1,12 +1,19 @@
/* @flow strict */

import { isFunction } from './utils/is';
import { TypeComposer } from './TypeComposer';
import { InputTypeComposer } from './InputTypeComposer';
import { EnumTypeComposer } from './EnumTypeComposer';
import type { GraphQLNamedType } from './graphql';

type K = string;
type V<TContext> = TypeComposer<TContext> | InputTypeComposer | EnumTypeComposer | GraphQLNamedType;

// TypeStorage has all methods from Map class
export class TypeStorage<V, K = string> {
types: Map<K, V>;
export class TypeStorage<TContext> {
types: Map<K, V<TContext>>;

constructor(): TypeStorage<V, K> {
constructor(): TypeStorage<TContext> {
this.types = new Map();

// alive proper Flow type casting in autosuggestions
Expand All @@ -21,44 +28,47 @@ export class TypeStorage<V, K = string> {
this.types.clear();
}

delete(key: K): boolean {
return this.types.delete(key);
delete(typeName: K): boolean {
return this.types.delete(typeName);
}

entries(): Iterator<[K, V]> {
entries(): Iterator<[K, V<TContext>]> {
return this.types.entries();
}

forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => mixed, thisArg?: any): void {
forEach(
callbackfn: (value: V<TContext>, index: K, map: Map<K, V<TContext>>) => mixed,
thisArg?: any
): void {
return this.types.forEach(callbackfn, thisArg);
}

get(key: K): V {
const v = this.types.get(key);
get(typeName: K): V<TContext> {
const v = this.types.get(typeName);
if (!v) {
throw new Error(`Type with name ${JSON.stringify(key)} does not exists in TypeStorage`);
throw new Error(`Type with name ${JSON.stringify(typeName)} does not exists in TypeStorage`);
}
return v;
}

has(key: K): boolean {
return this.types.has(key);
has(typeName: K): boolean {
return this.types.has(typeName);
}

keys(): Iterator<K> {
return this.types.keys();
}

set(key: K, value: V): TypeStorage<V, K> {
this.types.set(key, value);
set(typeName: K, value: V<TContext>): TypeStorage<TContext> {
this.types.set(typeName, value);
return this;
}

values(): Iterator<V> {
values(): Iterator<V<TContext>> {
return this.types.values();
}

add(value: V): void {
add(value: V<TContext>): void {
if (value) {
if (value.getTypeName && value.getTypeName.call) {
// $FlowFixMe
Expand All @@ -70,26 +80,47 @@ export class TypeStorage<V, K = string> {
}
}

hasInstance(key: K, ClassObj: any): boolean {
if (!this.has(key)) return false;
const existedType = (this.get(key): any);
hasInstance(typeName: K, ClassObj: any): boolean {
if (!this.has(typeName)) return false;
const existedType = this.get(typeName);
if (existedType && existedType instanceof ClassObj) {
return true;
}
return false;
}

getOrSet(key: K, typeOrThunk: V | (() => V)): V {
const existedType = (this.types.get(key): any);
getOrSet(typeName: K, typeOrThunk: V<TContext> | (() => V<TContext>)): V<TContext> {
const existedType = (this.types.get(typeName): any);
if (existedType) {
return existedType;
}

const gqType: any = isFunction(typeOrThunk) ? typeOrThunk() : typeOrThunk;
if (gqType) {
this.set(key, gqType);
this.set(typeName, gqType);
}

return gqType;
}

getTC(typeName: string): TypeComposer<TContext> {
if (!this.hasInstance(typeName, TypeComposer)) {
throw new Error(`Cannot find TypeComposer with name ${typeName}`);
}
return (this.get(typeName): any);
}

getITC(typeName: string): InputTypeComposer {
if (!this.hasInstance(typeName, InputTypeComposer)) {
throw new Error(`Cannot find InputTypeComposer with name ${typeName}`);
}
return (this.get(typeName): any);
}

getETC(typeName: string): EnumTypeComposer {
if (!this.hasInstance(typeName, EnumTypeComposer)) {
throw new Error(`Cannot find EnumTypeComposer with name ${typeName}`);
}
return (this.get(typeName): any);
}
}
21 changes: 10 additions & 11 deletions src/__tests__/TypeStorage-test.js
@@ -1,8 +1,7 @@
/* @flow strict */

import { TypeStorage } from '../TypeStorage';

const GraphQLType = 'SomeTypeInstance';
import { GraphQLString } from '../graphql';

let typeStorage;

Expand All @@ -17,8 +16,8 @@ describe('typeStorage', () => {

it('should work `get`, `set`, `has`, `clear` methods and `size` property', () => {
expect(typeStorage.size).toEqual(0);
typeStorage.set('MyType', GraphQLType);
expect(typeStorage.get('MyType')).toEqual(GraphQLType);
typeStorage.set('MyType', GraphQLString);
expect(typeStorage.get('MyType')).toEqual(GraphQLString);
expect(typeStorage.has('MyType')).toEqual(true);
expect(typeStorage.size).toEqual(1);
typeStorage.clear();
Expand All @@ -27,22 +26,22 @@ describe('typeStorage', () => {

describe('getOrSet() method', () => {
it('should return existed value', () => {
typeStorage.set('MyType', GraphQLType);
expect(typeStorage.getOrSet('MyType', () => 'any')).toEqual(GraphQLType);
typeStorage.set('MyType', GraphQLString);
expect(typeStorage.getOrSet('MyType', () => ('SomeOtherType': any))).toEqual(GraphQLString);
});

it('should set new type as function and return type, if key not exists', () => {
expect(typeStorage.getOrSet('MyType', () => GraphQLType)).toEqual(GraphQLType);
expect(typeStorage.get('MyType')).toEqual(GraphQLType);
expect(typeStorage.getOrSet('MyType', () => GraphQLString)).toEqual(GraphQLString);
expect(typeStorage.get('MyType')).toEqual(GraphQLString);
});

it('should set new type and return it, if key not exists', () => {
expect(typeStorage.getOrSet('MyType', GraphQLType)).toEqual(GraphQLType);
expect(typeStorage.get('MyType')).toEqual(GraphQLType);
expect(typeStorage.getOrSet('MyType', GraphQLString)).toEqual(GraphQLString);
expect(typeStorage.get('MyType')).toEqual(GraphQLString);
});

it('should not set new value if it is empty', () => {
expect(typeStorage.getOrSet('MyType', () => null)).toEqual(null);
expect(typeStorage.getOrSet('MyType', () => (null: any))).toEqual(null);
expect(typeStorage.has('MyType')).toEqual(false);
});
});
Expand Down

0 comments on commit f7b0a19

Please sign in to comment.