chai
chai copied to clipboard
assert.throws does not perform equality check against Error message
It appears that assert.throws
does some sort of .endsWith
comparison instead of an equality check if provided 2 arguments and the second argument is a string. From the docs:
assert.throws(fn, 'Error thrown must have this msg');
This definitely makes me believe that the string provided should match the Error message. However, I discovered the following:
import { describe, it } from "mocha";
import { assert } from "chai";
describe("Test throws", () => {
const errMsg = "ABCD is a bad value";
// Passes as expected
it("Full Comparison", () => {
assert.throws(() => {
throw new Error(errMsg);
}, errMsg);
});
// ERROR: this unexpectedly passes
it("endsWith Comparison", () => {
assert.throws(() => {
throw new Error(errMsg);
}, "bad value");
});
// Fails as expected
it("Bad Comparison", () => {
assert.throws(() => {
throw new Error(errMsg);
}, "good value");
});
});
Digging through the code, I found the offending line (https://github.com/chaijs/chai/blob/master/chai.js#L9576) which uses an indexOf rather than equality.
function compatibleMessage(thrown, errMatcher) {
var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
if (errMatcher instanceof RegExp) {
return errMatcher.test(comparisonString);
} else if (typeof errMatcher === 'string') {
return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
}
return false;
}
The naming of the function makes me think not using equality was deliberate but this is incorrect behavior,
The same
I'm also faced this issue. And it is a bug, because partial match can be performed with RegExp, so case with string should check exact match.
I also came across this issue along with the same strange compatibleMessage
behavior. This behavior is documented in the code and in the .throw()
documentation here, so I guess it's not really a bug, but it does seem counter-intuitive (and risky).