diff --git a/src/rules/__tests__/valid-describe.test.ts b/src/rules/__tests__/valid-describe.test.ts index e38a8c836..20bb40a99 100644 --- a/src/rules/__tests__/valid-describe.test.ts +++ b/src/rules/__tests__/valid-describe.test.ts @@ -16,6 +16,7 @@ ruleTester.run('valid-describe', rule, { 'describe["each"](() => {})("foo")', 'describe["each"]()(() => {})', 'describe["each"]("foo")(() => {})', + 'describe.each([1, 2, 3])("%s", (a, b) => {});', 'describe("foo", function() {})', 'describe("foo", () => {})', 'describe(`foo`, () => {})', diff --git a/src/rules/utils.ts b/src/rules/utils.ts index c78cf5349..12a03709a 100644 --- a/src/rules/utils.ts +++ b/src/rules/utils.ts @@ -550,6 +550,7 @@ export enum TestCaseProperty { } export type JestFunctionName = DescribeAlias | TestCaseName | HookName; +export type JestPropertyName = DescribeProperty | TestCaseProperty; export interface JestFunctionIdentifier extends TSESTree.Identifier { @@ -557,15 +558,24 @@ export interface JestFunctionIdentifier } export interface JestFunctionMemberExpression< - FunctionName extends JestFunctionName -> extends TSESTree.MemberExpression { + FunctionName extends JestFunctionName, + PropertyName extends JestPropertyName = JestPropertyName +> extends KnownMemberExpression { + object: JestFunctionIdentifier; +} + +export interface JestFunctionMemberExpression< + FunctionName extends JestFunctionName, + PropertyName extends JestPropertyName = JestPropertyName +> extends KnownMemberExpression { object: JestFunctionIdentifier; } export interface JestFunctionCallExpressionWithMemberExpressionCallee< - FunctionName extends JestFunctionName + FunctionName extends JestFunctionName, + PropertyName extends JestPropertyName = JestPropertyName > extends TSESTree.CallExpression { - callee: JestFunctionMemberExpression; + callee: JestFunctionMemberExpression; } export interface JestFunctionCallExpressionWithIdentifierCallee< @@ -651,6 +661,21 @@ export const isDescribe = ( ); }; +/** + * Checks if the given `describe` is a call to `describe.each`. + * + * @param {JestFunctionCallExpression} node + * @return {node is JestFunctionCallExpression} + */ +export const isDescribeEach = ( + node: JestFunctionCallExpression, +): node is JestFunctionCallExpressionWithMemberExpressionCallee< + DescribeAlias, + DescribeProperty.each +> => + node.callee.type === AST_NODE_TYPES.MemberExpression && + isSupportedAccessor(node.callee.property, DescribeProperty.each); + /** * Gets the arguments of the given `JestFunctionCallExpression`. * diff --git a/src/rules/valid-describe.ts b/src/rules/valid-describe.ts index d2a8ad83d..6815f9221 100644 --- a/src/rules/valid-describe.ts +++ b/src/rules/valid-describe.ts @@ -6,6 +6,7 @@ import { createRule, getJestFunctionArguments, isDescribe, + isDescribeEach, isFunction, } from './utils'; @@ -85,7 +86,7 @@ export default createRule({ }); } - if (callback.params.length) { + if (!isDescribeEach(node) && callback.params.length) { context.report({ messageId: 'unexpectedDescribeArgument', loc: paramsLocation(callback.params),