metamon/coverage
Coverage and classification primitives for property-based tests.
classify tags a generated input with a label so the runner can
report the distribution at the end of a successful run.
cover additionally asserts a minimum percentage — if fewer
inputs hit the label than required, the property fails even when
every individual run passed.
collect records the value itself (via a user-supplied show)
for histogram-style reporting.
Types
One coverage requirement. A requirement is met when the label’s
hit count is at least target_pct% of total runs (Pct kind) or
at least min_hits absolute occurrences (Count kind).
pub type Requirement {
Requirement(label: String, kind: RequirementKind, hits: Int)
}
Constructors
-
Requirement(label: String, kind: RequirementKind, hits: Int)
Distinguishes percentage-based from absolute-count requirements so the runner knows which threshold to compare against.
pub type RequirementKind {
Pct(target_pct: Float)
Count(min_hits: Int)
}
Constructors
-
Pct(target_pct: Float)At least
target_pct% of inputs must hit the label. -
Count(min_hits: Int)At least
min_hitsinputs must hit the label.
Snapshot of the coverage state for one property run.
pub type Snapshot {
Snapshot(
total: Int,
counts: dict.Dict(String, Int),
requirements: List(Requirement),
collected: dict.Dict(String, Int),
)
}
Constructors
-
Snapshot( total: Int, counts: dict.Dict(String, Int), requirements: List(Requirement), collected: dict.Dict(String, Int), )
Values
pub fn actual_pct(hits: Int, total: Int) -> Float
(hits / total) * 100, returning 0.0 if total is zero.
pub fn classify(label: String, condition: Bool) -> Nil
Tag the current input with label if condition is true. Only
labelled hits are counted, but every call to classify advances
the total-runs denominator.
pub fn classify_in_bucket(group: String, bucket: String) -> Nil
Tag the current input as belonging to a mutually-exclusive
bucket within group. Buckets are recorded as
"<group>=<bucket>" so the failure report can show distribution
by group at a glance. Calling classify_in_bucket more than once
per input within the same group is a programming error and is
silently kept (the runner does not enforce mutual exclusion).
pub fn collect(value: a, show: fn(a) -> String) -> Nil
Render value via show and add the result to the histogram of
collected values.
pub fn collected_of(snap: Snapshot) -> dict.Dict(String, Int)
Convenience accessor used by the runner / report.
pub fn cover(
target_pct: Float,
label: String,
condition: Bool,
) -> Nil
Like classify but also asserts that the label hits at least
target_pct percent of all inputs in the run.
target_pct must be a finite number in [0.0, 100.0]. Values
outside that range — and NaN — are programming errors (an
off-by-percent typo turns a target of 50 into 500, a negative
target trivially passes for zero hits) and panic with a structured
message so the misconfiguration surfaces immediately rather than
as a confusing coverage shortfall.
pub fn cover_at_least(
min_hits: Int,
label: String,
condition: Bool,
) -> Nil
Absolute-count variant of cover: assert that the label is hit
at least min_hits times across the entire run. Useful when you
know the exact number of edge cases that should fire (e.g. “at
least 3 inputs trigger the empty-list path”).
min_hits must be >= 0. A negative threshold is trivially
satisfied (zero hits clear a negative bar) and almost always a
sign mistake on the caller’s part, so it panics with a structured
message at the call site.
pub fn first_shortfall(
snap: Snapshot,
) -> option.Option(Requirement)
Some(req) when at least one shortfall exists, otherwise None.
pub fn requirements_of(snap: Snapshot) -> List(Requirement)
Convenience accessor used by the runner / report.
pub fn reset() -> Nil
Reset all coverage state. Called by the runner at the start of each property.
pub fn shortfalls(snap: Snapshot) -> List(Requirement)
Find requirements whose actual coverage falls short of the target.
Pct requirements are checked against actual_pct; Count
requirements are checked against the absolute hit count.
pub fn target_pct_of(req: Requirement, total: Int) -> Float
Backwards-compat helper: extract the percentage target if the
requirement is a Pct one, otherwise compute it from the
minimum-count requirement and the recorded total. Used by the
failure formatter and the target_pct accessor in older code.