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
//! # Self-emitter bridge — nornir's own `functional_status` → test-matrix feed
//!
//! The single internal call site nornir's own code (render / side-effect paths)
//! and its `#[test]`s use to push a *functional* row into the [`nornir_testmatrix`]
//! matrix — so the framework's author **eats its own dogfood** (AUT8).
//!
//! ## EMIT-DOCTRINE (the law this module enforces)
//! The default for a self-test is to **assert on the return value / object state**
//! (the returned result + `state()`/`state_json()`). A `#[test]` does that with a
//! normal `assert!`, then calls [`emit`] to *also* record the verdict as a matrix
//! row — the emit is observation, NOT the assertion's substitute. ONLY when the
//! result cannot be observed from outside (a render / side-effect: an egui paint, a
//! PNG written by a screenshot command) do we **implant** an [`emit`] *inside* the
//! function under test, gated by `#[cfg(feature = "testmatrix")]`, and read it back.
//!
//! ## Release strips everything
//! Every call site is wrapped in `#[cfg(feature = "testmatrix")]`, and the
//! underlying `functional_status` is a compiled-out no-op when the feature is OFF,
//! so a plain `cargo build` carries zero emit cost — no row, no file touched.
//! Lit ONLY under `cargo … --features testmatrix`.
//!
//! ## Read-back: the in-process buffer (not a file)
//! nornir's `nornir-testmatrix` records into a **process-global buffer**; the
//! [`Aspect::Functional`](nornir_testmatrix::Aspect) runner drains it via
//! [`nornir_testmatrix::drain_functional_rows`]. nornir's own self-tests run
//! IN-PROCESS, so they read their emitted rows back by draining that buffer — no
//! JSON sink (the sink is the cross-process path for separate leaf-repo test
//! processes).
/// The aspect tag every self-emitted row carries (matches `functional_row`).
pub const ASPECT_FUNCTIONAL: &str = "functional";
/// Push ONE functional-status row for a single real check.
///
/// * `component` — the unit under test (a viz tab, a gRPC handler, a warehouse
/// append path, a CLI verb). Becomes the matrix row's `suite`.
/// * `check` — the specific assertion's name. Becomes the row's `test_name`.
/// * `ok` — the **real** verdict (a return value compared, a count checked).
/// * `detail` — the **measured** value (a count, a hash, a route name).
///
/// When `testmatrix` is OFF this is an `#[inline]` no-op (the underlying
/// `functional_status` is also a no-op), so a stray non-gated call still costs
/// nothing. Prefer to gate the call site so the *detail-building* work is stripped.
/// `assert!`-with-emit: assert on the real return value / object state AND record
/// the verdict as a matrix row. The doctrine's preferred shape — the `assert!` is
/// the test's actual gate; the emit is the matrix observation.
///
/// ```ignore
/// assert_emit!("arch::classify", "viz_tab_owner_is_a_component",
/// node.kind == NodeKind::Component,
/// "kind={:?} id={}", node.kind, node.id);
/// ```