Conversation
|
Cursor Agent can help with this pull request. Just |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Bugbot Autofix prepared fixes for 1 of the 1 bugs found in the latest run.
|
eslint-plugin-epic-web.js
Outdated
There was a problem hiding this comment.
Outer mutation heuristic misses method calls
Low Severity
writesOuterState only treats AssignmentExpression and UpdateExpression as mutations. Hooks that mutate shared outer state through method calls like array.push(...), map.set(...), or mutating helpers are not recognized, so epic-web/prefer-dispose-in-tests reports hooks that the rule intends to exempt for outer-state mutation.
eslint-plugin-epic-web.js
Outdated
There was a problem hiding this comment.
Non-test APIs counted as test cases
Medium Severity
isTestCallExpression treats almost any test.*(...) call as a test, so helper APIs like test.use, test.extend, or similar configuration calls inflate testCount. This breaks suite analysis in analyzeSuiteNode, causing hook warnings to be emitted or suppressed based on non-test calls.
Additional Locations (1)
eslint-plugin-epic-web.js
Outdated
There was a problem hiding this comment.
Test counting includes non-executed test calls
Low Severity
analyzeSuiteNode counts every test/it call anywhere under the suite AST, including calls inside nested helper functions. That inflates testCount, so minimumTestsForSuiteHooks exemptions can trigger even when the suite has too few runnable tests, causing epic-web/prefer-dispose-in-tests to miss reports.
| if (currentNode.type === 'CallExpression' && isTestCallExpression(currentNode)) { | ||
| testCount += 1 | ||
| } | ||
| }) |
There was a problem hiding this comment.
Suite test counting includes non-executed definitions
Low Severity
analyzeSuiteNode counts every test/it call found anywhere under the suite AST. That includes calls inside nested helper functions or other non-executed scopes, which can inflate testCount and incorrectly skip reports for lifecycle hooks in suites that do not actually have enough runnable tests.
|
|
||
| function getHookCallback(node) { | ||
| return node.arguments.find((argument) => isFunctionNode(argument)) ?? null | ||
| } |
There was a problem hiding this comment.
Function reference hooks bypass the rule
Low Severity
getHookCallback only accepts inline FunctionExpression and ArrowFunctionExpression arguments. Hooks written as beforeEach(setupFn) return null, and create exits early, so epic-web/prefer-dispose-in-tests never evaluates or reports those hook usages.
Additional Locations (1)
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
cf2a7e7 to
61f9607
Compare
| writeTarget = currentNode.left | ||
| } else if (currentNode.type === 'UpdateExpression') { | ||
| writeTarget = currentNode.argument | ||
| } |
There was a problem hiding this comment.
Outer mutation heuristic misses method-based writes
Low Severity
writesOuterState only treats AssignmentExpression and UpdateExpression as outer-state writes. Hooks that mutate captured objects via calls like arr.push(...), map.set(...), or obj.method(...) are not recognized, so epic-web/prefer-dispose-in-tests can report hooks that actually rely on shared outer mutation.
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
|
🎉 This PR is included in version 1.24.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |


Add
epic-web/prefer-dispose-in-testsESLint rule to enforce usingdisposeanddisposeAsyncoverbefore*/after*hooks in tests.This rule encourages a more robust and explicit resource management pattern in tests, as described in the EpicWeb.dev article "Better Test Setup with Disposable Objects," by flagging traditional hooks when a disposable pattern is feasible. It includes heuristics to automatically allow exceptions where
disposeis not reasonably possible (e.g., callback parameters,thiscontext, outer state mutation, multi-test suite-level hooks, or known framework-wide timer/mock hooks).Note
Medium Risk
Introduces a new, enabled-by-default lint rule for all test files, which can surface new warnings and relies on AST/scope heuristics that may have edge-case false positives/negatives.
Overview
Adds a new lint rule,
epic-web/prefer-dispose-in-tests, that warns onbeforeEach/afterEach/beforeAll/afterAllusage in test suites when setup/cleanup can be moved into per-test disposable setup (using/await using), with heuristics to skip common non-trivial cases (callback params/this, outer-state mutation, setup-only files, known timer/mock helpers, and larger suites).Registers the rule in the
epic-webplugin, exports a dedicated./eslint-pluginentrypoint, enables the rule aswarnfor test-file overrides in botheslint.jsandoxlint-config.json, and adds docs plus aRuleTestersuite covering allowed/reported scenarios.Written by Cursor Bugbot for commit 1ca4870. This will update automatically on new commits. Configure here.