Skip to content

Comments

feat(linter): merge vitest/prefer-to-be rule into existing jest/prefer-to-be rule implementation#14738

Merged
camc314 merged 15 commits intooxc-project:mainfrom
taearls:linter/vitest/prefer-to-be
Oct 20, 2025
Merged

feat(linter): merge vitest/prefer-to-be rule into existing jest/prefer-to-be rule implementation#14738
camc314 merged 15 commits intooxc-project:mainfrom
taearls:linter/vitest/prefer-to-be

Conversation

@taearls
Copy link
Contributor

@taearls taearls commented Oct 17, 2025

It seems that most of the functionality from vitest's version of the prefer-to-be rule were already present in the Jest implementation, except when comparing floats. I added support for this and a unit test for it.

I updated the diagnostic messaging to be more consistent:

  1. there were some missing start brackets [ when giving help messages for
  2. the snippet from the source code in the help text did not match what was underlined
  3. not was omitted from the help messaging when it was in a computed expression

I added prefer-to-be to the list of VITEST_COMPATIBLE_RULES too.

taearls and others added 7 commits October 17, 2025 14:10
Implements the eslint-plugin-vitest prefer-to-be rule that enforces using
more specific Vitest matchers instead of generic equality matchers.

Transformations:
- toEqual(null) / toBe(null) → toBeNull()
- toEqual(undefined) / toBe(undefined) → toBeUndefined()
- toBe(NaN) / toEqual(NaN) → toBeNaN()
- toEqual("string") → toBe("string") for primitives (excluding floats)

Features:
- Automatic fixes for all violations
- TypeScript type assertion unwrapping
- Computed member expression support (e.g., ["toBe"])
- Float literal detection to avoid precision issues
- Comprehensive test coverage (29 pass, 11 fail cases)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Collapse nested if statements using let-chain pattern matching
as suggested by clippy::collapsible_if.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add float detection to avoid suggesting toBe for floating point comparisons
- Enhance diagnostic messages with detailed help text
- Add test case for float literal handling

This merges enhancements from the vitest version of prefer-to-be into
the jest version for consistency and better user experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Remove the duplicate vitest/prefer-to-be rule since the jest version
now supports all vitest use cases after incorporating improvements from
both implementations. Add prefer-to-be to the list of Jest rules that
are compatible with Vitest.

Changes:
- Remove vitest/prefer-to-be rule implementation and tests
- Add prefer-to-be to VITEST_COMPATIBLE_JEST_RULES list
- Regenerate rule runner implementations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@taearls taearls requested a review from camc314 as a code owner October 17, 2025 20:30
@github-actions github-actions bot added A-linter Area - Linter C-enhancement Category - New feature or request labels Oct 17, 2025
Update diagnostic messages to include the actual text being replaced,
making the help messages more specific and informative. This matches
the format used by other linter rules and provides better user feedback.

Changes:
- Include actual matcher text in help messages (e.g., "Replace `toEqual` with `toBe`")
- Make warning messages more concise
- Update snapshots to reflect new diagnostic format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@codspeed-hq
Copy link

codspeed-hq bot commented Oct 17, 2025

CodSpeed Performance Report

Merging #14738 will not alter performance

Comparing taearls:linter/vitest/prefer-to-be (6513f33) with main (ba6517b)1

Summary

✅ 4 untouched
⏩ 33 skipped2

Footnotes

  1. No successful run was found on main (df48416) during the generation of this report, so ba6517b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 33 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

taearls and others added 3 commits October 17, 2025 15:42
Fix missing opening bracket in diagnostic messages for computed member
expressions. When replacing matchers like ["toBe"](null), we now correctly
include the opening bracket in the source text shown to users.

Example fix:
- Before: help: Replace `"toBe"](null)` with `toBeNull()`
- After: help: Replace `["toBe"](null)` with `toBeNull()`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@taearls taearls marked this pull request as draft October 17, 2025 20:47
taearls and others added 4 commits October 17, 2025 15:52
Improved diagnostic messages in the jest/prefer-to-be rule to match
the syntax style of the source code. When the source uses computed
member expressions (e.g., ["toBe"](null)), the suggestion now also
uses computed syntax (["toBeNull"]()) instead of static member
expressions.

Changes:
- Renamed diagnostic function parameters from x0/x1 to source_text/suggestion for clarity
- Updated all diagnostic functions to accept both source text and suggested replacement
- Modified check_and_fix to determine appropriate suggestion syntax based on is_cmp_mem_expr
- Updated snapshots to reflect the improved suggestions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the prefer-to-be rule to properly handle the "not" modifier in
diagnostic messages for null and NaN cases. The rule now correctly includes
the "not" modifier (whether static `.not` or computed `["not"]`) in help
messages, since these cases keep the modifier while changing the matcher.

Key changes:
- For null/NaN with "not": Keep the "not" in help text (e.g., "Replace `not.toBe(null)` with `not.toBeNull()`")
- For undefined/defined with "not": Remove the "not" in help text (e.g., "Replace `not.toBe(undefined)` with `toBeDefined()`")
- Added detection for computed member expression "not" (`["not"]`)
- Properly construct suggestions based on both matcher and modifier syntax styles

Examples of improved messages:
- `.not.toBe(null)` → Replace `not.toBe(null)` with `not.toBeNull()`
- `.not["toBe"](null)` → Replace `not["toBe"](null)` with `not["toBeNull"]()`
- `["not"]["toBe"](null)` → Replace `["not"]["toBe"](null)` with `["not"]["toBeNull"]()`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Previously, the diagnostic underlines only covered the matcher (e.g., `toBe`),
while the help text described replacing a larger span (e.g., `not.toBe(null)`).
This caused a mismatch between what was underlined and what was described
in the help message.

Now the underlined span matches the source text shown in the help message,
providing clearer and more accurate diagnostics. For example:
- Help: "Replace `not.toBe(null)` with `not.toBeNull()`"
  Underline: `not.toBe(null)` (not just `toBe`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Consolidate nearly identical logic for Null and NaN cases into a single
helper function `build_suggestion_with_not_modifier`. This eliminates
~70 lines of duplicated code while maintaining identical behavior.

Benefits:
- Single source of truth for "not" modifier + computed member logic
- Easier to maintain and fix bugs
- More concise and readable code

The helper handles all combinations:
- Static/computed "not" modifier
- Static/computed matcher
- With or without "not" modifier

All tests continue to pass with no behavioral changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@taearls taearls marked this pull request as ready for review October 17, 2025 21:50
Copy link
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

@camc314 camc314 merged commit 8b02074 into oxc-project:main Oct 20, 2025
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-enhancement Category - New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants