mannequin/tests/look_preset_robot.rs
//! Robot-UI cell — the app-level **look-preset switcher** atom, driven in code.
//!
//! The mannequin GUI's look switcher used to be a click with no remote handle:
//! `selectable_label(...).clicked() -> self.set_look_preset(i)`, its result
//! invisible to a test. Now `MannequinGui::state_json()` exposes the active
//! preset and `set_look_preset` drives it — so this cell drives + observes the
//! atom with no display, no GPU, no AI. LAW: inject real input, assert real
//! output (never "didn't panic").
use std::sync::Arc;
use mannequin::event_log::EventLog;
use mannequin::gui::MannequinGui;
use mannequin::PkiService;
#[test]
fn look_preset_switcher_is_remote_drivable_and_observable() {
let pki = Arc::new(PkiService::new().expect("build a mannequin PkiService"));
let mut gui = MannequinGui::new(EventLog::new(), pki);
// Observe the starting state.
let s0 = gui.state_json();
let count = s0["preset_count"]
.as_u64()
.expect("preset_count is a number") as usize;
assert!(
count >= 5,
"facett ships >=5 look presets (Windows L/D, macOS L/D, Device); got {count}"
);
let start = s0["look_preset"].as_u64().expect("look_preset index") as usize;
// Drive: switch to a different preset IN CODE; assert state reflects it.
let target = (start + 1) % count;
let name = gui.set_look_preset(target);
let s1 = gui.state_json();
assert_eq!(
s1["look_preset"].as_u64(),
Some(target as u64),
"the selected preset is remote-observable"
);
assert_eq!(
s1["look_name"].as_str(),
Some(name.as_str()),
"look_name round-trips the set preset"
);
// Clamp: an out-of-range index clamps to the last preset (never panics).
gui.set_look_preset(9999);
assert_eq!(
gui.state_json()["look_preset"].as_u64(),
Some((count - 1) as u64),
"out-of-range preset index clamps to the last one"
);
}