feat(linter): implement vitest/no-unneeded-async-expect-function rule#17494
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements the no-unneeded-async-expect-function vitest linter rule, which detects and auto-fixes unnecessary async function wrappers in expect() calls when they only contain a single awaited expression.
Key Changes:
- Detects async function wrappers (arrow and function expressions) that only contain
await someCall() - Provides auto-fix to replace the wrapper with the direct call
- Handles both block body and expression body arrow functions
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
crates/oxc_linter/src/rules/vitest/no_unneeded_async_expect_function.rs |
Main rule implementation with detection logic, auto-fix, helper functions, and comprehensive test suite |
crates/oxc_linter/src/rules.rs |
Module declaration for the new rule |
crates/oxc_linter/src/generated/rule_runner_impls.rs |
Generated RuleRunner implementation configured to use RunOnJestNode |
crates/oxc_linter/src/snapshots/vitest_no_unneeded_async_expect_function.snap |
Test snapshot showing diagnostic output for all failing test cases |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Based on the PR description and code comments I presume this was - at least in large part - generated using AI tooling. Please ensure that the PR description is updated to note the AI usage in accordance with our policy, preferably including models/tools used and a confirmation that you have personally reviewed the code generated and ensured it works/makes sense: https://oxc.rs/docs/contribute/introduction.html#ai-usage-policy |
|
The test looks that are AI generated. In the eslint plugin, most of the expects are wrapped inside a |
camc314
left a comment
There was a problem hiding this comment.
Thanks for working on this.
I have re-ported the test cases from the original rule. A significant number of them are failing, these should be passing before this can be merged.
I've converted this to a draft so I can keep track of what needs my review and what doesn't. Please mark ready for review once you've fixed all cases and reviewed any AI generated code.
CodSpeed Performance ReportMerging #17494 will not alter performanceComparing Summary
Footnotes
|
|
@camc314 I've fixed the failing tests by adding I've reviewed the AI-generated code and ensured it follows oxc patterns. Ready for re-review. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2710c23 to
94f65f0
Compare
Add rule to detect and auto-fix unnecessary async function wrappers in expect() calls. When the only statement in an async wrapper is `await someCall()`, the wrapper is unnecessary and the promise can be passed directly to expect. Example: ```js // Bad await expect(async () => await doSomething()).rejects.toThrow(); // Good await expect(doSomething()).rejects.toThrow(); ``` Closes oxc-project#9
- Add missing test cases for better coverage: - Empty expect() edge case - Await in expect argument position - Async reference function call - .not matcher variant - Improve inline comments for clarity: - Document function return value semantics - Clarify AST representation detail for concise arrow body - Add comment explaining .to_string() lifetime requirement
…on tests Add `.with_vitest_plugin(true)` to ensure the rule is correctly detected in test environment. Without this, the vitest framework context is not enabled and the rule's `run_on_jest_node` method is never called, causing test cases to incorrectly pass.
94f65f0 to
1e56dad
Compare
# Oxlint ### 🚀 Features - 9699a1b linter/prefer-global-this: Add suggestion (#17873) (Mikhail Baev) - 51c2815 linter/no-invalid-regexp: Add labels and help text to flag diagnostics (#17865) (camchenry) - 344d77d linter/no-ex-assign: Improve diagnostic with more detail (#17864) (camchenry) - 7d280e0 linter: Add fixer for `unicorn/no-useless-error-capture-stack-trace` rule (#17839) (Mikhail Baev) - af1d0e3 linter/prefer-optional-chain: Add rule (#17831) (camc314) - e3c4108 vscode: Add more supported languages to extension (#17812) (Alexander Lichter) - 4a46678 vscode: Activate extension on more languages (#17717) (Sysix) - b1298fc vscode: Sync formatter with supported files (#17615) (Alexander Lichter) - c7f0848 linte/rno-required-prop-with-default: Implement suggestion (#17747) (Minsu Lee) - 0e8127e linter/vue: Implement no-lifecycle-after-await (#17701) (yefan) - 3567304 linter/vitest: Implement `consistent-each-for` (#17601) (Said Atrahouch) - 883e156 linter: Add fixer for `unicorn/no-useless-collection-argument` rule (#17594) (Mikhail Baev) - 4eb335c linter/vitest: Implemented prefer-called-once (#17674) (Said Atrahouch) - 2bd2d5a linter/vitest: Implement hoisted-apis-on-top (#17658) (Said Atrahouch) - cfb2bcc linter/vue: Implement no-arrow-functions-in-watch (#17672) (yefan) - a68208a linter/eslint-plugin-vitest: Implements `prefer-describe-function-title` (#17677) (Said Atrahouch) - efa029f linter/vitest: Implement no-unneeded-async-expect-function (#17494) (Minsu Lee) ### 🐛 Bug Fixes - 49cf66e lsp: Fix workspace worker selection for nested and similar-named workspaces (#17853) (Copilot) - 84f4f3c linter: Add doc url for tsgolint diagnostics (#17879) (Sysix) - 76c903f linter/consistent-indexed-object-style: Skip fixing default exported interface (#17874) (Copilot) - 7e87d16 linter/tabindex-no-positive: Improve diagnostic phrasing (#17849) (connorshea) - 28f9fba vscode: Fix nested search for binaries (#17832) (Sysix) - 8ca2cd2 linter: Move jsx-a11y/no-static-element-interactions rule to nursery. (#17818) (connorshea) - dc9fdd6 linter/consistent-indexed-object-style: Re-port test cases and fix some bugs (#17802) (camc314) - 7bbd880 linter: Update prefer-destructuring rule metadata (#17642) (Hamir Mahal) - 3c45185 linter/consistent-indexed-object-style: False positive with circular reference (#17789) (heygsc) - bd186b4 vscode: Search for `oxlint` and `oxfmt` in every workspace directory (#17760) (Sysix) - 3e0dff7 linter/no-hooks: Add punctuation to diagnostic message (#17751) (camc314) - 6ae21f9 linter/prefer-called-once: Avoid panic on trailing comma (#17735) (Said Atrahouch) - 32c3901 oxlint: Do not panic on invalid `no-unused-vars` configuration (#17719) (Sysix) - 59a6228 parser: Detect TS1363 error for type-only imports with mixed default and named/namespace bindings (#17712) (Copilot) ### ⚡ Performance - f87a1e2 linter: Check for giving reserved plugin name before calling `load_plugin` on napi side (#17841) (Sysix) ### 📚 Documentation - a2b3a24 linter/no-caller: Improve docs and diagnostic for rule. (#17890) (connorshea) - aa48247 linter/no-unsafe-finally: Improve rule docs. (#17891) (connorshea) - 1b0bdee linter: Tweak docs for no-useless-constructor and hoisted-apis-on-top (#17888) (connorshea) - 8f24fa9 vscode: Remove mention of a built-in server (#17836) (Sysix) - e81a306 linter: Update the tsconfig flag mention for the import plugin. (#17778) (connorshea) # Oxfmt ### 🚀 Features - 539b350 formatter/sort_imports: Update `NODE_BUILTINS` modules (#17771) (nilptr) - 2e03ebf oxfmt/lsp: Use `SourceFormatter` to support non-JS files and napi features (#17655) (leaysgur) - 623f7eb oxfmt/sort_package_json: Use `options.sort_scripts` (#17740) (leaysgur) - 86c0168 oxfmt/sort_package_json: Handle `oxfmtrc.sort_scripts` option (#17738) (leaysgur) - 256636a oxfmt/lsp: Add `.editorconfig` to `get_watcher_patterns` (#17694) (leaysgur) - 3f3db39 oxfmt/lsp: Use `ConfigResolver` to align with CLI (#17654) (leaysgur) ### 🐛 Bug Fixes - fdd1e1e formatter: Don't wrap parenthesis for type assertion when it's an declaration of export default (#17878) (Dunqing) - f0813ad formatter: Incorrect type annotation check for short argument (#17877) (Dunqing) - 9e89389 formatter/tailwindcss: Nested class string doesn't respect `singleQuote: true` (#17838) (Dunqing) - e2f534c formatter/sort_imports: Handle alignable comment with JsLabels (#17791) (leaysgur) - f0cedd4 formatter/tailwindcss: Class name is broken after sorting when its contains single quotes with `singleQuote: true` (#17790) (Dunqing) - 1864142 oxfmt/tailwindcss: Bundle `prettier/plugins/*` (#17782) (leaysgur) - 3a9d43b oxfmt: Ignore explicit positional path which is ignored by directory (#17732) (leaysgur) - 0563217 formatter: Classes will be stripped out when both `experimentalTailwindcss` and `experimentalSortImports` are enabled (#17726) (Dunqing) ### ⚡ Performance - d1bc514 formatter: Optimize RegExpLiteral formatting to avoid heap allocations (#17797) (Dunqing) ### 📚 Documentation - 62b7a01 formatter: Clarify `experimentalTailwindcss` configuration comments (#17898) (Dunqing) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Summary
Implement the
no-unneeded-async-expect-functionvitest rule which detects unnecessary async function wrappers inexpect()calls.Features
expect()callsasync () => { await doSomething(); })async () => await doSomething())async function() { await doSomething(); })rejectsandresolvesmatchersExample
Test Cases
10 passing test cases and 6 failing test cases covering:
Test Plan
no_unneeded_async_expect_functiontest passesRelated
Reference: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-unneeded-async-expect-function.md
https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/src/rules/no-unneeded-async-expect-function.ts
https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/tests/no-unneeded-async-expect-function.test.ts
#4656
This PR was generated with AI assistance. The implementation has been thoroughly reviewed and tested.