diff --git a/src/decimal128.ts b/src/decimal128.ts index 0427dad8..3f8dc734 100644 --- a/src/decimal128.ts +++ b/src/decimal128.ts @@ -1,6 +1,7 @@ import { Buffer } from 'buffer'; import { BSONTypeError } from './error'; import { Long } from './long'; +import { isUint8Array } from './parser/utils'; const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/; const PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i; @@ -132,8 +133,13 @@ export class Decimal128 { if (typeof bytes === 'string') { this.bytes = Decimal128.fromString(bytes).bytes; - } else { + } else if (isUint8Array(bytes)) { + if (bytes.byteLength !== 16) { + throw new BSONTypeError('Decimal128 must take a Buffer of 16 bytes'); + } this.bytes = bytes; + } else { + throw new BSONTypeError('Decimal128 must take a Buffer or string'); } } diff --git a/test/.eslintrc.json b/test/.eslintrc.json index 9e002e3e..9f0d77ef 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -31,6 +31,21 @@ "error", "global" ], - "promise/no-native": "off" + "promise/no-native": "off", + "no-restricted-properties": [ + "error", + { + "object": "describe", + "property": "only" + }, + { + "object": "it", + "property": "only" + }, + { + "object": "context", + "property": "only" + } + ] } } diff --git a/test/node/decimal128_tests.js b/test/node/decimal128_tests.js index e5ba7df3..edd8e80c 100644 --- a/test/node/decimal128_tests.js +++ b/test/node/decimal128_tests.js @@ -1205,7 +1205,7 @@ describe('Decimal128', function () { done(); }); - it('accepts strings in the constructor', function (done) { + it('accepts strings in the constructor', () => { 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'); @@ -1216,6 +1216,30 @@ describe('Decimal128', function () { expect(new Decimal128('0.0011').toString()).to.equal('0.0011'); expect(new Decimal128('0.00110').toString()).to.equal('0.00110'); expect(new Decimal128('-1e400').toString()).to.equal('-1E+400'); - done(); + }); + + it('throws correct error for invalid constructor argument type', () => { + const constructorArgErrMsg = 'Decimal128 must take a Buffer or string'; + + expect(() => new Decimal128(-0)).to.throw(constructorArgErrMsg); + expect(() => new Decimal128(-1)).to.throw(constructorArgErrMsg); + expect(() => new Decimal128(10)).to.throw(constructorArgErrMsg); + expect(() => new Decimal128(1111111111111111)).to.throw(constructorArgErrMsg); + }); + + it('throws correct error for an invalid Buffer constructor argument', () => { + const byteLengthErrMsg = 'Decimal128 must take a Buffer of 16 bytes'; + + expect(() => new Decimal128(new Uint8Array(0))).to.throw(byteLengthErrMsg); + expect(() => new Decimal128(Buffer.alloc(0))).to.throw(byteLengthErrMsg); + expect(() => new Decimal128(new Uint8Array(3))).to.throw(byteLengthErrMsg); + expect(() => new Decimal128(Buffer.alloc(3))).to.throw(byteLengthErrMsg); + expect(() => new Decimal128(new Uint8Array(17))).to.throw(byteLengthErrMsg); + expect(() => new Decimal128(Buffer.alloc(17))).to.throw(byteLengthErrMsg); + }); + + it('does not throw error for an empty Buffer of correct length constructor argument', () => { + expect(() => new Decimal128(Buffer.alloc(16))).to.not.throw(); + expect(() => new Decimal128(new Uint8Array(16))).to.not.throw(); }); }); diff --git a/test/node/extended_json_tests.js b/test/node/extended_json_tests.js index 926a242d..2be132ff 100644 --- a/test/node/extended_json_tests.js +++ b/test/node/extended_json_tests.js @@ -227,7 +227,7 @@ describe('Extended JSON', function () { binary: new Binary(''), code: new Code('function() {}'), dbRef: new DBRef('tests', new Int32(1), 'test'), - decimal128: new Decimal128(128), + decimal128: new Decimal128('128'), double: new Double(10.1), int32: new Int32(10), long: new Long(234), @@ -248,7 +248,7 @@ describe('Extended JSON', function () { binary: { $binary: { base64: '', subType: '00' } }, code: { $code: 'function() {}' }, dbRef: { $ref: 'tests', $id: { $numberInt: '1' }, $db: 'test' }, - decimal128: { $numberDecimal: '0E-6176' }, + decimal128: { $numberDecimal: '128' }, double: { $numberDouble: '10.1' }, int32: { $numberInt: '10' }, long: { $numberLong: '234' },