diff --git a/README.md b/README.md index a5db90365..c16b97ab7 100644 --- a/README.md +++ b/README.md @@ -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][] | | @@ -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 diff --git a/docs/rules/require-tothrow-message.md b/docs/rules/require-tothrow-message.md new file mode 100644 index 000000000..444d36437 --- /dev/null +++ b/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'); +``` diff --git a/index.js b/index.js index 44ec39abb..0ae57b9e7 100644 --- a/index.js +++ b/index.js @@ -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'); @@ -89,5 +90,6 @@ module.exports = { 'valid-expect-in-promise': validExpectInPromise, 'prefer-inline-snapshots': preferInlineSnapshots, 'prefer-strict-equal': preferStrictEqual, + 'require-tothrow-message': requireTothrowMessage, }, }; diff --git a/rules/__tests__/require-tothrow-message.js b/rules/__tests__/require-tothrow-message.js new file mode 100644 index 000000000..536e9ec6c --- /dev/null +++ b/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, + }, + ], + }, + ], +}); diff --git a/rules/require-tothrow-message.js b/rules/require-tothrow-message.js new file mode 100644 index 000000000..f637c39b3 --- /dev/null +++ b/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, + }); + } + }, + }; + }, +};