Skip to content

Commit d87de24

Browse files
committed
assertion-arguments: Detect error constructors passed as assertion messages
Fixes #178
1 parent 449013a commit d87de24

3 files changed

Lines changed: 18 additions & 9 deletions

File tree

docs/rules/assertion-arguments.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ test('1', t => {
2828
t.is(value); // Not enough arguments
2929
t.is(value, expected, message, extra); // Too many arguments
3030
t.is(value, expected, false); // Assertion message is not a string
31+
t.notThrows(() => { /**/ }, TypeError); // Second argument should be a string message
3132
t.plan('1'); // Argument is not a non-negative integer
3233
t.plan(2.5); // Argument is not a non-negative integer
3334
t.regex(/foo/, string); // First argument should be a string, not a regex

rules/assertion-arguments.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,20 +333,19 @@ const create = context => {
333333

334334
if (lastArgument.type === 'Identifier') {
335335
const variable = findVariable(context.sourceCode.getScope(node), lastArgument);
336-
if (!variable) {
337-
return;
338-
}
339336

340-
let value;
341-
for (const reference of variable.references) {
342-
value = reference.writeExpr ?? value;
337+
let resolved;
338+
if (variable) {
339+
for (const reference of variable.references) {
340+
resolved = reference.writeExpr ?? resolved;
341+
}
343342
}
344343

345-
if (!value) {
344+
if (resolved) {
345+
lastArgument = resolved;
346+
} else if (!/^(?:[A-Z][a-z\d]*)*Error$/.test(lastArgument.name)) {
346347
return;
347348
}
348-
349-
lastArgument = value;
350349
}
351350

352351
if (!isString(lastArgument)) {

test/assertion-arguments.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,15 @@ ruleTester.run('assertion-arguments', rule, {
509509
testCase(false, 't.fail({});', messageIsNotStringError),
510510
testCase(false, 'let message = "ok"; message = false; t.assert(true, message);', messageIsNotStringError),
511511

512+
// Error constructors are not valid assertion messages
513+
testCase(false, 't.notThrows(() => {}, TypeError);', messageIsNotStringError),
514+
testCase(false, 't.notThrowsAsync(Promise.resolve(), TypeError);', messageIsNotStringError),
515+
testCase(false, 't.notThrows(() => {}, Error);', messageIsNotStringError),
516+
testCase(false, 't.notThrows(() => {}, RangeError);', messageIsNotStringError),
517+
testCase(false, 't.fail(CustomError);', messageIsNotStringError),
518+
testCase(false, 't.is(1, 2, TypeError);', messageIsNotStringError),
519+
testCase(false, 't.throws(() => {}, null, TypeError);', messageIsNotStringError),
520+
512521
// Regex as first argument
513522
testCase(false, 't.regex(/foo/, variable);', regexFirstError, {output: 't.regex(variable, /foo/);'}),
514523
testCase(false, 't.notRegex(/foo/, variable);', regexFirstError, {output: 't.notRegex(variable, /foo/);'}),

0 commit comments

Comments
 (0)