@@ -20,6 +20,7 @@ import {
20
20
valueAt ,
21
21
succeed ,
22
22
tuple ,
23
+ result ,
23
24
fail ,
24
25
lazy
25
26
} from '../src/index' ;
@@ -329,18 +330,18 @@ describe('array', () => {
329
330
} ) ;
330
331
331
332
it ( 'decodes any array when the array members decoder is not specified' , ( ) => {
332
- const validNumbersDecoder = array ( )
333
- . map ( ( arr : unknown [ ] ) => arr . map ( number ( ) . run ) )
334
- . map ( Result . successes ) ;
335
-
336
- expect ( validNumbersDecoder . run ( [ 1 , true , 2 , 3 , 'five' , 4 , [ ] ] ) ) . toEqual ( {
333
+ expect ( array ( ) . run ( [ 1 , true , 2 , 3 , 'five' , 4 , [ ] ] ) ) . toEqual ( {
337
334
ok : true ,
338
- result : [ 1 , 2 , 3 , 4 ]
335
+ result : [ 1 , true , 2 , 3 , 'five' , 4 , [ ] ]
339
336
} ) ;
340
337
341
- expect ( validNumbersDecoder . run ( [ false , 'hi' , { } ] ) ) . toEqual ( { ok : true , result : [ ] } ) ;
338
+ expect (
339
+ array ( )
340
+ . map ( a => a . length )
341
+ . run ( [ 'a' , true , 15 , 'z' ] )
342
+ ) . toEqual ( { ok : true , result : 4 } ) ;
342
343
343
- expect ( validNumbersDecoder . run ( false ) ) . toMatchObject ( {
344
+ expect ( array ( ) . run ( false ) ) . toMatchObject ( {
344
345
ok : false ,
345
346
error : { message : 'expected an array, got a boolean' }
346
347
} ) ;
@@ -778,6 +779,56 @@ describe('fail', () => {
778
779
} ) ;
779
780
} ) ;
780
781
782
+ describe ( 'result' , ( ) => {
783
+ describe ( 'can decode properties of an object separately' , ( ) => {
784
+ type PropResults < T > = { [ K in keyof T ] : DecoderResult < T [ K ] > } ;
785
+ interface Book {
786
+ title : string ;
787
+ author : string ;
788
+ pageCount ?: number ;
789
+ }
790
+
791
+ const decoder : Decoder < PropResults < Book > > = object ( {
792
+ title : result ( string ( ) ) ,
793
+ author : result ( string ( ) ) ,
794
+ pageCount : result ( optional ( number ( ) ) )
795
+ } ) ;
796
+
797
+ it ( 'succeeds when given an object' , ( ) => {
798
+ const book = { title : 'The Only Harmless Great Thing' , author : 'Brooke Bolander' } ;
799
+ expect ( decoder . run ( book ) ) . toEqual ( {
800
+ ok : true ,
801
+ result : {
802
+ author : { ok : true , result : 'Brooke Bolander' } ,
803
+ pageCount : { ok : true , result : undefined } ,
804
+ title : { ok : true , result : 'The Only Harmless Great Thing' }
805
+ }
806
+ } ) ;
807
+ } ) ;
808
+ } ) ;
809
+
810
+ describe ( 'can decode items of an array separately' , ( ) => {
811
+ it ( 'succeeds even when some array items fail to decode' , ( ) => {
812
+ const decoder = array ( result ( string ( ) ) ) ;
813
+ expect ( decoder . run ( [ 'a' , 1 ] ) ) . toMatchObject ( {
814
+ ok : true ,
815
+ result : [
816
+ { ok : true , result : 'a' } ,
817
+ { ok : false , error : { message : 'expected a string, got a number' } }
818
+ ]
819
+ } ) ;
820
+ } ) ;
821
+
822
+ it ( 'fails when the array decoder fails' , ( ) => {
823
+ const decoder = array ( result ( boolean ( ) ) ) ;
824
+ expect ( decoder . run ( false ) ) . toMatchObject ( {
825
+ ok : false ,
826
+ error : { message : 'expected an array, got a boolean' }
827
+ } ) ;
828
+ } ) ;
829
+ } ) ;
830
+ } ) ;
831
+
781
832
describe ( 'lazy' , ( ) => {
782
833
describe ( 'decoding a primitive data type' , ( ) => {
783
834
const decoder = lazy ( ( ) => string ( ) ) ;
0 commit comments