mod column;
mod drive;
mod keys;
use super::super::render;
use super::fixture::{World, world};
use super::input;
use crate::cli_outbound::Cli;
use crate::paint_probe::Painted;
const CHILD: &str = "c-1-20260803T045643Z-1e5f99d4";
const GRANDCHILD: &str = "c-1-20260803T045643Z-1e5f99d4-20260803T045700Z-2a6b88c5";
fn nested_world() -> World {
let mut world = world();
std::fs::write(
world.model.state_root().join("cadence.yaml"),
"cadence:\n watcher:\n debounce_ms: 0\n",
)
.unwrap();
world.model.after_lernie_verb();
world.converge();
world.add_child("c-1", CHILD);
world.add_child(CHILD, GRANDCHILD);
let ws = world.ws.clone();
world.model.mark_dirty([ws]);
world.converge();
world
}
fn painted(world: &mut World) -> Vec<Painted> {
let (lernie, bl, bz) = (Cli::new("lernie"), Cli::new("bl"), Cli::new("bz"));
let ctx = egui::Context::default();
let frame = |world: &mut World| {
ctx.run(input(), |ctx| {
render(ctx, &mut world.model, &mut world.state, &lernie, &bl, &bz);
})
};
let _ = frame(world);
world.settle();
let _ = frame(world);
world.settle();
let out = crate::paint_probe::painted_of(&frame(world));
drive::one_title_each(&out, &drive::visible(world));
out
}
fn left_of(painted: &[Painted], needle: &str) -> Option<f32> {
painted
.iter()
.filter(|(text, _)| drive::reads_as(text, needle))
.map(|(_, rect)| rect.min.x)
.reduce(f32::min)
}
fn elbows(painted: &[Painted]) -> usize {
painted
.iter()
.filter(|(text, _)| text.ends_with(crate::theme::ELBOW))
.count()
}
fn rows(world: &World) -> Vec<(usize, String)> {
crate::test_support::convs::visible(
&world.model,
super::super::now_unix(),
&world.state.expanded,
)
.iter()
.map(|r| (r.depth, r.display_name()))
.collect()
}
pub(super) fn name_of(world: &World, id: &str) -> String {
let open: std::collections::HashSet<String> = world
.model
.tree(&world.ws)
.map(|t| t.agents.iter().map(|a| a.agent_id.clone()).collect())
.unwrap_or_default();
crate::test_support::convs::visible(&world.model, super::super::now_unix(), &open)
.iter()
.find(|r| r.root_id == id)
.map_or_else(
|| panic!("the wide-open list must hold a row for {id}"),
crate::nav::convs::ConvRow::display_name,
)
}
#[test]
fn a_collapsed_row_states_direct_and_total_right_of_its_title_and_hides_the_descent() {
let mut world = nested_world();
let list = rows(&world);
assert_eq!(
list.len(),
1,
"collapsed, the three-generation conversation is one row: {list:?}"
);
let shut = painted(&mut world);
let title = left_of(&shut, &list[0].1).expect("the root row paints its title");
let field = left_of(&shut, "▶ 1/2").unwrap_or_else(|| {
panic!(
"the subagent field states ▶ direct/total — 1 dispatched here, 2 under it \
altogether:\n{:?}",
shut.iter().map(|(t, _)| t).collect::<Vec<_>>()
)
});
assert!(
field > title,
"the field rides the trailing right-pinned group: {field} <= {title}"
);
assert_eq!(elbows(&shut), 0, "a shut list draws no reply elbow");
let hidden: Vec<String> = [CHILD, GRANDCHILD]
.iter()
.map(|id| name_of(&world, id))
.collect();
for name in &hidden {
assert!(
left_of(&shut, name).is_none(),
"{name} is folded away, so nothing paints it"
);
}
world.state.expanded.insert("c-1".to_owned());
world.state.expanded.insert(CHILD.to_owned());
let open = painted(&mut world);
for name in &hidden {
assert!(
left_of(&open, name).is_some(),
"and the very same needle lands once the fold opens: {name}"
);
}
}
#[test]
fn unfolding_indents_each_generation_past_the_one_above_it() {
let mut world = nested_world();
world.state.expanded.insert("c-1".to_owned());
world.state.expanded.insert(CHILD.to_owned());
let list = rows(&world);
assert_eq!(
list.iter().map(|(d, _)| *d).collect::<Vec<_>>(),
vec![0, 1, 2],
"three generations, one row each: {list:?}"
);
let painted = painted(&mut world);
let edges: Vec<f32> = list
.iter()
.map(|(_, name)| left_of(&painted, name).unwrap_or_else(|| panic!("{name} paints")))
.collect();
for pair in edges.windows(2) {
assert!(
pair[1] > pair[0] + 1.0,
"each depth's title edge sits right of the one above it: {edges:?}"
);
}
assert_eq!(elbows(&painted), 2, "one reply elbow per revealed child");
let elbow_left = painted
.iter()
.filter(|(text, _)| text.ends_with(crate::theme::ELBOW))
.map(|(_, rect)| rect.min.x)
.reduce(f32::min)
.unwrap();
assert!(
elbow_left < edges[1],
"the elbow leads the child's row: {elbow_left} >= {}",
edges[1]
);
assert!(
left_of(&painted, "▼ 1/2").is_some() && left_of(&painted, "▼ 1/1").is_some(),
"the root says 1/2 open, the middle row 1/1 open:\n{:?}",
painted.iter().map(|(t, _)| t).collect::<Vec<_>>()
);
assert!(
left_of(&painted, "▶ 1/2").is_none(),
"and no row still wears the shut arrow it was opened from"
);
}