@@ -3,14 +3,28 @@ import { bufferFromHexArray } from './tools/utils';
33import { expect } from 'chai' ;
44import { BSON_DATA_LONG } from '../../src/constants' ;
55
6- describe ( 'BSON BigInt support' , function ( ) {
7- beforeEach ( function ( ) {
6+ describe ( 'BSON BigInt support' , function ( ) {
7+ beforeEach ( function ( ) {
88 if ( __noBigInt__ ) {
99 this . currentTest ?. skip ( ) ;
1010 }
1111 } ) ;
1212
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 ( ) {
1428 type DeserialzationOptions = {
1529 useBigInt64 : boolean | undefined ;
1630 promoteValues : boolean | undefined ;
@@ -65,15 +79,12 @@ describe('BSON BigInt support', function () {
6579
6680 function generateTestDescription ( entry : TestTableEntry ) : string {
6781 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+ } `;
7788 const flagString = `${ useBigInt64 } , ${ promoteValues } , and ${ promoteLongs } ` ;
7889 if ( entry . shouldThrow ) {
7990 return `throws when ${ flagString } ` ;
@@ -107,7 +118,7 @@ describe('BSON BigInt support', function () {
107118 }
108119 } ) ;
109120
110- describe ( 'BSON.serialize()' , function ( ) {
121+ describe ( 'BSON.serialize()' , function ( ) {
111122 // Index for the data type byte of a BSON document with a
112123 // NOTE: These offsets only apply for documents with the shape {a : <n>}
113124 // where n is a BigInt
@@ -147,13 +158,13 @@ describe('BSON BigInt support', function () {
147158 } ;
148159 }
149160
150- it ( 'serializes bigints with the correct BSON type' , function ( ) {
161+ it ( 'serializes bigints with the correct BSON type' , function ( ) {
151162 const testDoc = { a : 0n } ;
152163 const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
153164 expect ( serializedDoc . dataType ) . to . equal ( BSON_DATA_LONG ) ;
154165 } ) ;
155166
156- it ( 'serializes bigints into little-endian byte order' , function ( ) {
167+ it ( 'serializes bigints into little-endian byte order' , function ( ) {
157168 const testDoc = { a : 0x1234567812345678n } ;
158169 const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
159170 const expectedResult = getSerializedDocParts (
@@ -167,7 +178,7 @@ describe('BSON BigInt support', function () {
167178 expect ( expectedResult . value ) . to . equal ( serializedDoc . value ) ;
168179 } ) ;
169180
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 ( ) {
171182 const testDoc = { a : 0x23n } ;
172183 const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
173184 const expectedResult = getSerializedDocParts (
@@ -180,7 +191,7 @@ describe('BSON BigInt support', function () {
180191 expect ( serializedDoc ) . to . deep . equal ( expectedResult ) ;
181192 } ) ;
182193
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 ( ) {
184195 const testDoc = { a : 0xfffffffffffffff1n } ;
185196 const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
186197 const expectedResult = getSerializedDocParts (
@@ -193,7 +204,7 @@ describe('BSON BigInt support', function () {
193204 expect ( serializedDoc ) . to . deep . equal ( expectedResult ) ;
194205 } ) ;
195206
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 ( ) {
197208 const maxIntPlusOne = { a : 2n ** 63n } ;
198209 const serializedMaxIntPlusOne = getSerializedDocParts ( BSON . serialize ( maxIntPlusOne ) ) ;
199210 const expectedResultForMaxIntPlusOne = getSerializedDocParts (
@@ -206,7 +217,7 @@ describe('BSON BigInt support', function () {
206217 expect ( serializedMaxIntPlusOne ) . to . deep . equal ( expectedResultForMaxIntPlusOne ) ;
207218 } ) ;
208219
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 ( ) {
210221 const maxPositiveInt64 = { a : 2n ** 63n - 1n } ;
211222 const serializedMaxPositiveInt64 = getSerializedDocParts ( BSON . serialize ( maxPositiveInt64 ) ) ;
212223 const expectedSerializationForMaxPositiveInt64 = getSerializedDocParts (
@@ -230,7 +241,7 @@ describe('BSON BigInt support', function () {
230241 expect ( serializedMinPositiveInt64 ) . to . deep . equal ( expectedSerializationForMinPositiveInt64 ) ;
231242 } ) ;
232243
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 ( ) {
234245 const testDoc = { a : 2n ** 64n + 1n } ;
235246 const serializedDoc = getSerializedDocParts ( BSON . serialize ( testDoc ) ) ;
236247 const expectedSerialization = getSerializedDocParts (
@@ -243,7 +254,7 @@ describe('BSON BigInt support', function () {
243254 expect ( serializedDoc ) . to . deep . equal ( expectedSerialization ) ;
244255 } ) ;
245256
246- it ( 'serializes array of BigInts' , function ( ) {
257+ it ( 'serializes array of BigInts' , function ( ) {
247258 const testArr = { a : [ 1n ] } ;
248259 const serializedArr = BSON . serialize ( testArr ) ;
249260 const expectedSerialization = bufferFromHexArray ( [
@@ -258,7 +269,7 @@ describe('BSON BigInt support', function () {
258269 expect ( serializedArr ) . to . deep . equal ( expectedSerialization ) ;
259270 } ) ;
260271
261- it ( 'serializes Map with BigInt values' , function ( ) {
272+ it ( 'serializes Map with BigInt values' , function ( ) {
262273 const testMap = new Map ( ) ;
263274 testMap . set ( 'a' , 1n ) ;
264275 const serializedMap = getSerializedDocParts ( BSON . serialize ( testMap ) ) ;
@@ -273,7 +284,7 @@ describe('BSON BigInt support', function () {
273284 } ) ;
274285 } ) ;
275286
276- describe ( 'EJSON.parse()' , function ( ) {
287+ describe ( 'EJSON.parse()' , function ( ) {
277288 type ParseOptions = {
278289 useBigInt64 : boolean | undefined ;
279290 relaxed : boolean | undefined ;
@@ -330,13 +341,13 @@ describe('BSON BigInt support', function () {
330341 const condDescription = generateConditionDescription ( entry ) ;
331342 const behaviourDescription = generateBehaviourDescription ( entry , sampleString ) ;
332343
333- describe ( condDescription , function ( ) {
344+ describe ( condDescription , function ( ) {
334345 it ( behaviourDescription , test ) ;
335346 } ) ;
336347 }
337348 }
338349
339- describe ( 'canonical input' , function ( ) {
350+ describe ( 'canonical input' , function ( ) {
340351 const canonicalInputTestTable = useBigInt64Values . flatMap ( useBigInt64 => {
341352 return relaxedValues . flatMap ( relaxed => {
342353 return genTestTable (
@@ -359,7 +370,7 @@ describe('BSON BigInt support', function () {
359370 createTestsFromTestTable ( canonicalInputTestTable , sampleCanonicalString ) ;
360371 } ) ;
361372
362- describe ( 'relaxed integer input' , function ( ) {
373+ describe ( 'relaxed integer input' , function ( ) {
363374 const relaxedIntegerInputTestTable = useBigInt64Values . flatMap ( useBigInt64 => {
364375 return relaxedValues . flatMap ( relaxed => {
365376 return genTestTable (
@@ -381,7 +392,7 @@ describe('BSON BigInt support', function () {
381392 createTestsFromTestTable ( relaxedIntegerInputTestTable , sampleRelaxedIntegerString ) ;
382393 } ) ;
383394
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 ( ) {
385396 const relaxedDoubleInputTestTable = relaxedValues . flatMap ( relaxed => {
386397 return genTestTable ( true , relaxed , ( _ , relaxedIsSet : boolean ) =>
387398 relaxedIsSet ? { a : 2147483647.9 } : { a : new BSON . Double ( 2147483647.9 ) }
@@ -396,15 +407,15 @@ describe('BSON BigInt support', function () {
396407 } ) ;
397408 } ) ;
398409
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 ( ) {
402413 const numbers = { a : 2n ** 64n + 1n , b : - ( 2n ** 64n ) - 1n } ;
403414 const serialized = EJSON . stringify ( numbers , { relaxed : false } ) ;
404415 expect ( serialized ) . to . equal ( '{"a":{"$numberLong":"1"},"b":{"$numberLong":"-1"}}' ) ;
405416 } ) ;
406417
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 ( ) {
408419 const number = { a : 0x1234_5678_1234_5678_9999n } ;
409420 const stringified = EJSON . stringify ( number , { relaxed : false } ) ;
410421 const serialized = BSON . serialize ( number ) ;
@@ -424,15 +435,15 @@ describe('BSON BigInt support', function () {
424435
425436 expect ( parsed . a . $numberLong ) . to . equal ( serializedValue . toString ( ) ) ;
426437 } ) ;
427- it ( 'serializes bigint values to numberLong in canonical mode' , function ( ) {
438+ it ( 'serializes bigint values to numberLong in canonical mode' , function ( ) {
428439 const number = { a : 2n } ;
429440 const serialized = EJSON . stringify ( number , { relaxed : false } ) ;
430441 expect ( serialized ) . to . equal ( '{"a":{"$numberLong":"2"}}' ) ;
431442 } ) ;
432443 } ) ;
433444
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 ( ) {
436447 const number = { a : 0x1234_0000_1234_5678_9999n } ; // Ensure that the truncated number can be exactly represented as a JS number
437448 const stringified = EJSON . stringify ( number , { relaxed : true } ) ;
438449 const serializedDoc = BSON . serialize ( number ) ;
@@ -451,23 +462,23 @@ describe('BSON BigInt support', function () {
451462 expect ( parsed . a ) . to . equal ( Number ( dataView . getBigInt64 ( VALUE_OFFSET , true ) ) ) ;
452463 } ) ;
453464
454- it ( 'serializes bigint values to Number' , function ( ) {
465+ it ( 'serializes bigint values to Number' , function ( ) {
455466 const number = { a : 10000n } ;
456467 const serialized = EJSON . stringify ( number , { relaxed : true } ) ;
457468 expect ( serialized ) . to . equal ( '{"a":10000}' ) ;
458469 } ) ;
459470
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 ( ) {
461472 const numbers = { a : - ( 2n ** 53n ) - 1n , b : 2n ** 53n + 2n } ;
462473 const serialized = EJSON . stringify ( numbers , { relaxed : true } ) ;
463474 expect ( serialized ) . to . equal ( '{"a":-9007199254740992,"b":9007199254740994}' ) ;
464475 } ) ;
465476 } ) ;
466477
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 ( ) {
468479 let parsed ;
469480
470- before ( function ( ) {
481+ before ( function ( ) {
471482 if ( __noBigInt__ ) {
472483 return ;
473484 }
@@ -476,20 +487,20 @@ describe('BSON BigInt support', function () {
476487 parsed = JSON . parse ( serialized ) ;
477488 } ) ;
478489
479- it ( 'passes loose equality checks with native bigint values' , function ( ) {
490+ it ( 'passes loose equality checks with native bigint values' , function ( ) {
480491 // eslint-disable-next-line eqeqeq
481492 expect ( parsed . a . $numberLong == 12345n ) . true ;
482493 } ) ;
483494
484- it ( 'equals the result of BigInt.toString' , function ( ) {
495+ it ( 'equals the result of BigInt.toString' , function ( ) {
485496 expect ( parsed . a . $numberLong ) . to . equal ( 12345n . toString ( ) ) ;
486497 } ) ;
487498 } ) ;
488499
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 ( ) {
490501 let parsed ;
491502
492- before ( function ( ) {
503+ before ( function ( ) {
493504 if ( __noBigInt__ ) {
494505 return ;
495506 }
@@ -498,12 +509,12 @@ describe('BSON BigInt support', function () {
498509 parsed = JSON . parse ( serialized ) ;
499510 } ) ;
500511
501- it ( 'fails loose equality checks with native bigint values' , function ( ) {
512+ it ( 'fails loose equality checks with native bigint values' , function ( ) {
502513 // eslint-disable-next-line eqeqeq
503514 expect ( parsed . a . $numberLong == 0x1234_5678_1234_5678_9999n ) . false ;
504515 } ) ;
505516
506- it ( 'not equal to results of BigInt.toString' , function ( ) {
517+ it ( 'not equal to results of BigInt.toString' , function ( ) {
507518 expect ( parsed . a . $numberLong ) . to . not . equal ( 0x1234_5678_1234_5678_9999n . toString ( ) ) ;
508519 } ) ;
509520 } ) ;
0 commit comments