use crate::query;
use super::blocks::{compact_block, ref_kind_block_if_any};
use super::markers::{compact_marker, count_suffix, heuristic_suffix, test_via_suffix};
use super::refs::bus_hop_line;
pub fn render_tests_text(model: &query::TestsModel) -> String {
let files = model.rows.len();
let mut out: Vec<String> = vec![format!(
"tests for {}{}",
model.symbol,
count_suffix("files", files, files)
)];
if model.rows.is_empty() && model.bus.total == 0 {
out.push("no test references found".to_string());
name_hint_lines(&mut out, &model.name_hint);
return out.join("\n");
}
out.push(format!(
"covered by {} test file(s), {} reference(s)",
model.test_file_count, model.ref_count
));
out.push(String::new());
for r in &model.rows {
out.push(format!(
"{}{}{}",
r.file,
heuristic_suffix(r.heuristic, r.tier),
test_via_suffix(r.via)
));
let lines = r
.lines
.iter()
.map(|l| l.to_string())
.collect::<Vec<_>>()
.join(", ");
if r.test_defs.is_empty() {
out.push(format!(" lines: {lines}"));
} else {
for def_id in &r.test_defs {
out.push(format!(" {def_id} lines: {lines}"));
}
}
}
ref_kind_block_if_any(&mut out, "bus-hop", &model.bus, bus_hop_line);
out.join("\n")
}
fn more_suffix(total: usize, listed: usize) -> String {
match total.checked_sub(listed) {
Some(n) if n > 0 => format!(" (+{n} more)"),
_ => String::new(),
}
}
fn name_hint_lines(out: &mut Vec<String>, hint: &[query::NameHintRow]) {
if hint.is_empty() {
return;
}
out.push("hint (file name only, not a test reference):".to_string());
for row in hint {
out.push(if row.references.is_empty() {
format!(" {} references no indexed production symbol", row.file)
} else {
format!(
" {} references {}{}",
row.file,
row.references.join(", "),
more_suffix(row.reference_total, row.references.len())
)
});
}
}
pub fn render_tests_compact(model: &query::TestsModel) -> String {
let heur = if model.heuristic_file_count != 0 {
format!(" heuristic={}", model.heuristic_file_count)
} else {
String::new()
};
let files = model.rows.len();
let mut out: Vec<String> = vec![format!(
"tests {} files={} refs={}{heur}{}",
model.symbol,
model.test_file_count,
model.ref_count,
count_suffix("files", files, files)
)];
for row in &model.name_hint {
let refs = if row.references.is_empty() {
"none".to_string()
} else {
format!(
"{}{}",
row.references.join(","),
more_suffix(row.reference_total, row.references.len())
)
};
out.push(format!("hint {} -> {refs}", row.file));
}
for r in &model.rows {
let lines = r
.lines
.iter()
.map(|l| format!("{l}{}", compact_marker(r.heuristic, r.tier)))
.collect::<Vec<_>>()
.join(",");
out.push(format!("{} {lines}", r.file));
}
let file_of_bus: fn(&query::BusHopRow) -> &str = |r| r.file.as_str();
let line_bus = |r: &query::BusHopRow| format!("{}?", r.line);
compact_block(
&mut out,
"bus-hop (? = possible route, rerun without --compact for the full row)",
Some(&model.bus),
file_of_bus,
line_bus,
);
out.join("\n")
}