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).