1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Reference witness: the conformance metric newtypes enforce the [0,1] bound at
// construction (reject NaN/±∞/out-of-range), and ConformanceResult carries a
// verdict (COVERAGE.md §2 — conformance metric carriers + verdict container).
//
// Each metric newtype (Fitness/Precision/F1/Generalization/Simplicity) validates
// its f64 to be finite and in [0,1] via `new(v) -> Option`. ConformanceResult is
// the verdict container an engine populates. This witnesses the bound law (admit
// in-range, refuse out-of-range/NaN) and the builder's metric accumulation.
use wasm4pm_compat::conformance::{
ConformanceResult, Fitness, Generalization, Precision, Simplicity, F1,
};
#[test]
fn metric_newtypes_enforce_zero_one_bound() {
// In-range values are admitted and recoverable.
assert_eq!(
Fitness::new(0.0).map(|m| m.get()),
Some(0.0),
"lower bound admitted"
);
assert_eq!(
Fitness::new(1.0).map(|m| m.get()),
Some(1.0),
"upper bound admitted"
);
assert_eq!(
Precision::new(0.5).map(|m| m.get()),
Some(0.5),
"interior admitted"
);
// Out-of-range and non-finite are REFUSED (None) — the bound is a real law.
assert_eq!(Fitness::new(1.5), None, "above 1.0 refused");
assert_eq!(Precision::new(-0.1), None, "below 0.0 refused");
assert_eq!(F1::new(f64::NAN), None, "NaN refused");
assert_eq!(Generalization::new(f64::INFINITY), None, "+inf refused");
assert_eq!(Simplicity::new(f64::NEG_INFINITY), None, "-inf refused");
}
#[test]
fn conformance_result_accumulates_a_verdict() {
// fitness + 7 of 10 traces fitting; then layer precision/generalization/simplicity.
let r = ConformanceResult::new(0.83, 10, 7, 3)
.with_precision(0.9)
.with_generalization(0.8)
.with_simplicity(0.7);
assert_eq!(r.fitness, 0.83);
assert_eq!(r.precision, Some(0.9));
assert_eq!(r.generalization, Some(0.8));
assert_eq!(r.simplicity, Some(0.7));
assert_eq!(r.total_traces, 10);
assert_eq!(r.fitting_traces, 7);
assert_eq!(r.deviating_traces, 3);
// conformance_rate is derived from the trace counts (a real computation, in [0,1]).
let rate = r.conformance_rate();
assert!(
(0.0..=1.0).contains(&rate),
"conformance_rate in [0,1]; got {rate}"
);
}