Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prefer-expect-assertions): support onlyFunctionsWithAsyncKeyword option #677

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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