diff --git a/src/rules/__tests__/consistent-test-it.test.ts b/src/rules/__tests__/consistent-test-it.test.ts index 50eeecfbb..ad4e8ce63 100644 --- a/src/rules/__tests__/consistent-test-it.test.ts +++ b/src/rules/__tests__/consistent-test-it.test.ts @@ -1,5 +1,6 @@ import { TSESLint } from '@typescript-eslint/experimental-utils'; import rule from '../consistent-test-it'; +import { TestCaseName } from '../utils'; const ruleTester = new TSESLint.RuleTester({ parserOptions: { @@ -11,90 +12,105 @@ ruleTester.run('consistent-test-it with fn=test', rule, { valid: [ { code: 'test("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], }, { code: 'test.only("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], }, { code: 'test.skip("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], }, { code: 'xtest("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], }, { code: 'describe("suite", () => { test("foo") })', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], }, ], invalid: [ { code: 'it("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test("foo")', }, { code: 'xit("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'xtest("foo")', }, { code: 'fit("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test.only("foo")', }, { code: 'it.skip("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test.skip("foo")', }, { code: 'it.only("foo")', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test.only("foo")', }, { code: 'describe("suite", () => { it("foo") })', - options: [{ fn: 'test' }], + options: [{ fn: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -107,83 +123,95 @@ ruleTester.run('consistent-test-it with fn=it', rule, { valid: [ { code: 'it("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, { code: 'fit("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, { code: 'xit("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, { code: 'it.only("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, { code: 'it.skip("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, { code: 'describe("suite", () => { it("foo") })', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], }, ], invalid: [ { code: 'test("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'it', oppositeTestKeyword: 'test' }, + data: { + testKeyword: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, + }, }, ], output: 'it("foo")', }, { code: 'xtest("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'it', oppositeTestKeyword: 'test' }, + data: { + testKeyword: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, + }, }, ], output: 'xit("foo")', }, { code: 'test.skip("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'it', oppositeTestKeyword: 'test' }, + data: { + testKeyword: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, + }, }, ], output: 'it.skip("foo")', }, { code: 'test.only("foo")', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'it', oppositeTestKeyword: 'test' }, + data: { + testKeyword: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, + }, }, ], output: 'it.only("foo")', }, { code: 'describe("suite", () => { test("foo") })', - options: [{ fn: 'it' }], + options: [{ fn: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -196,35 +224,35 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, { valid: [ { code: 'test("foo")', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], }, { code: 'test.only("foo")', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], }, { code: 'test.skip("foo")', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], }, { code: 'xtest("foo")', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], }, { code: '[1,2,3].forEach(() => { test("foo") })', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], }, ], invalid: [ { code: 'describe("suite", () => { test("foo") })', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -232,13 +260,13 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, { }, { code: 'describe("suite", () => { test.only("foo") })', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -246,13 +274,13 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, { }, { code: 'describe("suite", () => { xtest("foo") })', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -260,13 +288,13 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, { }, { code: 'describe("suite", () => { test.skip("foo") })', - options: [{ fn: 'test', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -279,35 +307,35 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=test ', rule, { valid: [ { code: 'it("foo")', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], }, { code: 'it.only("foo")', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], }, { code: 'it.skip("foo")', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], }, { code: 'xit("foo")', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], }, { code: '[1,2,3].forEach(() => { it("foo") })', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], }, ], invalid: [ { code: 'describe("suite", () => { it("foo") })', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -315,13 +343,13 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=test ', rule, { }, { code: 'describe("suite", () => { it.only("foo") })', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -329,13 +357,13 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=test ', rule, { }, { code: 'describe("suite", () => { xit("foo") })', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -343,13 +371,13 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=test ', rule, { }, { code: 'describe("suite", () => { it.skip("foo") })', - options: [{ fn: 'it', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -365,23 +393,23 @@ ruleTester.run( valid: [ { code: 'describe("suite", () => { test("foo") })', - options: [{ fn: 'test', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.test }], }, { code: 'test("foo");', - options: [{ fn: 'test', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.test }], }, ], invalid: [ { code: 'describe("suite", () => { it("foo") })', - options: [{ fn: 'test', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], @@ -389,11 +417,14 @@ ruleTester.run( }, { code: 'it("foo")', - options: [{ fn: 'test', withinDescribe: 'test' }], + options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test("foo")', @@ -406,23 +437,23 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=it ', rule, { valid: [ { code: 'describe("suite", () => { it("foo") })', - options: [{ fn: 'it', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.it }], }, { code: 'it("foo")', - options: [{ fn: 'it', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.it }], }, ], invalid: [ { code: 'describe("suite", () => { test("foo") })', - options: [{ fn: 'it', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -430,11 +461,14 @@ ruleTester.run('consistent-test-it with fn=it and withinDescribe=it ', rule, { }, { code: 'test("foo")', - options: [{ fn: 'it', withinDescribe: 'it' }], + options: [{ fn: TestCaseName.it, withinDescribe: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'it', oppositeTestKeyword: 'test' }, + data: { + testKeyword: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, + }, }, ], output: 'it("foo")', @@ -453,10 +487,10 @@ ruleTester.run('consistent-test-it defaults without config object', rule, { code: 'describe("suite", () => { test("foo") })', errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -469,34 +503,37 @@ ruleTester.run('consistent-test-it with withinDescribe=it', rule, { valid: [ { code: 'test("foo")', - options: [{ withinDescribe: 'it' }], + options: [{ withinDescribe: TestCaseName.it }], }, { code: 'describe("suite", () => { it("foo") })', - options: [{ withinDescribe: 'it' }], + options: [{ withinDescribe: TestCaseName.it }], }, ], invalid: [ { code: 'it("foo")', - options: [{ withinDescribe: 'it' }], + options: [{ withinDescribe: TestCaseName.it }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test("foo")', }, { code: 'describe("suite", () => { test("foo") })', - options: [{ withinDescribe: 'it' }], + options: [{ withinDescribe: TestCaseName.it }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'it', - oppositeTestKeyword: 'test', + testKeywordWithinDescribe: TestCaseName.it, + oppositeTestKeyword: TestCaseName.test, }, }, ], @@ -509,34 +546,37 @@ ruleTester.run('consistent-test-it with withinDescribe=test', rule, { valid: [ { code: 'test("foo")', - options: [{ withinDescribe: 'test' }], + options: [{ withinDescribe: TestCaseName.test }], }, { code: 'describe("suite", () => { test("foo") })', - options: [{ withinDescribe: 'test' }], + options: [{ withinDescribe: TestCaseName.test }], }, ], invalid: [ { code: 'it("foo")', - options: [{ withinDescribe: 'test' }], + options: [{ withinDescribe: TestCaseName.test }], errors: [ { messageId: 'consistentMethod', - data: { testKeyword: 'test', oppositeTestKeyword: 'it' }, + data: { + testKeyword: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, + }, }, ], output: 'test("foo")', }, { code: 'describe("suite", () => { it("foo") })', - options: [{ withinDescribe: 'test' }], + options: [{ withinDescribe: TestCaseName.test }], errors: [ { - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', data: { - testKeywordWithinDescribe: 'test', - oppositeTestKeyword: 'it', + testKeywordWithinDescribe: TestCaseName.test, + oppositeTestKeyword: TestCaseName.it, }, }, ], diff --git a/src/rules/__tests__/expect-expect.test.ts b/src/rules/__tests__/expect-expect.test.ts index c748795fb..31b0b47b2 100644 --- a/src/rules/__tests__/expect-expect.test.ts +++ b/src/rules/__tests__/expect-expect.test.ts @@ -32,6 +32,10 @@ ruleTester.run('expect-expect', rule, { ].join('\n'), options: [{ assertFunctionNames: ['td.verify'] }], }, + { + code: 'it("should pass", () => expect(true).toBeDefined())', + options: [{ assertFunctionNames: undefined }], + }, ], invalid: [ diff --git a/src/rules/__tests__/no-hooks.test.ts b/src/rules/__tests__/no-hooks.test.ts index 0b8de3ded..b0c8e7f6c 100644 --- a/src/rules/__tests__/no-hooks.test.ts +++ b/src/rules/__tests__/no-hooks.test.ts @@ -17,6 +17,7 @@ ruleTester.run('no-hooks', rule, { code: 'afterEach(() => {}); afterAll(() => {});', options: [{ allow: [HookName.afterEach, HookName.afterAll] }], }, + { code: 'test("foo")', options: [{ allow: undefined }] }, ], invalid: [ { diff --git a/src/rules/consistent-test-it.ts b/src/rules/consistent-test-it.ts index 9dc45d71e..9e1fde1e6 100644 --- a/src/rules/consistent-test-it.ts +++ b/src/rules/consistent-test-it.ts @@ -1,7 +1,21 @@ import { AST_NODE_TYPES } from '@typescript-eslint/experimental-utils'; -import { createRule, getNodeName, isDescribe, isTestCase } from './utils'; +import { + TestCaseName, + createRule, + getNodeName, + isDescribe, + isTestCase, +} from './utils'; -export default createRule({ +export default createRule< + [ + Partial<{ + fn: TestCaseName.it | TestCaseName.test; + withinDescribe: TestCaseName.it | TestCaseName.test; + }>, + ], + 'consistentMethod' | 'consistentMethodWithinDescribe' +>({ name: __filename, meta: { docs: { @@ -13,7 +27,7 @@ export default createRule({ messages: { consistentMethod: "Prefer using '{{ testKeyword }}' instead of '{{ oppositeTestKeyword }}'", - consistentMethodWithingDescribe: + consistentMethodWithinDescribe: "Prefer using '{{ testKeywordWithinDescribe }}' instead of '{{ oppositeTestKeyword }}' within describe", }, schema: [ @@ -21,10 +35,10 @@ export default createRule({ type: 'object', properties: { fn: { - enum: ['it', 'test'], + enum: [TestCaseName.it, TestCaseName.test], }, withinDescribe: { - enum: ['it', 'test'], + enum: [TestCaseName.it, TestCaseName.test], }, }, additionalProperties: false, @@ -32,17 +46,12 @@ export default createRule({ ], type: 'suggestion', }, - defaultOptions: [ - { fn: 'test', withinDescribe: 'it' } as { - fn?: 'it' | 'test'; - withinDescribe?: 'it' | 'test'; - }, - ], + defaultOptions: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }], create(context) { const configObj = context.options[0] || {}; - const testKeyword = configObj.fn || 'test'; + const testKeyword = configObj.fn || TestCaseName.test; const testKeywordWithinDescribe = - configObj.withinDescribe || configObj.fn || 'it'; + configObj.withinDescribe || configObj.fn || TestCaseName.it; let describeNestingLevel = 0; @@ -91,7 +100,7 @@ export default createRule({ ); context.report({ - messageId: 'consistentMethodWithingDescribe', + messageId: 'consistentMethodWithinDescribe', node: node.callee, data: { testKeywordWithinDescribe, oppositeTestKeyword }, fix(fixer) { @@ -118,9 +127,12 @@ export default createRule({ }, }); -function getPreferredNodeName(nodeName: string, preferredTestKeyword: string) { +function getPreferredNodeName( + nodeName: string, + preferredTestKeyword: TestCaseName.test | TestCaseName.it, +) { switch (nodeName) { - case 'fit': + case TestCaseName.fit: return 'test.only'; default: return nodeName.startsWith('f') || nodeName.startsWith('x') @@ -129,10 +141,10 @@ function getPreferredNodeName(nodeName: string, preferredTestKeyword: string) { } } -function getOppositeTestKeyword(test: string) { - if (test === 'test') { - return 'it'; +function getOppositeTestKeyword(test: TestCaseName.test | TestCaseName.it) { + if (test === TestCaseName.test) { + return TestCaseName.it; } - return 'test'; + return TestCaseName.test; } diff --git a/src/rules/expect-expect.ts b/src/rules/expect-expect.ts index 784c67642..80669947e 100644 --- a/src/rules/expect-expect.ts +++ b/src/rules/expect-expect.ts @@ -7,9 +7,12 @@ import { AST_NODE_TYPES, TSESTree, } from '@typescript-eslint/experimental-utils'; -import { createRule, getNodeName } from './utils'; +import { TestCaseName, createRule, getNodeName } from './utils'; -export default createRule({ +export default createRule< + [Partial<{ assertFunctionNames: readonly string[] }>], + 'noAssertions' +>({ name: __filename, meta: { docs: { @@ -35,13 +38,13 @@ export default createRule({ type: 'suggestion', }, defaultOptions: [{ assertFunctionNames: ['expect'] }], - create(context, [{ assertFunctionNames }]) { + create(context, [{ assertFunctionNames = ['expect'] }]) { const unchecked: TSESTree.CallExpression[] = []; return { CallExpression(node) { const name = getNodeName(node.callee); - if (name === 'it' || name === 'test') { + if (name === TestCaseName.it || name === TestCaseName.test) { unchecked.push(node); } else if (name && assertFunctionNames.includes(name)) { // Return early in case of nested `it` statements. diff --git a/src/rules/lowercase-name.ts b/src/rules/lowercase-name.ts index 1a1f801f0..cf09a57d6 100644 --- a/src/rules/lowercase-name.ts +++ b/src/rules/lowercase-name.ts @@ -6,7 +6,6 @@ import { import { DescribeAlias, JestFunctionCallExpressionWithIdentifierCallee, - JestFunctionName, TestCaseName, createRule, isDescribe, @@ -19,8 +18,13 @@ interface FirstArgumentStringCallExpression extends TSESTree.CallExpression { arguments: [ArgumentLiteral]; } +type IgnorableFunctionExpressions = + | TestCaseName.it + | TestCaseName.test + | DescribeAlias.describe; + type CallExpressionWithCorrectCalleeAndArguments = JestFunctionCallExpressionWithIdentifierCallee< - TestCaseName.it | TestCaseName.test | DescribeAlias.describe + IgnorableFunctionExpressions > & FirstArgumentStringCallExpression; @@ -80,7 +84,7 @@ const jestFunctionName = ( export default createRule< [ Partial<{ - ignore: readonly JestFunctionName[]; + ignore: readonly IgnorableFunctionExpressions[]; allowedPrefixes: readonly string[]; }>, ], @@ -105,7 +109,13 @@ export default createRule< properties: { ignore: { type: 'array', - items: { enum: ['describe', 'test', 'it'] }, + items: { + enum: [ + DescribeAlias.describe, + TestCaseName.test, + TestCaseName.it, + ], + }, additionalItems: false, }, allowedPrefixes: { diff --git a/src/rules/no-commented-out-tests.ts b/src/rules/no-commented-out-tests.ts index 269ee6da9..fc76186cf 100644 --- a/src/rules/no-commented-out-tests.ts +++ b/src/rules/no-commented-out-tests.ts @@ -21,7 +21,7 @@ export default createRule({ }, schema: [], type: 'suggestion', - } as const, + }, defaultOptions: [], create(context) { const sourceCode = context.getSourceCode(); diff --git a/src/rules/no-hooks.ts b/src/rules/no-hooks.ts index cc186840e..6894093bc 100644 --- a/src/rules/no-hooks.ts +++ b/src/rules/no-hooks.ts @@ -1,6 +1,9 @@ import { HookName, createRule, isHook } from './utils'; -export default createRule({ +export default createRule< + [Partial<{ allow: readonly HookName[] }>], + 'unexpectedHook' +>({ name: __filename, meta: { docs: { @@ -25,8 +28,8 @@ export default createRule({ ], type: 'suggestion', }, - defaultOptions: [{ allow: [] } as { allow: readonly HookName[] }], - create(context, [{ allow }]) { + defaultOptions: [{ allow: [] }], + create(context, [{ allow = [] }]) { return { CallExpression(node) { if (isHook(node) && !allow.includes(node.callee.name)) {