Skip to content

Commit

Permalink
test(NODE-4873): move EJSON bigint tests
Browse files Browse the repository at this point in the history
  • Loading branch information
W-A-James committed Jan 6, 2023
1 parent 78c0513 commit 4d1f84e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 88 deletions.
90 changes: 89 additions & 1 deletion test/node/bigint.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BSON, BSONError } from '../register-bson';
import { BSON, EJSON, BSONError } from '../register-bson';
import { bufferFromHexArray } from './tools/utils';
import { expect } from 'chai';
import { BSON_DATA_LONG } from '../../src/constants';
Expand Down Expand Up @@ -263,4 +263,92 @@ describe('BSON BigInt support', function () {
expect(serializedMap).to.deep.equal(expectedSerialization);
});
});

describe('EJSON.stringify()', function () {
it('truncates bigint values when they are outside the range [BSON_INT64_MIN, BSON_INT64_MAX] in canonical mode', function () {
const numbers = { a: 2n ** 64n + 1n, b: -(2n ** 64n) - 1n };
const serialized = EJSON.stringify(numbers, { relaxed: false });
expect(serialized).to.equal('{"a":{"$numberLong":"1"},"b":{"$numberLong":"-1"}}');
});

it('truncates bigint values in the same way as BSON.serialize in canonical mode', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const stringified = EJSON.stringify(number, { relaxed: false });
const serialized = BSON.serialize(number);

const VALUE_OFFSET = 7;
const dataView = BSONDataView.fromUint8Array(serialized);
const serializedValue = dataView.getBigInt64(VALUE_OFFSET, true);
const parsed = JSON.parse(stringified);

expect(parsed).to.have.property('a');
expect(parsed['a']).to.have.property('$numberLong');
expect(parsed.a.$numberLong).to.equal(0x5678_1234_5678_9999n.toString());

expect(parsed.a.$numberLong).to.equal(serializedValue.toString());
});

it('truncates bigint values in the same way as BSON.serialize in relaxed mode', function () {
const number = { a: 0x1234_0000_1234_5678_9999n }; // Ensure that the truncated number can be exactly represented as a JS number
const stringified = EJSON.stringify(number, { relaxed: true });
const serializedDoc = BSON.serialize(number);

const VALUE_OFFSET = 7;
const dataView = BSONDataView.fromUint8Array(serializedDoc);
const parsed = JSON.parse(stringified);

expect(parsed).to.have.property('a');
expect(parsed.a).to.equal(0x0000_1234_5678_9999);

expect(parsed.a).to.equal(Number(dataView.getBigInt64(VALUE_OFFSET, true)));
});

it('serializes bigint values to numberLong in canonical mode', function () {
const number = { a: 2n };
const serialized = EJSON.stringify(number, { relaxed: false });
expect(serialized).to.equal('{"a":{"$numberLong":"2"}}');
});

it('serializes bigint values to Number in relaxed mode', function () {
const number = { a: 10000n };
const serialized = EJSON.stringify(number, { relaxed: true });
expect(serialized).to.equal('{"a":10000}');
});

it('loses precision when serializing bigint values outside of range [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] in relaxed mode', function () {
const numbers = { a: -(2n ** 53n) - 1n, b: 2n ** 53n + 2n };
const serialized = EJSON.stringify(numbers, { relaxed: true });
expect(serialized).to.equal('{"a":-9007199254740992,"b":9007199254740994}');
});

it('produces bigint strings that pass loose equality checks with native bigint values that are are 64 bits wide or less', function () {
const number = { a: 12345n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
// eslint-disable-next-line eqeqeq
expect(parsed.a.$numberLong == 12345n).true;
});

it('produces bigint strings that are equal to the strings generated when using BigInt.toString when the bigint values used are 64 bits wide or less', function () {
const number = { a: 12345n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
expect(parsed.a.$numberLong).to.equal(12345n.toString());
});

it('produces bigint strings that fail loose equality checks with native bigint values that are more than 64 bits wide', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
// eslint-disable-next-line eqeqeq
expect(parsed.a.$numberLong == 0x1234_5678_1234_5678_9999n).false;
});

it('produces bigint strings that are not equal to the strings generated when using BigInt.toString when the bigint values used are more than 64 bits wide', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
expect(parsed.a.$numberLong).to.not.equal(0x1234_5678_1234_5678_9999n.toString());
});
});
});
87 changes: 0 additions & 87 deletions test/node/extended_json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as BSON from '../register-bson';
const EJSON = BSON.EJSON;
import * as vm from 'node:vm';
import { expect } from 'chai';
import { BSONDataView } from '../../src/utils/byte_utils';
import { BSONError } from '../../src';

// BSON types
Expand Down Expand Up @@ -182,92 +181,6 @@ describe('Extended JSON', function () {
expect(EJSON.parse(serialized)).to.deep.equal(numbers);
});

it('truncates bigint values when they are outside the range [BSON_INT64_MIN, BSON_INT64_MAX] in canonical mode', function () {
const numbers = { a: 2n ** 64n + 1n, b: -(2n ** 64n) - 1n };
const serialized = EJSON.stringify(numbers, { relaxed: false });
expect(serialized).to.equal('{"a":{"$numberLong":"1"},"b":{"$numberLong":"-1"}}');
});

it('truncates bigint values in the same way as BSON.serialize in canonical mode', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const stringified = EJSON.stringify(number, { relaxed: false });
const serialized = BSON.serialize(number);

const VALUE_OFFSET = 7;
const dataView = BSONDataView.fromUint8Array(serialized);
const serializedValue = dataView.getBigInt64(VALUE_OFFSET, true);
const parsed = JSON.parse(stringified);

expect(parsed).to.have.property('a');
expect(parsed['a']).to.have.property('$numberLong');
expect(parsed.a.$numberLong).to.equal(0x5678_1234_5678_9999n.toString());

expect(parsed.a.$numberLong).to.equal(serializedValue.toString());
});

it('truncates bigint values in the same way as BSON.serialize in relaxed mode', function () {
const number = { a: 0x1234_0000_1234_5678_9999n }; // Ensure that the truncated number can be exactly represented as a JS number
const stringified = EJSON.stringify(number, { relaxed: true });
const serializedDoc = BSON.serialize(number);

const VALUE_OFFSET = 7;
const dataView = BSONDataView.fromUint8Array(serializedDoc);
const parsed = JSON.parse(stringified);

expect(parsed).to.have.property('a');
expect(parsed.a).to.equal(0x0000_1234_5678_9999);

expect(parsed.a).to.equal(Number(dataView.getBigInt64(VALUE_OFFSET, true)));
});

it('serializes bigint values to numberLong in canonical mode', function () {
const number = { a: 2n };
const serialized = EJSON.stringify(number, { relaxed: false });
expect(serialized).to.equal('{"a":{"$numberLong":"2"}}');
});

it('serializes bigint values to Number in relaxed mode', function () {
const number = { a: 10000n };
const serialized = EJSON.stringify(number, { relaxed: true });
expect(serialized).to.equal('{"a":10000}');
});

it('loses precision when serializing bigint values outside of range [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] in relaxed mode', function () {
const numbers = { a: -(2n ** 53n) - 1n, b: 2n ** 53n + 2n };
const serialized = EJSON.stringify(numbers, { relaxed: true });
expect(serialized).to.equal('{"a":-9007199254740992,"b":9007199254740994}');
});

it('produces bigint strings that pass loose equality checks with native bigint values that are are 64 bits wide or less', function () {
const number = { a: 12345n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
// eslint-disable-next-line eqeqeq
expect(parsed.a.$numberLong == 12345n).true;
});

it('produces bigint strings that are equal to the strings generated when using BigInt.toString when the bigint values used are 64 bits wide or less', function () {
const number = { a: 12345n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
expect(parsed.a.$numberLong).to.equal(12345n.toString());
});

it('produces bigint strings that fail loose equality checks with native bigint values that are more than 64 bits wide', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
// eslint-disable-next-line eqeqeq
expect(parsed.a.$numberLong == 0x1234_5678_1234_5678_9999n).false;
});

it('produces bigint strings that are not equal to the strings generated when using BigInt.toString when the bigint values used are more than 64 bits wide', function () {
const number = { a: 0x1234_5678_1234_5678_9999n };
const serialized = EJSON.stringify(number, { relaxed: false });
const parsed = JSON.parse(serialized);
expect(parsed.a.$numberLong).to.not.equal(0x1234_5678_1234_5678_9999n.toString());
});

it('should correctly parse null values', function () {
expect(EJSON.parse('null')).to.be.null;
expect(EJSON.parse('[null]')[0]).to.be.null;
Expand Down

0 comments on commit 4d1f84e

Please sign in to comment.