1pub const ASPECT_FUNCTIONAL: &str = "functional";
15
16#[cfg(feature = "testmatrix")]
18#[inline]
19pub fn emit(component: &str, check: &str, ok: bool, detail: &str) {
20 nornir_testmatrix::functional_status(component, check, ok, detail);
21}
22
23#[cfg(not(feature = "testmatrix"))]
25#[inline]
26pub fn emit(_component: &str, _check: &str, _ok: bool, _detail: &str) {}
27
28#[macro_export]
31macro_rules! assert_emit {
32 ($component:expr, $check:expr, $ok:expr, $($detail:tt)+) => {{
33 let __ok: bool = $ok;
34 let __detail = ::std::format!($($detail)+);
35 $crate::selftest::emit($component, $check, __ok, &__detail);
36 ::std::assert!(__ok, "{}::{} — {}", $component, $check, __detail);
37 }};
38}
39
40#[cfg(all(test, feature = "testmatrix"))]
42mod wiring {
43 use crate::gitio;
44 use std::io::Write;
45
46 #[test]
50 fn emits_honest_rows_for_git_ops() {
51 let dir = tempfile::tempdir().unwrap();
52 let root = dir.path();
53
54 let inited = gitio::init(root).is_ok();
56 crate::selftest::emit("nornir-git", "init_creates_repo", inited, &format!("root={}", root.display()));
57
58 {
60 let mut f = std::fs::File::create(root.join("README.md")).unwrap();
61 writeln!(f, "hello").unwrap();
62 }
63 let sha = gitio::commit_all(root, "initial");
64 let committed = sha.as_ref().map(|s| s.len() >= 40).unwrap_or(false);
65 crate::selftest::emit(
66 "nornir-git",
67 "commit_all_returns_sha",
68 committed,
69 &format!("sha_len={:?}", sha.as_ref().map(|s| s.len())),
70 );
71
72 let head = gitio::head_sha(root);
74 let head_ok = matches!((&head, &sha), (Ok(h), Ok(s)) if h == s);
75 assert_emit!(
76 "nornir-git",
77 "head_sha_matches_commit",
78 head_ok,
79 "head={:?} commit={:?}",
80 head.as_deref().ok(),
81 sha.as_deref().ok()
82 );
83
84 let branch = gitio::head_branch(root);
86 crate::selftest::emit(
87 "nornir-git",
88 "head_branch_resolves",
89 branch.as_ref().map(|b| !b.is_empty()).unwrap_or(false),
90 &format!("branch={:?}", branch.as_deref().ok()),
91 );
92
93 let fresh = gitio::worktree_freshness(root);
95 crate::selftest::emit(
96 "nornir-git",
97 "worktree_freshness_reads",
98 fresh.is_ok(),
99 &format!("ok={}", fresh.is_ok()),
100 );
101
102 let ssh_ok = gitio::is_ssh_url("git@codeberg.org:nordisk/nornir.git")
104 && !gitio::is_ssh_url("https://codeberg.org/nordisk/nornir.git");
105 assert_emit!("nornir-git", "is_ssh_url_classifies", ssh_ok, "ssh+https classified");
106 let rewrite_ok = gitio::https_to_ssh("https://codeberg.org/nordisk/nornir.git")
107 .as_deref()
108 .map(|s| gitio::is_ssh_url(s))
109 .unwrap_or(false);
110 assert_emit!("nornir-git", "https_to_ssh_roundtrips", rewrite_ok, "https→ssh yields ssh url");
111
112 let rows = nornir_testmatrix::drain_functional_rows();
113 for want in [
114 "init_creates_repo",
115 "commit_all_returns_sha",
116 "head_sha_matches_commit",
117 "head_branch_resolves",
118 "worktree_freshness_reads",
119 "is_ssh_url_classifies",
120 "https_to_ssh_roundtrips",
121 ] {
122 assert!(
123 rows.iter().any(|r| r.suite == "nornir-git" && r.test_name == want && r.status == "pass"),
124 "missing green row {want}: {rows:?}"
125 );
126 }
127 assert!(rows.iter().all(|r| r.aspect == "functional"), "rows={rows:?}");
128 }
129}