Motivation
Croft's Test Explorer (src/testing/) runs cargo test, pytest, vitest, and jest with live pass/fail glyphs, gutter run buttons, and debug-test-at-cursor, but it stops where modern test UX starts paying off: there is no coverage view and no watch mode. VS Code shipped a Test Coverage API in 2024 (gutter + explorer percentages) and continuous run ("eye" toggle per test) that reruns tests on save. Both map naturally onto machinery croft already has (git-gutter-style margin marks; tasks in panes; file-save events).
Current state
src/testing/: runner registry from [[test_runners]] manifests (cargo/pytest/vitest/jest), suite tree, run-all/one/filter/suite, failure badge, test-name→location resolution by workspace walk.
- Gutter infrastructure: git added/modified/deleted bars and breakpoint glyphs already share the margin; a coverage layer is a third tenant, not new plumbing.
- File-save events exist (auto-save, format-on-save, history snapshots hook them).
Proposed design
Coverage
- Per-runner coverage commands in the
[[test_runners]] manifest: pytest → --cov --cov-report=json (pytest-cov), vitest → --coverage --coverage.reporter=json (v8), jest → --coverage --coverageReporters=json, cargo → cargo llvm-cov --json when cargo-llvm-cov is installed (offer the existing auto-provision flow, since it's a cargo-installable binary). Each declares its report format; croft parses the two formats involved (istanbul JSON for the JS pair + pytest-cov's JSON, and llvm-cov's JSON) into one internal line/branch model.
- UI. "Run with Coverage" beside the existing run actions (explorer header, per-suite, per-test). Results render as: a percentage column in the Test Explorer per file/suite, editor gutter marks (covered / uncovered / partial-branch, using the same bar style as the git gutter but a distinct hue from the theme), and a status-bar percentage for the active file. "Coverage: Clear" removes the layer. Coverage marks coexist with git marks (split the margin column or stack glyphs; follow whatever the breakpoint/git coexistence rule already is).
- Staleness. Editing a line marks that file's coverage stale (dim the marks) until the next coverage run, so nobody trusts marks that no longer correspond to the code.
Watch mode
- A per-scope continuous toggle (explorer header for all, per-suite, per-test), rendered as the "watching" glyph. Implementation is runner-aware: vitest/jest have native watch modes, but driving them through the explorer means parsing their interactive output; simpler and uniform is croft-driven: on save of any file within the runner's root (debounced, gitignore-aware), rerun the watched scope through the normal run path, reusing the pane. Native watch integration can come later per-runner; croft-driven rerun is the deliverable here.
- Failure focus. In watch mode, a run that newly fails raises the activity-bar badge and (optional setting) a status notice with jump-to-first-failure; a run that goes green clears quietly. Never steal focus.
Acceptance criteria
References
Motivation
Croft's Test Explorer (
src/testing/) runs cargo test, pytest, vitest, and jest with live pass/fail glyphs, gutter run buttons, and debug-test-at-cursor, but it stops where modern test UX starts paying off: there is no coverage view and no watch mode. VS Code shipped a Test Coverage API in 2024 (gutter + explorer percentages) and continuous run ("eye" toggle per test) that reruns tests on save. Both map naturally onto machinery croft already has (git-gutter-style margin marks; tasks in panes; file-save events).Current state
src/testing/: runner registry from[[test_runners]]manifests (cargo/pytest/vitest/jest), suite tree, run-all/one/filter/suite, failure badge, test-name→location resolution by workspace walk.Proposed design
Coverage
[[test_runners]]manifest: pytest →--cov --cov-report=json(pytest-cov), vitest →--coverage --coverage.reporter=json(v8), jest →--coverage --coverageReporters=json, cargo →cargo llvm-cov --jsonwhencargo-llvm-covis installed (offer the existing auto-provision flow, since it's a cargo-installable binary). Each declares its report format; croft parses the two formats involved (istanbul JSON for the JS pair + pytest-cov's JSON, and llvm-cov's JSON) into one internal line/branch model.Watch mode
Acceptance criteria
References
cargo-llvm-cov: https://github.com/taiki-e/cargo-llvm-cov