Skip to content

Commit

Permalink
feat(rule): add allow option to expect-expect rule (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
hulkish authored and SimenB committed Aug 24, 2018
1 parent e039fed commit 97a5fce
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
55 changes: 51 additions & 4 deletions docs/rules/expect-expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ Ensure that there is at least one `expect` call made in a test.
This rule triggers when there is no call made to `expect` in a test, to prevent
users from forgetting to add assertions.

### Default configuration

The following patterns are considered warnings:
Examples of **incorrect** code for this rule:

```js
it('should be a test', () => {
Expand All @@ -18,7 +16,7 @@ it('should be a test', () => {
test('should assert something', () => {});
```

The following patterns are not warnings:
Examples of **correct** code for this rule:

```js
it('should be a test', () => {
Expand All @@ -28,3 +26,52 @@ it('should work with callbacks/async', () => {
somePromise().then(res => expect(res).toBe('passed'));
});
```

## Options

```json
{
"jest/expect-expect": [
"error",
{
"assertFunctionNames": ["expect"]
}
]
}
```

### `assertFunctionNames`

This array option whitelists the assertion function names to look for.

Examples of **incorrect** code for the `{ "assertFunctionNames": ["expect"] }`
option:

```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect"] }] */

import { expectSaga } from 'redux-saga-test-plan';
import { addSaga } from '../src/sagas';

test('returns sum', () => {
expectSaga(addSaga, 1, 1)
.returns(2)
.run();
});
```

Examples of **correct** code for the
`{ "assertFunctionNames": ["expect", "expectSaga"] }` option:

```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "expectSaga"] }] */

import { expectSaga } from 'redux-saga-test-plan';
import { addSaga } from '../src/sagas';

test('returns sum', () => {
expectSaga(addSaga, 1, 1)
.returns(2)
.run();
});
```
29 changes: 29 additions & 0 deletions rules/__tests__/expect-expect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ ruleTester.run('expect-expect', rule, {
'it("should pass", () => expect(true).toBeDefined())',
'test("should pass", () => expect(true).toBeDefined())',
'it("should pass", () => somePromise().then(() => expect(true).toBeDefined()))',
{
code:
'test("should pass", () => { expect(true).toBeDefined(); foo(true).toBe(true); })',
options: [{ assertFunctionNames: ['expect', 'foo'] }],
},
{
code: 'it("should return undefined",() => expectSaga(mySaga).returns());',
options: [{ assertFunctionNames: ['expectSaga'] }],
},
],

invalid: [
Expand Down Expand Up @@ -44,5 +53,25 @@ ruleTester.run('expect-expect', rule, {
},
],
},
{
code: 'test("should fail", () => { foo(true).toBe(true); })',
options: [{ assertFunctionNames: ['expect'] }],
errors: [
{
message: 'Test has no assertions',
type: 'CallExpression',
},
],
},
{
code: 'it("should also fail",() => expectSaga(mySaga).returns());',
options: [{ assertFunctionNames: ['expect'] }],
errors: [
{
message: 'Test has no assertions',
type: 'CallExpression',
},
],
},
],
});
20 changes: 18 additions & 2 deletions rules/expect-expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,35 @@ module.exports = {
docs: {
url: getDocsUrl(__filename),
},
schema: [
{
type: 'object',
properties: {
assertFunctionNames: {
type: 'array',
items: [{ type: 'string' }],
},
},
additionalProperties: false,
},
],
},
create(context) {
// variables should be defined here
const unchecked = [];
const assertFunctionNames =
context.options[0] && context.options[0].assertFunctionNames
? context.options[0].assertFunctionNames
: ['expect'];

//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
const isExpectCall = node =>
// if we're not calling a function, ignore
node.type === 'CallExpression' &&
// if we're not calling expect, ignore
node.callee.name === 'expect';
// if we're not calling allowed assertion
assertFunctionNames.some(name => name === node.callee.name);
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
Expand Down

0 comments on commit 97a5fce

Please # to comment.