@@ -6,123 +6,145 @@ import { NativeAttributeValue } from "./models";
6
6
7
7
describe ( "convertToAttr" , ( ) => {
8
8
describe ( "null" , ( ) => {
9
- it ( `returns for null` , ( ) => {
10
- expect ( convertToAttr ( null ) ) . toEqual ( { NULL : true } ) ;
9
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
10
+ it ( `returns for null` , ( ) => {
11
+ expect ( convertToAttr ( null , { convertClassInstanceToMap } ) ) . toEqual ( { NULL : true } ) ;
12
+ } ) ;
11
13
} ) ;
12
14
} ) ;
13
15
14
16
describe ( "boolean" , ( ) => {
15
- [ true , false ] . forEach ( ( bool ) => {
16
- it ( `returns for boolean: ${ bool } ` , ( ) => {
17
- expect ( convertToAttr ( bool ) ) . toEqual ( { BOOL : bool } ) ;
17
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
18
+ [ true , false ] . forEach ( ( isClassInstance ) => {
19
+ [ true , false ] . forEach ( ( boolValue ) => {
20
+ const bool = isClassInstance ? new Boolean ( boolValue ) : boolValue ;
21
+ it ( `returns for boolean: ${ bool } ` , ( ) => {
22
+ expect ( convertToAttr ( bool , { convertClassInstanceToMap } ) ) . toEqual ( { BOOL : bool . valueOf ( ) } ) ;
23
+ } ) ;
24
+ } ) ;
18
25
} ) ;
19
26
} ) ;
20
27
} ) ;
21
28
22
29
describe ( "number" , ( ) => {
23
- [ 1 , Number . MAX_SAFE_INTEGER , Number . MIN_SAFE_INTEGER ] . forEach ( ( num ) => {
24
- it ( `returns for number (integer): ${ num } ` , ( ) => {
25
- expect ( convertToAttr ( num ) ) . toEqual ( { N : num . toString ( ) } ) ;
26
- } ) ;
27
- } ) ;
28
-
29
- [ 1.01 , Math . PI , Math . E , Number . MIN_VALUE , Number . EPSILON ] . forEach ( ( num ) => {
30
- it ( `returns for number (floating point): ${ num } ` , ( ) => {
31
- expect ( convertToAttr ( num ) ) . toEqual ( { N : num . toString ( ) } ) ;
32
- } ) ;
33
- } ) ;
34
-
35
- [ Number . NaN , Number . POSITIVE_INFINITY , Number . NEGATIVE_INFINITY ] . forEach ( ( num ) => {
36
- it ( `throws for number (special numeric value): ${ num } ` , ( ) => {
37
- expect ( ( ) => {
38
- convertToAttr ( num ) ;
39
- } ) . toThrowError ( `Special numeric value ${ num } is not allowed` ) ;
40
- } ) ;
41
- } ) ;
42
-
43
- [ Number . MAX_SAFE_INTEGER + 1 , Number . MAX_VALUE ] . forEach ( ( num ) => {
44
- it ( `throws for number greater than Number.MAX_SAFE_INTEGER: ${ num } ` , ( ) => {
45
- const errorPrefix = `Number ${ num } is greater than Number.MAX_SAFE_INTEGER.` ;
46
-
47
- expect ( ( ) => {
48
- convertToAttr ( num ) ;
49
- } ) . toThrowError ( `${ errorPrefix } Use BigInt.` ) ;
30
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
31
+ [ true , false ] . forEach ( ( isClassInstance ) => {
32
+ [ 1 , Number . MAX_SAFE_INTEGER , Number . MIN_SAFE_INTEGER ] . forEach ( ( numValue ) => {
33
+ const num = isClassInstance ? new Number ( numValue ) : numValue ;
34
+ it ( `returns for number (integer): ${ num } ` , ( ) => {
35
+ expect ( convertToAttr ( num , { convertClassInstanceToMap } ) ) . toEqual ( { N : num . toString ( ) } ) ;
36
+ } ) ;
37
+ } ) ;
50
38
51
- const BigIntConstructor = BigInt ;
52
- ( BigInt as any ) = undefined ;
53
- expect ( ( ) => {
54
- convertToAttr ( num ) ;
55
- } ) . toThrowError ( `${ errorPrefix } Pass string value instead.` ) ;
56
- BigInt = BigIntConstructor ;
57
- } ) ;
58
- } ) ;
39
+ [ 1.01 , Math . PI , Math . E , Number . MIN_VALUE , Number . EPSILON ] . forEach ( ( numValue ) => {
40
+ const num = isClassInstance ? new Number ( numValue ) : numValue ;
41
+ it ( `returns for number (floating point): ${ num } ` , ( ) => {
42
+ expect ( convertToAttr ( num , { convertClassInstanceToMap } ) ) . toEqual ( { N : num . toString ( ) } ) ;
43
+ } ) ;
44
+ } ) ;
59
45
60
- [ Number . MIN_SAFE_INTEGER - 1 ] . forEach ( ( num ) => {
61
- it ( `throws for number lesser than Number.MIN_SAFE_INTEGER: ${ num } ` , ( ) => {
62
- const errorPrefix = `Number ${ num } is lesser than Number.MIN_SAFE_INTEGER.` ;
46
+ [ Number . NaN , Number . POSITIVE_INFINITY , Number . NEGATIVE_INFINITY ] . forEach ( ( numValue ) => {
47
+ const num = isClassInstance ? new Number ( numValue ) : numValue ;
48
+ it ( `throws for number (special numeric value): ${ num } ` , ( ) => {
49
+ expect ( ( ) => {
50
+ convertToAttr ( num , { convertClassInstanceToMap } ) ;
51
+ } ) . toThrowError ( `Special numeric value ${ num . toString ( ) } is not allowed` ) ;
52
+ } ) ;
53
+ } ) ;
63
54
64
- expect ( ( ) => {
65
- convertToAttr ( num ) ;
66
- } ) . toThrowError ( `${ errorPrefix } Use BigInt.` ) ;
55
+ [ Number . MAX_SAFE_INTEGER + 1 , Number . MAX_VALUE ] . forEach ( ( numValue ) => {
56
+ const num = isClassInstance ? new Number ( numValue ) : numValue ;
57
+ it ( `throws for number greater than Number.MAX_SAFE_INTEGER: ${ num } ` , ( ) => {
58
+ const errorPrefix = `Number ${ num . toString ( ) } is greater than Number.MAX_SAFE_INTEGER.` ;
59
+
60
+ expect ( ( ) => {
61
+ convertToAttr ( num , { convertClassInstanceToMap } ) ;
62
+ } ) . toThrowError ( `${ errorPrefix } Use BigInt.` ) ;
63
+
64
+ const BigIntConstructor = BigInt ;
65
+ ( BigInt as any ) = undefined ;
66
+ expect ( ( ) => {
67
+ convertToAttr ( num , { convertClassInstanceToMap } ) ;
68
+ } ) . toThrowError ( `${ errorPrefix } Pass string value instead.` ) ;
69
+ BigInt = BigIntConstructor ;
70
+ } ) ;
71
+ } ) ;
67
72
68
- const BigIntConstructor = BigInt ;
69
- ( BigInt as any ) = undefined ;
70
- expect ( ( ) => {
71
- convertToAttr ( num ) ;
72
- } ) . toThrowError ( `${ errorPrefix } Pass string value instead.` ) ;
73
- BigInt = BigIntConstructor ;
73
+ [ Number . MIN_SAFE_INTEGER - 1 ] . forEach ( ( numValue ) => {
74
+ const num = isClassInstance ? new Number ( numValue ) : numValue ;
75
+ it ( `throws for number lesser than Number.MIN_SAFE_INTEGER: ${ num } ` , ( ) => {
76
+ const errorPrefix = `Number ${ num . toString ( ) } is lesser than Number.MIN_SAFE_INTEGER.` ;
77
+
78
+ expect ( ( ) => {
79
+ convertToAttr ( num , { convertClassInstanceToMap } ) ;
80
+ } ) . toThrowError ( `${ errorPrefix } Use BigInt.` ) ;
81
+
82
+ const BigIntConstructor = BigInt ;
83
+ ( BigInt as any ) = undefined ;
84
+ expect ( ( ) => {
85
+ convertToAttr ( num , { convertClassInstanceToMap } ) ;
86
+ } ) . toThrowError ( `${ errorPrefix } Pass string value instead.` ) ;
87
+ BigInt = BigIntConstructor ;
88
+ } ) ;
89
+ } ) ;
74
90
} ) ;
75
91
} ) ;
76
92
} ) ;
77
93
78
94
describe ( "bigint" , ( ) => {
79
- const maxSafe = BigInt ( Number . MAX_SAFE_INTEGER ) ;
80
- [
81
- // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
82
- 1n ,
83
- // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
84
- maxSafe * 2n ,
85
- // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
86
- maxSafe * - 2n ,
87
- BigInt ( Number . MAX_VALUE ) ,
88
- BigInt ( "0x1fffffffffffff" ) ,
89
- BigInt ( "0b11111111111111111111111111111111111111111111111111111" ) ,
90
- ] . forEach ( ( num ) => {
91
- it ( `returns for bigint: ${ num } ` , ( ) => {
92
- expect ( convertToAttr ( num ) ) . toEqual ( { N : num . toString ( ) } ) ;
95
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
96
+ const maxSafe = BigInt ( Number . MAX_SAFE_INTEGER ) ;
97
+ [
98
+ // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
99
+ 1n ,
100
+ // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
101
+ maxSafe * 2n ,
102
+ // @ts -expect-error BigInt literals are not available when targeting lower than ES2020.
103
+ maxSafe * - 2n ,
104
+ BigInt ( Number . MAX_VALUE ) ,
105
+ BigInt ( "0x1fffffffffffff" ) ,
106
+ BigInt ( "0b11111111111111111111111111111111111111111111111111111" ) ,
107
+ ] . forEach ( ( num ) => {
108
+ it ( `returns for bigint: ${ num } ` , ( ) => {
109
+ expect ( convertToAttr ( num , { convertClassInstanceToMap } ) ) . toEqual ( { N : num . toString ( ) } ) ;
110
+ } ) ;
93
111
} ) ;
94
112
} ) ;
95
113
} ) ;
96
114
97
115
describe ( "binary" , ( ) => {
98
- const buffer = new ArrayBuffer ( 64 ) ;
99
- const arr = [ ...Array ( 64 ) . keys ( ) ] ;
100
- const addPointOne = ( num : number ) => num + 0.1 ;
101
-
102
- [
103
- buffer ,
104
- new Blob ( [ new Uint8Array ( buffer ) ] ) ,
105
- Buffer . from ( buffer ) ,
106
- new DataView ( buffer ) ,
107
- new Int8Array ( arr ) ,
108
- new Uint8Array ( arr ) ,
109
- new Uint8ClampedArray ( arr ) ,
110
- new Int16Array ( arr ) ,
111
- new Uint16Array ( arr ) ,
112
- new Int32Array ( arr ) ,
113
- new Uint32Array ( arr ) ,
114
- new Float32Array ( arr . map ( addPointOne ) ) ,
115
- new Float64Array ( arr . map ( addPointOne ) ) ,
116
- new BigInt64Array ( arr . map ( BigInt ) ) ,
117
- new BigUint64Array ( arr . map ( BigInt ) ) ,
118
- ] . forEach ( ( data ) => {
119
- it ( `returns for binary: ${ data . constructor . name } ` , ( ) => {
120
- expect ( convertToAttr ( data ) ) . toEqual ( { B : data } ) ;
116
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
117
+ const buffer = new ArrayBuffer ( 64 ) ;
118
+ const arr = [ ...Array ( 64 ) . keys ( ) ] ;
119
+ const addPointOne = ( num : number ) => num + 0.1 ;
120
+
121
+ [
122
+ buffer ,
123
+ new Blob ( [ new Uint8Array ( buffer ) ] ) ,
124
+ Buffer . from ( buffer ) ,
125
+ new DataView ( buffer ) ,
126
+ new Int8Array ( arr ) ,
127
+ new Uint8Array ( arr ) ,
128
+ new Uint8ClampedArray ( arr ) ,
129
+ new Int16Array ( arr ) ,
130
+ new Uint16Array ( arr ) ,
131
+ new Int32Array ( arr ) ,
132
+ new Uint32Array ( arr ) ,
133
+ new Float32Array ( arr . map ( addPointOne ) ) ,
134
+ new Float64Array ( arr . map ( addPointOne ) ) ,
135
+ new BigInt64Array ( arr . map ( BigInt ) ) ,
136
+ new BigUint64Array ( arr . map ( BigInt ) ) ,
137
+ ] . forEach ( ( data ) => {
138
+ it ( `returns for binary: ${ data . constructor . name } ` , ( ) => {
139
+ expect ( convertToAttr ( data , { convertClassInstanceToMap } ) ) . toEqual ( { B : data } ) ;
140
+ } ) ;
121
141
} ) ;
122
- } ) ;
123
142
124
- it ( "returns null for Binary when options.convertEmptyValues=true" , ( ) => {
125
- expect ( convertToAttr ( new Uint8Array ( ) , { convertEmptyValues : true } ) ) . toEqual ( { NULL : true } ) ;
143
+ it ( "returns null for Binary when options.convertEmptyValues=true" , ( ) => {
144
+ expect ( convertToAttr ( new Uint8Array ( ) , { convertClassInstanceToMap, convertEmptyValues : true } ) ) . toEqual ( {
145
+ NULL : true ,
146
+ } ) ;
147
+ } ) ;
126
148
} ) ;
127
149
} ) ;
128
150
@@ -273,7 +295,6 @@ describe("convertToAttr", () => {
273
295
describe ( "unallowed set" , ( ) => {
274
296
it ( "throws error" , ( ) => {
275
297
expect ( ( ) => {
276
- // @ts -expect-error Type 'Set<boolean>' is not assignable
277
298
convertToAttr ( new Set ( [ true , false ] ) ) ;
278
299
} ) . toThrowError ( `Only Number Set (NS), Binary Set (BS) or String Set (SS) are allowed.` ) ;
279
300
} ) ;
@@ -362,19 +383,25 @@ describe("convertToAttr", () => {
362
383
} ) ;
363
384
364
385
describe ( "string" , ( ) => {
365
- [ "" , "string" , "'single-quote'" , '"double-quote"' ] . forEach ( ( str ) => {
366
- it ( `returns for string: ${ str } ` , ( ) => {
367
- expect ( convertToAttr ( str ) ) . toEqual ( { S : str } ) ;
368
- } ) ;
369
- } ) ;
386
+ [ true , false ] . forEach ( ( convertClassInstanceToMap ) => {
387
+ [ true , false ] . forEach ( ( isClassInstance ) => {
388
+ [ "" , "string" , "'single-quote'" , '"double-quote"' ] . forEach ( ( strValue ) => {
389
+ const str = isClassInstance ? new String ( strValue ) : strValue ;
390
+ it ( `returns for string: ${ str } ` , ( ) => {
391
+ expect ( convertToAttr ( str , { convertClassInstanceToMap } ) ) . toEqual ( { S : str . toString ( ) } ) ;
392
+ } ) ;
393
+ } ) ;
370
394
371
- it ( "returns null for string when options.convertEmptyValues=true" , ( ) => {
372
- expect ( convertToAttr ( "" , { convertEmptyValues : true } ) ) . toEqual ( { NULL : true } ) ;
395
+ it ( "returns null for string when options.convertEmptyValues=true" , ( ) => {
396
+ const str = isClassInstance ? new String ( "" ) : "" ;
397
+ expect ( convertToAttr ( str , { convertClassInstanceToMap, convertEmptyValues : true } ) ) . toEqual ( { NULL : true } ) ;
398
+ } ) ;
399
+ } ) ;
373
400
} ) ;
374
401
} ) ;
375
402
376
403
describe ( `unsupported type` , ( ) => {
377
- class FooObj {
404
+ class FooClass {
378
405
constructor ( private readonly foo : string ) { }
379
406
}
380
407
@@ -385,13 +412,72 @@ describe("convertToAttr", () => {
385
412
} ) ;
386
413
387
414
// ToDo: Serialize ES6 class objects as string https://github.com/aws/aws-sdk-js-v3/issues/1535
388
- [ new Date ( ) , new FooObj ( "foo" ) ] . forEach ( ( data ) => {
415
+ [ new Date ( ) , new FooClass ( "foo" ) ] . forEach ( ( data ) => {
389
416
it ( `throws for: ${ String ( data ) } ` , ( ) => {
390
417
expect ( ( ) => {
391
- // @ts -expect-error Argument is not assignable to parameter of type 'NativeAttributeValue'
392
418
convertToAttr ( data ) ;
393
- } ) . toThrowError ( `Unsupported type passed: ${ String ( data ) } ` ) ;
419
+ } ) . toThrowError (
420
+ `Unsupported type passed: ${ String (
421
+ data
422
+ ) } . Pass options.convertClassInstanceToMap=true to marshall typeof object as map attribute.`
423
+ ) ;
394
424
} ) ;
395
425
} ) ;
396
426
} ) ;
427
+
428
+ describe ( "typeof object with options.convertClassInstanceToMap=true" , ( ) => {
429
+ it ( "returns map for class" , ( ) => {
430
+ class FooClass {
431
+ constructor (
432
+ private readonly nullAttr : null ,
433
+ private readonly boolAttr : boolean ,
434
+ private readonly strAttr : string ,
435
+ private readonly numAttr : number ,
436
+ private readonly bigintAttr : bigint ,
437
+ private readonly binaryAttr : Uint8Array ,
438
+ private readonly listAttr : any [ ] ,
439
+ private readonly mapAttr : { [ key : string ] : any }
440
+ ) { }
441
+ }
442
+ expect (
443
+ convertToAttr (
444
+ new FooClass (
445
+ null ,
446
+ true ,
447
+ "string" ,
448
+ 1 ,
449
+ BigInt ( Number . MAX_VALUE ) ,
450
+ new Uint8Array ( [ ...Array ( 64 ) . keys ( ) ] ) ,
451
+ [ null , 1 , "two" , true ] ,
452
+ {
453
+ nullKey : null ,
454
+ numKey : 1 ,
455
+ strKey : "string" ,
456
+ boolKey : true ,
457
+ }
458
+ ) ,
459
+ {
460
+ convertClassInstanceToMap : true ,
461
+ }
462
+ )
463
+ ) . toEqual ( {
464
+ M : {
465
+ nullAttr : { NULL : true } ,
466
+ boolAttr : { BOOL : true } ,
467
+ strAttr : { S : "string" } ,
468
+ numAttr : { N : "1" } ,
469
+ bigintAttr : { N : BigInt ( Number . MAX_VALUE ) . toString ( ) } ,
470
+ binaryAttr : { B : new Uint8Array ( [ ...Array ( 64 ) . keys ( ) ] ) } ,
471
+ listAttr : { L : [ { NULL : true } , { N : "1" } , { S : "two" } , { BOOL : true } ] } ,
472
+ mapAttr : {
473
+ M : { nullKey : { NULL : true } , numKey : { N : "1" } , strKey : { S : "string" } , boolKey : { BOOL : true } } ,
474
+ } ,
475
+ } ,
476
+ } ) ;
477
+ } ) ;
478
+
479
+ it ( "returns empty for Date object" , ( ) => {
480
+ expect ( convertToAttr ( new Date ( ) , { convertClassInstanceToMap : true } ) ) . toEqual ( { M : { } } ) ;
481
+ } ) ;
482
+ } ) ;
397
483
} ) ;
0 commit comments