Skip to content

Commit fedfaa1

Browse files
test(NODE-6438): check that BSON undefined is returned from deserialize (#721)
Co-authored-by: Bailey Pearson <[email protected]>
1 parent 5f6bbf0 commit fedfaa1

File tree

3 files changed

+109
-74
lines changed

3 files changed

+109
-74
lines changed

test/node/bson_test.js

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -298,80 +298,6 @@ describe('BSON', function () {
298298
done();
299299
});
300300

301-
/**
302-
* @ignore
303-
*/
304-
it('Should correctly ignore undefined values in arrays', function (done) {
305-
var doc = { doc: { notdefined: undefined } };
306-
var serialized_data = BSON.serialize(doc, {
307-
ignoreUndefined: true
308-
});
309-
var serialized_data2 = Buffer.alloc(
310-
BSON.calculateObjectSize(doc, {
311-
ignoreUndefined: true
312-
})
313-
);
314-
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
315-
ignoreUndefined: true
316-
});
317-
318-
assertBuffersEqual(done, serialized_data, serialized_data2, 0);
319-
var doc1 = BSON.deserialize(serialized_data);
320-
321-
expect(undefined).to.deep.equal(doc1.doc.notdefined);
322-
done();
323-
});
324-
325-
it('Should correctly serialize undefined array entries as null values', function (done) {
326-
var doc = { doc: { notdefined: undefined }, a: [1, 2, undefined, 3] };
327-
var serialized_data = BSON.serialize(doc, {
328-
ignoreUndefined: true
329-
});
330-
var serialized_data2 = Buffer.alloc(
331-
BSON.calculateObjectSize(doc, {
332-
ignoreUndefined: true
333-
})
334-
);
335-
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
336-
ignoreUndefined: true
337-
});
338-
assertBuffersEqual(done, serialized_data, serialized_data2, 0);
339-
var doc1 = BSON.deserialize(serialized_data);
340-
expect(undefined).to.deep.equal(doc1.doc.notdefined);
341-
expect(null).to.equal(doc1.a[2]);
342-
done();
343-
});
344-
345-
it('Should correctly serialize undefined array entries as undefined values', function (done) {
346-
var doc = { doc: { notdefined: undefined }, a: [1, 2, undefined, 3] };
347-
var serialized_data = BSON.serialize(doc, {
348-
ignoreUndefined: false
349-
});
350-
var serialized_data2 = Buffer.alloc(
351-
BSON.calculateObjectSize(doc, {
352-
ignoreUndefined: false
353-
})
354-
);
355-
BSON.serializeWithBufferAndIndex(doc, serialized_data2, {
356-
ignoreUndefined: false
357-
});
358-
359-
// console.log("======================================== 0")
360-
// console.log(serialized_data.toString('hex'))
361-
// console.log(serialized_data2.toString('hex'))
362-
363-
assertBuffersEqual(done, serialized_data, serialized_data2, 0);
364-
var doc1 = BSON.deserialize(serialized_data);
365-
var doc2 = BSON.deserialize(serialized_data2);
366-
// console.log("======================================== 0")
367-
// console.dir(doc1)
368-
// console.dir(doc2)
369-
370-
expect(null).to.deep.equal(doc1.doc.notdefined);
371-
expect(null).to.deep.equal(doc2.doc.notdefined);
372-
done();
373-
});
374-
375301
/**
376302
* @ignore
377303
*/

test/node/bson_undefined.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { expect } from 'chai';
2+
import { bufferFromHexArray } from './tools/utils';
3+
import { BSON } from '../register-bson';
4+
import { BSON_DATA_NULL } from '../../src/constants';
5+
6+
describe('BSON undefined', () => {
7+
const KEY_A = '6100';
8+
const KEY_0 = '3000';
9+
const KEY_1 = '3100';
10+
const KEY_2 = '3200';
11+
12+
describe('when deserialize is given BSON bytes with undefined value', function () {
13+
it('returns a javascript undefined value', () => {
14+
const bsonDocWithUndefined = bufferFromHexArray([
15+
'06', // BSON undefined
16+
KEY_A
17+
]);
18+
const doc = BSON.deserialize(bsonDocWithUndefined);
19+
expect(doc).to.have.own.property('a').that.is.undefined;
20+
});
21+
});
22+
23+
describe('when serialize is given a javascript object that contains undefined', () => {
24+
describe('when ignoreUndefined is set to false', function () {
25+
it('serializes to document with a set to BSON null (type=10)', () => {
26+
const jsObject = { a: undefined };
27+
const bytes = BSON.serialize(jsObject, { ignoreUndefined: false });
28+
expect(bytes).to.have.lengthOf(8);
29+
const elements = BSON.onDemand.parseToElements(bytes);
30+
expect(elements).to.have.lengthOf(1);
31+
expect(elements[0][0]).to.deep.equal(BSON_DATA_NULL);
32+
});
33+
});
34+
35+
describe('when ignoreUndefined is set to true', function () {
36+
it('serializes to empty document', () => {
37+
const jsObject = { a: undefined };
38+
const bytes = BSON.serialize(jsObject, { ignoreUndefined: true });
39+
expect(bytes).to.deep.equal(Uint8Array.of(5, 0, 0, 0, 0));
40+
});
41+
});
42+
43+
describe('when ignoreUndefined is unset', function () {
44+
it('serializes to empty document', () => {
45+
const jsObject = { a: undefined };
46+
const bytes = BSON.serialize(jsObject);
47+
expect(bytes).to.deep.equal(Uint8Array.of(5, 0, 0, 0, 0));
48+
});
49+
});
50+
});
51+
52+
describe('when undefined appears inside an array', function () {
53+
describe('when ignoreUndefined is set to true', function () {
54+
it('serializes undefined values as null', function () {
55+
// because this would change the size of the array
56+
const doc = { a: [1, undefined, 3] };
57+
const bytes = BSON.serialize(doc, { ignoreUndefined: true });
58+
expect(bytes).to.deep.equal(
59+
bufferFromHexArray([
60+
'04', // array
61+
KEY_A,
62+
bufferFromHexArray([
63+
...['10', KEY_0, '01000000'], // int "0" = 1
64+
...['0A', KEY_1], // null "1"
65+
...['10', KEY_2, '03000000'] // int "2" = 3
66+
]).toString('hex')
67+
])
68+
);
69+
});
70+
});
71+
72+
describe('when ignoreUndefined is set to false', function () {
73+
it('serializes undefined values as null', function () {
74+
const doc = { a: [1, undefined, 3] };
75+
const bytes = BSON.serialize(doc, { ignoreUndefined: false });
76+
expect(bytes).to.deep.equal(
77+
bufferFromHexArray([
78+
'04', // array
79+
KEY_A,
80+
bufferFromHexArray([
81+
...['10', KEY_0, '01000000'], // int "0" = 1
82+
...['0A', KEY_1], // null "1"
83+
...['10', KEY_2, '03000000'] // int "2" = 3
84+
]).toString('hex')
85+
])
86+
);
87+
});
88+
});
89+
90+
describe('when ignoreUndefined is unset', function () {
91+
it('serializes undefined values as null', function () {
92+
const doc = { a: [1, undefined, 3] };
93+
const bytes = BSON.serialize(doc);
94+
expect(bytes).to.deep.equal(
95+
bufferFromHexArray([
96+
'04', // array
97+
KEY_A,
98+
bufferFromHexArray([
99+
...['10', KEY_0, '01000000'], // int "0" = 1
100+
...['0A', KEY_1], // null "1"
101+
...['10', KEY_2, '03000000'] // int "2" = 3
102+
]).toString('hex')
103+
])
104+
);
105+
});
106+
});
107+
});
108+
});

test/node/parser/serializer.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ describe('serialize()', () => {
2626
});
2727

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

0 commit comments

Comments
 (0)