Skip to content

Commit

Permalink
Better support valid each (#460)
Browse files Browse the repository at this point in the history
* chore(utils): create `getJestFunctionArguments` utility function

* fix(valid-describe): better support `.each` function

* fix(valid-title): better support `.each` function
  • Loading branch information
G-Rath committed Oct 28, 2019
1 parent ea9558b commit 10e5087
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 16 deletions.
25 changes: 20 additions & 5 deletions src/rules/__tests__/valid-describe.test.ts
Expand Up @@ -11,16 +11,11 @@ const ruleTester = new TSESLint.RuleTester({

ruleTester.run('valid-describe', rule, {
valid: [
'describe.each()()',
'describe.each(() => {})()',
'describe["each"]()()',
'describe["each"](() => {})()',
'describe["each"](() => {})("foo")',
'describe.each(() => {})("foo")',
'describe["each"]()(() => {})',
'describe.each()(() => {})',
'describe["each"]("foo")(() => {})',
'describe.each("foo")(() => {})',
'describe("foo", function() {})',
'describe("foo", () => {})',
'describe(`foo`, () => {})',
Expand Down Expand Up @@ -55,6 +50,26 @@ ruleTester.run('valid-describe', rule, {
`,
],
invalid: [
{
code: 'describe.each()()',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 1 }],
},
{
code: 'describe.each(() => {})()',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 1 }],
},
{
code: 'describe.each(() => {})("foo")',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 25 }],
},
{
code: 'describe.each()(() => {})',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 17 }],
},
{
code: 'describe.each("foo")(() => {})',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 22 }],
},
{
code: 'describe(() => {})',
errors: [{ messageId: 'nameAndCallback', line: 1, column: 10 }],
Expand Down
10 changes: 10 additions & 0 deletions src/rules/__tests__/valid-title.test.ts
Expand Up @@ -33,6 +33,16 @@ ruleTester.run('title-must-be-string', rule, {
},
],
invalid: [
{
code: 'it.each([])(1, () => {});',
errors: [
{
messageId: 'titleMustBeString',
column: 13,
line: 1,
},
],
},
{
code: 'it(123, () => {});',
errors: [
Expand Down
20 changes: 20 additions & 0 deletions src/rules/utils.ts
Expand Up @@ -651,6 +651,26 @@ export const isDescribe = (
);
};

/**
* Gets the arguments of the given `JestFunctionCallExpression`.
*
* If the `node` is an `each` call, then the arguments of the actual suite
* are returned, rather then the `each` array argument.
*
* @param {JestFunctionCallExpression<DescribeAlias | TestCaseName>} node
*
* @return {Expression[]}
*/
export const getJestFunctionArguments = (
node: JestFunctionCallExpression<DescribeAlias | TestCaseName>,
) =>
node.callee.type === AST_NODE_TYPES.MemberExpression &&
isSupportedAccessor(node.callee.property, DescribeProperty.each) &&
node.parent &&
node.parent.type === AST_NODE_TYPES.CallExpression
? node.parent.arguments
: node.arguments;

const collectReferences = (scope: TSESLint.Scope.Scope) => {
const locals = new Set();
const unresolved = new Set();
Expand Down
18 changes: 8 additions & 10 deletions src/rules/valid-describe.ts
Expand Up @@ -4,9 +4,9 @@ import {
} from '@typescript-eslint/experimental-utils';
import {
createRule,
getJestFunctionArguments,
isDescribe,
isFunction,
isSupportedAccessor,
} from './utils';

const paramsLocation = (
Expand All @@ -21,10 +21,6 @@ const paramsLocation = (
};
};

const isDescribeEach = (node: TSESTree.CallExpression) =>
node.callee.type === AST_NODE_TYPES.MemberExpression &&
isSupportedAccessor(node.callee.property, 'each');

export default createRule({
name: __filename,
meta: {
Expand All @@ -49,23 +45,25 @@ export default createRule({
create(context) {
return {
CallExpression(node) {
if (!isDescribe(node) || isDescribeEach(node)) {
if (!isDescribe(node)) {
return;
}

if (node.arguments.length < 1) {
const nodeArguments = getJestFunctionArguments(node);

if (nodeArguments.length < 1) {
return context.report({
messageId: 'nameAndCallback',
loc: node.loc,
});
}

const [, callback] = node.arguments;
const [, callback] = nodeArguments;

if (!callback) {
context.report({
messageId: 'nameAndCallback',
loc: paramsLocation(node.arguments),
loc: paramsLocation(nodeArguments),
});

return;
Expand All @@ -74,7 +72,7 @@ export default createRule({
if (!isFunction(callback)) {
context.report({
messageId: 'secondArgumentMustBeFunction',
loc: paramsLocation(node.arguments),
loc: paramsLocation(nodeArguments),
});

return;
Expand Down
3 changes: 2 additions & 1 deletion src/rules/valid-title.ts
Expand Up @@ -6,6 +6,7 @@ import {
DescribeAlias,
TestCaseName,
createRule,
getJestFunctionArguments,
getNodeName,
getStringValue,
isDescribe,
Expand Down Expand Up @@ -53,7 +54,7 @@ export default createRule({
return;
}

const [argument] = node.arguments;
const [argument] = getJestFunctionArguments(node);

if (!isStringNode(argument)) {
if (
Expand Down

0 comments on commit 10e5087

Please sign in to comment.