#![allow(clippy::unwrap_used)]
use std::fs;
use std::path::Path;
use yog::multiplex::dispatch;
#[path = "multiplex_bl/fixtures.rs"]
mod fixtures;
use fixtures::{IDENT, fixture_gitconfig, found_project, git, plugin_wrapper, sole_child};
use yog::git_env::INHERITED as INHERITED_GIT_ENV;
fn set(key: &str, value: &Path) {
unsafe { std::env::set_var(key, value) };
}
fn argv(parts: &[&str]) -> Vec<String> {
parts.iter().map(|s| (*s).to_string()).collect()
}
fn probes_answer_and_found_nothing(world: &Path) {
for probe in ["--help", "-h", "--skill"] {
assert_eq!(dispatch(&argv(&["yog", "bl", probe])), Some(0), "{probe}");
assert!(!world.exists(), "{probe} founded {}", world.display());
}
}
fn an_unusable_anchor_fails_every_verb_but_a_probe(tmp: &Path) {
let blocked = tmp.join("not-a-dir");
fs::write(&blocked, "").unwrap();
set("XDG_DATA_HOME", &blocked.join("xdg-data"));
assert_eq!(dispatch(&argv(&["yog", "bl", "--skill", "prime"])), Some(1));
assert_eq!(dispatch(&argv(&["yog", "bl", "--help"])), Some(0));
}
#[test]
fn the_bl_arm_runs_the_whole_rung_on_the_embedded_balls() {
let tmp = tempfile::TempDir::new().unwrap();
for var in INHERITED_GIT_ENV {
unsafe { std::env::remove_var(var) };
}
for var in [
"BL_BINARY",
"LERNIE_BINARY",
"BZ_BINARY",
"YOG_NAME",
"BALLS_CLOCK",
"GIT_AUTHOR_NAME",
"GIT_AUTHOR_EMAIL",
"GIT_AUTHOR_DATE",
"GIT_COMMITTER_NAME",
"GIT_COMMITTER_EMAIL",
"GIT_COMMITTER_DATE",
] {
unsafe { std::env::remove_var(var) };
}
let bin = tmp.path().join("bin");
fs::create_dir(&bin).unwrap();
set("BL_DELIVERY_BINARY", &plugin_wrapper(&bin, "bl-delivery"));
set("BL_TRACKER_BINARY", &plugin_wrapper(&bin, "bl-tracker"));
set("HOME", &tmp.path().join("home"));
set("XDG_DATA_HOME", &tmp.path().join("data"));
set("XDG_STATE_HOME", &tmp.path().join("state"));
set("USER", Path::new("rung-actor"));
set("GIT_CONFIG_GLOBAL", &fixture_gitconfig(tmp.path()));
set("GIT_CONFIG_SYSTEM", Path::new("/dev/null"));
probes_answer_and_found_nothing(&tmp.path().join("data").join("yog"));
let proj = found_project(tmp.path());
assert_eq!(dispatch(&argv(&["yog", "bl", "--skill"])), Some(0));
assert_eq!(dispatch(&argv(&["yog", "bl"])), Some(2));
assert_eq!(dispatch(&argv(&["yog", "bl", "no-such-verb"])), Some(2));
for verb in ["prime", "sync", "install"] {
assert_eq!(
dispatch(&argv(&["yog", "bl", "--skill", verb])),
Some(0),
"{verb}"
);
}
assert_eq!(
dispatch(&argv(&["yog", "bl", "prime", "--as", "seam"])),
Some(0)
);
let tools = tmp.path().join("data/yog/world/tools");
for shim in ["bl", "lernie", "bz", "bl-delivery", "bl-tracker"] {
assert!(tools.join(shim).is_file(), "shim {shim} converged");
}
let clone = sole_child(&tmp.path().join("state/balls/clones"));
assert!(clone.join("config").is_dir(), "landing founded");
for plugin in ["bl-delivery", "bl-tracker"] {
let bound = fs::read_link(clone.join("config/config/plugins/bin").join(plugin)).unwrap();
assert_eq!(
bound,
tools.join(plugin),
"{plugin} bound to the world shim"
);
}
assert_eq!(
dispatch(&argv(&["yog", "bl", "create", "rung ball", "--as", "seam"])),
Some(0)
);
let mut balls_md: Vec<_> = fs::read_dir(clone.join("tasks/tasks"))
.unwrap()
.map(|e| e.unwrap().path())
.filter(|p| p.extension().is_some_and(|e| e == "md"))
.collect();
assert_eq!(balls_md.len(), 1, "one sealed ball: {balls_md:?}");
let task = balls_md.remove(0);
let id = task.file_stem().unwrap().to_str().unwrap().to_string();
assert_eq!(
dispatch(&argv(&["yog", "bl", "claim", &id, "--as", "seam"])),
Some(0)
);
let territory = tmp.path().join("state/balls/plugins/bl-delivery");
let worktree = territory.join(proj.strip_prefix("/").unwrap()).join(&id);
assert!(
worktree.join("README.md").is_file(),
"worktree materialized at {}",
worktree.display()
);
fs::write(worktree.join("work.txt"), "delivered\n").unwrap();
assert_eq!(
dispatch(&argv(&["yog", "bl", "close", &id, "--as", "seam"])),
Some(0)
);
let (name, email) = IDENT;
let head = git(&proj, &["log", "-1", "--format=%s%n%an <%ae>", "main"]);
assert!(head.contains(&format!("[{id}]")), "delivery tag: {head}");
assert!(
head.contains(&format!("{name} <{email}>")),
"author: {head}"
);
assert!(!task.exists(), "closed ball's file is gone");
let delivered = git(&proj, &["show", "main:work.txt"]);
assert_eq!(delivered, "delivered\n");
an_unusable_anchor_fails_every_verb_but_a_probe(tmp.path());
}