Skip to content

Commit

Permalink
feat(prefer-expect-assertions): add onlyFunctionsWithAsyncKeyword o…
Browse files Browse the repository at this point in the history
…ption (#677)

Co-authored-by: Mario Campa <mcampa@twitter.com>
  • Loading branch information
mcampa and Mario Campa committed Oct 5, 2020
1 parent 387d970 commit d0cea37
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 5 deletions.
42 changes: 42 additions & 0 deletions docs/rules/prefer-expect-assertions.md
Expand Up @@ -55,3 +55,45 @@ test('my test', () => {
expect(someThing()).toEqual('foo');
});
```

## Options

#### `onlyFunctionsWithAsyncKeyword`

When `true`, this rule will only warn for tests that use the `async` keyword.

```json
{
"rules": {
"jest/prefer-expect-assertions": [
"warn",
{ "onlyFunctionsWithAsyncKeyword": true }
]
}
}
```

When `onlyFunctionsWithAsyncKeyword` option is set to `true`, the following
pattern would be a warning:

```js
test('my test', async () => {
const result = await someAsyncFunc();
expect(result).toBe('foo');
});
```

While the following patterns would not be considered warnings:

```js
test('my test', () => {
const result = someFunction();
expect(result).toBe('foo');
});

test('my test', async () => {
expect.assertions(1);
const result = await someAsyncFunc();
expect(result).toBe('foo');
});
```
39 changes: 38 additions & 1 deletion src/rules/__tests__/prefer-expect-assertions.test.ts
Expand Up @@ -6,7 +6,7 @@ import rule from '../prefer-expect-assertions';
const ruleTester = new TSESLint.RuleTester({
parser: resolveFrom(require.resolve('eslint'), 'espree'),
parserOptions: {
ecmaVersion: 2015,
ecmaVersion: 2017,
},
});

Expand Down Expand Up @@ -205,6 +205,21 @@ ruleTester.run('prefer-expect-assertions', rule, {
},
],
},
{
code: dedent`
it("it1", async function() {
expect(someValue).toBe(true);
})
`,
options: [{ onlyFunctionsWithAsyncKeyword: true }],
errors: [
{
messageId: 'haveExpectAssertions',
column: 1,
line: 1,
},
],
},
],

valid: [
Expand All @@ -223,5 +238,27 @@ ruleTester.run('prefer-expect-assertions', rule, {
'test("it1")',
'itHappensToStartWithIt("foo", function() {})',
'testSomething("bar", function() {})',
'it(async () => {expect.assertions(0);})',
{
code: dedent`
it("it1", async () => {
expect.assertions(1);
expect(someValue).toBe(true)
})
`,
options: [{ onlyFunctionsWithAsyncKeyword: true }],
},
{
code: dedent`
it("it1", function() {
expect(someValue).toBe(true)
})
`,
options: [{ onlyFunctionsWithAsyncKeyword: true }],
},
{
code: 'it("it1", () => {})',
options: [{ onlyFunctionsWithAsyncKeyword: true }],
},
],
});
25 changes: 21 additions & 4 deletions src/rules/prefer-expect-assertions.ts
Expand Up @@ -46,6 +46,9 @@ interface PreferExpectAssertionsCallExpression extends TSESTree.CallExpression {
TSESTree.ArrowFunctionExpression & { body: TSESTree.BlockStatement },
];
}
interface RuleOptions {
onlyFunctionsWithAsyncKeyword?: boolean;
}

type MessageIds =
| 'hasAssertionsTakesNoArguments'
Expand All @@ -61,7 +64,7 @@ const suggestions: Array<[MessageIds, string]> = [
['suggestAddingAssertions', 'expect.assertions();'],
];

export default createRule<[], MessageIds>({
export default createRule<[RuleOptions], MessageIds>({
name: __filename,
meta: {
docs: {
Expand All @@ -85,14 +88,28 @@ export default createRule<[], MessageIds>({
suggestRemovingExtraArguments: 'Remove extra arguments',
},
type: 'suggestion',
schema: [],
schema: [
{
type: 'object',
properties: {
onlyFunctionsWithAsyncKeyword: {
type: 'boolean',
},
},
additionalProperties: false,
},
],
},
defaultOptions: [],
create(context) {
defaultOptions: [{ onlyFunctionsWithAsyncKeyword: false }],
create(context, [options]) {
return {
'CallExpression[callee.name=/^(it|test)$/][arguments.1.body.body]'(
node: PreferExpectAssertionsCallExpression,
) {
if (options.onlyFunctionsWithAsyncKeyword && !node.arguments[1].async) {
return;
}

const testFuncBody = node.arguments[1].body.body;

if (!isFirstLineExprStmt(testFuncBody)) {
Expand Down

0 comments on commit d0cea37

Please sign in to comment.