@@ -399,12 +399,12 @@ describe('dict', () => {
399399} ) ;
400400
401401describe ( 'optional' , ( ) => {
402- describe ( 'decoding an interface with optional fields' , ( ) => {
403- interface User {
404- id : number ;
405- isDog ?: boolean ;
406- }
402+ interface User {
403+ id : number ;
404+ isDog ?: boolean ;
405+ }
407406
407+ describe ( 'decoding an interface with optional fields' , ( ) => {
408408 const decoder = object < User > ( {
409409 id : number ( ) ,
410410 isDog : optional ( boolean ( ) )
@@ -426,6 +426,36 @@ describe('optional', () => {
426426 } ) ;
427427 } ) ;
428428 } ) ;
429+
430+ it ( 'supports map' , ( ) => {
431+ const decoder = object < User > ( {
432+ id : number ( ) ,
433+ isDog : optional ( number ( ) ) . map ( num => num !== 0 )
434+ } ) ;
435+
436+ expect ( decoder . run ( { id : 1 , isDog : 0 } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : false } } ) ;
437+ expect ( decoder . run ( { id : 1 , isDog : 77 } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : true } } ) ;
438+ expect ( decoder . run ( { id : 1 } ) ) . toEqual ( { ok : true , result : { id : 1 } } ) ;
439+ } ) ;
440+
441+ it ( 'supports andThen' , ( ) => {
442+ const decoder = object < User > ( {
443+ id : number ( ) ,
444+ isDog : optional ( string ( ) ) . andThen (
445+ dogName =>
446+ dogName . toLowerCase ( ) [ 0 ] === 'd'
447+ ? succeed ( true )
448+ : fail ( `${ dogName } is not a dog, all dog names start with 'D'` )
449+ )
450+ } ) ;
451+
452+ expect ( decoder . run ( { id : 1 , isDog : 'Doug' } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : true } } ) ;
453+ expect ( decoder . run ( { id : 1 , isDog : 'Wanda' } ) ) . toMatchObject ( {
454+ ok : false ,
455+ error : { message : "Wanda is not a dog, all dog names start with 'D'" }
456+ } ) ;
457+ expect ( decoder . run ( { id : 1 } ) ) . toEqual ( { ok : true , result : { id : 1 } } ) ;
458+ } ) ;
429459} ) ;
430460
431461describe ( 'oneOf' , ( ) => {
@@ -531,7 +561,7 @@ describe('withDefault', () => {
531561} ) ;
532562
533563describe ( 'valueAt' , ( ) => {
534- describe ( 'decode an value' , ( ) => {
564+ describe ( 'decode a value accessed from a path ' , ( ) => {
535565 it ( 'can decode a single object field' , ( ) => {
536566 const decoder = valueAt ( [ 'a' ] , string ( ) ) ;
537567 expect ( decoder . run ( { a : 'boots' , b : 'cats' } ) ) . toEqual ( { ok : true , result : 'boots' } ) ;
@@ -573,7 +603,10 @@ describe('valueAt', () => {
573603 } ) ;
574604
575605 describe ( 'decode an optional field' , ( ) => {
576- const decoder = valueAt ( [ 'a' , 'b' , 'c' ] , oneOf ( string ( ) , constant ( undefined ) ) ) ;
606+ const decoder : Decoder < string | undefined > = valueAt (
607+ [ 'a' , 'b' , 'c' ] ,
608+ union ( string ( ) , constant ( undefined ) )
609+ ) ;
577610
578611 it ( 'fails when the path does not exist' , ( ) => {
579612 const error = decoder . run ( { a : { x : 'cats' } } ) ;
0 commit comments