diff --git a/src/decimal128.ts b/src/decimal128.ts index f798cbf9..d3d197d6 100644 --- a/src/decimal128.ts +++ b/src/decimal128.ts @@ -167,11 +167,18 @@ export class Decimal128 { readonly bytes!: Buffer; - /** @param bytes - a buffer containing the raw Decimal128 bytes in little endian order */ - constructor(bytes: Buffer) { + /** + * @param bytes - a buffer containing the raw Decimal128 bytes in little endian order, + * or a string representation as returned by .toString() + */ + constructor(bytes: Buffer | string) { if (!(this instanceof Decimal128)) return new Decimal128(bytes); - this.bytes = bytes; + if (typeof bytes === 'string') { + this.bytes = Decimal128.fromString(bytes).bytes; + } else { + this.bytes = bytes; + } } /** @@ -796,7 +803,7 @@ export class Decimal128 { } inspect(): string { - return `Decimal128.fromString("${this.toString()}")`; + return `new Decimal128("${this.toString()}")`; } } diff --git a/src/long.ts b/src/long.ts index 0d059e25..977a9d39 100644 --- a/src/long.ts +++ b/src/long.ts @@ -97,16 +97,28 @@ export class Long { /** * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers. * See the from* functions below for more convenient ways of constructing Longs. + * + * Acceptable signatures are: + * - Long(low, high, unsigned?) + * - Long(bigint, unsigned?) + * - Long(string, unsigned?) + * * @param low - The low (signed) 32 bits of the long * @param high - The high (signed) 32 bits of the long * @param unsigned - Whether unsigned or not, defaults to signed */ - constructor(low = 0, high = 0, unsigned?: boolean) { + constructor(low: number | bigint | string = 0, high?: number | boolean, unsigned?: boolean) { if (!(this instanceof Long)) return new Long(low, high, unsigned); - this.low = low | 0; - this.high = high | 0; - this.unsigned = !!unsigned; + if (typeof low === 'bigint') { + Object.assign(this, Long.fromBigInt(low, !!high)); + } else if (typeof low === 'string') { + Object.assign(this, Long.fromString(low, !!high)); + } else { + this.low = low | 0; + this.high = (high as number) | 0; + this.unsigned = !!unsigned; + } Object.defineProperty(this, '__isLong__', { value: true, @@ -994,7 +1006,7 @@ export class Long { } inspect(): string { - return `Long.fromString("${this.toString()}"${this.unsigned ? ', true' : ''})`; + return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`; } } diff --git a/test/node/bigint_tests.js b/test/node/bigint_tests.js index b8d17bd3..32262c79 100644 --- a/test/node/bigint_tests.js +++ b/test/node/bigint_tests.js @@ -55,4 +55,18 @@ describe('BSON BigInt Support', function () { expect(() => BSON.serialize(testDoc)).to.throw(TypeError); // expect(() => BSON.serialize(testDoc)).to.throw(); }); + + it('Should accept BigInts in Long constructor', function (done) { + const Long = BSON.Long; + expect(new Long(BigInt('0')).toString()).to.equal('0'); + expect(new Long(BigInt('-1')).toString()).to.equal('-1'); + expect(new Long(BigInt('-1'), true).toString()).to.equal('18446744073709551615'); + expect(new Long(BigInt('123456789123456789')).toString()).to.equal('123456789123456789'); + expect(new Long(BigInt('123456789123456789'), true).toString()).to.equal('123456789123456789'); + expect(new Long(BigInt('13835058055282163712')).toString()).to.equal('-4611686018427387904'); + expect(new Long(BigInt('13835058055282163712'), true).toString()).to.equal( + '13835058055282163712' + ); + done(); + }); }); diff --git a/test/node/bson_test.js b/test/node/bson_test.js index 56c246d9..81134994 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -2332,7 +2332,7 @@ describe('BSON', function () { */ it('Decimal128', function () { const dec = Decimal128.fromString('1.42'); - expect(inspect(dec)).to.equal('Decimal128.fromString("1.42")'); + expect(inspect(dec)).to.equal('new Decimal128("1.42")'); }); /** @@ -2356,10 +2356,10 @@ describe('BSON', function () { */ it('Long', function () { const long = Long.fromString('42'); - expect(inspect(long)).to.equal('Long.fromString("42")'); + expect(inspect(long)).to.equal('new Long("42")'); const unsignedLong = Long.fromString('42', true); - expect(inspect(unsignedLong)).to.equal('Long.fromString("42", true)'); + expect(inspect(unsignedLong)).to.equal('new Long("42", true)'); }); /** diff --git a/test/node/bson_types_construction_tests.js b/test/node/bson_types_construction_tests.js index ad7507ed..fc8b1cbd 100644 --- a/test/node/bson_types_construction_tests.js +++ b/test/node/bson_types_construction_tests.js @@ -9,7 +9,7 @@ describe('Constructing BSON types', function () { new BSON.BSONSymbol('aaa'); new BSON.Binary('aaa'); new BSON.Code(function () {}); - new BSON.Decimal128('aaa'); + new BSON.Decimal128('123'); new BSON.Double(2.3); new BSON.Int32(1); new BSON.Long(0, 0); @@ -24,7 +24,7 @@ describe('Constructing BSON types', function () { BSON.BSONSymbol('aaa'); BSON.Binary('aaa'); BSON.Code(function () {}); - BSON.Decimal128('aaa'); + BSON.Decimal128('123'); BSON.Double(2.3); BSON.Int32(1); BSON.Long(0, 0); diff --git a/test/node/decimal128_tests.js b/test/node/decimal128_tests.js index 38e6cf14..3ed7051f 100644 --- a/test/node/decimal128_tests.js +++ b/test/node/decimal128_tests.js @@ -2131,4 +2131,13 @@ describe('Decimal128', function () { done(); }); + + it('accepts strings in the constructor', function (done) { + expect(new Decimal128('0').toString()).to.equal('0'); + expect(new Decimal128('00').toString()).to.equal('0'); + expect(new Decimal128('0.5').toString()).to.equal('0.5'); + expect(new Decimal128('-0.5').toString()).to.equal('-0.5'); + expect(new Decimal128('-1e400').toString()).to.equal('-1E+400'); + done(); + }); }); diff --git a/test/node/long_tests.js b/test/node/long_tests.js new file mode 100644 index 00000000..a1ea2e4c --- /dev/null +++ b/test/node/long_tests.js @@ -0,0 +1,18 @@ +'use strict'; + +const BSON = require('../register-bson'); +const Long = BSON.Long; + +describe('Long', function () { + it('accepts strings in the constructor', function (done) { + expect(new Long('0').toString()).to.equal('0'); + expect(new Long('00').toString()).to.equal('0'); + expect(new Long('-1').toString()).to.equal('-1'); + expect(new Long('-1', true).toString()).to.equal('18446744073709551615'); + expect(new Long('123456789123456789').toString()).to.equal('123456789123456789'); + expect(new Long('123456789123456789', true).toString()).to.equal('123456789123456789'); + expect(new Long('13835058055282163712').toString()).to.equal('-4611686018427387904'); + expect(new Long('13835058055282163712', true).toString()).to.equal('13835058055282163712'); + done(); + }); +});