From 32931c331d5eb5584c7b6a24306d834d620c8470 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 29 May 2022 06:46:55 +1200 Subject: [PATCH] fix(no-disabled-tests): switch to using jest function call parser (#1125) --- src/rules/__tests__/no-disabled-tests.test.ts | 38 ++++----- src/rules/no-disabled-tests.ts | 80 +++++++++---------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/rules/__tests__/no-disabled-tests.test.ts b/src/rules/__tests__/no-disabled-tests.test.ts index 4013b7aea..e41d1a46a 100644 --- a/src/rules/__tests__/no-disabled-tests.test.ts +++ b/src/rules/__tests__/no-disabled-tests.test.ts @@ -65,63 +65,63 @@ ruleTester.run('no-disabled-tests', rule, { invalid: [ { code: 'describe.skip("foo", function () {})', - errors: [{ messageId: 'skippedTestSuite', column: 1, line: 1 }], + errors: [{ messageId: 'disabledSuite', column: 1, line: 1 }], }, { code: 'describe.skip.each([1, 2, 3])("%s", (a, b) => {});', - errors: [{ messageId: 'skippedTestSuite', column: 1, line: 1 }], + errors: [{ messageId: 'disabledSuite', column: 1, line: 1 }], }, { code: 'xdescribe.each([1, 2, 3])("%s", (a, b) => {});', - errors: [{ messageId: 'skippedTestSuite', column: 1, line: 1 }], + errors: [{ messageId: 'disabledSuite', column: 1, line: 1 }], }, { code: 'describe[`skip`]("foo", function () {})', - errors: [{ messageId: 'skippedTestSuite', column: 1, line: 1 }], + errors: [{ messageId: 'disabledSuite', column: 1, line: 1 }], }, { code: 'describe["skip"]("foo", function () {})', - errors: [{ messageId: 'skippedTestSuite', column: 1, line: 1 }], + errors: [{ messageId: 'disabledSuite', column: 1, line: 1 }], }, { code: 'it.skip("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'it.concurrent.skip("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'it["skip"]("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'test.skip("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'it.skip.each``("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'test.skip.each``("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'it.skip.each([])("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'test.skip.each([])("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'test.concurrent.skip("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'test["skip"]("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'xdescribe("foo", function () {})', @@ -137,19 +137,19 @@ ruleTester.run('no-disabled-tests', rule, { }, { code: 'xit.each``("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'xtest.each``("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'xit.each([])("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'xtest.each([])("foo", function () {})', - errors: [{ messageId: 'skippedTest', column: 1, line: 1 }], + errors: [{ messageId: 'disabledTest', column: 1, line: 1 }], }, { code: 'it("has title but no callback")', diff --git a/src/rules/no-disabled-tests.ts b/src/rules/no-disabled-tests.ts index 1ce0d6bf4..02b391faa 100644 --- a/src/rules/no-disabled-tests.ts +++ b/src/rules/no-disabled-tests.ts @@ -1,4 +1,9 @@ -import { createRule, getNodeName, scopeHasLocalReference } from './utils'; +import { + createRule, + getAccessorValue, + parseJestFnCall, + scopeHasLocalReference, +} from './utils'; export default createRule({ name: __filename, @@ -10,8 +15,6 @@ export default createRule({ }, messages: { missingFunction: 'Test is missing function argument', - skippedTestSuite: 'Skipped test suite', - skippedTest: 'Skipped test', pending: 'Call to pending()', pendingSuite: 'Call to pending() within test suite', pendingTest: 'Call to pending() within test', @@ -27,40 +30,49 @@ export default createRule({ let testDepth = 0; return { - 'CallExpression[callee.name="describe"]'() { - suiteDepth++; - }, - 'CallExpression[callee.name=/^(it|test)$/]'() { - testDepth++; - }, 'CallExpression[callee.name=/^(it|test)$/][arguments.length<2]'(node) { context.report({ messageId: 'missingFunction', node }); }, CallExpression(node) { - const functionName = getNodeName(node.callee); + const jestFnCall = parseJestFnCall(node, context.getScope()); - // prevent duplicate warnings for it.each()() - if (node.callee.type === 'CallExpression') { + if (!jestFnCall) { return; } - switch (functionName) { - case 'describe.skip.each': - case 'xdescribe.each': - case 'describe.skip': - context.report({ messageId: 'skippedTestSuite', node }); - break; + if (jestFnCall.type === 'describe') { + suiteDepth++; + } + + if (jestFnCall.type === 'test') { + testDepth++; + } - case 'it.skip': - case 'it.concurrent.skip': - case 'test.skip': - case 'test.concurrent.skip': - case 'it.skip.each': - case 'test.skip.each': - case 'xit.each': - case 'xtest.each': - context.report({ messageId: 'skippedTest', node }); - break; + if ( + // the only jest functions that are with "x" are "xdescribe", "xtest", and "xit" + jestFnCall.name.startsWith('x') || + jestFnCall.members.some(s => getAccessorValue(s) === 'skip') + ) { + context.report({ + messageId: + jestFnCall.type === 'describe' ? 'disabledSuite' : 'disabledTest', + node, + }); + } + }, + 'CallExpression:exit'(node) { + const jestFnCall = parseJestFnCall(node, context.getScope()); + + if (!jestFnCall) { + return; + } + + if (jestFnCall.type === 'describe') { + suiteDepth--; + } + + if (jestFnCall.type === 'test') { + testDepth--; } }, 'CallExpression[callee.name="pending"]'(node) { @@ -76,18 +88,6 @@ export default createRule({ context.report({ messageId: 'pending', node }); } }, - 'CallExpression[callee.name="xdescribe"]'(node) { - context.report({ messageId: 'disabledSuite', node }); - }, - 'CallExpression[callee.name=/^(xit|xtest)$/]'(node) { - context.report({ messageId: 'disabledTest', node }); - }, - 'CallExpression[callee.name="describe"]:exit'() { - suiteDepth--; - }, - 'CallExpression[callee.name=/^(it|test)$/]:exit'() { - testDepth--; - }, }; }, });