diff --git a/docs/rules/prefer-expect-assertions.md b/docs/rules/prefer-expect-assertions.md index d99720356..bbf25ab48 100644 --- a/docs/rules/prefer-expect-assertions.md +++ b/docs/rules/prefer-expect-assertions.md @@ -55,3 +55,17 @@ test('my test', () => { expect(someThing()).toEqual('foo'); }); ``` + +## Options + +#### `asyncOnly` + +Run this rule only on async test functions + +```json +{ + "rules": { + "jest/prefer-expect-assertions": ["error", { "asyncOnly": true }] + } +} +``` diff --git a/src/rules/__tests__/prefer-expect-assertions.test.ts b/src/rules/__tests__/prefer-expect-assertions.test.ts index 648b7904f..400cd1cf4 100644 --- a/src/rules/__tests__/prefer-expect-assertions.test.ts +++ b/src/rules/__tests__/prefer-expect-assertions.test.ts @@ -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, }, }); @@ -205,6 +205,21 @@ ruleTester.run('prefer-expect-assertions', rule, { }, ], }, + { + code: dedent` + it("it1", async function() { + expect(someValue).toBe(true) + }) + `, + options: [{ asyncOnly: true }], + errors: [ + { + messageId: 'haveExpectAssertions', + column: 1, + line: 1, + }, + ], + }, ], valid: [ @@ -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: [{ asyncOnly: true }], + }, + { + code: dedent` + it("it1", function() { + expect(someValue).toBe(true) + }) + `, + options: [{ asyncOnly: true }], + }, + { + code: 'it("it1", () => {})', + options: [{ asyncOnly: true }], + }, ], }); diff --git a/src/rules/prefer-expect-assertions.ts b/src/rules/prefer-expect-assertions.ts index 6cc707da9..2152c4fed 100644 --- a/src/rules/prefer-expect-assertions.ts +++ b/src/rules/prefer-expect-assertions.ts @@ -46,6 +46,9 @@ interface PreferExpectAssertionsCallExpression extends TSESTree.CallExpression { TSESTree.ArrowFunctionExpression & { body: TSESTree.BlockStatement }, ]; } +interface RuleOptions { + asyncOnly?: boolean; +} type MessageIds = | 'hasAssertionsTakesNoArguments' @@ -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: { @@ -85,14 +88,28 @@ export default createRule<[], MessageIds>({ suggestRemovingExtraArguments: 'Remove extra arguments', }, type: 'suggestion', - schema: [], + schema: [ + { + type: 'object', + properties: { + asyncOnly: { + type: 'boolean', + }, + }, + additionalProperties: false, + }, + ], }, - defaultOptions: [], - create(context) { + defaultOptions: [{ asyncOnly: false }], + create(context, [options]) { return { 'CallExpression[callee.name=/^(it|test)$/][arguments.1.body.body]'( node: PreferExpectAssertionsCallExpression, ) { + if (options.asyncOnly && !node.arguments[1].async) { + return; + } + const testFuncBody = node.arguments[1].body.body; if (!isFirstLineExprStmt(testFuncBody)) {