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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! # nornir-testmatrix
//!
//! The portable core of nornir's **multi-aspect test matrix** — extracted from
//! `nornir` (EPIC L) so any leaf repo (znippy, skade, lbzip2-rs …) can run the
//! same matrix with a *tiny* dep set: `std` + `serde`/`serde_json` + `anyhow`.
//! No iceberg, arrow, eframe, tantivy, or skade.
//!
//! ## What it does
//! 1. **Runner** ([`runner`]) — wrap a repo's *native* Rust test framework
//! (`cargo nextest run --message-format libtest-json` if nextest is on PATH,
//! else plain `cargo test`), parse each test's pass/fail + duration, enforce a
//! stall watchdog. Pure subprocess driving — no test registration.
//! 2. **Multi-aspect engine** ([`aspect`]) — beyond unit tests, run MANY
//! *aspects* of a repo's health ([`Aspect`]): build, doctest, clippy, fmt,
//! audit, bench-smoke, coverage, feature-powerset, msrv, examples. Each
//! shells the right `cargo` subcommand, parses its result, and emits
//! [`TestResultRow`]s carrying an `aspect` tag + a numeric `metric` (coverage
//! %, warning count, advisory count …). A missing tool is a **skip**, never a
//! hard fail.
//! 3. **Model** ([`model`]) — the pure row/summary types ([`TestResultRow`],
//! [`RunSummary`], [`TestSelector`], the [`status`] tags) + the renderers
//! ([`render_matrix`], [`summarize_runs`], [`rows_to_json`]).
//! 4. **Sinks** ([`sink`]) — the [`TestSink`] trait + built-in [`JsonFileSink`]
//! and [`NullSink`] so a leaf repo with no warehouse can still persist its
//! matrix. nornir implements `TestSink` over its Iceberg warehouse.
//! 5. **Discovery** ([`discover`]) — the autonom (AUT2) anti-drift core: pure
//! enumerators that build the testable [`Surface`] from data (facett
//! components, viz tabs × {thin,fat}, CLI subcommands, MCP tools, and the
//! unreached-function set from `symbol_facts − test-reachable(call_edges)`),
//! then [`compute_gap`] differences it against coverage so the gate can
//! enforce `Gap == ∅`. No warehouse here — the caller feeds the rows.
//! 6. **Functional-status mode** ([`functional`]) — a component reports whether
//! it *actually works* (`functional_status(component, check, ok, detail)`)
//! from its own headless-render / self-test path. The
//! [`Aspect::Functional`] runner drains those into rows so a broken render is
//! a RED matrix row WITHOUT eyeballing a GUI. Gated behind the **`testmatrix`
//! cargo feature**: release builds (feature off) strip the emit to a no-op.
//!
//! ## How a leaf repo uses it
//! ```no_run
//! use nornir_testmatrix::{run_full_matrix, Aspect, JsonFileSink, TestSink};
//! use std::path::Path;
//!
//! let aspects = [Aspect::Build, Aspect::Unit, Aspect::Doctest, Aspect::Clippy, Aspect::Fmt];
//! let rows = run_full_matrix(Path::new("."), &aspects);
//! let sink = JsonFileSink::new("target/nornir-testmatrix.json");
//! sink.append(&rows).unwrap();
//! ```
// ─── flat re-exports (the crate's public façade) ───────────────────────────
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;