@@ -197,4 +197,165 @@ describe('(unit) dist/resolver.js', () => {
197197 childResolver ( null , null , null , { info : 'info' } )
198198 } )
199199 } )
200+
201+ describe ( 'Compose resolvers' , ( ) => {
202+ const compositionErr = new Error ( 'composition error' ) ;
203+ const successResolver = createResolver ( ( ) => null , ( ) => null ) ;
204+ const failureResolver = createResolver ( ( ) => { throw compositionErr ; } , ( ) => null ) ;
205+
206+ it ( 'composed resolvers are chained, and base resolver is called for each' , ( ) => {
207+
208+ const b = {
209+ resolve : ( ) => { } ,
210+ error : d => compositionErr
211+ } ;
212+
213+ stub ( b , 'resolve' , b . resolve ) ;
214+
215+ const base = createResolver ( b . resolve , b . error ) ;
216+ const comp = base . compose ( {
217+ r1 : ( ) => true ,
218+ r2 : ( ) => true ,
219+ r3 : ( ) => true ,
220+ } ) ;
221+
222+ return Promise . all ( [
223+
224+ comp . r1 ( ) . then ( r => {
225+ expect ( b . resolve . calledThrice ) . to . be . true ;
226+ expect ( r ) . to . be . true ;
227+ } ) ,
228+
229+ comp . r2 ( ) . then ( r => {
230+ expect ( b . resolve . calledThrice ) . to . be . true ;
231+ expect ( r ) . to . be . true ;
232+ } ) ,
233+
234+ comp . r3 ( ) . then ( r => {
235+ expect ( r ) . to . be . true ;
236+ expect ( b . resolve . calledThrice ) . to . be . true ;
237+ } )
238+
239+ ] ) ;
240+ } ) ;
241+
242+ it ( 'when base throws, child is not called ' , ( ) => {
243+
244+ const b = {
245+ resolve : null ,
246+ error : d => compositionErr
247+ } ;
248+
249+ const r1 = {
250+ resolve : ( ) => true ,
251+ error : ( ) => compositionErr
252+ } ;
253+
254+ stub ( b , 'error' , b . error ) ;
255+ stub ( r1 , 'error' , r1 . error ) ;
256+
257+ const base = createResolver ( b . resolve , b . error ) ;
258+ const comp = base . compose ( { r1 : r1 } ) ;
259+
260+ comp . r1 ( )
261+ . catch ( e => {
262+ expect ( b . error . calledOnce ) . to . be . true ;
263+ expect ( r1 . resolve . notCalled ) . to . be . true ;
264+ expect ( r1 . error . notCalled ) . to . be . true ;
265+ expect ( e ) . to . equal ( compositionErr ) ;
266+ } ) ;
267+ } ) ;
268+
269+ it ( 'when child throws, parent error is called ' , ( ) => {
270+ const b = {
271+ resolve : null ,
272+ error : d => null
273+ } ;
274+
275+ const r1 = {
276+ resolve : ( ) => true ,
277+ error : ( ) => compositionErr
278+ } ;
279+
280+ stub ( b , 'error' , b . error ) ;
281+ stub ( r1 , 'error' , r1 . error ) ;
282+
283+ const base = createResolver ( b . resolve , b . error ) ;
284+ const comp = base . compose ( { r1 : r1 } ) ;
285+
286+ comp . r1 ( )
287+ . catch ( e => {
288+ expect ( b . error . calledOnce ) . to . be . true ;
289+ expect ( r1 . error . calledOnce ) . to . be . true ;
290+ expect ( e ) . to . equal ( compositionErr ) ;
291+ } ) ;
292+ } ) ;
293+
294+ it ( 'composed resolvers with { resolve: resFn, error: resFn } syntax, resolve and bubble errors correctly' , ( ) => {
295+
296+ const b = {
297+ resolve : ( ) => { } ,
298+ error : d => compositionErr
299+ } ;
300+
301+ const r1 = {
302+ resolve : ( ) => { throw Error ( 'some other error' ) } ,
303+ error : ( ) => compositionErr } ;
304+
305+ const r2 = { resolve : ( ) => 'r2Result' , error : ( ) => compositionErr } ;
306+
307+ stub ( b , 'resolve' , b . resolve ) ;
308+ stub ( r1 , 'error' , r1 . error ) ;
309+ stub ( r1 , 'resolve' , r1 . resolve ) ;
310+ stub ( r2 , 'resolve' , r2 . resolve ) ;
311+ stub ( r2 , 'error' , r2 . error ) ;
312+
313+ const base = createResolver ( b . resolve , b . error ) ;
314+ const comp = base . compose ( {
315+ r1 : r1 ,
316+ r2 : r2 ,
317+ } ) ;
318+
319+ return Promise . all ( [
320+ comp . r1 ( ) . catch ( e => {
321+ expect ( e ) . to . equal ( compositionErr ) ;
322+ } ) ,
323+ comp . r2 ( ) . then ( r => {
324+ expect ( r ) . to . equal ( 'r2Result' ) ;
325+ } ) ,
326+
327+ ] ) . then ( ( ) => {
328+ expect ( r1 . resolve . calledOnce ) . to . be . true ;
329+ expect ( r1 . error . calledOnce ) . to . be . true ;
330+ expect ( r2 . resolve . calledOnce ) . to . be . true ;
331+ expect ( r2 . error . notCalled ) . to . be . true ;
332+ } ) ;
333+ } ) ;
334+
335+ it ( 'composed result has correct structure' , ( ) => {
336+
337+ const b = {
338+ resolve : ( ) => { } ,
339+ error : d => compositionErr
340+ } ;
341+
342+ stub ( b , 'resolve' , b . resolve ) ;
343+
344+ const base = createResolver ( b . resolve , b . error ) ;
345+ const comp = base . compose ( {
346+ r1 : { resolve : ( ) => { throw Error ( 'some other error' ) } , error : ( ) => compositionErr } ,
347+ r2 : { resolve : ( ) => 'r2Result' , error : ( ) => compositionErr } ,
348+ r3 : { } // should we throw an exception since it is not a resolver or createResolver params?
349+ } ) ;
350+
351+ const composed = { r0 : ( ) => { } , ...comp } ;
352+
353+ expect ( composed . r0 ) . to . be . a ( typeof Function ) ;
354+ expect ( composed . r1 ) . to . be . a ( typeof Function ) ;
355+ expect ( composed . r2 ) . to . be . a ( typeof Function ) ;
356+ expect ( composed . r3 ) . to . be . a ( typeof Function ) ;
357+
358+ } ) ;
359+
360+ } ) ;
200361} ) ;
0 commit comments