| 154 | * [CMAP Spec Test README](https://github.com/mongodb/specifications/tree/master/source/connection-monitoring-and-pooling/tests#spec-test-match-function) |
| 155 | */ |
| 156 | const compareInputToSpec = (input, expected, message) => { |
| 157 | // the spec uses 42 and "42" as special keywords to express that the value does not matter |
| 158 | // however, "42" does not appear in the spec tests, so only the numeric value is checked here |
| 159 | if (expected === 42) { |
| 160 | expect(input, message).not.to.be.undefined; |
| 161 | expect(input, message).not.to.be.null; |
| 162 | return; |
| 163 | } |
| 164 | |
| 165 | if (Array.isArray(expected)) { |
| 166 | expect(input, message).to.be.an('array'); |
| 167 | for (const [index, expectedValue] of input.entries()) { |
| 168 | compareInputToSpec(input[index], expectedValue, `${message} at index ${index}`); |
| 169 | } |
| 170 | return; |
| 171 | } |
| 172 | |
| 173 | const expectedEntries: [string, unknown][] = Object.entries(expected).map(([k, v]) => { |
| 174 | // Node uses `durationMS` instead of `duration` on CMAP events. |
| 175 | if (k === 'duration') return ['durationMS', v]; |
| 176 | return [k, v]; |
| 177 | }); |
| 178 | |
| 179 | if (expected && typeof expected === 'object') { |
| 180 | for (const [expectedPropName, expectedValue] of expectedEntries) { |
| 181 | expect(input, message).to.have.property(expectedPropName); |
| 182 | compareInputToSpec( |
| 183 | input[expectedPropName], |
| 184 | expectedValue, |
| 185 | `${message} property ${expectedPropName}` |
| 186 | ); |
| 187 | } |
| 188 | return; |
| 189 | } |
| 190 | |
| 191 | expect(input, message).to.equal(expected); |
| 192 | }; |
| 193 | |
| 194 | const getTestOpDefinitions = (threadContext: ThreadContext) => ({ |
| 195 | checkOut: async function (op) { |