use super::{empty_model, model, model_focused, set_list, world};
use crate::projects::join::JoinState;
use crate::start::{BallSpec, Payload, Target};
use std::fs;
#[test]
fn internal_clones_are_hidden_until_the_toggle_reveals_them() {
let w = world();
let internal = w
.roots
.balls_clones
.parent()
.unwrap()
.join("plugins/bl-delivery/home/u/p/bl-x");
let enc = internal.to_string_lossy().replace('/', "%2F");
fs::create_dir_all(w.roots.balls_clones.join(enc)).unwrap();
let (_c, mut m) = model(&w);
assert!(
!m.show_internal(),
"internal clones hidden by default (§5.1 #1)"
);
assert_eq!(
m.project_paths(),
vec![w.project.clone()],
"the internal clone is filtered out of the project surface"
);
m.set_show_internal(true);
assert!(m.show_internal());
let mut want = vec![w.project.clone(), internal.clone()];
want.sort();
assert_eq!(m.project_paths(), want, "toggle reveals the internal clone");
m.set_show_internal(false);
assert_eq!(m.project_paths(), vec![w.project.clone()]);
}
#[test]
fn start_inputs_expose_the_ball_payload_and_roots() {
let w = world();
set_list(
&w,
r#"[{"id":"bl-rdy","title":"Go","body":"do it"},{"id":"bl-me","claimant":"me"}]"#,
);
let (_c, m) = model(&w);
let cards = m.startable();
assert_eq!(cards.len(), 1);
let Payload::Ball {
project,
ball: BallSpec::Existing { id, body, join, .. },
} = &cards[0].payload
else {
panic!("existing ball payload expected");
};
assert_eq!(id, "bl-rdy");
assert_eq!(body, "do it");
assert_eq!(*join, JoinState::ReadyStartable);
assert_eq!(project, &w.project);
assert_eq!(cards[0].home.as_path(), w.roots.home.as_path());
assert_eq!(
cards[0].balls_state_root.as_path(),
w.roots.balls_clones.parent().unwrap()
);
assert!(cards[0].claimants.contains(&"me".to_owned()));
let nb = m.new_ball_inputs(&w.project, "T", "B");
assert!(matches!(
nb.payload,
Payload::Ball {
ball: BallSpec::New { .. },
..
}
));
assert_eq!(
nb.target, cards[0].target,
"one resolved target per instance"
);
assert_eq!(m.yog_data_root(), w.roots.yog_data.as_path());
assert_eq!(m.project_paths(), vec![w.project.clone()]);
}
#[test]
fn bare_target_is_the_focused_workspace_named_or_foreign() {
let w = world();
let (_c, m) = model_focused(&w, &w.ws_cobalt);
assert_eq!(
m.start_bare_inputs().target,
Target::Existing {
workspace: w.ws_cobalt.clone()
}
);
let foreign = w.roots.lernie_data.join("workspaces/foreign");
let (_c2, mf) = model_focused(&w, &foreign);
assert_eq!(
mf.start_bare_inputs().target,
Target::Existing {
workspace: foreign.clone()
}
);
}
#[test]
fn bare_target_mints_without_a_focus() {
let (_root, m) = empty_model();
assert_eq!(m.start_bare_inputs().target, Target::Mint);
}
#[test]
fn new_workspace_inputs_always_mints_even_with_a_focus() {
let w = world();
let (_c, mut m) = model(&w);
m.focus_workspace(&w.ws_cobalt);
let inputs = m.new_workspace_inputs();
assert_eq!(
inputs.target,
Target::Mint,
"always Mint, not the focused Existing"
);
assert!(inputs.claimants.contains(&"boss".to_owned()));
}
#[test]
fn start_path_inputs_carries_the_path_payload_at_the_focused_target() {
let w = world();
let (_c, mut m) = model(&w);
m.focus_workspace(&w.ws_cobalt);
let inputs = m.start_path_inputs(std::path::Path::new("/work/here"));
assert_eq!(
inputs.target,
Target::Existing {
workspace: w.ws_cobalt.clone()
}
);
let Payload::Path { dir } = inputs.payload else {
panic!("path payload");
};
assert_eq!(dir, std::path::PathBuf::from("/work/here"));
}
#[test]
fn empty_project_hint_only_with_zero_projects() {
let w = world();
let (_c, m) = model(&w);
assert_eq!(m.empty_project_hint(), None, "a project is present");
let (_root, empty) = empty_model();
assert_eq!(
empty.empty_project_hint().as_deref(),
Some("yog exec bl prime")
);
}
#[test]
fn workspace_names_lists_the_named_workspaces_excluding_foreign() {
let w = world();
fs::create_dir_all(w.roots.lernie_data.join("workspaces/adhoc/repo.git")).unwrap();
let (_c, m) = model(&w);
let mut names = m.workspace_names();
names.sort();
assert_eq!(
names,
vec!["cobalt".to_owned(), "spare".to_owned()],
"foreign 'adhoc' excluded",
);
}
#[test]
fn focused_ws_name_is_the_focused_leaf_else_none() {
let w = world();
let (_c, mut m) = model(&w);
m.focus_workspace(&w.ws_cobalt);
assert_eq!(m.focused_ws_name(), Some("cobalt".to_owned()));
let (_root, empty) = empty_model();
assert_eq!(empty.focused_ws_name(), None, "no focus ⇒ no target");
}
#[test]
fn resumable_targets_the_bound_balls_own_workspace() {
let w = world();
let (_c, m) = model(&w);
let cards = m.resumable();
assert_eq!(cards.len(), 1, "only bl-work (Bound under cobalt)");
assert_eq!(
cards[0].target,
Target::Existing {
workspace: w.ws_cobalt.clone()
}
);
let Payload::Ball {
ball: BallSpec::Existing { id, join, .. },
..
} = &cards[0].payload
else {
panic!("existing-ball payload");
};
assert_eq!(id, "bl-work");
assert_eq!(*join, JoinState::Bound);
}