Skip to content

Commit

Permalink
feat(rules): require-tothrow-message (#160)
Browse files Browse the repository at this point in the history
This rule checks if `toThrow` or `toThrowError` has a message.

Fixes #154.
  • Loading branch information
garyking authored and SimenB committed Sep 29, 2018
1 parent a194da6 commit 7515458
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -98,6 +98,7 @@ for more information about extending configuration files.
| [prefer-to-be-undefined][] | Suggest using `toBeUndefined()` | | ![fixable-green][] |
| [prefer-to-have-length][] | Suggest using `toHaveLength()` | ![recommended][] | ![fixable-green][] |
| [prefer-inline-snapshots][] | Suggest using `toMatchInlineSnapshot()` | | ![fixable-green][] |
| [require-tothrow-message][] | Require that `toThrow()` and `toThrowError` includes a message | | |
| [valid-describe][] | Enforce valid `describe()` callback | | |
| [valid-expect-in-promise][] | Enforce having return statement when testing with promises | | |
| [valid-expect][] | Enforce valid `expect()` usage | ![recommended][] | |
Expand Down Expand Up @@ -125,6 +126,7 @@ for more information about extending configuration files.
[prefer-to-be-undefined]: docs/rules/prefer-to-be-undefined.md
[prefer-to-have-length]: docs/rules/prefer-to-have-length.md
[prefer-inline-snapshots]: docs/rules/prefer-inline-snapshots.md
[require-tothrow-message]: docs/rules/require-tothrow-message.md
[valid-describe]: docs/rules/valid-describe.md
[valid-expect-in-promise]: docs/rules/valid-expect-in-promise.md
[valid-expect]: docs/rules/valid-expect.md
Expand Down
29 changes: 29 additions & 0 deletions docs/rules/require-tothrow-message.md
@@ -0,0 +1,29 @@
# Require a message for `toThrow()` (require-tothrow-message)

`toThrow()`, and its alias `toThrowError()`, are used to check if an error is
thrown by a function call, such as in `expect(() => a()).toThrow()`. However, if
no message is defined, then the test will pass for any thrown error. Requiring a
message ensures that the intended error is thrown.

## Rule details

This rule triggers a warning if `toThrow()` or `toThrowError()` is used without
an error message.

### Default configuration

The following patterns are considered warnings:

```js
expect(() => a()).toThrow();

expect(() => a()).toThrowError();
```

The following patterns are not considered warnings:

```js
expect(() => a()).toThrow('a');

expect(() => a()).toThrowError('a');
```
2 changes: 2 additions & 0 deletions index.js
Expand Up @@ -21,6 +21,7 @@ const preferExpectAssertions = require('./rules/prefer-expect-assertions');
const validExpectInPromise = require('./rules/valid-expect-in-promise');
const preferInlineSnapshots = require('./rules/prefer-inline-snapshots');
const preferStrictEqual = require('./rules/prefer-strict-equal');
const requireTothrowMessage = require('./rules/require-tothrow-message');

const snapshotProcessor = require('./processors/snapshot-processor');

Expand Down Expand Up @@ -89,5 +90,6 @@ module.exports = {
'valid-expect-in-promise': validExpectInPromise,
'prefer-inline-snapshots': preferInlineSnapshots,
'prefer-strict-equal': preferStrictEqual,
'require-tothrow-message': requireTothrowMessage,
},
};
32 changes: 32 additions & 0 deletions rules/__tests__/require-tothrow-message.js
@@ -0,0 +1,32 @@
'use strict';

const RuleTester = require('eslint').RuleTester;
const rule = require('../require-tothrow-message');

const ruleTester = new RuleTester();

ruleTester.run('require-tothrow-message', rule, {
valid: [
"expect(function() { a() }).toThrow('a');",
"expect(function() { a() }).toThrowError('a');",
],

invalid: [
{
code: 'expect(function() { a() }).toThrow();',
errors: [
{ message: 'Add an error message to toThrow()', column: 28, line: 1 },
],
},
{
code: 'expect(function() { a() }).toThrowError();',
errors: [
{
message: 'Add an error message to toThrowError()',
column: 28,
line: 1,
},
],
},
],
});
32 changes: 32 additions & 0 deletions rules/require-tothrow-message.js
@@ -0,0 +1,32 @@
'use strict';

const getDocsUrl = require('./util').getDocsUrl;

module.exports = {
meta: {
docs: {
url: getDocsUrl(__filename),
},
},
create(context) {
return {
CallExpression(node) {
const propertyName = node.callee.property && node.callee.property.name;

// Look for `toThrow` calls with no arguments.
if (
['toThrow', 'toThrowError'].indexOf(propertyName) > -1 &&
!(node.arguments[0] && node.arguments[0].type === 'Literal')
) {
context.report({
message: `Add an error message to {{ propertyName }}()`,
data: {
propertyName,
},
node: node.callee.property,
});
}
},
};
},
};

0 comments on commit 7515458

Please sign in to comment.