Skip to content

test(NODE-6438): check that BSON undefined is returned from deserialize #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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