You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mutation testing, cost visibility, CI, and docs (#40)
* Mutation testing, cost visibility, CI, and docs
- storage_json: tests for refresh_summary, get_event_stats (empty/single/by_repo), prune boundary
- docs/mutation-testing.md: how to run, equivalent mutants, pre-push vs CI, file globs
- CI: mutation job on *storage_json* with timeout and missed-count baseline (15)
- README/CLAUDE: pre-push vs CI mutation note; optional --no-verify
- Analytics: show est. cost (reviews) from useEventStats when available
- web: cost.test.ts for formatCost, estimateCost, totalCost
Made-with: Cursor
* Publish Docker image on merge to main; review job skips when image unavailable
- publish-image.yml: on push to main, build and push ghcr.io/evalops/diffscope:latest and :sha-<sha>
- diffscope.yml: check image available before Run DiffScope; skip gracefully with notice if pull fails (job no longer fails)
Made-with: Cursor
* diffscope review: continue-on-error on Run DiffScope so image pull failure never fails job
Made-with: Cursor
* DiffScope Review: use docker run instead of uses docker:// to avoid pre-pull failing job
GitHub pre-pulls container actions before any steps run; that pull was failing the job.
Run DiffScope via 'docker run' only when image is already available from Check image step.
Made-with: Cursor
* Fix prune boundary test race (Sentry feedback): use prune_at(now) for single timestamp
- Extract prune_at(max_age_secs, max_count, now_secs) so test and production share logic
- prune() calls prune_at(..., SystemTime::now()); test calls prune_at(..., now_ts()) once
Made-with: Cursor
Copy file name to clipboardExpand all lines: CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ cargo run -- --help # CLI usage
22
22
-`examples/` — Usage examples
23
23
24
24
## Development
25
-
- Run `bash scripts/install-hooks.sh` once to install pre-commit and pre-push hooks (merge conflict check, trailing newline, conditional Rust/web checks, shellcheck; pre-push adds version sync, cargo audit, full web build+test).
25
+
- Run `bash scripts/install-hooks.sh` once to install pre-commit and pre-push hooks (merge conflict check, trailing newline, conditional Rust/web checks, shellcheck; pre-push adds version sync, cargo audit, full web build+test). Mutation testing runs in CI only; see `docs/mutation-testing.md`.
26
26
27
27
## Conventions
28
28
- Use frontier models for reviews — never default to smaller models
- When `web/` is staged: `npm run lint`, `tsc -b`, and `npm run test` in `web/`
1018
1018
- When `scripts/` or `.githooks/` change: `shellcheck` (if installed)
1019
1019
1020
-
**Pre-push** runs the full gate: workflow check, version sync (`Cargo.toml` vs git tags), `cargo fmt`, `cargo clippy`, `cargo audit` (if installed), `npm ci && npm run build && npm run test` in `web/`, and `cargo test`. The first push after clone may take longer due to `npm ci`.
1020
+
**Pre-push** runs the full gate: workflow check, version sync (`Cargo.toml` vs git tags), `cargo fmt`, `cargo clippy`, `cargo audit` (if installed), `npm ci && npm run build && npm run test` in `web/`, and `cargo test`. The first push after clone may take longer due to `npm ci`. Mutation testing runs in CI only (see `docs/mutation-testing.md`), not on pre-push, to keep pushes fast. For a quick push without full checks use `git push --no-verify` (use sparingly).
We use [cargo-mutants](https://github.com/sourcefrog/cargo-mutants) to find gaps in test coverage. Mutants are small code changes (e.g. `*` → `/`, `>` → `>=`); if tests still pass, the mutant is "missed" and the behavior is under-tested.
4
+
5
+
## Running
6
+
7
+
```bash
8
+
# All mutants (slow; 6000+)
9
+
cargo mutants
10
+
11
+
# One file / path (faster; glob)
12
+
cargo mutants -f '*storage_json*'
13
+
cargo mutants -f '*state*'
14
+
cargo mutants -f '*storage_pg*'
15
+
cargo mutants -f '*cost*'
16
+
```
17
+
18
+
CI runs mutation on `storage_json` with a timeout; see [CI job](#ci) below.
19
+
20
+
## Known equivalent / accepted mutants
21
+
22
+
These mutants are either equivalent (same behavior) or accepted by design. CI does not fail on them.
23
+
24
+
### cost.rs
25
+
26
+
| Location | Mutation | Reason |
27
+
|----------|----------|--------|
28
+
|~line 43 |`* FALLBACK_PRICE_PER_M` → `/ FALLBACK_PRICE_PER_M`| With `FALLBACK_PRICE_PER_M = 1.0`, `* 1` and `/ 1` are equivalent. No test can distinguish without changing the constant. |
29
+
30
+
### storage_json.rs
31
+
32
+
After adding targeted tests (refresh_summary, get_event_stats exact aggregates/single-event/by_repo, prune boundary), many previously missed mutants are now killed. Any remaining misses in these areas are documented here after a run:
33
+
34
+
-**refresh_summary**: Condition `summary.is_some() \|\| !comments.is_empty()` — tests now assert synthesized summary when comments exist and no summary.
-**prune**: Boundary `now - started_at > max_age_secs` — test asserts review exactly at boundary is not pruned; max_count test asserts oldest removed.
37
+
38
+
If new mutants appear in these regions, add assertions that would fail on the wrong operator/formula, or add them to this table with a one-line rationale.
39
+
40
+
## Pre-push vs CI
41
+
42
+
-**Pre-push** (`.githooks/pre-push`): Runs unit tests, `cargo audit`, web build+test. Does *not* run mutation (too slow for every push).
43
+
-**CI mutation job**: Runs `cargo mutants -f storage_json` (or one crate) on a schedule or on PRs to main. Fails if "missed" count increases beyond the baseline in this doc.
44
+
- For a quick local push without full checks: `git push --no-verify` (use sparingly; CI will still run).
45
+
46
+
## CI
47
+
48
+
The `mutation` job in `.github/workflows/ci.yml` runs mutation on the `storage_json` crate with a timeout. Update the "allowed missed" baseline in the job when you intentionally accept new equivalent mutants (and add them to the table above).
0 commit comments