use serde_json::Value;
use std::fmt::Write;
fn text(value: &Value) -> &str {
value.as_str().unwrap_or("")
}
fn items(value: &Value) -> &[Value] {
value.as_array().map(Vec::as_slice).unwrap_or(&[])
}
fn quote(value: &str) -> String {
format!("'{}'", value.replace('\'', "'\\''"))
}
fn location(at: &Value) -> String {
format!("{}:{}:{}", text(&at["file"]), at["line"], at["column"])
}
fn code(out: &mut String, source: &str, indent: &str) {
for line in source.lines() {
let _ = writeln!(out, "{indent}{line}");
}
}
fn page_footer(out: &mut String, data: &Value, command: &str) {
let page = &data["pagination"];
let offset = page["offset"].as_u64().unwrap_or(0);
let returned = page["returned"].as_u64().unwrap_or(0);
let start = if returned == 0 { 0 } else { offset + 1 };
let end = if returned == 0 { 0 } else { offset + returned };
let _ = writeln!(out, "\nShowing {start}-{end} of {}", page["total"]);
if let Some(next) = page["nextOffset"].as_u64() {
let _ = writeln!(out, "Next: {command} --offset {next} --limit {returned}");
}
}
fn notes(out: &mut String, data: &Value) {
if data["workingTree"]["stale"] == true {
let _ = writeln!(
out,
"\nThe current checkout has changed; this view describes the archived run."
);
}
for error in items(&data["validationErrors"]) {
let _ = writeln!(out, "Map error: {}", text(error));
}
}
fn summary(out: &mut String, data: &Value) {
let score = &data["summary"]["statements"];
if let Some(pct) = score["percentage"].as_f64() {
let _ = writeln!(
out,
"Assertion coverage: {pct:.2}% ({}/{}) agent-assessed statements",
score["asserted"], score["total"]
);
} else {
let _ = writeln!(
out,
"Assertion coverage: {} โ {}",
text(&data["summary"]["status"]),
text(&data["summary"]["reason"])
);
}
if let Some(path) = data["map"].as_str() {
let _ = writeln!(out, "Map: {path}");
}
for skipped in items(&data["inheritance"]["skipped"]) {
let _ = writeln!(
out,
"Map reuse skipped {}: {}",
text(&skipped["run"]),
text(&skipped["reason"])
);
}
}
fn source(data: &Value) -> String {
let mut out = format!(
"{} โ matching current source, run {}\n\n",
text(&data["file"]),
text(&data["run"])
);
let width = data["pagination"]["total"].to_string().len();
for line in items(&data["items"]) {
let number = line["line"].as_u64().unwrap_or(0);
let _ = writeln!(out, "{number:>width$} โ {}", text(&line["text"]));
}
let command = format!(
"supercov runs {} source {}",
quote(text(&data["run"])),
quote(text(&data["file"]))
);
page_footer(&mut out, data, &command);
notes(&mut out, data);
out
}
fn assertions(data: &Value) -> String {
let mut out = format!("Assertions โ run {}\n", text(&data["run"]));
summary(&mut out, data);
for a in items(&data["items"]) {
let flows = items(&a["flows"]);
let dirty = flows.iter().filter(|f| f["current"] != true).count();
let review = if flows.is_empty() {
"no flows".to_owned()
} else if dirty > 0 {
format!("{dirty}/{} flows need rechecking", flows.len())
} else {
format!(
"{} current {}",
flows.len(),
if flows.len() == 1 { "flow" } else { "flows" }
)
};
let observed = items(&a["observedPassingTests"]).len();
let test_label = if observed == 1 { "test" } else { "tests" };
let _ = writeln!(
out,
"\n{} ยท {review} ยท {observed} passing {test_label}",
text(&a["id"])
);
let _ = writeln!(out, " {}", location(&a["at"]));
let expression = text(&a["at"]["text"]);
let first = expression.lines().next().unwrap_or("");
let preview = first.chars().take(140).collect::<String>();
let suffix = if expression.lines().count() > 1 || first.chars().count() > 140 {
" โฆ"
} else {
""
};
let _ = writeln!(out, " {preview}{suffix}");
if a["inMap"] == false {
let _ = writeln!(
out,
" Missing from assertions.json; this site was found in matching current source."
);
}
}
let mut command = format!("supercov runs {} assertions", quote(text(&data["run"])));
if let Some(file) = data["file"].as_str() {
let _ = write!(command, " --file {}", quote(file));
}
if data["needsAttention"] == true {
command.push_str(" --needs-attention");
}
page_footer(&mut out, data, &command);
let _ = writeln!(
out,
"Details: supercov runs {} assertion <id>",
quote(text(&data["run"]))
);
notes(&mut out, data);
out
}
fn assertion(data: &Value) -> String {
let a = &data["assertion"];
let mut out = format!(
"Assertion {} โ run {}\n{}\n",
text(&a["id"]),
text(&data["run"]),
location(&a["at"])
);
code(&mut out, text(&a["at"]["text"]), " ");
for question in items(&a["questions"]) {
let _ = writeln!(out, "Question: {}", text(question));
}
if a["inMap"] == false {
let _ = writeln!(
out,
"Missing from assertions.json; add this discovered site to the map."
);
}
for property in items(&a["observes"]) {
let _ = writeln!(out, "Observes: {}", text(property));
}
if items(&data["tests"]).is_empty() {
let _ = writeln!(out, "No passing assertion occurrence was recorded.");
}
for test in items(&data["tests"]) {
let _ = writeln!(out, "Observed in passing test: {}", text(&test["name"]));
}
if items(&a["flows"]).is_empty() {
let _ = writeln!(out, "\nNo flows mapped yet.");
}
for flow in items(&a["flows"]) {
let current = if flow["current"] == true {
"current"
} else {
"needs rechecking"
};
let eligible = if flow["eligible"] == true {
"eligible for credit"
} else {
"not eligible for credit"
};
let _ = writeln!(
out,
"\nFlow {}/{} โ {current}, {eligible}",
text(&a["id"]),
text(&flow["id"])
);
code(&mut out, text(&flow["explanation"]), " ");
for case in items(&flow["appliesTo"]) {
let _ = writeln!(
out,
" Applies to: {} โ {}",
text(&case["file"]),
text(&case["name"])
);
}
for reason in items(&flow["reasons"])
.iter()
.chain(items(&flow["blockers"]))
{
let _ = writeln!(out, " Review/evidence: {}", text(reason));
}
for node in items(&flow["nodes"]) {
let counted = if items(&flow["countsAsAsserted"]).contains(&node["id"]) {
" [claimed as asserted]"
} else {
""
};
let _ = writeln!(
out,
" Node {} โ {}{counted}",
text(&node["id"]),
location(&node["at"])
);
code(&mut out, text(&node["at"]["text"]), " ");
if let Some(meaning) = node["meaning"].as_str().filter(|s| !s.is_empty()) {
let _ = writeln!(out, " {meaning}");
}
}
for edge in items(&flow["edges"]) {
let _ = writeln!(
out,
" {} โ {} ({}) {}",
text(&edge["from"]),
text(&edge["to"]),
text(&edge["kind"]),
text(&edge["basis"])
);
}
for watch in items(&flow["watch"]) {
let _ = writeln!(out, " Watches file: {}", text(watch));
}
}
let _ = writeln!(out);
summary(&mut out, data);
notes(&mut out, data);
out
}
pub fn render(data: &Value) -> Option<String> {
match data["view"].as_str()? {
"source" => Some(source(data)),
"assertions" => Some(assertions(data)),
"assertion" => Some(assertion(data)),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn source_preserves_indentation_blank_lines_and_unicode_and_quotes_next_path() {
let data = json!({"view":"source","run":"run_one","file":"tests/a b's.ts",
"items":[{"line":34,"text":" const x = '๐งช';"},{"line":35,"text":""},{"line":36,"text":"\tassert(x);"}],
"pagination":{"offset":33,"returned":3,"total":100,"nextOffset":36}});
let rendered = render(&data).unwrap();
assert!(rendered.contains(" 34 โ const x = '๐งช';\n 35 โ \n 36 โ \tassert(x);\n"));
assert!(rendered.contains("Showing 34-36 of 100"));
assert!(rendered.contains("source 'tests/a b'\\''s.ts' --offset 36 --limit 3"));
assert!(!rendered.contains("\"text\""));
}
#[test]
fn empty_source_page_never_reports_imaginary_line_numbers() {
let data = json!({"view":"source","run":"run_one","file":"empty.ts","items":[],
"pagination":{"offset":100,"returned":0,"total":0,"nextOffset":null}});
let rendered = render(&data).unwrap();
assert!(rendered.contains("Showing 0-0 of 0"));
assert!(!rendered.contains("Next:"));
}
}