feat(biome_js_analyze): add useExplicitTestAssertions rule#5995
feat(biome_js_analyze): add useExplicitTestAssertions rule#5995drwpow wants to merge 17 commits intobiomejs:mainfrom
Conversation
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
|
|
||
| it('should pass', () => expect(true).toBeDefined()); | ||
|
|
||
| test('should pass', () => expect(true).toBeDefined()); |
There was a problem hiding this comment.
These test cases were pulled from the original expect-expect ESLint rule, so these are all correct. Now to just get them passing
There was a problem hiding this comment.
There’s one test case from the original that may be beyond my abilities to get passing:
it("should pass", myTest);
function myTest() {
expect(true).toBeDefined();
}The current logic just does a shallow scan for expect() at the top level, but doesn’t trace references within the same file. Would love help with this, if it’s trivial. Or we could punt on it for now and just wait till someone reports it.
There was a problem hiding this comment.
I think we can leave it for future oppotunities.
b3ddcb8 to
3c475e8
Compare
CodSpeed Performance ReportMerging #5995 will not alter performanceComparing Summary
Footnotes
|
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
63a602f to
a501c07
Compare
|
OK It’s getting closer! Some tests (snapshots) are passing, some are failing. I’ll mark it “Ready for review” when the tests seem to be in a better spot |
a501c07 to
5aa1a0f
Compare
0416cad to
2fff644
Compare
|
|
||
| i Missing assertion in test body. | ||
|
|
||
| > 1 │ it('should fail', () => {}); |
There was a problem hiding this comment.
🙏 Please double-check these to make sure they’re correct! I know it’s mostly correct but needs a better eye
2fff644 to
8db699f
Compare
|
Hooray! It works! 🎉 And it’s blowing up another test :P. This seems like it’s moving in the right direction, but not sure what to do here / how to disable this rule in other contexts |
318c4e5 to
ede0e33
Compare
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
Outdated
Show resolved
Hide resolved
|
|
||
| it('should pass', () => expect(true).toBeDefined()); | ||
|
|
||
| test('should pass', () => expect(true).toBeDefined()); |
There was a problem hiding this comment.
I think we can leave it for future oppotunities.
|
For currently failing tests, I think we can just update and accept the snapshots. As this PR introduces a new rule for tests, it also should be enabled in the test domain. |
f6e21e5 to
bc9341a
Compare
b21c318 to
0dcabcf
Compare
🦋 Changeset detectedLatest commit: 07bae43 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 |
WalkthroughAdds a new nursery lint rule, Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
crates/biome_js_analyze/tests/specs/nursery/useExplicitTestAssertions/valid.js (1)
7-8: Tiny nit: swap the self-calling array for a noop arrow
['x']()will explode if someone ever runs this JS. A benign self-invoking arrow keeps the intention (“arbitrary call”) without the potential runtime TypeError.-['x'](); +(() => {})();crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs (2)
43-43: Consider expanding the assertion function list.The current list covers common cases, but you might want to add more assertion functions like
chai.expect,should, ort.is(for AVA). However, keeping it minimal initially is sensible.
171-190: Complex else-if handling could be simplified.The nested else-if logic is quite complex and hard to follow. Consider extracting this into a separate function for better readability.
+fn handle_else_clause(else_clause: &JsElseClause) -> bool { + if let Ok(else_alternate) = else_clause.alternate() { + match else_alternate { + AnyJsStatement::JsBlockStatement(else_block) => { + statements_contain_expect(&else_block.statements()) + } + AnyJsStatement::JsIfStatement(else_if_statement) => { + // Handle else-if recursively + statements_contain_expect(&[else_if_statement.into()]) + } + _ => false, + } + } else { + false + } +}
| AnyJsExpression::JsConditionalExpression(conditional_expression) => { | ||
| if let Ok(left) = conditional_expression.test() { | ||
| return expression_contains_expect(&left); | ||
| } | ||
| if let Ok(right) = conditional_expression.alternate() { | ||
| return expression_contains_expect(&right); | ||
| } | ||
| false |
There was a problem hiding this comment.
Incomplete conditional expression handling.
You're only checking the test and alternate branches of conditional expressions, but missing the consequent branch. This could miss assertions in ternary operations.
AnyJsExpression::JsConditionalExpression(conditional_expression) => {
- if let Ok(left) = conditional_expression.test() {
- return expression_contains_expect(&left);
- }
- if let Ok(right) = conditional_expression.alternate() {
- return expression_contains_expect(&right);
- }
+ if let Ok(test) = conditional_expression.test() {
+ if expression_contains_expect(&test) {
+ return true;
+ }
+ }
+ if let Ok(consequent) = conditional_expression.consequent() {
+ if expression_contains_expect(&consequent) {
+ return true;
+ }
+ }
+ if let Ok(alternate) = conditional_expression.alternate() {
+ if expression_contains_expect(&alternate) {
+ return true;
+ }
+ }
falseCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
around lines 137 to 144, the code handles conditional expressions by checking
only the test and alternate branches but omits the consequent branch. To fix
this, add a check for the consequent branch of the conditional expression by
retrieving it and passing it to expression_contains_expect, ensuring all parts
of the ternary operation are covered.
| "useExplicitTestAssertions": { | ||
| "description": "Require each test function (test(), it()) to have an assertion (expect(), assert(), etc.).", | ||
| "anyOf": [ | ||
| { "$ref": "#/definitions/RuleConfiguration" }, | ||
| { "type": "null" } | ||
| ] |
There was a problem hiding this comment.
Do not patch the generated schema directly
This JSON schema is auto-generated; manual tweaks here will be overwritten on the next code-gen run and risk desynchronising the rule name or docs. Please add useExplicitTestAssertions in the generator source (look under crates/biome_configuration compile step) and re-generate the schema instead.
🤖 Prompt for AI Agents
In packages/@biomejs/biome/configuration_schema.json around lines 5049 to 5054,
do not manually edit the generated JSON schema as changes will be overwritten.
Instead, locate the source definition for useExplicitTestAssertions in the
generator source code under crates/biome_configuration, add or update the rule
there, and then re-run the schema generation process to apply the change
correctly.
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/nursery/useExplicitTestAssertions/invalid.js.snapis excluded by!**/*.snap
📒 Files selected for processing (2)
crates/biome_configuration/src/analyzer/linter/rules.rs(13 hunks)crates/biome_js_analyze/src/lint/nursery.rs(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just formatFormat Rust and TOML files using
just f(alias forjust format).
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
**/*.rs
📄 CodeRabbit Inference Engine (CONTRIBUTING.md)
Update documentation for new features or changes, using inline rustdoc for rules, assists, and their options.
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: You are encouraged to split the work for a new rule into multiple PRs and describe your plan in an issue if unfamiliar with Biome's APIs.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Test rules using quick tests in the appropriate test file (e.g., `biome_js_analyze/tests/quick_test.rs`) and snapshot tests in `tests/specs/`.
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Create new lint rules using `just new-js-lintrule`, `just new-css-lintrule`, `just new-json-lintrule`, or `just new-graphql-lintrule`, and the rule name must be camelCase
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Document and test the effect of rule options as part of the rule's documentation and test suite.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*.rs : If a rule overwhelmingly applies to a specific framework, it should be named using the `use<Framework>...` or `no<Framework>...` pattern (e.g., `noVueReservedProps`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : New rules must be placed inside the `nursery` group for incubation before promotion.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `declare_lint_rule!` macro must be used to declare an analyzer rule type and implement the RuleMeta trait.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `version` field in `declare_lint_rule!` must be set to `next` for new rules.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When deprecating a rule, specify the reason using the `deprecated:` field in the `declare_lint_rule!` macro.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Assign the `domains` field in `declare_lint_rule!` if the rule belongs to a specific domain (e.g., testing, framework).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule documentation must start with a single-line summary, followed by detailed paragraphs, and include `## Examples` with `### Invalid` and `### Valid` sections.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a rule provides a code action, add the `fix_kind` metadata to the `declare_lint_rule!` macro and implement the `action` function.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When banning certain functions or variables, always check if the variable is global using the semantic model to avoid false positives.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_consistent*_*.rs : Rules that ensure consistency should use the `useConsistent<Concept>` naming convention (e.g., `useConsistentArrayType`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use*_*.rs : Rules that mandate a single concept should be named using the `use<Concept>` prefix (e.g., `useValidLang` for mandating valid HTML `lang` attribute values).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_shorthand*_*.rs : Rules that promote shorthand syntax should use the `useShorthand<Concept>` naming convention (e.g., `useShorthandAssign`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_redundant*_*.rs : Rules that report redundant code should use the `noRedundant<Concept>` naming convention (e.g., `noRedundantUseStrict`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*.rs : If a rule overwhelmingly applies to a specific framework, it should be named using the `use<Framework>...` or `no<Framework>...` pattern (e.g., `noVueReservedProps`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no*_*.rs : Rules that forbid a single concept should be named using the `no<Concept>` prefix (e.g., `noDebugger` for disallowing `debugger` statements).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Avoid deep indentation by using combinators like `map`, `filter`, and `and_then` instead of nested `if let` or `match` statements.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule options must be documented in the `## Options` section of the rule's documentation, with each option having its own header and example.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `rule_category!` macro should be used in diagnostics to statically inject the category at compile time.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_excessive*_*.rs : Rules that report code exceeding certain limits should use the `noExcessive<Concept>` naming convention (e.g., `noExcessiveNestedTestSuites`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_useless*_*.rs : Rules that report unnecessary code should use the `noUseless<Concept>` naming convention (e.g., `noUselessConstructor`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{no_invalid*,use_valid*}_*.rs : Rules that report invalid code should use the `noInvalid<Concept>` or `useValid<Concept>` naming conventions (e.g., `noInvalidConstructorSuper`, `useValidTypeof`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_misleading*_*.rs : Rules that report misleading code should use the `noMisleading<Concept>` naming convention (e.g., `noMisleadingCharacterClass`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unknown*_*.rs : Rules that report unknown entities (e.g., CSS units) should use the `noUnknown<Concept>` naming convention (e.g., `noUnknownUnit`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_restricted*_*.rs : Rules that report restricted entities should use the `noRestricted<Concept>` naming convention (e.g., `noRestrictedGlobals`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T13:25:32.395Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Move rules from nursery to stable group using `just move-rule stable ruleName`
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : For rules that emit multiple diagnostics or actions, use an iterable type (e.g., `Box<[_]>`) for the `Signals` associated type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When a rule needs to query multiple node types, use the `declare_node_union!` macro to define a union type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When implementing the `run` function for a rule, prefer transforming `Result` into `Option` and using the `?` operator for concise code.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:49:35.574Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Use Rust's `dbg!()` macro for debugging and pass `--show-output` to `cargo` to display debug output during tests.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
🔇 Additional comments (12)
crates/biome_js_analyze/src/lint/nursery.rs (2)
44-44: Module added and named correctly.Good call on
use_explicit_test_assertions; matches Biome’suse<Concept>convention and belongs in nursery.
65-65: Rule wired into Nursery group — looks good.The rule is present in the group. Nice and tidy.
crates/biome_configuration/src/analyzer/linter/rules.rs (10)
360-360: New rule is correctly registered (enum, name strings, and parsing).Variant, as_str, and FromStr entries for useExplicitTestAssertions look consistent with naming conventions.
Also applies to: 715-716, 1426-1426
1066-1066: Group mapping is correct.useExplicitTestAssertions belongs to the Nursery group. All good.
4313-4313: Nursery option wire-up for useExplicitTestAssertions is sound.Field, serde casing, and options type are correct. Docstring reads well.
4358-4361: Alphabetical placement in GROUP_RULES is correct."useExplicitTestAssertions" sits between useExhaustiveSwitchCases and useExplicitType as expected.
4459-4460: ALL_RULES_AS_FILTERS updated for new tail index.Good catch adding index 63 after extending the group rules.
4676-4684: Enabled rules wiring for useExplicitTestAssertions looks right.Index 41 matches its position in GROUP_RULES; logic mirrors surrounding entries.
5000-5008: Disabled rules wiring for useExplicitTestAssertions is consistent.Matches the enabled branch index usage; no issues.
5309-5313: Configuration retrieval arm added correctly.Key matches "useExplicitTestAssertions"; returns (level, options) as expected.
5450-5454: From initialiser includes the new rule.Keeps defaulting behaviour consistent with other Nursery rules.
4391-4394: Indices sanity-checked and correctThe
Nursery::GROUP_RULESentries at the specified offsets match the intended rules:
- Index 47 →
useIndexOf- Index 48 →
useIterableCallbackReturn- Index 51 →
useNamedOperation- Index 55 →
useParseIntRadixNo changes required.
| Self::UseNamingConvention => RuleGroup::Style, | ||
| Self::UseNodeAssertStrict => RuleGroup::Style, |
There was a problem hiding this comment.
useNamingConvention is duplicated across Nursery and Style; please remove it from Nursery.
RuleName::group maps UseNamingConvention to Style, but Nursery still declares and wires it (field, GROUP_RULES, enabled/disabled/config arms). This causes conflicting configuration and filters for the same rule name.
As this file is generated, please update the codegen to:
- Drop useNamingConvention from Nursery::GROUP_RULES, struct fields, get_enabled_rules/get_disabled_rules/get_rule_configuration, From, and related filters.
- Keep it only in Style (as currently mapped in RuleName::group).
This will avoid ambiguous configuration and rule lookups.
Also applies to: 4358-4371, 4676-4684, 4729-4735, 5000-5008, 5053-5059, 5309-5313, 5450-5462
🤖 Prompt for AI Agents
In crates/biome_configuration/src/analyzer/linter/rules.rs around lines 1103 to
1104 and also in the specified ranges (4358-4371, 4676-4684, 4729-4735,
5000-5008, 5053-5059, 5309-5313, 5450-5462), remove all references to
useNamingConvention from the Nursery group including struct fields, GROUP_RULES,
get_enabled_rules, get_disabled_rules, get_rule_configuration,
From<GroupPlainConfiguration>, and any related filters. Ensure
useNamingConvention remains only in the Style group as mapped in RuleName::group
to prevent conflicting configurations and ambiguous rule lookups. Update the
code generation logic accordingly to reflect this change.
| pub mod use_unified_type_signature; | ||
| pub mod use_unique_element_ids; | ||
| declare_lint_group! { pub Nursery { name : "nursery" , rules : [self :: no_await_in_loop :: NoAwaitInLoop , self :: no_bitwise_operators :: NoBitwiseOperators , self :: no_constant_binary_expression :: NoConstantBinaryExpression , self :: no_destructured_props :: NoDestructuredProps , self :: no_excessive_lines_per_function :: NoExcessiveLinesPerFunction , self :: no_floating_promises :: NoFloatingPromises , self :: no_global_dirname_filename :: NoGlobalDirnameFilename , self :: no_implicit_coercion :: NoImplicitCoercion , self :: no_import_cycles :: NoImportCycles , self :: no_magic_numbers :: NoMagicNumbers , self :: no_misused_promises :: NoMisusedPromises , self :: no_nested_component_definitions :: NoNestedComponentDefinitions , self :: no_next_async_client_component :: NoNextAsyncClientComponent , self :: no_non_null_asserted_optional_chain :: NoNonNullAssertedOptionalChain , self :: no_noninteractive_element_interactions :: NoNoninteractiveElementInteractions , self :: no_process_global :: NoProcessGlobal , self :: no_qwik_use_visible_task :: NoQwikUseVisibleTask , self :: no_react_prop_assign :: NoReactPropAssign , self :: no_restricted_elements :: NoRestrictedElements , self :: no_secrets :: NoSecrets , self :: no_shadow :: NoShadow , self :: no_ts_ignore :: NoTsIgnore , self :: no_unassigned_variables :: NoUnassignedVariables , self :: no_unnecessary_conditions :: NoUnnecessaryConditions , self :: no_unresolved_imports :: NoUnresolvedImports , self :: no_unwanted_polyfillio :: NoUnwantedPolyfillio , self :: no_useless_backref_in_regex :: NoUselessBackrefInRegex , self :: no_useless_escape_in_string :: NoUselessEscapeInString , self :: no_useless_undefined :: NoUselessUndefined , self :: no_vue_data_object_declaration :: NoVueDataObjectDeclaration , self :: no_vue_reserved_keys :: NoVueReservedKeys , self :: no_vue_reserved_props :: NoVueReservedProps , self :: use_adjacent_getter_setter :: UseAdjacentGetterSetter , self :: use_anchor_href :: UseAnchorHref , self :: use_consistent_object_definition :: UseConsistentObjectDefinition , self :: use_consistent_response :: UseConsistentResponse , self :: use_consistent_type_definitions :: UseConsistentTypeDefinitions , self :: use_exhaustive_switch_cases :: UseExhaustiveSwitchCases , self :: use_explicit_type :: UseExplicitType , self :: use_exports_last :: UseExportsLast , self :: use_for_component :: UseForComponent , self :: use_google_font_preconnect :: UseGoogleFontPreconnect , self :: use_image_size :: UseImageSize , self :: use_index_of :: UseIndexOf , self :: use_iterable_callback_return :: UseIterableCallbackReturn , self :: use_json_import_attribute :: UseJsonImportAttribute , self :: use_max_params :: UseMaxParams , self :: use_numeric_separators :: UseNumericSeparators , self :: use_object_spread :: UseObjectSpread , self :: use_parse_int_radix :: UseParseIntRadix , self :: use_qwik_classlist :: UseQwikClasslist , self :: use_react_function_components :: UseReactFunctionComponents , self :: use_readonly_class_properties :: UseReadonlyClassProperties , self :: use_single_js_doc_asterisk :: UseSingleJsDocAsterisk , self :: use_sorted_classes :: UseSortedClasses , self :: use_symbol_description :: UseSymbolDescription , self :: use_unified_type_signature :: UseUnifiedTypeSignature , self :: use_unique_element_ids :: UseUniqueElementIds ,] } } | ||
| declare_lint_group! { pub Nursery { name : "nursery" , rules : [self :: no_await_in_loop :: NoAwaitInLoop , self :: no_bitwise_operators :: NoBitwiseOperators , self :: no_constant_binary_expression :: NoConstantBinaryExpression , self :: no_destructured_props :: NoDestructuredProps , self :: no_excessive_lines_per_function :: NoExcessiveLinesPerFunction , self :: no_floating_promises :: NoFloatingPromises , self :: no_global_dirname_filename :: NoGlobalDirnameFilename , self :: no_implicit_coercion :: NoImplicitCoercion , self :: no_import_cycles :: NoImportCycles , self :: no_magic_numbers :: NoMagicNumbers , self :: no_misused_promises :: NoMisusedPromises , self :: no_nested_component_definitions :: NoNestedComponentDefinitions , self :: no_next_async_client_component :: NoNextAsyncClientComponent , self :: no_non_null_asserted_optional_chain :: NoNonNullAssertedOptionalChain , self :: no_noninteractive_element_interactions :: NoNoninteractiveElementInteractions , self :: no_process_global :: NoProcessGlobal , self :: no_qwik_use_visible_task :: NoQwikUseVisibleTask , self :: no_react_prop_assign :: NoReactPropAssign , self :: no_restricted_elements :: NoRestrictedElements , self :: no_secrets :: NoSecrets , self :: no_shadow :: NoShadow , self :: no_ts_ignore :: NoTsIgnore , self :: no_unassigned_variables :: NoUnassignedVariables , self :: no_unnecessary_conditions :: NoUnnecessaryConditions , self :: no_unresolved_imports :: NoUnresolvedImports , self :: no_unwanted_polyfillio :: NoUnwantedPolyfillio , self :: no_useless_backref_in_regex :: NoUselessBackrefInRegex , self :: no_useless_escape_in_string :: NoUselessEscapeInString , self :: no_useless_undefined :: NoUselessUndefined , self :: no_vue_data_object_declaration :: NoVueDataObjectDeclaration , self :: no_vue_reserved_keys :: NoVueReservedKeys , self :: no_vue_reserved_props :: NoVueReservedProps , self :: use_adjacent_getter_setter :: UseAdjacentGetterSetter , self :: use_anchor_href :: UseAnchorHref , self :: use_consistent_object_definition :: UseConsistentObjectDefinition , self :: use_consistent_response :: UseConsistentResponse , self :: use_consistent_type_definitions :: UseConsistentTypeDefinitions , self :: use_exhaustive_switch_cases :: UseExhaustiveSwitchCases , self :: use_explicit_test_assertions :: UseExplicitTestAssertions , self :: use_explicit_type :: UseExplicitType , self :: use_exports_last :: UseExportsLast , self :: use_for_component :: UseForComponent , self :: use_google_font_preconnect :: UseGoogleFontPreconnect , self :: use_image_size :: UseImageSize , self :: use_index_of :: UseIndexOf , self :: use_iterable_callback_return :: UseIterableCallbackReturn , self :: use_json_import_attribute :: UseJsonImportAttribute , self :: use_max_params :: UseMaxParams , self :: use_numeric_separators :: UseNumericSeparators , self :: use_object_spread :: UseObjectSpread , self :: use_parse_int_radix :: UseParseIntRadix , self :: use_qwik_classlist :: UseQwikClasslist , self :: use_react_function_components :: UseReactFunctionComponents , self :: use_readonly_class_properties :: UseReadonlyClassProperties , self :: use_single_js_doc_asterisk :: UseSingleJsDocAsterisk , self :: use_sorted_classes :: UseSortedClasses , self :: use_symbol_description :: UseSymbolDescription , self :: use_unified_type_signature :: UseUnifiedTypeSignature , self :: use_unique_element_ids :: UseUniqueElementIds ,] } } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Sanity-check rule metadata, registration, and tests across the repo.
Please verify the new rule has:
- version set to "next"
- language set for JS/TS variants (js, jsx, ts, tsx as applicable)
- domains includes "testing"
- sources attribute referencing eslint-plugin-jest/expect-expect and @vitest/eslint-plugin/expect-expect
- registration in diagnostics categories, configuration schema, CLI migrate mapping, and docs with Valid/Invalid examples
- quick and snapshot tests for edge-cases (loops, conditionals, callback indirections noted in the PR)
Run this to confirm:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Locate rule file =="
fd -a -t f 'use_explicit_test_assertions.rs' || true
echo "== Check rule macro and meta =="
rg -n -S 'declare_lint_rule!\s*\{\s*pub\s+UseExplicitTestAssertions' -U || true
rg -n -S 'name\s*:\s*"useExplicitTestAssertions"' || true
rg -n -S 'version\s*:\s*"next"' || true
rg -n -Si 'domains\s*:\s*\[.*testing.*\]' || true
rg -n -Si 'language\s*:' || true
rg -n -Si 'sources\s*:' || true
rg -n -Si 'jest/expect-expect|@vitest/.*/expect-expect' || true
echo "== Check categories and config schema =="
rg -n -S 'UseExplicitTestAssertions|useExplicitTestAssertions' crates/biome_diagnostics_categories || true
rg -n -S 'useExplicitTestAssertions' packages/@biomejs/biome/configuration_schema.json || true
echo "== Check CLI migrate mapping =="
rg -n -S 'jest/expect-expect' crates/biome_cli/src/execute/migrate || true
echo "== Check tests exist =="
rg -n -S 'useExplicitTestAssertions' crates/biome_js_analyze/tests || true
fd -a 'useExplicitTestAssertions' crates/biome_js_analyze/tests/specs || trueLength of output: 128230
Add missing domains, Vitest source, and quick tests for useExplicitTestAssertions
- In
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs, update thedeclare_lint_rule!metadata to includedomains: ["testing"]- both sources:
sources: &[ RuleSource::EslintJest("expect-expect").inspired(), RuleSource::EslintVitest("expect-expect").same(), ],
- In
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs, add a branch for"@vitest/eslint-plugin/expect-expect"alongside the existing Jest mapping. - Add a quick‐test in
crates/biome_js_analyze/tests/quick_test.rsthat covers loops, conditionals and callback indirections for invalid cases.
🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/lint/nursery.rs at line 65, update the
useExplicitTestAssertions lint rule metadata to include the missing domains and
sources by adding domains: ["testing"] and sources with both
RuleSource::EslintJest("expect-expect").inspired() and
RuleSource::EslintVitest("expect-expect").same(). Then, in
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs, add a new
branch to handle the "@vitest/eslint-plugin/expect-expect" rule alongside the
existing Jest mapping. Finally, add a quick test in
crates/biome_js_analyze/tests/quick_test.rs that covers invalid cases involving
loops, conditionals, and callback indirections for the useExplicitTestAssertions
rule.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
crates/biome_configuration/src/analyzer/linter/rules.rs (1)
4313-4313: Follow-ups outside this file: set rule domain and sources metadataSince this is a testing-specific rule, ensure declare_lint_rule! sets domains to include testing and adds sources pointing to eslint-plugin-jest/expect-expect and @vitest/eslint-plugin/expect-expect in the rule file. Shout if you want a patch.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/nursery/useExplicitTestAssertions/invalid.js.snapis excluded by!**/*.snap
📒 Files selected for processing (2)
crates/biome_configuration/src/analyzer/linter/rules.rs(13 hunks)crates/biome_js_analyze/src/lint/nursery.rs(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just formatFormat Rust and TOML files using
just f(alias forjust format).
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
**/*.rs
📄 CodeRabbit Inference Engine (CONTRIBUTING.md)
Update documentation for new features or changes, using inline rustdoc for rules, assists, and their options.
Files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: You are encouraged to split the work for a new rule into multiple PRs and describe your plan in an issue if unfamiliar with Biome's APIs.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Test rules using quick tests in the appropriate test file (e.g., `biome_js_analyze/tests/quick_test.rs`) and snapshot tests in `tests/specs/`.
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Create new lint rules using `just new-js-lintrule`, `just new-css-lintrule`, `just new-json-lintrule`, or `just new-graphql-lintrule`, and the rule name must be camelCase
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Document and test the effect of rule options as part of the rule's documentation and test suite.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*.rs : If a rule overwhelmingly applies to a specific framework, it should be named using the `use<Framework>...` or `no<Framework>...` pattern (e.g., `noVueReservedProps`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : New rules must be placed inside the `nursery` group for incubation before promotion.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `declare_lint_rule!` macro must be used to declare an analyzer rule type and implement the RuleMeta trait.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `version` field in `declare_lint_rule!` must be set to `next` for new rules.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When deprecating a rule, specify the reason using the `deprecated:` field in the `declare_lint_rule!` macro.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Assign the `domains` field in `declare_lint_rule!` if the rule belongs to a specific domain (e.g., testing, framework).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule documentation must start with a single-line summary, followed by detailed paragraphs, and include `## Examples` with `### Invalid` and `### Valid` sections.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When banning certain functions or variables, always check if the variable is global using the semantic model to avoid false positives.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a rule provides a code action, add the `fix_kind` metadata to the `declare_lint_rule!` macro and implement the `action` function.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_consistent*_*.rs : Rules that ensure consistency should use the `useConsistent<Concept>` naming convention (e.g., `useConsistentArrayType`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use*_*.rs : Rules that mandate a single concept should be named using the `use<Concept>` prefix (e.g., `useValidLang` for mandating valid HTML `lang` attribute values).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_shorthand*_*.rs : Rules that promote shorthand syntax should use the `useShorthand<Concept>` naming convention (e.g., `useShorthandAssign`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_redundant*_*.rs : Rules that report redundant code should use the `noRedundant<Concept>` naming convention (e.g., `noRedundantUseStrict`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*.rs : If a rule overwhelmingly applies to a specific framework, it should be named using the `use<Framework>...` or `no<Framework>...` pattern (e.g., `noVueReservedProps`).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no*_*.rs : Rules that forbid a single concept should be named using the `no<Concept>` prefix (e.g., `noDebugger` for disallowing `debugger` statements).
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rscrates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Avoid deep indentation by using combinators like `map`, `filter`, and `and_then` instead of nested `if let` or `match` statements.
Applied to files:
crates/biome_js_analyze/src/lint/nursery.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule options must be documented in the `## Options` section of the rule's documentation, with each option having its own header and example.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Set the `severity` field in `declare_lint_rule!` to `Severity::Warning` or `Severity::Error` as appropriate for the rule.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `rule_category!` macro should be used in diagnostics to statically inject the category at compile time.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_excessive*_*.rs : Rules that report code exceeding certain limits should use the `noExcessive<Concept>` naming convention (e.g., `noExcessiveNestedTestSuites`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_useless*_*.rs : Rules that report unnecessary code should use the `noUseless<Concept>` naming convention (e.g., `noUselessConstructor`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{no_invalid*,use_valid*}_*.rs : Rules that report invalid code should use the `noInvalid<Concept>` or `useValid<Concept>` naming conventions (e.g., `noInvalidConstructorSuper`, `useValidTypeof`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_misleading*_*.rs : Rules that report misleading code should use the `noMisleading<Concept>` naming convention (e.g., `noMisleadingCharacterClass`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unknown*_*.rs : Rules that report unknown entities (e.g., CSS units) should use the `noUnknown<Concept>` naming convention (e.g., `noUnknownUnit`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_restricted*_*.rs : Rules that report restricted entities should use the `noRestricted<Concept>` naming convention (e.g., `noRestrictedGlobals`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T13:25:32.395Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Move rules from nursery to stable group using `just move-rule stable ruleName`
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : For rules that emit multiple diagnostics or actions, use an iterable type (e.g., `Box<[_]>`) for the `Signals` associated type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When a rule needs to query multiple node types, use the `declare_node_union!` macro to define a union type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:50:18.454Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When implementing the `run` function for a rule, prefer transforming `Result` into `Option` and using the `?` operator for concise code.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: 2025-08-05T14:49:35.574Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Use Rust's `dbg!()` macro for debugging and pass `--show-output` to `cargo` to display debug output during tests.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (12)
crates/biome_js_analyze/src/lint/nursery.rs (2)
44-44: Module registered for the new rule — looks right.Name and placement are consistent with existing rules. Good to see it landing in Nursery first.
65-65: Nursery rule wiring and metadata are all good—no action needed
- declare_lint_rule! in use_explicit_test_assertions.rs includes version: "next", language: "js", domains: [Test], sources: RuleSource::EslintJest("expect-expect").inspired().
- Rule name is camelCase (
useExplicitTestAssertions) everywhere: tests/specs, configuration_schema.json, workspace.ts, diagnostics categories, migration mapping.- Tests live under crates/biome_js_analyze/tests/specs/nursery/useExplicitTestAssertions.
- Config/schema and CLI migration for “jest/expect-expect” → useExplicitTestAssertions are wired.
- Ordering in declare_lint_group! is already correct (snake_case alphabetical: exhaustive before explicit).
crates/biome_configuration/src/analyzer/linter/rules.rs (10)
360-361: Rule name wiring is complete and consistentEnum variant, as_str, group mapping, and FromStr entry for UseExplicitTestAssertions are all correctly added and in sync with "useExplicitTestAssertions".
Also applies to: 715-716, 1066-1067, 1426-1427
4313-4313: Nursery config surface added correctlyField use_explicit_test_assertions with RuleConfiguration and a clear doc comment looks good. CamelCase serialisation will expose "useExplicitTestAssertions" as expected.
4358-4359: Included in Nursery::GROUP_RULES in the right spotPlaced after useExhaustiveSwitchCases and before useExplicitType, preserving alphabetical order enforced by test_order.
4391-4394: Recommended indices updated appropriatelyIndex shifts in RECOMMENDED_RULES_AS_FILTERS line up with the new insertion; nothing sneaky here.
4460-4460: ALL_RULES_AS_FILTERS coverage intactArray tail updated to include the last entry (index 63). Looks tidy.
4676-4680: Enabled rules getter covers the new ruleget_enabled_rules now emits the correct filter at index 41 when enabled. Matches GROUP_RULES.
5000-5004: Disabled rules getter covers the new ruleget_disabled_rules mirrors the enabled path for index 41. All good.
5309-5313: Config lookup addedget_rule_configuration match arm for "useExplicitTestAssertions" is present and consistent with other entries.
5450-5451: Group default initialisation wiredFrom initialises use_explicit_test_assertions like its peers. No nits.
4313-4313: Sanity-check rule registrationI ran the grep/fd checks and didn’t spot any references to
use_explicit_test_assertions. Please confirm that the rule is wired up everywhere:
- Declared in the enums/mappings config
- Implementation file present in the
biome_analyzecrate- Registered in the JS analyse nursery group (
crates/biome_js_analyze)- Mapped in the CLI migrations (for ESLint’s
jest/expect-expect)- Included in diagnostics categories (
biome_diagnostics_categories)- Exposed in the configuration schema (packages folder)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
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_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**
📒 Files selected for processing (1)
.changeset/tasty-moose-mix.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/*.md: In changesets, only use #### or ##### headers; other header levels are not allowed
Changesets should cover user-facing changes only; internal changes do not need changesets
Use past tense for what you did and present tense for current Biome behavior in changesets
When fixing a bug in a changeset, start with an issue link (e.g., “Fixed #1234: …”)
When referencing a rule or assist in a changeset, include a link to its page on the website
Include code blocks in changesets when applicable to illustrate changes
End every sentence in a changeset with a period
Files:
.changeset/tasty-moose-mix.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Check JS Files
- GitHub Check: autofix
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_analyze)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**
📒 Files selected for processing (2)
.changeset/tasty-moose-mix.md(1 hunks)crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Format Rust files before committing (e.g., viajust fwhich formats Rust)
Document rules, assists, and options with inline rustdoc in source
Files:
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
.changeset/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/*.md: In changesets, only use #### or ##### headers; other header levels are not allowed
Changesets should cover user-facing changes only; internal changes do not need changesets
Use past tense for what you did and present tense for current Biome behavior in changesets
When fixing a bug in a changeset, start with an issue link (e.g., “Fixed #1234: …”)
When referencing a rule or assist in a changeset, include a link to its page on the website
Include code blocks in changesets when applicable to illustrate changes
End every sentence in a changeset with a period
Files:
.changeset/tasty-moose-mix.md
🧠 Learnings (2)
📚 Learning: 2025-10-15T09:22:45.991Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:45.991Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes
Applied to files:
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
📚 Learning: 2025-10-15T09:20:19.126Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:20:19.126Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : For options types, derive Serialize, Deserialize, Deserializable (and JsonSchema under the schema feature) and use #[serde(rename_all="camelCase", deny_unknown_fields, default)] with skip_serializing_if where appropriate
Applied to files:
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs (3)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
RuleDomain(904-912)crates/biome_analyze/src/rule.rs (4)
sources(576-579)inspired(252-257)recommended(561-564)domains(591-594)crates/biome_js_syntax/src/generated/nodes.rs (1)
else_clause(3427-3429)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Check JS Files
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: autofix
🔇 Additional comments (8)
.changeset/tasty-moose-mix.md (1)
1-26: Excellent work on the changeset!The changeset follows all guidelines, incorporates all past feedback, and clearly documents the new rule with proper examples.
crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs (7)
1-7: Imports look good.Proper use of
AstNodeListtrait as discussed in past feedback.
8-41: Rule declaration is well-structured.Metadata, documentation, and examples are clear and follow conventions.
43-43: Note on assertion function names.As discussed in past comments, this set covers the common cases. Additional assertion functions can be added in future iterations based on user feedback.
45-92: Rule implementation logic is sound.The flow correctly identifies test calls, extracts the callback, and checks for assertions.
94-118: Assertion detection handles common patterns.Correctly handles both direct identifier calls and chained member expressions. The explicit returns are fine for clarity.
160-223: Statement traversal logic is thorough.Handles expression statements, conditionals, and various loop types correctly. The use of
any()is appropriate here.
225-231: Clean helper function.Simple and effective for checking block statements.
| AnyJsExpression::JsConditionalExpression(conditional_expression) => { | ||
| if let Ok(left) = conditional_expression.test() { | ||
| return expression_contains_expect(&left); | ||
| } | ||
| if let Ok(right) = conditional_expression.alternate() { | ||
| return expression_contains_expect(&right); | ||
| } | ||
| false | ||
| } |
There was a problem hiding this comment.
Critical: Missing consequent branch in conditional expression.
You're checking the test and alternate branches but omitting the consequent (the middle part of a ternary). This causes the rule to miss assertions like:
test('foo', () => {
const x = condition ? expect(true) : false;
});Apply this diff to check all three branches:
AnyJsExpression::JsConditionalExpression(conditional_expression) => {
- if let Ok(left) = conditional_expression.test() {
- return expression_contains_expect(&left);
+ if let Ok(test) = conditional_expression.test() {
+ if expression_contains_expect(&test) {
+ return true;
+ }
}
- if let Ok(right) = conditional_expression.alternate() {
- return expression_contains_expect(&right);
+ if let Ok(consequent) = conditional_expression.consequent() {
+ if expression_contains_expect(&consequent) {
+ return true;
+ }
+ }
+ if let Ok(alternate) = conditional_expression.alternate() {
+ if expression_contains_expect(&alternate) {
+ return true;
+ }
}
false
}🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/lint/nursery/use_explicit_test_assertions.rs
around lines 141 to 149, the conditional branch handling only checks the test
and alternate of a JsConditionalExpression and omits the consequent (middle)
branch; update the code to also attempt to get and check the consequent (e.g.,
conditional_expression.consequent()) and call expression_contains_expect on it,
returning true if any of test, consequent, or alternate contain an expect, with
the same Ok handling pattern used for the other branches.
Summary
Adds
expect-expectrule as discussed in #5862. Aims to matcheslint-plugin-jest/expect-expectand@vitest/eslint-plugin/expect-expect, but without options to start.Alternatives
noImplicitTestAssertionsif that’s clearer.Test Plan