Skip to content

Commit

Permalink
test(NODE-6438): check that BSON undefined is returned from deseriali…
Browse files Browse the repository at this point in the history
…ze (#721)

Co-authored-by: Bailey Pearson <[email protected]>
  • Loading branch information
nbbeeken and baileympearson authored Oct 22, 2024
1 parent 5f6bbf0 commit fedfaa1
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 74 deletions.
74 changes: 0 additions & 74 deletions test/node/bson_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,80 +298,6 @@ describe('BSON', function () {
done();
});

/**
* @ignore
*/
it('Should correctly ignore undefined values in arrays', function (done) {
var doc = { doc: { notdefined: undefined } };
var serialized_data = BSON.serialize(doc, {
ignoreUndefined: true
});
var serialized_data2 = Buffer.alloc(
BSON.calculateObjectSize(doc, {
ignoreUndefined: true
})
);
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
ignoreUndefined: true
});

assertBuffersEqual(done, serialized_data, serialized_data2, 0);
var doc1 = BSON.deserialize(serialized_data);

expect(undefined).to.deep.equal(doc1.doc.notdefined);
done();
});

it('Should correctly serialize undefined array entries as null values', function (done) {
var doc = { doc: { notdefined: undefined }, a: [1, 2, undefined, 3] };
var serialized_data = BSON.serialize(doc, {
ignoreUndefined: true
});
var serialized_data2 = Buffer.alloc(
BSON.calculateObjectSize(doc, {
ignoreUndefined: true
})
);
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
ignoreUndefined: true
});
assertBuffersEqual(done, serialized_data, serialized_data2, 0);
var doc1 = BSON.deserialize(serialized_data);
expect(undefined).to.deep.equal(doc1.doc.notdefined);
expect(null).to.equal(doc1.a[2]);
done();
});

it('Should correctly serialize undefined array entries as undefined values', function (done) {
var doc = { doc: { notdefined: undefined }, a: [1, 2, undefined, 3] };
var serialized_data = BSON.serialize(doc, {
ignoreUndefined: false
});
var serialized_data2 = Buffer.alloc(
BSON.calculateObjectSize(doc, {
ignoreUndefined: false
})
);
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
ignoreUndefined: false
});

// console.log("======================================== 0")
// console.log(serialized_data.toString('hex'))
// console.log(serialized_data2.toString('hex'))

assertBuffersEqual(done, serialized_data, serialized_data2, 0);
var doc1 = BSON.deserialize(serialized_data);
var doc2 = BSON.deserialize(serialized_data2);
// console.log("======================================== 0")
// console.dir(doc1)
// console.dir(doc2)

expect(null).to.deep.equal(doc1.doc.notdefined);
expect(null).to.deep.equal(doc2.doc.notdefined);
done();
});

/**
* @ignore
*/
Expand Down
108 changes: 108 additions & 0 deletions test/node/bson_undefined.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { expect } from 'chai';
import { bufferFromHexArray } from './tools/utils';
import { BSON } from '../register-bson';
import { BSON_DATA_NULL } from '../../src/constants';

describe('BSON undefined', () => {
const KEY_A = '6100';
const KEY_0 = '3000';
const KEY_1 = '3100';
const KEY_2 = '3200';

describe('when deserialize is given BSON bytes with undefined value', function () {
it('returns a javascript undefined value', () => {
const bsonDocWithUndefined = bufferFromHexArray([
'06', // BSON undefined
KEY_A
]);
const doc = BSON.deserialize(bsonDocWithUndefined);
expect(doc).to.have.own.property('a').that.is.undefined;
});
});

describe('when serialize is given a javascript object that contains undefined', () => {
describe('when ignoreUndefined is set to false', function () {
it('serializes to document with a set to BSON null (type=10)', () => {
const jsObject = { a: undefined };
const bytes = BSON.serialize(jsObject, { ignoreUndefined: false });
expect(bytes).to.have.lengthOf(8);
const elements = BSON.onDemand.parseToElements(bytes);
expect(elements).to.have.lengthOf(1);
expect(elements[0][0]).to.deep.equal(BSON_DATA_NULL);
});
});

describe('when ignoreUndefined is set to true', function () {
it('serializes to empty document', () => {
const jsObject = { a: undefined };
const bytes = BSON.serialize(jsObject, { ignoreUndefined: true });
expect(bytes).to.deep.equal(Uint8Array.of(5, 0, 0, 0, 0));
});
});

describe('when ignoreUndefined is unset', function () {
it('serializes to empty document', () => {
const jsObject = { a: undefined };
const bytes = BSON.serialize(jsObject);
expect(bytes).to.deep.equal(Uint8Array.of(5, 0, 0, 0, 0));
});
});
});

describe('when undefined appears inside an array', function () {
describe('when ignoreUndefined is set to true', function () {
it('serializes undefined values as null', function () {
// because this would change the size of the array
const doc = { a: [1, undefined, 3] };
const bytes = BSON.serialize(doc, { ignoreUndefined: true });
expect(bytes).to.deep.equal(
bufferFromHexArray([
'04', // array
KEY_A,
bufferFromHexArray([
...['10', KEY_0, '01000000'], // int "0" = 1
...['0A', KEY_1], // null "1"
...['10', KEY_2, '03000000'] // int "2" = 3
]).toString('hex')
])
);
});
});

describe('when ignoreUndefined is set to false', function () {
it('serializes undefined values as null', function () {
const doc = { a: [1, undefined, 3] };
const bytes = BSON.serialize(doc, { ignoreUndefined: false });
expect(bytes).to.deep.equal(
bufferFromHexArray([
'04', // array
KEY_A,
bufferFromHexArray([
...['10', KEY_0, '01000000'], // int "0" = 1
...['0A', KEY_1], // null "1"
...['10', KEY_2, '03000000'] // int "2" = 3
]).toString('hex')
])
);
});
});

describe('when ignoreUndefined is unset', function () {
it('serializes undefined values as null', function () {
const doc = { a: [1, undefined, 3] };
const bytes = BSON.serialize(doc);
expect(bytes).to.deep.equal(
bufferFromHexArray([
'04', // array
KEY_A,
bufferFromHexArray([
...['10', KEY_0, '01000000'], // int "0" = 1
...['0A', KEY_1], // null "1"
...['10', KEY_2, '03000000'] // int "2" = 3
]).toString('hex')
])
);
});
});
});
});
1 change: 1 addition & 0 deletions test/node/parser/serializer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('serialize()', () => {
});

it('does not turn nested nulls into empty documents', () => {
// In JS typeof null is 'object' so it is possible it could be misinterpreted as an object with no keys
const nestedNull = bufferFromHexArray([
'0A', // null type
'6100', // 'a\x00'
Expand Down

0 comments on commit fedfaa1

Please sign in to comment.