Skip to content

feat(rstest): add valid-expect-with-promise rule - #2151

Merged
fansenze merged 5 commits into
mainfrom
feat/rstest-valid-expect-with-promise
Sep 16, 2026
Merged

fansenze merged 5 commits into
mainfrom
feat/rstest-valid-expect-with-promise

Conversation

@elecmonkey

@elecmonkey elecmonkey commented Sep 12, 2026

Copy link
Copy Markdown
Member

Motivation

Assertions on Promise values need resolves or rejects to inspect the settled value rather than the Promise object itself. Conversely, applying either modifier to a non-promise subject fails at runtime.

Rstest adds framework-specific cases that require type-aware handling: expect(...).rejects invokes function subjects without arguments, expect.soft and Chai assertion chains share ordinary expect semantics, while expect.poll and expect.element provide separate asynchronous assertion APIs.

Related #935

Changes

Add the type-aware rstest/valid-expect-with-promise rule and register it outside the recommended preset.

The rule recognizes Rstest globals, named and renamed imports, namespace and CommonJS forms, rstack/test, import.meta.rstest, Playwright, and Test Context expect calls. It checks ordinary expect and expect.soft assertions, including promise modifiers between Chai assertions, and excludes expect.poll and expect.element.

TypeScript expressions that preserve their runtime value—as, angle-bracket assertions, satisfies, non-null assertions, and parentheses—are handled consistently across member extraction, call-chain traversal, root resolution, and import.meta.rstest recognition. This behavior remains opt-in so existing parser consumers retain their established wrapper boundaries.

Chai subject transformations such as property, ownProperty, and haveOwnProperty are tracked in source order. The rule checks the subject used by each subsequent matcher or promise modifier while conservatively stopping when a transformed subject cannot be determined.

Native Promise instances and subclasses are recognized through the shared default-library symbol helper, while Promise constructors remain non-promise subjects. With checkThenables: true, custom thenables must expose a then method whose fulfillment and rejection parameters are both callable.

For callable subjects passed to .rejects, the rule uses TypeScript call resolution to inspect the return type selected by a zero-argument call, matching Rstest runtime behavior across overloaded and generic functions.

Add the complete eslint-plugin-jest@29.16.0 test suite, Rstest-specific and tsgo edge cases, source-only and compiler-backed capability proofs, JavaScript integration coverage, runtime probes, differential checks, and user documentation.

Credits

Adapted from eslint-plugin-jest@29.16.0's valid-expect-with-promise rule.

@elecmonkey
elecmonkey marked this pull request as ready for review September 13, 2026 19:01

@fansenze fansenze left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Found three reproducible false negatives. The existing targeted Go tests pass, but regression probes for the examples below each produce zero diagnostics.

Comment thread internal/plugins/rstest/utils/parse_rstest_expect.go Outdated
Comment thread internal/utils/test_framework/member_chain.go Outdated
@elecmonkey
elecmonkey marked this pull request as draft September 16, 2026 04:33
@elecmonkey
elecmonkey marked this pull request as ready for review September 16, 2026 12:15
@elecmonkey
elecmonkey force-pushed the feat/rstest-valid-expect-with-promise branch from 3189081 to d0b9895 Compare September 16, 2026 12:20
@fansenze
fansenze enabled auto-merge (squash) September 16, 2026 12:35
@fansenze
fansenze merged commit 91706fa into main Sep 16, 2026
26 of 28 checks passed
@fansenze
fansenze deleted the feat/rstest-valid-expect-with-promise branch September 16, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants