Skip to content

Commit 392c1bc

Browse files
authored
feat(NODE-3264): allow Decimal128(string), Long(string), Long(bigint) (#437)
Adds support for the following constructor signatures: - `[new] Decimal128(string)` - `[new] Long(string[, unsigned])` - `[new] Long(bigint[, unsigned])` While the first two of these would not have thrown exceptions before, they would also not have returned any meaningful results, so this is not a breaking change.
1 parent 7b351cc commit 392c1bc

7 files changed

+74
-14
lines changed

src/decimal128.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,18 @@ export class Decimal128 {
167167

168168
readonly bytes!: Buffer;
169169

170-
/** @param bytes - a buffer containing the raw Decimal128 bytes in little endian order */
171-
constructor(bytes: Buffer) {
170+
/**
171+
* @param bytes - a buffer containing the raw Decimal128 bytes in little endian order,
172+
* or a string representation as returned by .toString()
173+
*/
174+
constructor(bytes: Buffer | string) {
172175
if (!(this instanceof Decimal128)) return new Decimal128(bytes);
173176

174-
this.bytes = bytes;
177+
if (typeof bytes === 'string') {
178+
this.bytes = Decimal128.fromString(bytes).bytes;
179+
} else {
180+
this.bytes = bytes;
181+
}
175182
}
176183

177184
/**
@@ -796,7 +803,7 @@ export class Decimal128 {
796803
}
797804

798805
inspect(): string {
799-
return `Decimal128.fromString("${this.toString()}")`;
806+
return `new Decimal128("${this.toString()}")`;
800807
}
801808
}
802809

src/long.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,28 @@ export class Long {
9797
/**
9898
* Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
9999
* See the from* functions below for more convenient ways of constructing Longs.
100+
*
101+
* Acceptable signatures are:
102+
* - Long(low, high, unsigned?)
103+
* - Long(bigint, unsigned?)
104+
* - Long(string, unsigned?)
105+
*
100106
* @param low - The low (signed) 32 bits of the long
101107
* @param high - The high (signed) 32 bits of the long
102108
* @param unsigned - Whether unsigned or not, defaults to signed
103109
*/
104-
constructor(low = 0, high = 0, unsigned?: boolean) {
110+
constructor(low: number | bigint | string = 0, high?: number | boolean, unsigned?: boolean) {
105111
if (!(this instanceof Long)) return new Long(low, high, unsigned);
106112

107-
this.low = low | 0;
108-
this.high = high | 0;
109-
this.unsigned = !!unsigned;
113+
if (typeof low === 'bigint') {
114+
Object.assign(this, Long.fromBigInt(low, !!high));
115+
} else if (typeof low === 'string') {
116+
Object.assign(this, Long.fromString(low, !!high));
117+
} else {
118+
this.low = low | 0;
119+
this.high = (high as number) | 0;
120+
this.unsigned = !!unsigned;
121+
}
110122

111123
Object.defineProperty(this, '__isLong__', {
112124
value: true,
@@ -994,7 +1006,7 @@ export class Long {
9941006
}
9951007

9961008
inspect(): string {
997-
return `Long.fromString("${this.toString()}"${this.unsigned ? ', true' : ''})`;
1009+
return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`;
9981010
}
9991011
}
10001012

test/node/bigint_tests.js

+14
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,18 @@ describe('BSON BigInt Support', function () {
5555
expect(() => BSON.serialize(testDoc)).to.throw(TypeError);
5656
// expect(() => BSON.serialize(testDoc)).to.throw();
5757
});
58+
59+
it('Should accept BigInts in Long constructor', function (done) {
60+
const Long = BSON.Long;
61+
expect(new Long(BigInt('0')).toString()).to.equal('0');
62+
expect(new Long(BigInt('-1')).toString()).to.equal('-1');
63+
expect(new Long(BigInt('-1'), true).toString()).to.equal('18446744073709551615');
64+
expect(new Long(BigInt('123456789123456789')).toString()).to.equal('123456789123456789');
65+
expect(new Long(BigInt('123456789123456789'), true).toString()).to.equal('123456789123456789');
66+
expect(new Long(BigInt('13835058055282163712')).toString()).to.equal('-4611686018427387904');
67+
expect(new Long(BigInt('13835058055282163712'), true).toString()).to.equal(
68+
'13835058055282163712'
69+
);
70+
done();
71+
});
5872
});

test/node/bson_test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,7 @@ describe('BSON', function () {
23322332
*/
23332333
it('Decimal128', function () {
23342334
const dec = Decimal128.fromString('1.42');
2335-
expect(inspect(dec)).to.equal('Decimal128.fromString("1.42")');
2335+
expect(inspect(dec)).to.equal('new Decimal128("1.42")');
23362336
});
23372337

23382338
/**
@@ -2356,10 +2356,10 @@ describe('BSON', function () {
23562356
*/
23572357
it('Long', function () {
23582358
const long = Long.fromString('42');
2359-
expect(inspect(long)).to.equal('Long.fromString("42")');
2359+
expect(inspect(long)).to.equal('new Long("42")');
23602360

23612361
const unsignedLong = Long.fromString('42', true);
2362-
expect(inspect(unsignedLong)).to.equal('Long.fromString("42", true)');
2362+
expect(inspect(unsignedLong)).to.equal('new Long("42", true)');
23632363
});
23642364

23652365
/**

test/node/bson_types_construction_tests.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('Constructing BSON types', function () {
99
new BSON.BSONSymbol('aaa');
1010
new BSON.Binary('aaa');
1111
new BSON.Code(function () {});
12-
new BSON.Decimal128('aaa');
12+
new BSON.Decimal128('123');
1313
new BSON.Double(2.3);
1414
new BSON.Int32(1);
1515
new BSON.Long(0, 0);
@@ -24,7 +24,7 @@ describe('Constructing BSON types', function () {
2424
BSON.BSONSymbol('aaa');
2525
BSON.Binary('aaa');
2626
BSON.Code(function () {});
27-
BSON.Decimal128('aaa');
27+
BSON.Decimal128('123');
2828
BSON.Double(2.3);
2929
BSON.Int32(1);
3030
BSON.Long(0, 0);

test/node/decimal128_tests.js

+9
Original file line numberDiff line numberDiff line change
@@ -2131,4 +2131,13 @@ describe('Decimal128', function () {
21312131

21322132
done();
21332133
});
2134+
2135+
it('accepts strings in the constructor', function (done) {
2136+
expect(new Decimal128('0').toString()).to.equal('0');
2137+
expect(new Decimal128('00').toString()).to.equal('0');
2138+
expect(new Decimal128('0.5').toString()).to.equal('0.5');
2139+
expect(new Decimal128('-0.5').toString()).to.equal('-0.5');
2140+
expect(new Decimal128('-1e400').toString()).to.equal('-1E+400');
2141+
done();
2142+
});
21342143
});

test/node/long_tests.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const BSON = require('../register-bson');
4+
const Long = BSON.Long;
5+
6+
describe('Long', function () {
7+
it('accepts strings in the constructor', function (done) {
8+
expect(new Long('0').toString()).to.equal('0');
9+
expect(new Long('00').toString()).to.equal('0');
10+
expect(new Long('-1').toString()).to.equal('-1');
11+
expect(new Long('-1', true).toString()).to.equal('18446744073709551615');
12+
expect(new Long('123456789123456789').toString()).to.equal('123456789123456789');
13+
expect(new Long('123456789123456789', true).toString()).to.equal('123456789123456789');
14+
expect(new Long('13835058055282163712').toString()).to.equal('-4611686018427387904');
15+
expect(new Long('13835058055282163712', true).toString()).to.equal('13835058055282163712');
16+
done();
17+
});
18+
});

0 commit comments

Comments
 (0)