Skip to content

Commit 79cb5d3

Browse files
authored
test(NODE-3719): reorganize spec tests and remove unneeded skips (#486)
1 parent 9671773 commit 79cb5d3

File tree

6 files changed

+65
-1693
lines changed

6 files changed

+65
-1693
lines changed

test/node/bson_corpus.prose.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const BSON = require('../register-bson');
4+
const BSONRegExp = BSON.BSONRegExp;
5+
6+
describe('BSON Corpus Prose Tests', function () {
7+
/**
8+
* The BSON spec uses null-terminated strings to represent document field names and
9+
* regex components (i.e. pattern and flags/options). Drivers MUST assert that null
10+
* bytes are prohibited in the following contexts when encoding BSON (i.e. creating
11+
* raw BSON bytes or constructing BSON-specific type classes):
12+
* - Field name within a root document
13+
* - Field name within a sub-document
14+
* - Pattern for a regular expression
15+
* - Flags/options for a regular expression
16+
* Depending on how drivers implement BSON encoding, they MAY expect an error when
17+
* constructing a type class (e.g. BSON Document or Regex class) or when encoding a
18+
* language representation to BSON (e.g. converting a dictionary, which might allow
19+
* null bytes in its keys, to raw BSON bytes).
20+
*/
21+
describe('1. Prohibit null bytes in null-terminated strings when encoding BSON', () => {
22+
it('Field name within a root document', () => {
23+
expect(() => BSON.serialize({ 'a\x00b': 1 })).to.throw(/null bytes/);
24+
});
25+
26+
it('Field name within a sub-document', () => {
27+
expect(() => BSON.serialize({ a: { 'a\x00b': 1 } })).to.throw(/null bytes/);
28+
});
29+
30+
it('Pattern for a regular expression', () => {
31+
// eslint-disable-next-line no-control-regex
32+
expect(() => BSON.serialize({ a: new RegExp('a\x00b') })).to.throw(/null bytes/);
33+
expect(() => BSON.serialize({ a: new BSONRegExp('a\x00b') })).to.throw(/null bytes/);
34+
});
35+
36+
it('Flags/options for a regular expression', () => {
37+
expect(() => BSON.serialize({ a: new BSONRegExp('a', 'i\x00m') })).to.throw(/null bytes/);
38+
39+
// eslint-disable-next-line no-invalid-regexp
40+
expect(() => new RegExp('a', 'i\x00m')).to.throw(SyntaxError);
41+
});
42+
});
43+
});

test/node/bson_corpus_tests.js renamed to test/node/bson_corpus.spec.test.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -108,40 +108,29 @@ const parseErrorForRootDocument = scenario => {
108108
}
109109
};
110110

111-
const skipBSON = {
112-
'NaN with payload':
113-
'passing this would require building a custom type to store the NaN payload data.'
114-
};
115-
// tests from the corpus that we need to skip, and explanations why
116-
const skipExtendedJSON = {
117-
'Timestamp with high-order bit set on both seconds and increment':
118-
'Current BSON implementation of timestamp/long cannot hold these values - 1 too large.',
119-
'Timestamp with high-order bit set on both seconds and increment (not UINT32_MAX)':
120-
'Current BSON implementation of timestamp/long cannot hold these values - 1 too large.'
121-
};
122-
123-
const SKIP_TESTS = new Map([
124-
...Object.entries(skipBSON),
125-
...Object.entries(skipExtendedJSON),
126-
[
127-
'All BSON types',
128-
'there is just too much variation in the specified expectation to make this work'
129-
]
130-
]);
131-
132111
const corpus = require('./tools/bson_corpus_test_loader');
133112
describe('BSON Corpus', function () {
134113
for (const scenario of corpus) {
135114
const deprecated = scenario.deprecated;
136115
const description = scenario.description;
137-
const valid = scenario.valid || [];
116+
const scenarioName = `${description} (${scenario._filename})`;
117+
const valid = scenario.valid;
138118

139-
describe(description, function () {
119+
describe(scenarioName, function () {
140120
if (valid) {
141121
describe('valid-bson', function () {
142122
for (const v of valid) {
143123
it(v.description, function () {
144-
if (SKIP_TESTS.has(v.description)) {
124+
if (v.description === 'NaN with payload') {
125+
// TODO(NODE-3630): remove custom float parser so we can handle the NaN payload data
126+
this.skip();
127+
}
128+
129+
if (
130+
v.description === 'All BSON types' &&
131+
scenario._filename === 'multi-type-deprecated'
132+
) {
133+
// TODO(NODE-3987): fix multi-type-deprecated test
145134
this.skip();
146135
}
147136

@@ -181,9 +170,6 @@ describe('BSON Corpus', function () {
181170
describe('valid-extjson', function () {
182171
for (const v of valid) {
183172
it(v.description, function () {
184-
if (SKIP_TESTS.has(v.description)) {
185-
this.skip();
186-
}
187173
// read in test case data. if this scenario is for a deprecated
188174
// type, we want to use the "converted" BSON and EJSON, which
189175
// use the upgraded version of the deprecated type. otherwise,
@@ -230,6 +216,7 @@ describe('BSON Corpus', function () {
230216
expect(nativeToREJSON(nativeFromCB)).to.equal(rEJ);
231217

232218
// relaxed EJSON -> native -> relaxed EJSON unchanged
219+
// TODO(NODE-3396): jsonToNative doesn't correctly parse the relaxed form
233220
expect(nativeToREJSON(jsonToNative(rEJ))).to.equal(rEJ);
234221
}
235222
});
@@ -242,7 +229,7 @@ describe('BSON Corpus', function () {
242229
for (const d of scenario.decodeErrors) {
243230
it(d.description, function () {
244231
const B = Buffer.from(d.bson, 'hex');
245-
expect(() => BSON.deserialize(B, deserializeOptions)).to.throw();
232+
expect(() => BSON.deserialize(B, deserializeOptions)).to.throw(BSONError);
246233
});
247234
}
248235
});

test/node/bson_test.js

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,38 +1986,4 @@ describe('BSON', function () {
19861986
expect(inspect(timestamp)).to.equal('new Timestamp({ t: 100, i: 1 })');
19871987
});
19881988
});
1989-
1990-
/**
1991-
* The BSON spec uses null-terminated strings to represent document field names and
1992-
* regex components (i.e. pattern and flags/options). Drivers MUST assert that null
1993-
* bytes are prohibited in the following contexts when encoding BSON (i.e. creating
1994-
* raw BSON bytes or constructing BSON-specific type classes):
1995-
* - Field name within a root document
1996-
* - Field name within a sub-document
1997-
* - Pattern for a regular expression
1998-
* - Flags/options for a regular expression
1999-
* Depending on how drivers implement BSON encoding, they MAY expect an error when
2000-
* constructing a type class (e.g. BSON Document or Regex class) or when encoding a
2001-
* language representation to BSON (e.g. converting a dictionary, which might allow
2002-
* null bytes in its keys, to raw BSON bytes).
2003-
*/
2004-
describe('null byte handling during serializing', () => {
2005-
it('should throw when null byte in BSON Field name within a root document', () => {
2006-
expect(() => BSON.serialize({ 'a\x00b': 1 })).to.throw(/null bytes/);
2007-
});
2008-
2009-
it('should throw when null byte in BSON Field name within a sub-document', () => {
2010-
expect(() => BSON.serialize({ a: { 'a\x00b': 1 } })).to.throw(/null bytes/);
2011-
});
2012-
2013-
it('should throw when null byte in Pattern for a regular expression', () => {
2014-
// eslint-disable-next-line no-control-regex
2015-
expect(() => BSON.serialize({ a: new RegExp('a\x00b') })).to.throw(/null bytes/);
2016-
expect(() => BSON.serialize({ a: new BSONRegExp('a\x00b') })).to.throw(/null bytes/);
2017-
});
2018-
2019-
it('should throw when null byte in Flags/options for a regular expression', () => {
2020-
expect(() => BSON.serialize({ a: new BSONRegExp('a', 'i\x00m') })).to.throw(/null bytes/);
2021-
});
2022-
});
20231989
});

0 commit comments

Comments
 (0)