|
1 | 1 | # Equivalent mutants that cannot be killed by any test. |
2 | 2 | # |
3 | | -# These are mutations where the original and mutated code produce identical |
4 | | -# observable output for ALL valid inputs. Common patterns: |
| 3 | +# Each exclusion targets a SPECIFIC mutation (by file:line:col) that produces |
| 4 | +# identical observable output for ALL valid inputs. Only 19 mutations are |
| 5 | +# excluded — all others are caught by tests or unviable. |
5 | 6 | # |
6 | | -# 1. Max/min tracking: `> → >=` or `< → <=` where the assignment is idempotent |
7 | | -# (setting max_depth = sample.depth when they're equal doesn't change the value). |
8 | | -# |
9 | | -# 2. Guard conditions: `> → >=` on zero-checks where the boundary case (e.g., |
10 | | -# dt_min = 0.0) produces the same result through a different code path |
11 | | -# (e.g., dividing by 0 is guarded, and the else branch also returns 0). |
12 | | -# |
13 | | -# 3. Threshold guards: `> → >=` on epsilon comparisons (like `> 1e-10`) where |
14 | | -# real-world data never produces a value exactly at the threshold. |
15 | | -# |
16 | | -# 4. uniffi-bindgen.rs is generated code outside our control. |
| 7 | +# If production code changes shift line numbers, stale patterns will stop |
| 8 | +# matching and the mutation will surface as MISSED, prompting an update. |
17 | 9 |
|
18 | 10 | exclude_re = [ |
19 | | - # Generated UniFFI build script |
| 11 | + # ── Generated code ─────────────────────────────────────────────────── |
20 | 12 | "uniffi-bindgen\\.rs", |
21 | 13 |
|
22 | | - # metrics.rs: max/min tracking (idempotent assignment) |
23 | | - "replace [<>] with [<>]= in DiveStats::compute$", |
24 | | - "replace [<>] with [<>]= in SegmentStats::compute$", |
| 14 | + # ── metrics.rs: DiveStats::compute — idempotent max/min tracking ───── |
| 15 | + # Setting max/min = value when they're already equal is a no-op. |
| 16 | + "src/metrics\\.rs:141:.*replace > with >= in DiveStats::compute", # max_depth_m |
| 17 | + "src/metrics\\.rs:159:.*replace < with <= in DiveStats::compute", # min_temp_c |
| 18 | + "src/metrics\\.rs:162:.*replace > with >= in DiveStats::compute", # max_temp_c |
| 19 | + "src/metrics\\.rs:179:.*replace > with >= in DiveStats::compute", # max_ceiling_m |
| 20 | + "src/metrics\\.rs:186:.*replace > with >= in DiveStats::compute", # max_gf99 |
| 21 | + # weight_sum > 0.0: weight_sum is always strictly positive when samples exist |
| 22 | + "src/metrics\\.rs:220:.*replace > with >= in DiveStats::compute", |
| 23 | + |
| 24 | + # ── metrics.rs: DiveStats::compute_rates — boundary guards ─────────── |
| 25 | + # dt_min > 0.0 guards: dt_min=0 only when timestamps are duplicated, |
| 26 | + # which never occurs in real dive profiles. Either way, rate=0. |
| 27 | + "src/metrics\\.rs:311:.*replace > with >= in DiveStats::compute_rates", # descent dt_min |
| 28 | + "src/metrics\\.rs:313:.*replace > with >= in DiveStats::compute_rates", # descent dt_min inner |
| 29 | + "src/metrics\\.rs:326:.*replace > with >= in DiveStats::compute_rates", # ascent dt_min |
| 30 | + # last_max_idx < samples.len()-1: boundary and len-1 arithmetic |
| 31 | + "src/metrics\\.rs:323:43:.*replace < with <= in DiveStats::compute_rates", |
| 32 | + "src/metrics\\.rs:323:59:.*replace - with \\+ in DiveStats::compute_rates", |
| 33 | + "src/metrics\\.rs:323:59:.*replace - with / in DiveStats::compute_rates", |
25 | 34 |
|
26 | | - # metrics.rs: compute_rates boundary guards (dt_min=0 → rate=0 either way) |
27 | | - "replace [<>] with [<>]= in DiveStats::compute_rates$", |
28 | | - # metrics.rs: samples.len() - 1 in ascent guard (always true or dt_min=0) |
29 | | - "replace - with [+/] in DiveStats::compute_rates$", |
| 35 | + # ── metrics.rs: SegmentStats::compute — idempotent max/min tracking ── |
| 36 | + "src/metrics\\.rs:385:.*replace > with >= in SegmentStats::compute", # max_depth_m |
| 37 | + "src/metrics\\.rs:390:.*replace < with <= in SegmentStats::compute", # min_temp_c |
| 38 | + "src/metrics\\.rs:393:.*replace > with >= in SegmentStats::compute", # max_temp_c |
30 | 39 |
|
31 | | - # buhlmann.rs: leading compartment tie (exact FP equality never occurs) |
32 | | - "replace > with >= in TissueState::surface_gf_and_leading$", |
33 | | - # buhlmann.rs: threshold guards (real values never exactly at 1e-10) |
34 | | - "replace > with >= in TissueState::compartment_gf$", |
35 | | - "replace > with >= in compute_surface_gf$", |
| 40 | + # ── buhlmann.rs — FP threshold guards ──────────────────────────────── |
| 41 | + # Leading compartment tie-break: exact FP equality across 16 compartments' |
| 42 | + # weighted N2+He GF values never occurs in practice |
| 43 | + "src/buhlmann\\.rs:153:.*replace > with >= in TissueState::surface_gf_and_leading", |
| 44 | + # denom > 1e-10: Bühlmann constants always give denom >> 1e-10 |
| 45 | + "src/buhlmann\\.rs:180:.*replace > with >= in TissueState::compartment_gf", |
| 46 | + # dil_inert > 1e-10: gas fractions from real mixes never produce exactly 1e-10 |
| 47 | + "src/buhlmann\\.rs:254:.*replace > with >= in compute_surface_gf", |
36 | 48 | ] |
0 commit comments