use super::{default_rows, entry, model, tx};
use crate::transcript::{AutoExpand, Block, EntryKind, Tone, rows};
use std::collections::HashSet;
#[test]
fn a_delivered_message_with_no_body_says_so() {
let t = tx(vec![entry(
"004-kid.md",
EntryKind::Delivered {
sender: "kid".into(),
epitaph: None,
body: String::new(),
},
)]);
let got = default_rows(&t);
assert_eq!(got.len(), 1, "nothing is dropped: {got:?}");
assert_eq!(got[0].prefix, "kid:");
assert_eq!(got[0].preview, "(no message body)");
assert_eq!(got[0].tone, Tone::Weak);
}
#[test]
fn a_result_deposit_names_how_the_child_ended() {
let t = tx(vec![entry(
"040-kid.md",
EntryKind::Delivered {
sender: "kid".into(),
epitaph: Some(crate::inboxview::Epitaph::Stopped),
body: String::new(),
},
)]);
let got = default_rows(&t);
assert_eq!(got[0].prefix, "kid ended: stopped");
assert_eq!(got[0].preview, "(no message body)");
}
#[test]
fn a_result_deposit_that_spoke_keeps_its_body_under_the_ending() {
let t = tx(vec![entry(
"042-kid.md",
EntryKind::Delivered {
sender: "kid".into(),
epitaph: Some(crate::inboxview::Epitaph::FinalResponse),
body: "the findings".into(),
},
)]);
let got = default_rows(&t);
assert_eq!(got[0].prefix, "kid ended: final-response");
assert_eq!(got[0].preview, "the findings");
assert_eq!(got[0].tone, Tone::Plain);
}
#[test]
fn a_model_message_with_no_blocks_still_gets_a_row() {
let t = tx(vec![model(Vec::new())]);
let got = default_rows(&t);
assert_eq!(got.len(), 1, "nothing is dropped: {got:?}");
assert_eq!(got[0].prefix, "shudder-storeroom:");
assert_eq!(got[0].preview, "(no content blocks)");
assert!(got[0].hover.contains("opus"), "the model id still hovers");
}
#[test]
fn a_resolved_tool_call_stops_saying_running() {
let call = model(vec![Block::ToolUse {
id: "toolu_1".into(),
name: "Read".into(),
input_summary: "{}".into(),
}]);
let pending = default_rows(&tx(vec![call.clone()]));
assert_eq!(pending[0].prefix, "⚙ Read — running");
assert_eq!(pending[0].tone, Tone::InFlight);
let resolved = default_rows(&tx(vec![
call,
entry(
"003-tool.json",
EntryKind::ToolResult {
tool_use_id: "toolu_1".into(),
content: String::new(),
is_error: false,
},
),
]));
assert_eq!(resolved[0].prefix, "⚙ Read");
assert_eq!(resolved[0].tone, Tone::Plain);
}
#[test]
fn a_model_turn_is_labelled_with_the_agent_name_and_hovers_the_model_id() {
let t = tx(vec![model(vec![
Block::Text("Yes".into()),
Block::Thinking("hmm".into()),
])]);
let got = default_rows(&t);
assert_eq!(got[0].prefix, "shudder-storeroom:");
assert!(
!got[0].prefix.contains("opus"),
"the model id is not a speaker: {got:?}"
);
assert!(
got[0].hover.contains("opus"),
"the model id stays discoverable: {got:?}"
);
assert_eq!(got[1].prefix, "thinking:");
assert!(got[1].hover.is_empty(), "no hover to invent: {got:?}");
}
#[test]
fn a_tool_result_that_folds_says_how_big_the_fold_is_in_characters() {
let result = |content: &str| {
default_rows(&tx(vec![entry(
"003-tool.json",
EntryKind::ToolResult {
tool_use_id: "t".into(),
content: content.into(),
is_error: false,
},
)]))
};
let folds = result("αβγ\nδε");
assert_eq!(folds[0].prefix, "✔ tool result — ok · 6 chars");
assert!(!folds[0].body.is_empty(), "it folds: {folds:?}");
let whole = result("bytes");
assert_eq!(whole[0].prefix, "✔ tool result — ok");
assert!(whole[0].body.is_empty(), "nothing folds: {whole:?}");
}
#[test]
fn the_live_tail_states_no_size() {
let t = tx(vec![entry(
"004-live.json",
EntryKind::Streaming {
thinking: String::new(),
text: "half an\nanswer".into(),
},
)]);
let got = default_rows(&t);
assert_eq!(got[0].prefix, "live:");
assert!(got[0].expanded, "in flight, so already on screen: {got:?}");
}
#[test]
fn the_label_is_the_callers_name_verbatim() {
let t = tx(vec![model(vec![Block::Text("hi".into())])]);
let unnamed = rows(
&t,
"20260427T120000Z-aaaa",
AutoExpand::default(),
&HashSet::new(),
);
assert_eq!(unnamed[0].prefix, "20260427T120000Z-aaaa:");
}