crates/nornir-testmatrix/src/lib.rs
//! # 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.
//! 7b. **uiplane — UI-PLANE reachability (LAW 9)** ([`uiplane`]) — model a running
//! app as **planes** ([`UiPlane`]) + a **navigation plan** ([`UiPlan`]: planes
//! as nodes, transitions as edges), then [`RobotPlan::walk`] a [`PlaneDriver`]
//! over it to REACH every plane and prove every declared surface is
//! **present + RAN**. A surface that is unreachable (orphan plane / missing
//! transition) or reachable-but-didn't-run is a **RED** row. Generic +
//! UI-agnostic: a headless library has an empty plan (trivially green); the
//! native robot-UI and the deployed-wasm headless-browser are two backends
//! behind the same [`PlaneDriver`] seam.
//! 7c. **gatedtests — the silenced-test guard** ([`gatedtests`]) — a
//! `tests/*.rs` carrying a crate-level `#![cfg(feature = "X")]` where `X` is
//! not in that crate's `default` set compiles to an **empty test binary** and
//! reports `0 tests ... ok`. [`audit_gated_tests`] walks every test target of
//! every workspace member (`cargo metadata`), parses the leading `#![cfg]`
//! (`all`/`any`/`not`, nested), resolves the crate's transitive `default`
//! closure, and emits a RED [`TestResultRow`] on the `gated-tests` aspect for
//! every file that neither compiles by default nor is re-invoked by a matrix
//! arm the repo DECLARES in `.nornir/testmatrix-arms.json`. Silence is not
//! success.
//! 8. **utfallsrum — outcome-space coverage** ([`utfallsrum`]) — declare a
//! function's whole OUTCOME SPACE as equivalence partitions + boundary values
//! ([`Outcome`]), record which classes a test exercised with the exact output,
//! and score `utfallsrum_covered ∈ [0,1]` = exercised / declared. A single-value
//! test scores low even when green; the gate requires ≥K classes swept before a
//! surface counts as covered. Boundary-value + equivalence-partition analysis,
//! made first-class and persistable next to the functional verdict.
//!
//! ## 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();
//! ```
pub mod appliance;
pub mod aspect;
// The CHAIN MATRIX — the 7-stage road from a declared build thing to a server
// that answers, and the 4th verdict (`n/a`) the appliance rollup needed.
pub mod chain;
pub mod atom;
pub mod armcheck;
pub mod citations;
pub mod coverage;
pub mod discover;
pub mod functional;
pub mod gatedtests;
// The SHARED matrix-harness primitives (`run_cargo` + `stamp_row`) every repo's
// `*_matrix.rs` used to hand-roll byte-identically (holger, korp) — L5.
pub mod harness;
// **What does this constellation measure, and what does it claim?** — the
// discovery half of the two things that had no verb: every bench target
// (including the ones in detached manifests) and every declared matrix row
// against what actually emits it.
pub mod inventory;
pub mod model;
pub mod runner;
pub mod sink;
// **Does every declared test target COMPILE?** — the step before every other
// guard here: `cargo check` is not a proxy for `cargo test`, and a test target
// that does not compile is reported by nothing.
pub mod targetcheck;
// **Which features gate tests, and does anything declare a run of them?** — the
// question `gatedtests` cannot answer, because it walks test TARGETS and the
// ~850 measured dark tests live in the LIBRARY target behind a `#[cfg]` on a
// `mod`. Also the one place that resolves a feature turned on by a DEPENDENCY
// EDGE, the third source of "what is on" that makes a variants-only scan report
// a lit feature as dark.
pub mod testsurface;
pub mod uiplane;
pub mod utfallsrum;
// ─── flat re-exports (the crate's public façade) ───────────────────────────
pub use appliance::{
appliance_boot_preset, appliance_product, ApplianceBootGrid, ApplianceRollup, BootPreset,
BootReach, ProofVerdict, APPLIANCE_BOOT_COMPONENT, APPLIANCE_BOOT_PROOFS, APPLIANCE_PRODUCTS,
APPLIANCE_PROOFS,
};
pub use aspect::{
aspect_label, parse_aspect, parse_funnel_decompose, run_aspect, run_full_matrix, Aspect,
AspectOutcome,
};
pub use atom::{
atom_surface, verify_atoms, AtomFailReason, AtomFailure, AtomObservation, AtomSpec, AtomState,
AtomVerdict,
};
pub use armcheck::{
arm_args, arm_target_dir, count_listed_tests, test_artifacts, verify_arm, verify_arms,
ArmCheck, ArmVerification,
};
pub use citations::{
audit_citations, sibling_checkouts, CitationReport, PhantomCitation, ALLOW_FILE,
PLACEHOLDER_STEMS,
};
pub use coverage::{
covered_with_utfallsrum, rows_for, rows_for_with_utfallsrum, seed_allowlist,
stale_allowlist_entries, AllowEntry, Allowlist, CoverageRow, CoverageSummary, GateReport,
SurfaceUtfallsrum, Verdict, DEFAULT_UTFALLSRUM_THRESHOLD,
};
pub use discover::{
cli_commands, compute_gap, facett_components, mcp_tools, test_reachable, unreached_functions,
viz_tabs, workspace_keys, workspace_surface_key, CallEdge, FacetRow, Gap, Mode, Surface,
SurfaceKind, SurfaceNode, SymbolRow, SERVED_WORKSPACES,
};
pub use functional::{
functional_na, functional_na_row, NA_MARKER,
drain_functional_file, drain_functional_rows, emit_rows, functional_row, functional_status,
record_rows,
};
pub use harness::{now_micros, run_cargo, stamp_row};
pub use inventory::{
declares_workspace, forbidden_vocabulary, manifest_roots, module_doc_first_line, parse_targets,
mask_comments_and_strings, render as render_inventory, resolve_rows, scan_bench_arms,
scan_emit_sites, scan_repo, ScannedEmit, ignore_requirement, EMIT_CALL_MAX_LINES,
bare_literal, id_field, renderer_vocabulary, resolve_rows_with, scan_roots, scan_roots_with,
to_json as inventory_to_json, top_level_args, unresolved_registrations,
to_rows as inventory_to_rows, uses_criterion,
workspace_targets, ArmDecl, BenchKind, BenchTarget, EmitSite, Inventory, MatrixRowDecl,
MetaTarget, RepoInventory, State, ASPECT_INVENTORY, BENCH_EXAMPLE_LOCATIONS, EMIT_FNS, GATE_MARKER, NA_FN,
FORBIDDEN_WORD,
};
pub use gatedtests::{
assert_no_silenced_tests, audit_gated_tests, audit_repo, classify, count_test_fns,
default_features, extract_crate_cfg,
feature_closure, parse_cfg_expr, parse_metadata, workspace_crates, CfgExpr, CrateManifest,
DepEdge, DepKind,
GateVerdict, GatedTestFile, GatedTestReport, MatrixArm, MatrixArms, TestTarget, ARMS_FILE,
ASPECT_GATED_TESTS,
};
pub use testsurface::{
audit_test_surface, closure_split, config_for_arm, config_for_variant, default_config,
dep_closure, depths_per_line, file_mod_decl, gated_surfaces, inline_mod_decl, module_file,
outer_cfg_body, resolve, scan_unit_gates, surface_gaps, ConfigOrigin, GateSite, GatedSurface,
Resolved, RunVerdict, SurfaceGap, SurfaceRow, TestConfig, TestSurfaceReport, UnitGate,
ASPECT_TEST_SURFACE,
};
pub use model::{
listed_rows, new_run_id, parse_cargo_test_list, parse_nextest_list, render_matrix,
rows_to_json, short_run, status, summarize_runs, RunSummary, TestResultRow, TestSelector,
};
pub use runner::{
detect_runner, heavy_enabled, list_tests, nextest_outcome_args, parse_output, run_arm, run_arms, run_matrix,
stall_secs, suite_crate, ArmRun, MatrixRun, Runner, TestCase, DEFAULT_STALL_SECS,
NEXTEST_LIBTEST_JSON_ARGS, NEXTEST_LIBTEST_JSON_ENV,
};
pub use functional::ASPECT_FUNCTIONAL;
pub use sink::{JsonFileSink, NullSink, TestSink};
pub use targetcheck::{
assert_all_test_targets_compile, check_targets, compile_target_dir, configs_from_arms,
configs_from_metadata, configs_from_variants, dedup_configs, outside_this_workspace,
package_name_from_id,
parse_build_stream, run_config, BuildOutcome, CompileConfig, CompileReport, ConfigOutcome,
ConfigSource, Depth, TargetError, TargetState, TargetVerdict, VariantSpec,
SILENTLY_FATAL_LINTS,
ASPECT_TARGET_COMPILE,
};
pub use uiplane::{
MockDriver, PlaneDriver, RobotPlan, RouteStep, SurfaceVerdict, Transition, UiPlan, UiPlane,
UiSurface, WalkReport, WalkRow, UIPLANE_ASPECT,
};
pub use utfallsrum::{Outcome, OutcomeClass, UtfallsrumSummary, UTFALLSRUM_ASPECT};