use super::addressable;
use crate::app::Snapshot;
use crate::binding::{Workspace, WorkspaceKind};
use std::path::{Path, PathBuf};
use std::sync::Arc;
fn snap(workspaces: &[(&str, WorkspaceKind)], projects: &[&str]) -> Snapshot {
let mut s = Snapshot::empty(0);
s.workspaces = workspaces
.iter()
.map(|(p, kind)| Workspace {
path: PathBuf::from(p),
kind: kind.clone(),
})
.collect();
s.projects = projects.iter().map(PathBuf::from).collect();
s
}
fn named(name: &str) -> WorkspaceKind {
WorkspaceKind::Named {
name: name.to_owned(),
}
}
#[test]
fn workspace_round_trips_through_its_name() {
let s = snap(
&[
("/d/yog/workspaces/home", named("home")),
("/d/litany/workspaces/auto-1", WorkspaceKind::Foreign),
],
&[],
);
assert_eq!(s.ws_name(Path::new("/d/yog/workspaces/home")), "home");
assert_eq!(
s.ws_path("home"),
Ok(PathBuf::from("/d/yog/workspaces/home"))
);
assert_eq!(
s.ws_name(Path::new("/d/litany/workspaces/auto-1")),
"auto-1"
);
assert_eq!(
s.ws_path("auto-1"),
Ok(PathBuf::from("/d/litany/workspaces/auto-1"))
);
}
#[test]
fn project_round_trips_through_its_name() {
let s = snap(&[], &["/home/u/dev/yog", "/home/u/dev/litany"]);
assert_eq!(s.project_name(Path::new("/home/u/dev/yog")), "yog");
assert_eq!(s.project_path("yog"), Ok(PathBuf::from("/home/u/dev/yog")));
}
#[test]
fn unknown_names_refuse_and_name_the_set() {
let s = snap(&[("/d/yog/workspaces/home", named("home"))], &["/p/yog"]);
assert_eq!(
s.ws_path("nope"),
Err("unknown workspace \"nope\" — known: home".to_owned())
);
assert_eq!(
s.project_path("nope"),
Err("unknown project \"nope\" — known: yog".to_owned())
);
}
#[test]
fn the_live_enumeration_resolves_a_wall_the_derivation_has_not_read() {
let cached = snap(&[("/d/yog/workspaces/home", named("home"))], &[]);
let published = Arc::new(cached);
assert_eq!(
published.ws_path("fresh"),
Err("unknown workspace \"fresh\" — known: home".to_owned()),
"the cached set is what the defect resolved over"
);
let live = vec![
Workspace {
path: PathBuf::from("/d/yog/workspaces/home"),
kind: named("home"),
},
Workspace {
path: PathBuf::from("/d/yog/workspaces/fresh"),
kind: named("fresh"),
},
];
let current = addressable(Arc::clone(&published), live, published.projects.clone());
assert_eq!(
current.ws_path("fresh"),
Ok(PathBuf::from("/d/yog/workspaces/fresh"))
);
assert_eq!(current.derived_at_unix, published.derived_at_unix);
assert_eq!(current.projects, published.projects);
}
#[test]
fn a_workspace_disk_no_longer_holds_stops_resolving() {
let published = Arc::new(snap(&[("/d/yog/workspaces/gone", named("gone"))], &[]));
let current = addressable(published, Vec::new(), Vec::new());
assert_eq!(
current.ws_path("gone"),
Err("unknown workspace \"gone\" — none is enumerated here".to_owned())
);
}
#[test]
fn the_live_enumeration_resolves_a_project_the_derivation_has_not_read() {
let published = Arc::new(snap(&[], &["/d/clones/old"]));
assert_eq!(
published.project_path("proj"),
Err("unknown project \"proj\" — known: old".to_owned()),
"the cached set is what the defect resolved over"
);
let live = vec![PathBuf::from("/d/clones/old"), PathBuf::from("/d/proj")];
let current = addressable(Arc::clone(&published), Vec::new(), live);
assert_eq!(current.project_path("proj"), Ok(PathBuf::from("/d/proj")));
let gone = addressable(Arc::clone(&published), Vec::new(), Vec::new());
assert_eq!(
gone.project_path("old"),
Err("unknown project \"old\" — none is enumerated here".to_owned())
);
assert_eq!(current.derived_at_unix, published.derived_at_unix);
assert_eq!(current.balls_by_project, published.balls_by_project);
}
#[test]
fn an_unchanged_enumeration_is_handed_straight_back() {
let published = Arc::new(snap(&[("/d/yog/workspaces/home", named("home"))], &[]));
let live = vec![Workspace {
path: PathBuf::from("/d/yog/workspaces/home"),
kind: named("home"),
}];
let current = addressable(Arc::clone(&published), live, published.projects.clone());
assert!(Arc::ptr_eq(&published, ¤t));
}
#[test]
fn an_armed_name_resolves_off_the_arming_table_and_an_ambiguous_one_refuses() {
let policy = |project: &str| crate::fleet::Policy {
project: PathBuf::from(project),
cap: 1,
lease: None,
};
let mut s = snap(&[], &[]);
s.fleet
.insert("/elsewhere/otter".to_owned(), policy("/dev/p"));
assert_eq!(
s.armed_path("otter"),
Some(PathBuf::from("/elsewhere/otter"))
);
assert_eq!(s.armed_path("badger"), None, "no armed entry carries it");
s.fleet.insert("/other/otter".to_owned(), policy("/dev/p"));
assert_eq!(
s.armed_path("otter"),
None,
"one name for two armed workspaces addresses neither"
);
}