feat(lint/js): add useTestHooksInOrder#9394
Conversation
🦋 Changeset detectedLatest commit: dfe6101 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
60b9350 to
12e7d92
Compare
82d1b04 to
313106f
Compare
313106f to
eb19f67
Compare
12e7d92 to
491b171
Compare
eb19f67 to
ec9c74b
Compare
WalkthroughAdds a new nursery lint rule Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs (1)
91-99: Please moveHookOrderViolationbelow theimpl Ruleblock.Small consistency tweak: rule helpers are kept below
impl Rulein this codebase.Based on learnings: In
crates/biome_analyze/**/*.rsrule files, all helper functions, structs, and enums must be placed below theimpl Ruleblock.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around lines 91 - 99, Move the HookOrderViolation struct declaration so it appears below the impl Rule block: cut the entire pub struct HookOrderViolation { ... } and paste it after the impl Rule ... end brace, keeping its pub visibility and field types unchanged; ensure any uses inside impl Rule still compile (adjust visibility or add a use if necessary) and run cargo check to confirm there are no forward-reference errors after relocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.changeset/add-use-test-hooks-in-order.md:
- Line 2: The changeset currently uses a non-breaking change type "minor" for
"@biomejs/biome" but should be "patch" for a bugfix/non-breaking update; update
the entry in .changeset/add-use-test-hooks-in-order.md so the line containing
"@biomejs/biome": minor is changed to use "patch" instead of "minor" to target
main as a non-breaking change.
---
Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs`:
- Around line 91-99: Move the HookOrderViolation struct declaration so it
appears below the impl Rule block: cut the entire pub struct HookOrderViolation
{ ... } and paste it after the impl Rule ... end brace, keeping its pub
visibility and field types unchanged; ensure any uses inside impl Rule still
compile (adjust visibility or add a use if necessary) and run cargo check to
confirm there are no forward-reference errors after relocation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 64a6cb09-2bac-4537-b417-ac1429fbffbc
⛔ Files ignored due to path filters (5)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (8)
.changeset/add-use-test-hooks-in-order.mdcrates/biome_js_analyze/src/frameworks/unit_tests.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.jscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_test_hooks_in_order.rs
Merging this PR will not alter performance
Comparing Footnotes
|
0c1932d to
866c657
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs (1)
91-99: Please parkHookOrderViolationbelow the rule impl.Tiny filing-cabinet gripe, but this repo keeps rule-local helpers under
impl Rule; it keeps the interesting bit on stage and the scaffolding backstage.Based on learnings, "In crates/biome_analyze/**/*.rs rule files, all helper functions, structs, and enums must be placed below the
impl Ruleblock. The only exception is when declaring a node union to use in the rule's Query type, which can be kept above the rule block for better readability."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around lines 91 - 99, Move the helper struct HookOrderViolation so it appears below the impl Rule block: locate the HookOrderViolation declaration and cut/paste it to a position after the impl Rule implementation in this file; ensure any references to HookOrderViolation (e.g., in functions or methods inside impl Rule) still resolve by keeping visibility/pub as-is and update imports or use paths only if necessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/biome_js_analyze/src/frameworks/unit_tests.rs`:
- Around line 7-19: The enum LifecycleHook relies on its derived Ord which
treats BeforeAll < Before < BeforeEach and AfterAll < After, causing false
misorder flags when node:test hooks (Before/After) should be considered
equivalent to BeforeAll/AfterAll; update the ordering logic to use an explicit
phase-rank mapping (e.g., map LifecycleHook variants to a PhaseRank enum or
integer where Before and BeforeAll share the same rank and After and AfterAll
share the same rank) and change any comparisons that rely on the derived Ord
(search for uses of LifecycleHook ordering/comparisons) to compare by that
PhaseRank instead of the enum's Ord so mixed node:test + Jest/Vitest hooks are
treated as equivalent stages.
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs`:
- Around line 115-118: The current statements() closure uses
filter_map(module_item_to_statement) which drops non-statement module items and
makes imports/exports invisible; instead, change the logic in
top_level_module_items_for_call (and the repeated block at 214-218) to treat
module items where module_item_to_statement returns None as run separators:
produce an iterator/sequence over module items mapping each to Option<Statement>
and then split that sequence into contiguous segments of Some(Statement)
(resetting the run whenever a None is encountered), pass each segment into
first_scope_call(...) / check_hooks_order(...) so hooks separated by
imports/exports are not considered contiguous. Ensure you update both the
first_scope_call(check) usage and the signals.extend(check_hooks_order(...))
usage to operate on these split statement runs.
- Around line 111-113: The helper describe_body(call) currently only recognizes
bare describe(...) and single-hop test.describe(...), causing chained forms like
describe.each(...)(...), describe.only(...), or test.describe.each(...) to be
skipped; update describe_body to walk/unwind callee chains (MemberExpression and
nested CallExpression results) to detect the base identifier/member (e.g.,
"describe" or "test.describe") even when wrapped in .each/.only/.skip calls or
when the .each returns another CallExpression, and then extract the inner suite
body so check_hooks_order(statement_list) is still invoked for those chained
forms.
---
Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs`:
- Around line 91-99: Move the helper struct HookOrderViolation so it appears
below the impl Rule block: locate the HookOrderViolation declaration and
cut/paste it to a position after the impl Rule implementation in this file;
ensure any references to HookOrderViolation (e.g., in functions or methods
inside impl Rule) still resolve by keeping visibility/pub as-is and update
imports or use paths only if necessary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fa9f23b4-5964-4823-a669-55bdbb768683
⛔ Files ignored due to path filters (5)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (8)
.changeset/add-use-test-hooks-in-order.mdcrates/biome_js_analyze/src/frameworks/unit_tests.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.jscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_test_hooks_in_order.rs
✅ Files skipped from review due to trivial changes (4)
- crates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rs
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js
- crates/biome_rule_options/src/use_test_hooks_in_order.rs
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js
🚧 Files skipped from review as they are similar to previous changes (2)
- crates/biome_rule_options/src/lib.rs
- .changeset/add-use-test-hooks-in-order.md
| if let Some(statement_list) = describe_body(call) { | ||
| signals.extend(check_hooks_order(statement_list)); | ||
| } |
There was a problem hiding this comment.
describe.each and friends fall straight through here.
This branch depends on describe_body(call), but the shared helper only recognises bare describe(...) and single-hop test.describe(...). Common Jest/Vitest forms like describe.each(...)() and describe.only(...) never enter this path, so the new rule skips hook-order violations inside those suites.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around
lines 111 - 113, The helper describe_body(call) currently only recognizes bare
describe(...) and single-hop test.describe(...), causing chained forms like
describe.each(...)(...), describe.only(...), or test.describe.each(...) to be
skipped; update describe_body to walk/unwind callee chains (MemberExpression and
nested CallExpression results) to detect the base identifier/member (e.g.,
"describe" or "test.describe") even when wrapped in .each/.only/.skip calls or
when the .each returns another CallExpression, and then extract the inner suite
body so check_hooks_order(statement_list) is still invoked for those chained
forms.
| if let Some(module_items) = top_level_module_items_for_call(call) { | ||
| let statements = || module_items.iter().filter_map(module_item_to_statement); | ||
| if first_scope_call(statements()).is_some_and(|first| first.syntax() == call.syntax()) { | ||
| signals.extend(check_hooks_order(statements())); |
There was a problem hiding this comment.
Module items are currently invisible instead of being separators.
filter_map(module_item_to_statement) drops imports/exports entirely, so check_hooks_order() compares hooks across them as if nothing sat in between. In a module, beforeEach(); export const x = 1; beforeAll(); would be treated as one contiguous hook run, which contradicts the rule docs. Please make non-statement module items reset the run rather than disappear into the floorboards.
Also applies to: 214-218
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around
lines 115 - 118, The current statements() closure uses
filter_map(module_item_to_statement) which drops non-statement module items and
makes imports/exports invisible; instead, change the logic in
top_level_module_items_for_call (and the repeated block at 214-218) to treat
module items where module_item_to_statement returns None as run separators:
produce an iterator/sequence over module items mapping each to Option<Statement>
and then split that sequence into contiguous segments of Some(Statement)
(resetting the run whenever a None is encountered), pass each segment into
first_scope_call(...) / check_hooks_order(...) so hooks separated by
imports/exports are not considered contiguous. Ensure you update both the
first_scope_call(check) usage and the signals.extend(check_hooks_order(...))
usage to operate on these split statement runs.
866c657 to
4e33a61
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
crates/biome_js_analyze/src/frameworks/unit_tests.rs (1)
7-19:⚠️ Potential issue | 🟠 MajorAvoid using derived
Ordfor phase-equivalent hooks.
Before/BeforeAllandAfter/AfterAllare modelled as different enum ranks, andhook < prev_hook(incrates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs, Line 180) can still report misorder when equivalent phases are mixed.Suggested direction
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum LifecycleHook { BeforeAll, Before, BeforeEach, AfterEach, AfterAll, After, } impl LifecycleHook { + pub(crate) const fn phase_rank(self) -> u8 { + match self { + Self::BeforeAll | Self::Before => 0, + Self::BeforeEach => 1, + Self::AfterEach => 2, + Self::AfterAll | Self::After => 3, + } + }And in
crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs:- if let Some((ref prev_call, prev_hook)) = last_hook - && hook < prev_hook + if let Some((ref prev_call, prev_hook)) = last_hook + && hook.phase_rank() < prev_hook.phase_rank() {#!/bin/bash set -euo pipefail # Confirm enum ordering is derived from Rust Ord and comparator is direct `<`. rg -nP 'derive\([^)]*\bOrd\b' crates/biome_js_analyze/src/frameworks/unit_tests.rs rg -nP '\bhook\s*<\s*prev_hook\b' crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs # Confirm whether a phase-rank abstraction exists yet. rg -nP '\bphase_rank\s*\(' crates/biome_js_analyze/src/frameworks/unit_tests.rs crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rsExpected result: first two commands match and the third does not; that confirms the current strict-rank comparison path.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/frameworks/unit_tests.rs` around lines 7 - 19, The derived Ord on enum LifecycleHook causes distinct variants (Before vs BeforeAll, After vs AfterAll) to be treated as different ranks and makes the comparator hook < prev_hook in use_test_hooks_in_order.rs report false misorders; change the comparison to use an explicit phase-rank abstraction instead of the derived Ord: add a helper (e.g., a phase_rank(LifecycleHook) -> u8 or enum PhaseRank) that maps Before and BeforeAll to the same rank and After/AfterAll to the same rank, then replace direct comparisons of LifecycleHook (the hook < prev_hook check) with comparisons of phase_rank(hook) < phase_rank(prev_hook) so hooks in equivalent phases are treated equally. Ensure the helper is referenced where LifecycleHook ordering is used in use_test_hooks_in_order.rs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/biome_js_analyze/src/frameworks/unit_tests.rs`:
- Line 5: Update the top doc comment that currently reads "The four lifecycle
hooks recognised by Jest/Vitest/similar frameworks." to reflect the actual
number defined (six) or remove the numeric count entirely; locate the doc
comment above the enum in unit_tests.rs (the lifecycle hooks enum) and change
the wording to "The six lifecycle hooks recognised by Jest/Vitest/similar
frameworks." or a number-agnostic phrase like "The lifecycle hooks recognised by
Jest/Vitest/similar frameworks." so the documentation matches the enum
definition.
---
Duplicate comments:
In `@crates/biome_js_analyze/src/frameworks/unit_tests.rs`:
- Around line 7-19: The derived Ord on enum LifecycleHook causes distinct
variants (Before vs BeforeAll, After vs AfterAll) to be treated as different
ranks and makes the comparator hook < prev_hook in use_test_hooks_in_order.rs
report false misorders; change the comparison to use an explicit phase-rank
abstraction instead of the derived Ord: add a helper (e.g., a
phase_rank(LifecycleHook) -> u8 or enum PhaseRank) that maps Before and
BeforeAll to the same rank and After/AfterAll to the same rank, then replace
direct comparisons of LifecycleHook (the hook < prev_hook check) with
comparisons of phase_rank(hook) < phase_rank(prev_hook) so hooks in equivalent
phases are treated equally. Ensure the helper is referenced where LifecycleHook
ordering is used in use_test_hooks_in_order.rs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9d8e3dd7-b6b1-4a09-973c-347dedf53eca
⛔ Files ignored due to path filters (7)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (8)
.changeset/add-use-test-hooks-in-order.mdcrates/biome_js_analyze/src/frameworks/unit_tests.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.jscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_test_hooks_in_order.rs
✅ Files skipped from review due to trivial changes (5)
- crates/biome_rule_options/src/lib.rs
- .changeset/add-use-test-hooks-in-order.md
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js
- crates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rs
- crates/biome_rule_options/src/use_test_hooks_in_order.rs
🚧 Files skipped from review as they are similar to previous changes (2)
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js
- crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs
8368f10 to
ffae4b1
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs (2)
111-113:⚠️ Potential issue | 🟠 Major
describe.only/describe.eachsuites are still bypassed.This path only runs when
describe_body(call)matches, but chained describe variants don’t resolve through that helper, so hook-order violations inside those suites are missed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around lines 111 - 113, The check currently only runs when describe_body(call) matches, so chained describe variants like describe.only and describe.each are skipped; update the logic so that the callee is normalized before calling describe_body(call) (or extend describe_body to accept MemberExpression/chained call patterns) and ensure check_hooks_order(statement_list) is invoked for resolved chained describes as well as plain describe—specifically modify the call-site that uses describe_body(call) and/or the describe_body helper to unwrap MemberExpression chains (e.g., `describe.only`, `describe.each(...)`) into the base describe call so hook-order violations inside chained suites are detected.
116-118:⚠️ Potential issue | 🟠 MajorNon-statement module items should reset runs, not disappear.
filter_mapdrops imports/exports, so hooks on either side get compared as one continuous sequence. That can report false ordering violations in module files.Also applies to: 214-218
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around lines 116 - 118, The current lambda statements uses module_items.iter().filter_map(module_item_to_statement) which drops non-statement module items (imports/exports) and incorrectly treats hooks across them as contiguous; change the logic in the usages of statements (the block calling first_scope_call(statements()) and signals.extend(check_hooks_order(statements()))) to iterate module_items and treat a None from module_item_to_statement as a sequence reset (i.e., split into separate statement sequences whenever module_item_to_statement returns None), feeding each contiguous statement sequence into first_scope_call/check_hooks_order instead of using filter_map; apply the same change to the other occurrence referenced at lines 214-218.
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs (1)
91-99: Consider moving helper types belowimpl Rulefor local consistency.Tiny tidy-up: place
HookOrderViolationafter the rule implementation to match the usual nursery rule layout.Based on learnings: In crates/biome_analyze/**/*.rs rule files, all helper functions, structs, and enums must be placed below the
impl Ruleblock (except node unions used byQuery).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs` around lines 91 - 99, Move the helper struct HookOrderViolation so it appears after the impl Rule block in this file to match the nursery rule layout; locate the HookOrderViolation definition (pub struct HookOrderViolation { ... }) and cut/paste it below the impl Rule implementation, leaving Query node-union types (if any) in place per convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs`:
- Around line 111-113: The check currently only runs when describe_body(call)
matches, so chained describe variants like describe.only and describe.each are
skipped; update the logic so that the callee is normalized before calling
describe_body(call) (or extend describe_body to accept MemberExpression/chained
call patterns) and ensure check_hooks_order(statement_list) is invoked for
resolved chained describes as well as plain describe—specifically modify the
call-site that uses describe_body(call) and/or the describe_body helper to
unwrap MemberExpression chains (e.g., `describe.only`, `describe.each(...)`)
into the base describe call so hook-order violations inside chained suites are
detected.
- Around line 116-118: The current lambda statements uses
module_items.iter().filter_map(module_item_to_statement) which drops
non-statement module items (imports/exports) and incorrectly treats hooks across
them as contiguous; change the logic in the usages of statements (the block
calling first_scope_call(statements()) and
signals.extend(check_hooks_order(statements()))) to iterate module_items and
treat a None from module_item_to_statement as a sequence reset (i.e., split into
separate statement sequences whenever module_item_to_statement returns None),
feeding each contiguous statement sequence into
first_scope_call/check_hooks_order instead of using filter_map; apply the same
change to the other occurrence referenced at lines 214-218.
---
Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rs`:
- Around line 91-99: Move the helper struct HookOrderViolation so it appears
after the impl Rule block in this file to match the nursery rule layout; locate
the HookOrderViolation definition (pub struct HookOrderViolation { ... }) and
cut/paste it below the impl Rule implementation, leaving Query node-union types
(if any) in place per convention.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 323904c4-ae1f-4fb7-9e46-9e098750e0cd
⛔ Files ignored due to path filters (7)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (8)
.changeset/add-use-test-hooks-in-order.mdcrates/biome_js_analyze/src/frameworks/unit_tests.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_in_order.rscrates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.jscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_test_hooks_in_order.rs
✅ Files skipped from review due to trivial changes (3)
- crates/biome_js_analyze/src/lint/nursery/use_test_hooks_on_top.rs
- crates/biome_rule_options/src/use_test_hooks_in_order.rs
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/valid.js
🚧 Files skipped from review as they are similar to previous changes (3)
- crates/biome_rule_options/src/lib.rs
- .changeset/add-use-test-hooks-in-order.md
- crates/biome_js_analyze/tests/specs/nursery/useTestHooksInOrder/invalid.js
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2415) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15) ##### Patch Changes - [#​9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about. - [#​10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`. For example, the following snippet triggers the rule: ```js import { nextTick } from "vue"; nextTick(() => { updateDom(); }); ``` - [#​10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives. For example, the following snippet triggers the rule: ```vue <input @​keyup.13="submit" /> ``` - [#​10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables. - [#​10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@​dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available. - [#​10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@​realknove](https://github.com/realknove)! - Fixed [#​10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers. - [#​9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is. - [#​10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group. The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group. ```json { "assist": { "actions": { "source": { "organizeImports": { "options": { "groups": [":INEXISTENT:"] } } } } } } ``` - [#​10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`). These functions are now reported because `null` and `number` are included in the return annotations but never returned: ```ts function getUser(): string | null { return "hello"; } // null is never returned function getCode(): string | number { return "hello"; } // number is never returned ``` - [#​10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line. - [#​10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`. This function is now reported because the return annotation widens a property initialized with `as const`: ```ts function f(): { value: string } { return { value: "text" as const }; } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`. This conversion is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "text" as const }; String(message.value); ``` - [#​9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`. The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options. **Invalid**: ```js class Foo { bar() { // does not use `this`, invalid console.log("Hello Biome"); } } ``` - [#​10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@​ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated. - [#​10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts. - [#​9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option. - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`. This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it: ```ts const status = { kind: "ready" as const }; switch (status.kind) { } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`. This comparison is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "hello" as const }; message.value[0] === "h"; ``` </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/12
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2415) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15) ##### Patch Changes - [#​9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about. - [#​10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`. For example, the following snippet triggers the rule: ```js import { nextTick } from "vue"; nextTick(() => { updateDom(); }); ``` - [#​10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives. For example, the following snippet triggers the rule: ```vue <input @​keyup.13="submit" /> ``` - [#​10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables. - [#​10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@​dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available. - [#​10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@​realknove](https://github.com/realknove)! - Fixed [#​10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers. - [#​9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is. - [#​10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group. The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group. ```json { "assist": { "actions": { "source": { "organizeImports": { "options": { "groups": [":INEXISTENT:"] } } } } } } ``` - [#​10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`). These functions are now reported because `null` and `number` are included in the return annotations but never returned: ```ts function getUser(): string | null { return "hello"; } // null is never returned function getCode(): string | number { return "hello"; } // number is never returned ``` - [#​10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line. - [#​10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`. This function is now reported because the return annotation widens a property initialized with `as const`: ```ts function f(): { value: string } { return { value: "text" as const }; } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`. This conversion is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "text" as const }; String(message.value); ``` - [#​9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`. The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options. **Invalid**: ```js class Foo { bar() { // does not use `this`, invalid console.log("Hello Biome"); } } ``` - [#​10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@​ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated. - [#​10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts. - [#​9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option. - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`. This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it: ```ts const status = { kind: "ready" as const }; switch (status.kind) { } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`. This comparison is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "hello" as const }; message.value[0] === "h"; ``` </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Client/pulls/3

Summary
Ports
prefer-hooks-in-orderfrom jest/vitest eslint plugins.Generated with sonnet 4.6/gpt 5.4
You might notice some duplicated code between this PR and the previous PR in the stack. This will be resolved in the next PR in the stack #9395
Test Plan
snapshots
Docs