Skip to content

Commit dc464c6

Browse files
authored
test(NODE-5327): fix handling of embedded nulls in spec runner matcher (#3728)
1 parent e006347 commit dc464c6

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

test/tools/spec-runner/matcher.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function is42(input) {
2020
return valIs42(input) || valIs42(input.$numberInt) || valIs42(input.$numberLong);
2121
}
2222

23-
function generateMatchAndDiffSpecialCase(key, expectedObj, actualObj, metadata) {
23+
function generateMatchAndDiffSpecialCase(key, expectedObj, actualObj, metadata, isRoot) {
2424
const expected = expectedObj[key];
2525
const actual = actualObj[key];
2626

@@ -44,11 +44,16 @@ function generateMatchAndDiffSpecialCase(key, expectedObj, actualObj, metadata)
4444
};
4545
}
4646

47-
const match = !Object.prototype.hasOwnProperty.call(actualObj, key);
47+
// An expected null value is not the same as the value not being present
48+
// so an exact match is forced here when not at the root level of the
49+
// object.
50+
const match = isRoot
51+
? !Object.prototype.hasOwnProperty.call(actualObj, key)
52+
: expected === actual;
4853
return {
4954
match,
50-
expected: SYMBOL_DOES_NOT_EXIST,
51-
actual: match ? SYMBOL_DOES_NOT_EXIST : actual
55+
expected: expected,
56+
actual: actual === undefined ? SYMBOL_DOES_NOT_EXIST : actual
5257
};
5358
}
5459

@@ -88,7 +93,7 @@ function generateMatchAndDiffSpecialCase(key, expectedObj, actualObj, metadata)
8893
// Case lsid - assert that session matches session in session data
8994
const sessionData = metadata.sessionData;
9095
const lsid = sessionData[expected];
91-
return generateMatchAndDiff(lsid, actual, metadata);
96+
return generateMatchAndDiff(lsid, actual, metadata, false);
9297
} else if (key === 'getMore' && expectedIs42) {
9398
// cursorid - explicitly ignore 42 values
9499
return {
@@ -121,11 +126,11 @@ function generateMatchAndDiffSpecialCase(key, expectedObj, actualObj, metadata)
121126
};
122127
} else {
123128
// default
124-
return generateMatchAndDiff(expected, actual, metadata);
129+
return generateMatchAndDiff(expected, actual, metadata, false);
125130
}
126131
}
127132

128-
function generateMatchAndDiff(expected, actual, metadata) {
133+
function generateMatchAndDiff(expected, actual, metadata, isRoot) {
129134
const typeOfExpected = typeof expected;
130135

131136
if (typeOfExpected === 'object' && expected._bsontype === 'Int32' && typeof actual === 'number') {
@@ -154,7 +159,7 @@ function generateMatchAndDiff(expected, actual, metadata) {
154159
}
155160

156161
return expected
157-
.map((val, idx) => generateMatchAndDiff(val, actual[idx], metadata))
162+
.map((val, idx) => generateMatchAndDiff(val, actual[idx], metadata, false))
158163
.reduce(
159164
(ret, value) => {
160165
ret.match = ret.match && value.match;
@@ -168,7 +173,7 @@ function generateMatchAndDiff(expected, actual, metadata) {
168173

169174
return Object.keys(expected).reduce(
170175
(ret, key) => {
171-
const check = generateMatchAndDiffSpecialCase(key, expected, actual, metadata);
176+
const check = generateMatchAndDiffSpecialCase(key, expected, actual, metadata, isRoot);
172177
ret.match = ret.match && check.match;
173178
ret.expected[key] = check.expected;
174179
ret.actual[key] = check.actual;
@@ -192,7 +197,7 @@ function matchMongoSpec(chai, utils) {
192197

193198
const sessionData = utils.flag(this, 'testRunnerSessionData');
194199

195-
const result = generateMatchAndDiff(expected, actual, { sessionData });
200+
const result = generateMatchAndDiff(expected, actual, { sessionData }, true);
196201

197202
chai.Assertion.prototype.assert.call(
198203
this,

0 commit comments

Comments
 (0)