@@ -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