diff --git a/README.md b/README.md index 3f96e79..a2e20bc 100644 --- a/README.md +++ b/README.md @@ -120,57 +120,58 @@ export default [ πŸ”§ Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\ πŸ’‘ Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). -| NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  | Description | πŸ’Ό | ⚠️ | πŸ”§ | πŸ’‘ | -| :--------------------------------------------------------------------------- | :----------------------------------------------------------------------- | :- | :- | :- | :- | -| [consistent-test-filename](docs/rules/consistent-test-filename.md) | forbidden .spec test file pattern | | 🌐 | | | -| [consistent-test-it](docs/rules/consistent-test-it.md) | Prefer test or it but not both | | 🌐 | πŸ”§ | | -| [expect-expect](docs/rules/expect-expect.md) | Enforce having expectation in test body | βœ… | | | | -| [max-expects](docs/rules/max-expects.md) | Enforce a maximum number of expect per test | | 🌐 | | | -| [max-nested-describe](docs/rules/max-nested-describe.md) | Nested describe block should be less than set max value or default value | | 🌐 | | | -| [no-alias-methods](docs/rules/no-alias-methods.md) | Disallow alias methods | | 🌐 | πŸ”§ | | -| [no-commented-out-tests](docs/rules/no-commented-out-tests.md) | Disallow commented out tests | βœ… | | | | -| [no-conditional-expect](docs/rules/no-conditional-expect.md) | Disallow conditional expects | | 🌐 | | | -| [no-conditional-in-test](docs/rules/no-conditional-in-test.md) | Disallow conditional tests | | 🌐 | | | -| [no-conditional-tests](docs/rules/no-conditional-tests.md) | Disallow conditional tests | | 🌐 | | | -| [no-disabled-tests](docs/rules/no-disabled-tests.md) | Disallow disabled tests | | 🌐 | | | -| [no-done-callback](docs/rules/no-done-callback.md) | Disallow using a callback in asynchronous tests and hooks | | 🌐 | | πŸ’‘ | -| [no-duplicate-hooks](docs/rules/no-duplicate-hooks.md) | Disallow duplicate hooks and teardown hooks | | 🌐 | | | -| [no-focused-tests](docs/rules/no-focused-tests.md) | Disallow focused tests | | 🌐 | πŸ”§ | | -| [no-hooks](docs/rules/no-hooks.md) | Disallow setup and teardown hooks | | 🌐 | | | -| [no-identical-title](docs/rules/no-identical-title.md) | Disallow identical titles | βœ… | | πŸ”§ | | -| [no-interpolation-in-snapshots](docs/rules/no-interpolation-in-snapshots.md) | Disallow string interpolation in snapshots | | 🌐 | πŸ”§ | | -| [no-large-snapshots](docs/rules/no-large-snapshots.md) | Disallow large snapshots | | 🌐 | | | -| [no-mocks-import](docs/rules/no-mocks-import.md) | Disallow importing from __mocks__ directory | | 🌐 | | | -| [no-restricted-matchers](docs/rules/no-restricted-matchers.md) | Disallow the use of certain matchers | | 🌐 | | | -| [no-restricted-vi-methods](docs/rules/no-restricted-vi-methods.md) | Disallow specific `vi.` methods | | 🌐 | | | -| [no-standalone-expect](docs/rules/no-standalone-expect.md) | Disallow using `expect` outside of `it` or `test` blocks | | 🌐 | | | -| [no-test-prefixes](docs/rules/no-test-prefixes.md) | Disallow using `test` as a prefix | | 🌐 | πŸ”§ | | -| [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow return statements in tests | | 🌐 | | | -| [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` | | 🌐 | πŸ”§ | | -| [prefer-comparison-matcher](docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | 🌐 | πŸ”§ | | -| [prefer-each](docs/rules/prefer-each.md) | Prefer `each` rather than manual loops | | 🌐 | | | -| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in quality matchers | | 🌐 | | πŸ’‘ | -| [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Suggest using `expect().resolves` over `expect(await ...)` syntax | | 🌐 | πŸ”§ | | -| [prefer-hooks-in-order](docs/rules/prefer-hooks-in-order.md) | Prefer having hooks in consistent order | | 🌐 | | | -| [prefer-hooks-on-top](docs/rules/prefer-hooks-on-top.md) | Suggest having hooks before any test cases | | 🌐 | | | -| [prefer-lowercase-title](docs/rules/prefer-lowercase-title.md) | Enforce lowercase titles | | 🌐 | πŸ”§ | | -| [prefer-mock-promise-shorthand](docs/rules/prefer-mock-promise-shorthand.md) | Prefer mock resolved/rejected shorthands for promises | | 🌐 | πŸ”§ | | -| [prefer-snapshot-hint](docs/rules/prefer-snapshot-hint.md) | Prefer including a hint with external snapshots | | 🌐 | | | -| [prefer-spy-on](docs/rules/prefer-spy-on.md) | Suggest using `vi.spyOn` | | 🌐 | πŸ”§ | | -| [prefer-strict-equal](docs/rules/prefer-strict-equal.md) | Prefer strict equal over equal | | 🌐 | | πŸ’‘ | -| [prefer-to-be](docs/rules/prefer-to-be.md) | Suggest using toBe() | βœ… | | πŸ”§ | | -| [prefer-to-be-falsy](docs/rules/prefer-to-be-falsy.md) | Suggest using toBeFalsy() | | 🌐 | πŸ”§ | | -| [prefer-to-be-object](docs/rules/prefer-to-be-object.md) | Prefer toBeObject() | | 🌐 | πŸ”§ | | -| [prefer-to-be-truthy](docs/rules/prefer-to-be-truthy.md) | Suggest using `toBeTruthy` | | 🌐 | πŸ”§ | | -| [prefer-to-contain](docs/rules/prefer-to-contain.md) | Prefer using toContain() | | 🌐 | πŸ”§ | | -| [prefer-to-have-length](docs/rules/prefer-to-have-length.md) | Suggest using toHaveLength() | | 🌐 | πŸ”§ | | -| [prefer-todo](docs/rules/prefer-todo.md) | Suggest using `test.todo` | | 🌐 | πŸ”§ | | -| [require-hook](docs/rules/require-hook.md) | Require setup and teardown to be within a hook | | 🌐 | | | -| [require-to-throw-message](docs/rules/require-to-throw-message.md) | Require toThrow() to be called with an error message | | 🌐 | | | -| [require-top-level-describe](docs/rules/require-top-level-describe.md) | Enforce that all tests are in a top-level describe | | 🌐 | | | -| [valid-describe-callback](docs/rules/valid-describe-callback.md) | Enforce valid describe callback | βœ… | | | | -| [valid-expect](docs/rules/valid-expect.md) | Enforce valid `expect()` usage | βœ… | | | | -| [valid-title](docs/rules/valid-title.md) | Enforce valid titles | βœ… | | πŸ”§ | | +| NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  | Description | πŸ’Ό | ⚠️ | πŸ”§ | πŸ’‘ | +| :----------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------- | :- | :- | :- | :- | +| [consistent-test-filename](docs/rules/consistent-test-filename.md) | forbidden .spec test file pattern | | 🌐 | | | +| [consistent-test-it](docs/rules/consistent-test-it.md) | Prefer test or it but not both | | 🌐 | πŸ”§ | | +| [expect-expect](docs/rules/expect-expect.md) | Enforce having expectation in test body | βœ… | | | | +| [max-expects](docs/rules/max-expects.md) | Enforce a maximum number of expect per test | | 🌐 | | | +| [max-nested-describe](docs/rules/max-nested-describe.md) | Nested describe block should be less than set max value or default value | | 🌐 | | | +| [no-alias-methods](docs/rules/no-alias-methods.md) | Disallow alias methods | | 🌐 | πŸ”§ | | +| [no-commented-out-tests](docs/rules/no-commented-out-tests.md) | Disallow commented out tests | βœ… | | | | +| [no-conditional-expect](docs/rules/no-conditional-expect.md) | Disallow conditional expects | | 🌐 | | | +| [no-conditional-in-test](docs/rules/no-conditional-in-test.md) | Disallow conditional tests | | 🌐 | | | +| [no-conditional-tests](docs/rules/no-conditional-tests.md) | Disallow conditional tests | | 🌐 | | | +| [no-disabled-tests](docs/rules/no-disabled-tests.md) | Disallow disabled tests | | 🌐 | | | +| [no-done-callback](docs/rules/no-done-callback.md) | Disallow using a callback in asynchronous tests and hooks | | 🌐 | | πŸ’‘ | +| [no-duplicate-hooks](docs/rules/no-duplicate-hooks.md) | Disallow duplicate hooks and teardown hooks | | 🌐 | | | +| [no-focused-tests](docs/rules/no-focused-tests.md) | Disallow focused tests | | 🌐 | πŸ”§ | | +| [no-hooks](docs/rules/no-hooks.md) | Disallow setup and teardown hooks | | 🌐 | | | +| [no-identical-title](docs/rules/no-identical-title.md) | Disallow identical titles | βœ… | | πŸ”§ | | +| [no-interpolation-in-snapshots](docs/rules/no-interpolation-in-snapshots.md) | Disallow string interpolation in snapshots | | 🌐 | πŸ”§ | | +| [no-large-snapshots](docs/rules/no-large-snapshots.md) | Disallow large snapshots | | 🌐 | | | +| [no-mocks-import](docs/rules/no-mocks-import.md) | Disallow importing from __mocks__ directory | | 🌐 | | | +| [no-restricted-matchers](docs/rules/no-restricted-matchers.md) | Disallow the use of certain matchers | | 🌐 | | | +| [no-restricted-vi-methods](docs/rules/no-restricted-vi-methods.md) | Disallow specific `vi.` methods | | 🌐 | | | +| [no-standalone-expect](docs/rules/no-standalone-expect.md) | Disallow using `expect` outside of `it` or `test` blocks | | 🌐 | | | +| [no-test-prefixes](docs/rules/no-test-prefixes.md) | Disallow using `test` as a prefix | | 🌐 | πŸ”§ | | +| [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow return statements in tests | | 🌐 | | | +| [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` | | 🌐 | πŸ”§ | | +| [prefer-comparison-matcher](docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | 🌐 | πŸ”§ | | +| [prefer-each](docs/rules/prefer-each.md) | Prefer `each` rather than manual loops | | 🌐 | | | +| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in quality matchers | | 🌐 | | πŸ’‘ | +| [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Suggest using `expect().resolves` over `expect(await ...)` syntax | | 🌐 | πŸ”§ | | +| [prefer-hooks-in-order](docs/rules/prefer-hooks-in-order.md) | Prefer having hooks in consistent order | | 🌐 | | | +| [prefer-hooks-on-top](docs/rules/prefer-hooks-on-top.md) | Suggest having hooks before any test cases | | 🌐 | | | +| [prefer-lowercase-title](docs/rules/prefer-lowercase-title.md) | Enforce lowercase titles | | 🌐 | πŸ”§ | | +| [prefer-mock-promise-shorthand](docs/rules/prefer-mock-promise-shorthand.md) | Prefer mock resolved/rejected shorthands for promises | | 🌐 | πŸ”§ | | +| [prefer-snapshot-hint](docs/rules/prefer-snapshot-hint.md) | Prefer including a hint with external snapshots | | 🌐 | | | +| [prefer-spy-on](docs/rules/prefer-spy-on.md) | Suggest using `vi.spyOn` | | 🌐 | πŸ”§ | | +| [prefer-strict-equal](docs/rules/prefer-strict-equal.md) | Prefer strict equal over equal | | 🌐 | | πŸ’‘ | +| [prefer-to-be](docs/rules/prefer-to-be.md) | Suggest using toBe() | βœ… | | πŸ”§ | | +| [prefer-to-be-falsy](docs/rules/prefer-to-be-falsy.md) | Suggest using toBeFalsy() | | 🌐 | πŸ”§ | | +| [prefer-to-be-object](docs/rules/prefer-to-be-object.md) | Prefer toBeObject() | | 🌐 | πŸ”§ | | +| [prefer-to-be-truthy](docs/rules/prefer-to-be-truthy.md) | Suggest using `toBeTruthy` | | 🌐 | πŸ”§ | | +| [prefer-to-contain](docs/rules/prefer-to-contain.md) | Prefer using toContain() | | 🌐 | πŸ”§ | | +| [prefer-to-have-length](docs/rules/prefer-to-have-length.md) | Suggest using toHaveLength() | | 🌐 | πŸ”§ | | +| [prefer-todo](docs/rules/prefer-todo.md) | Suggest using `test.todo` | | 🌐 | πŸ”§ | | +| [require-hook](docs/rules/require-hook.md) | Require setup and teardown to be within a hook | | 🌐 | | | +| [require-local-test-context-for-concurrent-snapshots](docs/rules/require-local-test-context-for-concurrent-snapshots.md) | Require local Test Context for concurrent snapshot tests | βœ… | 🌐 | | | +| [require-to-throw-message](docs/rules/require-to-throw-message.md) | Require toThrow() to be called with an error message | | 🌐 | | | +| [require-top-level-describe](docs/rules/require-top-level-describe.md) | Enforce that all tests are in a top-level describe | | 🌐 | | | +| [valid-describe-callback](docs/rules/valid-describe-callback.md) | Enforce valid describe callback | βœ… | | | | +| [valid-expect](docs/rules/valid-expect.md) | Enforce valid `expect()` usage | βœ… | | | | +| [valid-title](docs/rules/valid-title.md) | Enforce valid titles | βœ… | | πŸ”§ | | diff --git a/docs/rules/require-local-test-context-for-concurrent-snapshots.md b/docs/rules/require-local-test-context-for-concurrent-snapshots.md index 23feef7..cf7fad6 100644 --- a/docs/rules/require-local-test-context-for-concurrent-snapshots.md +++ b/docs/rules/require-local-test-context-for-concurrent-snapshots.md @@ -1,6 +1,6 @@ # Require local Test Context for concurrent snapshot tests (`vitest/require-local-test-context-for-concurrent-snapshots`) -πŸ’Ό This rule is enabled in the βœ… `recommended` config. +πŸ’Όβš οΈ This rule is enabled in the βœ… `recommended` config. This rule _warns_ in the 🌐 `all` config. diff --git a/src/index.ts b/src/index.ts index 1da62a1..75d62e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -115,7 +115,7 @@ const recommended = { [validTitleName]: 'error', [validExpectName]: 'error', [validDescribeCallbackName]: 'error', - [requireLocalTestContextForConcurrentSnapshotsName]: 'error', + [requireLocalTestContextForConcurrentSnapshotsName]: 'error' } export default { diff --git a/src/rules/no-done-callback.ts b/src/rules/no-done-callback.ts index 796452c..168729c 100644 --- a/src/rules/no-done-callback.ts +++ b/src/rules/no-done-callback.ts @@ -46,7 +46,7 @@ export default createEslintRule({ if (isVitestEach && node.callee.type !== AST_NODE_TYPES.TaggedTemplateExpression) return - const isVitestConcurrent = getNodeName(node.callee)?.endsWith('.concurrent') ?? false; + const isVitestConcurrent = getNodeName(node.callee)?.endsWith('.concurrent') ?? false if (isVitestConcurrent) return const callback = findCallbackArg(node, isVitestEach, context) diff --git a/src/rules/require-local-test-context-for-concurrent-snapshots.ts b/src/rules/require-local-test-context-for-concurrent-snapshots.ts index 67b7ca0..9b8768c 100644 --- a/src/rules/require-local-test-context-for-concurrent-snapshots.ts +++ b/src/rules/require-local-test-context-for-concurrent-snapshots.ts @@ -1,56 +1,56 @@ -import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils"; -import { createEslintRule, getNodeName, isSupportedAccessor } from "../utils"; -import { isTypeOfVitestFnCall } from "../utils/parseVitestFnCall"; +import { AST_NODE_TYPES } from '@typescript-eslint/utils' +import { createEslintRule, isSupportedAccessor } from '../utils' +import { isTypeOfVitestFnCall } from '../utils/parseVitestFnCall' -export const RULE_NAME = "require-local-test-context-for-concurrent-snapshots"; +export const RULE_NAME = 'require-local-test-context-for-concurrent-snapshots' export default createEslintRule({ name: RULE_NAME, meta: { docs: { - description: "Require local Test Context for concurrent snapshot tests", - recommended: "error", + description: 'Require local Test Context for concurrent snapshot tests', + recommended: 'error' }, messages: { - requireLocalTestContext: "Use local Test Context instead", + requireLocalTestContext: 'Use local Test Context instead' }, - type: "problem", - schema: [], + type: 'problem', + schema: [] }, defaultOptions: [], create(context) { return { CallExpression(node) { const isNotAnAssertion = !isTypeOfVitestFnCall(node, context, ['expect']) - if (isNotAnAssertion) return; + if (isNotAnAssertion) return const isNotASnapshotAssertion = ![ 'toMatchSnapshot', 'toMatchInlineSnapshot' - ].includes(node.callee.property.name); + ].includes(node.callee.property.name) - if (isNotASnapshotAssertion) return; + if (isNotASnapshotAssertion) return const isInsideSequentialDescribeOrTest = !context.getAncestors().some((ancestor) => { - if (ancestor.type !== AST_NODE_TYPES.CallExpression) return false; + if (ancestor.type !== AST_NODE_TYPES.CallExpression) return false - const isNotInsideDescribeOrTest = !isTypeOfVitestFnCall(ancestor, context, ["describe", "test"]); - if (isNotInsideDescribeOrTest) return false; + const isNotInsideDescribeOrTest = !isTypeOfVitestFnCall(ancestor, context, ['describe', 'test']) + if (isNotInsideDescribeOrTest) return false const isTestRunningConcurrently = ancestor.callee.type === AST_NODE_TYPES.MemberExpression && - isSupportedAccessor(ancestor.callee.property, "concurrent"); + isSupportedAccessor(ancestor.callee.property, 'concurrent') return isTestRunningConcurrently - }); + }) - if (isInsideSequentialDescribeOrTest) return; + if (isInsideSequentialDescribeOrTest) return context.report({ node, - messageId: "requireLocalTestContext" + messageId: 'requireLocalTestContext' }) - }, - }; - }, -}); + } + } + } +}) diff --git a/tests/require-local-test-context-for-concurrent-snapshots.test.ts b/tests/require-local-test-context-for-concurrent-snapshots.test.ts index 758595c..f9692d9 100644 --- a/tests/require-local-test-context-for-concurrent-snapshots.test.ts +++ b/tests/require-local-test-context-for-concurrent-snapshots.test.ts @@ -1,5 +1,5 @@ import rule, { RULE_NAME } from '../src/rules/require-local-test-context-for-concurrent-snapshots' -import { ruleTester } from "./ruleTester"; +import { ruleTester } from './ruleTester' ruleTester.run(RULE_NAME, rule, { valid: [ @@ -15,7 +15,7 @@ ruleTester.run(RULE_NAME, rule, { 'describe("something", () => { it("something", (context) => { expect(1).toMatchInlineSnapshot() }) })', 'describe("something", () => { it("something", (context) => { context.expect(1).toMatchInlineSnapshot() }) })', 'describe("something", () => { it("something", (context) => { expect(1).toMatchInlineSnapshot() }) })', - 'it.concurrent("something", (context) => { context.expect(1).toMatchSnapshot() })', + 'it.concurrent("something", (context) => { context.expect(1).toMatchSnapshot() })' ], invalid: [ { @@ -53,6 +53,6 @@ ruleTester.run(RULE_NAME, rule, { expect(true).toMatchSnapshot(); })`, errors: [{ messageId: 'requireLocalTestContext' }] - }, - ], + } + ] })