@@ -197,4 +197,165 @@ describe('(unit) dist/resolver.js', () => {
197
197
childResolver ( null , null , null , { info : 'info' } )
198
198
} )
199
199
} )
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
+ } ) ;
200
361
} ) ;
0 commit comments