use super::Harness;
use crate::cli_outbound::Cli;
use crate::git_tree::AgentState;
use crate::git_tree::tests::fixture::Fixture;
use crate::opslog::{self, YOG_STEP};
use std::path::PathBuf;
fn unused_bl() -> Cli {
Cli::new("bl")
}
fn add_named(h: &Harness, name: &str, agent: &str) -> PathBuf {
let fx = Fixture::new();
fx.build_agent(agent, "hi");
let ws = crate::binding::names_root(&h.roots.yog_data).join(name);
std::fs::create_dir_all(&ws).unwrap();
for entry in std::fs::read_dir(&fx.path).unwrap().flatten() {
let from = entry.path();
let leaf = from.file_name().unwrap_or_default().to_owned();
std::os::unix::fs::symlink(&from, ws.join(leaf)).unwrap();
}
std::mem::forget(fx);
ws
}
#[test]
fn the_verb_is_offered_only_on_yogs_own_named_workspaces() {
let mut h = Harness::new();
let named = add_named(&h, "alba-koi", "c-1");
let replay = h.add_replay("20260101T-rr", "c-9");
let (_c, model) = h.model();
let confirm = model.delete_confirmation(&named).unwrap();
assert_eq!(confirm.name, "alba-koi");
assert_eq!(confirm.conversations, ["hi"], "named by its preview (§11)");
assert!(confirm.ball_ids().is_empty());
assert!(model.delete_confirmation(&h.ws).is_none(), "foreign");
assert!(model.delete_confirmation(&replay).is_none(), "replay");
assert!(model.delete_confirmation(&named.join("nope")).is_none());
}
#[test]
fn a_workspace_yog_did_not_place_is_refused_outright() {
let h = Harness::new();
let (_c, mut model) = h.model();
let err = model
.delete_workspace(&unused_bl(), &unused_bl(), &h.ws, "ws", "TS")
.unwrap_err();
assert_eq!(err, "not a yog-named workspace");
assert!(h.ws.exists());
}
#[test]
fn a_live_driver_refuses_the_unmaking_and_names_the_conversation() {
let h = Harness::new();
let named = add_named(&h, "alba-koi", "c-1");
let (_c, mut model) = h.model();
for agent in &mut model.deriver.trees.get_mut(&named).unwrap().agents {
agent.state = AgentState::Live;
}
model.publish();
let err = model
.delete_workspace(&unused_bl(), &unused_bl(), &named, "alba-koi", "TS")
.unwrap_err();
assert_eq!(err, "refused \u{2014} live conversations: hi");
assert!(named.exists(), "the wall stands until the driver stops");
}
#[test]
fn the_typed_name_is_the_safety_mechanism() {
let h = Harness::new();
let named = add_named(&h, "alba-koi", "c-1");
let (_c, mut model) = h.model();
let err = model
.delete_workspace(&unused_bl(), &unused_bl(), &named, "alba", "TS")
.unwrap_err();
assert_eq!(err, "type the workspace's name to confirm");
assert!(named.exists());
}
#[test]
fn the_unmaking_removes_the_wall_moves_the_focus_and_leaves_the_trail() {
let h = Harness::new();
let named = add_named(&h, "alba-koi", "c-1");
let (_c, mut model) = h.model_focused(Some(named.clone()));
assert_eq!(model.focused_workspace(), Some(named.as_path()));
model
.delete_workspace(&unused_bl(), &unused_bl(), &named, "alba-koi", "TS")
.unwrap();
model.tick();
assert!(!named.exists(), "the workspace directory is gone");
assert!(
!model.workspaces().iter().any(|w| w.path == named),
"the removal IS the de-registration (§3.1)"
);
assert_ne!(
model.focused_workspace(),
Some(named.as_path()),
"focus never points at a gone directory"
);
let ops = opslog::tail(&h.roots.yog_state, 8);
assert_eq!(
ops.last().map(|e| e.argv.clone()),
Some(vec![YOG_STEP.to_owned(), "delete-workspace".to_owned()])
);
assert!(model.ops_rows().iter().any(|r| !r.failed()));
}