@@ -3,14 +3,28 @@ import { bufferFromHexArray } from './tools/utils';
3
3
import { expect } from 'chai' ;
4
4
import { BSON_DATA_LONG } from '../../src/constants' ;
5
5
6
- describe ( 'BSON BigInt support' , function ( ) {
7
- beforeEach ( function ( ) {
6
+ describe ( 'BSON BigInt support' , function ( ) {
7
+ beforeEach ( function ( ) {
8
8
if ( __noBigInt__ ) {
9
9
this . currentTest ?. skip ( ) ;
10
10
}
11
11
} ) ;
12
12
13
- describe ( 'BSON.deserialize()' , function ( ) {
13
+ describe ( 'BSON roundtripping' , function ( ) {
14
+ const numbers = [ - ( 2n ** 63n ) , - 1n , 0n , 1n , ( 2n ** 63n ) - 1n ] ;
15
+
16
+ for ( const number of numbers ) {
17
+ it ( `correctly roundtrips ${ number } ` , function ( ) {
18
+ const inputDoc = { number } ;
19
+ const serializedDoc = BSON . serialize ( inputDoc ) ;
20
+ const outputDoc = BSON . deserialize ( serializedDoc , { useBigInt64 : true } ) ;
21
+
22
+ expect ( outputDoc ) . to . deep . equal ( inputDoc ) ;
23
+ } )
24
+ }
25
+ } ) ;
26
+
27
+ describe ( 'BSON.deserialize()' , function ( ) {
14
28
type DeserialzationOptions = {
15
29
useBigInt64 : boolean | undefined ;
16
30
promoteValues : boolean | undefined ;
@@ -65,15 +79,12 @@ describe('BSON BigInt support', function () {
65
79
66
80
function generateTestDescription ( entry : TestTableEntry ) : string {
67
81
const options = entry . options ;
68
- const promoteValues = `promoteValues ${
69
- options . promoteValues === undefined ? 'is default' : `is ${ options . promoteValues } `
70
- } `;
71
- const promoteLongs = `promoteLongs ${
72
- options . promoteLongs === undefined ? 'is default' : `is ${ options . promoteLongs } `
73
- } `;
74
- const useBigInt64 = `useBigInt64 ${
75
- options . useBigInt64 === undefined ? 'is default' : `is ${ options . useBigInt64 } `
76
- } `;
82
+ const promoteValues = `promoteValues ${ options . promoteValues === undefined ? 'is default' : `is ${ options . promoteValues } `
83
+ } `;
84
+ const promoteLongs = `promoteLongs ${ options . promoteLongs === undefined ? 'is default' : `is ${ options . promoteLongs } `
85
+ } `;
86
+ const useBigInt64 = `useBigInt64 ${ options . useBigInt64 === undefined ? 'is default' : `is ${ options . useBigInt64 } `
87
+ } `;
77
88
const flagString = `${ useBigInt64 } , ${ promoteValues } , and ${ promoteLongs } ` ;
78
89
if ( entry . shouldThrow ) {
79
90
return `throws when ${ flagString } ` ;
@@ -107,7 +118,7 @@ describe('BSON BigInt support', function () {
107
118
}
108
119
} ) ;
109
120
110
- describe ( 'BSON.serialize()' , function ( ) {
121
+ describe ( 'BSON.serialize()' , function ( ) {
111
122
// Index for the data type byte of a BSON document with a
112
123
// NOTE: These offsets only apply for documents with the shape {a : <n>}
113
124
// where n is a BigInt
@@ -147,13 +158,13 @@ describe('BSON BigInt support', function () {
147
158
} ;
148
159
}
149
160
150
- it ( 'serializes bigints with the correct BSON type' , function ( ) {
161
+ it ( 'serializes bigints with the correct BSON type' , function ( ) {
151
162
const testDoc = { a : 0n } ;
152
163
const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
153
164
expect ( serializedDoc . dataType ) . to . equal ( BSON_DATA_LONG ) ;
154
165
} ) ;
155
166
156
- it ( 'serializes bigints into little-endian byte order' , function ( ) {
167
+ it ( 'serializes bigints into little-endian byte order' , function ( ) {
157
168
const testDoc = { a : 0x1234567812345678n } ;
158
169
const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
159
170
const expectedResult = getSerializedDocParts (
@@ -167,7 +178,7 @@ describe('BSON BigInt support', function () {
167
178
expect ( expectedResult . value ) . to . equal ( serializedDoc . value ) ;
168
179
} ) ;
169
180
170
- it ( 'serializes a BigInt that can be safely represented as a Number' , function ( ) {
181
+ it ( 'serializes a BigInt that can be safely represented as a Number' , function ( ) {
171
182
const testDoc = { a : 0x23n } ;
172
183
const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
173
184
const expectedResult = getSerializedDocParts (
@@ -180,7 +191,7 @@ describe('BSON BigInt support', function () {
180
191
expect ( serializedDoc ) . to . deep . equal ( expectedResult ) ;
181
192
} ) ;
182
193
183
- it ( 'serializes a BigInt in the valid range [-2^63, 2^63 - 1]' , function ( ) {
194
+ it ( 'serializes a BigInt in the valid range [-2^63, 2^63 - 1]' , function ( ) {
184
195
const testDoc = { a : 0xfffffffffffffff1n } ;
185
196
const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
186
197
const expectedResult = getSerializedDocParts (
@@ -193,7 +204,7 @@ describe('BSON BigInt support', function () {
193
204
expect ( serializedDoc ) . to . deep . equal ( expectedResult ) ;
194
205
} ) ;
195
206
196
- it ( 'wraps to negative on a BigInt that is larger than (2^63 -1)' , function ( ) {
207
+ it ( 'wraps to negative on a BigInt that is larger than (2^63 -1)' , function ( ) {
197
208
const maxIntPlusOne = { a : 2n ** 63n } ;
198
209
const serializedMaxIntPlusOne = getSerializedDocParts ( BSON . serialize ( maxIntPlusOne ) ) ;
199
210
const expectedResultForMaxIntPlusOne = getSerializedDocParts (
@@ -206,7 +217,7 @@ describe('BSON BigInt support', function () {
206
217
expect ( serializedMaxIntPlusOne ) . to . deep . equal ( expectedResultForMaxIntPlusOne ) ;
207
218
} ) ;
208
219
209
- it ( 'serializes BigInts at the edges of the valid range [-2^63, 2^63 - 1]' , function ( ) {
220
+ it ( 'serializes BigInts at the edges of the valid range [-2^63, 2^63 - 1]' , function ( ) {
210
221
const maxPositiveInt64 = { a : 2n ** 63n - 1n } ;
211
222
const serializedMaxPositiveInt64 = getSerializedDocParts ( BSON . serialize ( maxPositiveInt64 ) ) ;
212
223
const expectedSerializationForMaxPositiveInt64 = getSerializedDocParts (
@@ -230,7 +241,7 @@ describe('BSON BigInt support', function () {
230
241
expect ( serializedMinPositiveInt64 ) . to . deep . equal ( expectedSerializationForMinPositiveInt64 ) ;
231
242
} ) ;
232
243
233
- it ( 'truncates a BigInt that is larger than a 64-bit int' , function ( ) {
244
+ it ( 'truncates a BigInt that is larger than a 64-bit int' , function ( ) {
234
245
const testDoc = { a : 2n ** 64n + 1n } ;
235
246
const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
236
247
const expectedSerialization = getSerializedDocParts (
@@ -243,7 +254,7 @@ describe('BSON BigInt support', function () {
243
254
expect ( serializedDoc ) . to . deep . equal ( expectedSerialization ) ;
244
255
} ) ;
245
256
246
- it ( 'serializes array of BigInts' , function ( ) {
257
+ it ( 'serializes array of BigInts' , function ( ) {
247
258
const testArr = { a : [ 1n ] } ;
248
259
const serializedArr = BSON . serialize ( testArr ) ;
249
260
const expectedSerialization = bufferFromHexArray ( [
@@ -258,7 +269,7 @@ describe('BSON BigInt support', function () {
258
269
expect ( serializedArr ) . to . deep . equal ( expectedSerialization ) ;
259
270
} ) ;
260
271
261
- it ( 'serializes Map with BigInt values' , function ( ) {
272
+ it ( 'serializes Map with BigInt values' , function ( ) {
262
273
const testMap = new Map ( ) ;
263
274
testMap . set ( 'a' , 1n ) ;
264
275
const serializedMap = getSerializedDocParts ( BSON . serialize ( testMap ) ) ;
@@ -273,7 +284,7 @@ describe('BSON BigInt support', function () {
273
284
} ) ;
274
285
} ) ;
275
286
276
- describe ( 'EJSON.parse()' , function ( ) {
287
+ describe ( 'EJSON.parse()' , function ( ) {
277
288
type ParseOptions = {
278
289
useBigInt64 : boolean | undefined ;
279
290
relaxed : boolean | undefined ;
@@ -330,13 +341,13 @@ describe('BSON BigInt support', function () {
330
341
const condDescription = generateConditionDescription ( entry ) ;
331
342
const behaviourDescription = generateBehaviourDescription ( entry , sampleString ) ;
332
343
333
- describe ( condDescription , function ( ) {
344
+ describe ( condDescription , function ( ) {
334
345
it ( behaviourDescription , test ) ;
335
346
} ) ;
336
347
}
337
348
}
338
349
339
- describe ( 'canonical input' , function ( ) {
350
+ describe ( 'canonical input' , function ( ) {
340
351
const canonicalInputTestTable = useBigInt64Values . flatMap ( useBigInt64 => {
341
352
return relaxedValues . flatMap ( relaxed => {
342
353
return genTestTable (
@@ -359,7 +370,7 @@ describe('BSON BigInt support', function () {
359
370
createTestsFromTestTable ( canonicalInputTestTable , sampleCanonicalString ) ;
360
371
} ) ;
361
372
362
- describe ( 'relaxed integer input' , function ( ) {
373
+ describe ( 'relaxed integer input' , function ( ) {
363
374
const relaxedIntegerInputTestTable = useBigInt64Values . flatMap ( useBigInt64 => {
364
375
return relaxedValues . flatMap ( relaxed => {
365
376
return genTestTable (
@@ -381,7 +392,7 @@ describe('BSON BigInt support', function () {
381
392
createTestsFromTestTable ( relaxedIntegerInputTestTable , sampleRelaxedIntegerString ) ;
382
393
} ) ;
383
394
384
- describe ( 'relaxed double input where double is outside of int32 range and useBigInt64 is true' , function ( ) {
395
+ describe ( 'relaxed double input where double is outside of int32 range and useBigInt64 is true' , function ( ) {
385
396
const relaxedDoubleInputTestTable = relaxedValues . flatMap ( relaxed => {
386
397
return genTestTable ( true , relaxed , ( _ , relaxedIsSet : boolean ) =>
387
398
relaxedIsSet ? { a : 2147483647.9 } : { a : new BSON . Double ( 2147483647.9 ) }
@@ -396,15 +407,15 @@ describe('BSON BigInt support', function () {
396
407
} ) ;
397
408
} ) ;
398
409
399
- describe ( 'EJSON.stringify()' , function ( ) {
400
- context ( 'canonical mode (relaxed=false)' , function ( ) {
401
- it ( 'truncates bigint values when they are outside the range [BSON_INT64_MIN, BSON_INT64_MAX]' , function ( ) {
410
+ describe ( 'EJSON.stringify()' , function ( ) {
411
+ context ( 'canonical mode (relaxed=false)' , function ( ) {
412
+ it ( 'truncates bigint values when they are outside the range [BSON_INT64_MIN, BSON_INT64_MAX]' , function ( ) {
402
413
const numbers = { a : 2n ** 64n + 1n , b : - ( 2n ** 64n ) - 1n } ;
403
414
const serialized = EJSON . stringify ( numbers , { relaxed : false } ) ;
404
415
expect ( serialized ) . to . equal ( '{"a":{"$numberLong":"1"},"b":{"$numberLong":"-1"}}' ) ;
405
416
} ) ;
406
417
407
- it ( 'truncates bigint values in the same way as BSON.serialize' , function ( ) {
418
+ it ( 'truncates bigint values in the same way as BSON.serialize' , function ( ) {
408
419
const number = { a : 0x1234_5678_1234_5678_9999n } ;
409
420
const stringified = EJSON . stringify ( number , { relaxed : false } ) ;
410
421
const serialized = BSON . serialize ( number ) ;
@@ -424,15 +435,15 @@ describe('BSON BigInt support', function () {
424
435
425
436
expect ( parsed . a . $numberLong ) . to . equal ( serializedValue . toString ( ) ) ;
426
437
} ) ;
427
- it ( 'serializes bigint values to numberLong in canonical mode' , function ( ) {
438
+ it ( 'serializes bigint values to numberLong in canonical mode' , function ( ) {
428
439
const number = { a : 2n } ;
429
440
const serialized = EJSON . stringify ( number , { relaxed : false } ) ;
430
441
expect ( serialized ) . to . equal ( '{"a":{"$numberLong":"2"}}' ) ;
431
442
} ) ;
432
443
} ) ;
433
444
434
- context ( 'relaxed mode (relaxed=true)' , function ( ) {
435
- it ( 'truncates bigint values in the same way as BSON.serialize' , function ( ) {
445
+ context ( 'relaxed mode (relaxed=true)' , function ( ) {
446
+ it ( 'truncates bigint values in the same way as BSON.serialize' , function ( ) {
436
447
const number = { a : 0x1234_0000_1234_5678_9999n } ; // Ensure that the truncated number can be exactly represented as a JS number
437
448
const stringified = EJSON . stringify ( number , { relaxed : true } ) ;
438
449
const serializedDoc = BSON . serialize ( number ) ;
@@ -451,23 +462,23 @@ describe('BSON BigInt support', function () {
451
462
expect ( parsed . a ) . to . equal ( Number ( dataView . getBigInt64 ( VALUE_OFFSET , true ) ) ) ;
452
463
} ) ;
453
464
454
- it ( 'serializes bigint values to Number' , function ( ) {
465
+ it ( 'serializes bigint values to Number' , function ( ) {
455
466
const number = { a : 10000n } ;
456
467
const serialized = EJSON . stringify ( number , { relaxed : true } ) ;
457
468
expect ( serialized ) . to . equal ( '{"a":10000}' ) ;
458
469
} ) ;
459
470
460
- it ( 'loses precision when serializing bigint values outside of range [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]' , function ( ) {
471
+ it ( 'loses precision when serializing bigint values outside of range [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]' , function ( ) {
461
472
const numbers = { a : - ( 2n ** 53n ) - 1n , b : 2n ** 53n + 2n } ;
462
473
const serialized = EJSON . stringify ( numbers , { relaxed : true } ) ;
463
474
expect ( serialized ) . to . equal ( '{"a":-9007199254740992,"b":9007199254740994}' ) ;
464
475
} ) ;
465
476
} ) ;
466
477
467
- context ( 'when passed bigint values that are 64 bits wide or less' , function ( ) {
478
+ context ( 'when passed bigint values that are 64 bits wide or less' , function ( ) {
468
479
let parsed ;
469
480
470
- before ( function ( ) {
481
+ before ( function ( ) {
471
482
if ( __noBigInt__ ) {
472
483
return ;
473
484
}
@@ -476,20 +487,20 @@ describe('BSON BigInt support', function () {
476
487
parsed = JSON . parse ( serialized ) ;
477
488
} ) ;
478
489
479
- it ( 'passes loose equality checks with native bigint values' , function ( ) {
490
+ it ( 'passes loose equality checks with native bigint values' , function ( ) {
480
491
// eslint-disable-next-line eqeqeq
481
492
expect ( parsed . a . $numberLong == 12345n ) . true ;
482
493
} ) ;
483
494
484
- it ( 'equals the result of BigInt.toString' , function ( ) {
495
+ it ( 'equals the result of BigInt.toString' , function ( ) {
485
496
expect ( parsed . a . $numberLong ) . to . equal ( 12345n . toString ( ) ) ;
486
497
} ) ;
487
498
} ) ;
488
499
489
- context ( 'when passed bigint values that are more than 64 bits wide' , function ( ) {
500
+ context ( 'when passed bigint values that are more than 64 bits wide' , function ( ) {
490
501
let parsed ;
491
502
492
- before ( function ( ) {
503
+ before ( function ( ) {
493
504
if ( __noBigInt__ ) {
494
505
return ;
495
506
}
@@ -498,12 +509,12 @@ describe('BSON BigInt support', function () {
498
509
parsed = JSON . parse ( serialized ) ;
499
510
} ) ;
500
511
501
- it ( 'fails loose equality checks with native bigint values' , function ( ) {
512
+ it ( 'fails loose equality checks with native bigint values' , function ( ) {
502
513
// eslint-disable-next-line eqeqeq
503
514
expect ( parsed . a . $numberLong == 0x1234_5678_1234_5678_9999n ) . false ;
504
515
} ) ;
505
516
506
- it ( 'not equal to results of BigInt.toString' , function ( ) {
517
+ it ( 'not equal to results of BigInt.toString' , function ( ) {
507
518
expect ( parsed . a . $numberLong ) . to . not . equal ( 0x1234_5678_1234_5678_9999n . toString ( ) ) ;
508
519
} ) ;
509
520
} ) ;
0 commit comments