Skip to content

Commit 9a0b8b8

Browse files
committed
rebase to master
1 parent 0cbe329 commit 9a0b8b8

File tree

2 files changed

+133
-2
lines changed

2 files changed

+133
-2
lines changed

src/helper.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { createResolver } from "./resolver";
12
import * as merge from "deepmerge";
3+
import { isFunction } from "./util";
24

35
// Helper function to combine multiple resolver definition hashes into a single hash for consumption by Apollostack's graphql-server
46
export const combineResolvers = (resolvers = []) => resolvers
@@ -26,4 +28,36 @@ export const or = (...conditions) => resolver => (...query) => {
2628
});
2729
attempt(0);
2830
});
29-
}
31+
}
32+
33+
export class Composable {
34+
resolver: any; // stricter types won't pass the compiler because createResolver is unexpected on Funciton.
35+
36+
/**
37+
*
38+
* @param resolver
39+
* TODO: a Resolver type is probably needed, but outside the scope of this PR because it requires refactoring resolver.ts
40+
*/
41+
constructor(resFn, errFn) {
42+
this.resolver = createResolver(resFn, errFn);
43+
}
44+
45+
/**
46+
*
47+
* @param resolvers
48+
*/
49+
public compose( resolvers: {} ) {
50+
const composed = {};
51+
52+
Object.keys(resolvers).forEach(key => {
53+
const resolver = resolvers[key];
54+
55+
composed[key] = (resolver.resolve || resolver.error)
56+
? this.resolver.createResolver(resolver.resolve, resolver.error)
57+
: this.resolver.createResolver(resolver);
58+
});
59+
60+
return composed;
61+
}
62+
63+
}

test/unit/helper_spec.js

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { expect } from 'chai';
22
import { stub } from 'sinon';
33

44
import {
5-
combineResolvers, and, or,
5+
combineResolvers, and, or, compose, Composable
66
} from '../../dist/helper';
77
import { createResolver } from '../../dist/resolver';
8+
import { resolveAll } from 'jspm-config';
89

910
describe('(unit) src/helper.js', () => {
1011
describe('combineResolvers', () => {
@@ -174,4 +175,100 @@ describe('(unit) src/helper.js', () => {
174175
});
175176

176177
});
178+
179+
describe('Compose resolvers', () => {
180+
const compositionErr = new Error('composition error');
181+
const successResolver = createResolver(() => null, () => null);
182+
const failureResolver = createResolver(() => { throw compositionErr; }, () => null);
183+
184+
it('composed resolvers are chained, and base resolver is called for each', () => {
185+
186+
const b = {
187+
resolve: () => {},
188+
error: d => compositionErr
189+
};
190+
191+
stub(b, 'resolve', b.resolve);
192+
193+
const base = new Composable(b.resolve, b.error);
194+
const comp = base.compose({
195+
r1: () => true,
196+
r2: () => true,
197+
r3: () => true,
198+
});
199+
200+
return Promise.all([
201+
202+
comp.r1().then(r => {
203+
expect(b.resolve.calledThrice).to.be.true;
204+
expect(r).to.be.true;
205+
}),
206+
207+
comp.r2().then(r => {
208+
expect(b.resolve.calledThrice).to.be.true;
209+
expect(r).to.be.true;
210+
}),
211+
212+
comp.r3().then(r => {
213+
expect(r).to.be.true;
214+
expect(b.resolve.calledThrice).to.be.true;
215+
})
216+
217+
]);
218+
});
219+
220+
it('when base throws, child is not called ', () => {
221+
222+
const b = {
223+
resolve: null,
224+
error: d => compositionErr
225+
};
226+
227+
const r1 = {
228+
resolve: () => true,
229+
error: () => compositionErr
230+
};
231+
232+
stub(b, 'error', b.error);
233+
stub(r1, 'error', r1.error);
234+
235+
const base = new Composable(b.resolve, b.error);
236+
const comp = base.compose( { r1: r1 } );
237+
238+
comp.r1()
239+
.catch( e => {
240+
expect(b.error.calledOnce).to.be.true;
241+
expect(r1.resolve.notCalled).to.be.true;
242+
expect(r1.error.notCalled).to.be.true;
243+
expect(e).to.equal(compositionErr);
244+
});
245+
});
246+
247+
it('when child throws, parent error is called ', () => {
248+
249+
const b = {
250+
resolve: null,
251+
error: d => null
252+
};
253+
254+
const r1 = {
255+
resolve: () => true,
256+
error: () => compositionErr
257+
};
258+
259+
stub(b, 'error', b.error);
260+
stub(r1, 'error', r1.error);
261+
262+
const base = new Composable(b.resolve, b.error);
263+
const comp = base.compose( { r1: r1 } );
264+
265+
comp.r1()
266+
.catch( e => {
267+
expect(b.error.calledOnce).to.be.true;
268+
expect(r1.error.calledOnce).to.be.true;
269+
expect(e).to.equal(compositionErr);
270+
});
271+
});
272+
273+
});
177274
});

0 commit comments

Comments
 (0)