From 384d3c756cbf3bb1caa4500f0a744b68b62ebdc4 Mon Sep 17 00:00:00 2001 From: Sean Reece Date: Wed, 21 Aug 2024 23:13:04 -0400 Subject: [PATCH] Improvements --- src/objectid.ts | 21 ++++++++++++++++----- test/node/bson_test.js | 12 ++++-------- test/node/bson_type_classes.test.ts | 13 +++++-------- test/node/extended_json.test.ts | 10 +++++----- test/node/object_id.test.ts | 28 +++++++++++++++++----------- test/node/tools/utils.js | 22 ---------------------- 6 files changed, 47 insertions(+), 59 deletions(-) diff --git a/src/objectid.ts b/src/objectid.ts index 7bce12e3..e98efdbc 100644 --- a/src/objectid.ts +++ b/src/objectid.ts @@ -69,11 +69,7 @@ export class ObjectId extends BSONValue { } static set poolSize(size: number) { - const iSize = Math.ceil(size); // Ensure new pool size is an integer - if (iSize <= 0) { - throw new BSONError('poolSize must be a positive integer greater than 0'); - } - poolSize = iSize; + poolSize = Math.max(Math.abs(Number(size)) >>> 0, 1); } /** ObjectId buffer pool pointer @internal */ @@ -241,6 +237,21 @@ export class ObjectId extends BSONValue { return (ObjectId.index = (ObjectId.index + 1) % 0xffffff); } + /** + * Generate a 12 byte id buffer used in ObjectId's + * + * @param time - pass in a second based timestamp. + */ + static generate(time?: number): Uint8Array; + /** + * Generate a 12 byte id buffer used in ObjectId's and write to the provided buffer at offset. + * @internal + * + * @param time - pass in a second based timestamp. + * @param buffer - Optionally pass in a buffer instance. + * @param offset - Optionally pass in a buffer offset. + */ + static generate(time?: number, buffer?: Uint8Array, offset?: number): Uint8Array; /** * Generate a 12 byte id buffer used in ObjectId's * diff --git a/test/node/bson_test.js b/test/node/bson_test.js index 12912b6e..9b5ba41f 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -20,11 +20,7 @@ const MaxKey = BSON.MaxKey; const BSONError = BSON.BSONError; const { BinaryParser } = require('./tools/binary_parser'); const vm = require('vm'); -const { - assertBuffersEqual, - isBufferOrUint8Array, - assertDeepEqualsWithObjectId -} = require('./tools/utils'); +const { assertBuffersEqual, isBufferOrUint8Array } = require('./tools/utils'); const { inspect } = require('util'); /** @@ -711,7 +707,7 @@ describe('BSON', function () { expect(serialized_data).to.deep.equal(serialized_data2); var doc2 = b.deserialize(serialized_data); - assertDeepEqualsWithObjectId(doc, doc2); + expect(b.serialize(doc)).to.deep.equal(b.serialize(doc2)); expect(doc2.dbref.oid.toHexString()).to.deep.equal(oid.toHexString()); done(); }); @@ -1005,7 +1001,7 @@ describe('BSON', function () { var deserialized_data = BSON.deserialize(serialized_data); expect(doc.b).to.deep.equal(deserialized_data.b); - assertDeepEqualsWithObjectId(doc, deserialized_data); + expect(BSON.serialize(doc)).to.deep.equal(BSON.serialize(deserialized_data)); done(); }); @@ -1217,7 +1213,7 @@ describe('BSON', function () { var doc2 = BSON.deserialize(serialized_data); - assertDeepEqualsWithObjectId(doc, doc2); + expect(BSON.serialize(doc)).to.deep.equal(BSON.serialize(doc2)); done(); }); diff --git a/test/node/bson_type_classes.test.ts b/test/node/bson_type_classes.test.ts index 8ef7a422..a3290091 100644 --- a/test/node/bson_type_classes.test.ts +++ b/test/node/bson_type_classes.test.ts @@ -16,9 +16,9 @@ import { ObjectId, Timestamp, UUID, - BSONValue + BSONValue, + BSON } from '../register-bson'; -import { assertDeepEqualsWithObjectId } from './tools/utils'; import * as vm from 'node:vm'; const BSONTypeClasses = [ @@ -130,12 +130,9 @@ describe('BSON Type classes common interfaces', () => { } vm.runInNewContext(`module.exports.result = ${bsonValue.inspect()}`, ctx); - if (ctx.ObjectId) { - // Since ObjectId uses a pool we expect offset to be different - assertDeepEqualsWithObjectId(ctx.module.exports.result, bsonValue); - } else { - expect(ctx.module.exports.result).to.deep.equal(bsonValue); - } + expect(BSON.serialize({ result: ctx.module.exports.result })).to.deep.equal( + BSON.serialize({ result: bsonValue }) + ); }); } }); diff --git a/test/node/extended_json.test.ts b/test/node/extended_json.test.ts index 51adce27..2760a4ce 100644 --- a/test/node/extended_json.test.ts +++ b/test/node/extended_json.test.ts @@ -4,7 +4,6 @@ import * as vm from 'node:vm'; import { expect } from 'chai'; import { BSONVersionError, BSONRuntimeError } from '../../src'; import { BSONError } from '../register-bson'; -import { assertDeepEqualsWithObjectId } from './tools/utils'; // BSON types const Binary = BSON.Binary; @@ -145,10 +144,11 @@ describe('Extended JSON', function () { const input = '{"result":[{"_id":{"$oid":"591801a468f9e7024b623939"},"emptyField":null}]}'; const parsed = EJSON.parse(input); - const expected = { - result: [{ _id: new ObjectId('591801a468f9e7024b623939'), emptyField: null }] - }; - assertDeepEqualsWithObjectId(parsed, expected); + expect(EJSON.serialize(parsed)).to.deep.equal( + EJSON.serialize({ + result: [{ _id: new ObjectId('591801a468f9e7024b623939'), emptyField: null }] + }) + ); }); it('should correctly throw when passed a non-string to parse', function () { diff --git a/test/node/object_id.test.ts b/test/node/object_id.test.ts index aba16d33..6fb93368 100644 --- a/test/node/object_id.test.ts +++ b/test/node/object_id.test.ts @@ -5,13 +5,6 @@ import { expect } from 'chai'; import { bufferFromHexArray } from './tools/utils'; import { isBufferOrUint8Array } from './tools/utils'; -declare module '../register-bson' { - interface ObjectId { - pool: Uint8Array; - offset: number; - } -} - describe('ObjectId', function () { describe('static createFromTime()', () => { it('creates an objectId with user defined value in the timestamp field', function () { @@ -325,11 +318,24 @@ describe('ObjectId', function () { ObjectId.poolSize = oldPoolSize; }); - it('should not allow 0 poolSize', function () { + it('should default to poolSize = 1 when invalid poolSize set', function () { const oldPoolSize = ObjectId.poolSize; - expect(() => { - ObjectId.poolSize = 0; - }).to.throw(BSONError); + + ObjectId.poolSize = 0; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = -1; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = 0n; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = ''; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = NaN; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = {}; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = false; + expect(ObjectId.poolSize).to.equal(1); + ObjectId.poolSize = '1'; ObjectId.poolSize = oldPoolSize; }); diff --git a/test/node/tools/utils.js b/test/node/tools/utils.js index 856fd1e7..36d51c2a 100644 --- a/test/node/tools/utils.js +++ b/test/node/tools/utils.js @@ -218,25 +218,3 @@ module.exports.sorted = (iterable, how) => { items.sort(how); return items; }; - -/** Deeply converts all ObjectIds into their hex value representation */ -const deepOidValue = obj => { - if (obj?._bsontype === 'ObjectId') { - return obj.toHexString(); - } - if (Array.isArray(obj)) { - return obj.map(item => deepOidValue(item)); - } else if (obj !== null && typeof obj === 'object' && !Buffer.isBuffer(obj)) { - return Object.entries(obj).reduce((acc, [key, value]) => { - acc[key] = deepOidValue(value); - return acc; - }, {}); - } - return obj; -}; - -module.exports.assertDeepEqualsWithObjectId = (actual, expected) => { - const a = deepOidValue(actual); - const b = deepOidValue(expected); - expect(a).to.deep.equal(b); -};