use super::*;
fn args(words: &[&str]) -> Vec<String> {
words.iter().map(|w| w.to_string()).collect()
}
#[test]
fn test9984_peer_sync_is_not_the_fleets_git_sync() {
assert!(USAGE.contains("sync <peer>"), "the peer verb is named");
assert!(
USAGE.contains("`wsb sync`"),
"the usage must say what the OTHER sync is: {USAGE}"
);
assert!(
USAGE.contains("never pulls, pushes, merges, rebases, commits"),
"the usage must state what continuity never does to git"
);
assert_eq!(dispatch(&args(&["wsb", "peer", "reticulate"])), 2);
assert_eq!(dispatch(&args(&["wsb", "peer", "help"])), 0);
}
#[test]
fn test9985_an_ambiguous_peer_name_is_refused() {
let laptop = PeerView {
id: "aaaa1111".into(),
name: "laptop".into(),
fingerprint: String::new(),
address: String::new(),
state: "connected".into(),
detail: None,
shared_worktrees: 0,
};
let other = PeerView {
id: "aaaa2222".into(),
name: "laptop-2".into(),
..laptop.clone()
};
let peers = vec![laptop.clone(), other.clone()];
let chosen = choose(&peers, "laptop").expect("an exact name is not ambiguous");
assert_eq!(chosen.id, laptop.id);
let error = choose(&peers, "aaaa").expect_err("an ambiguous prefix must be refused");
assert!(error.contains("laptop"), "{error}");
assert!(error.contains("laptop-2"), "{error}");
let error = choose(&peers, "desktop").expect_err("an unknown name must be refused");
assert!(error.contains("laptop"), "{error}");
}
fn choose(peers: &[PeerView], name: &str) -> Result<PeerView, String> {
let matches: Vec<&PeerView> = peers
.iter()
.filter(|peer| peer.name.eq_ignore_ascii_case(name) || peer.id == name)
.collect();
if let [one] = matches.as_slice() {
return Ok((*one).clone());
}
let prefixed: Vec<&PeerView> = peers
.iter()
.filter(|peer| peer.id.starts_with(name) || peer.name.starts_with(name))
.collect();
match prefixed.as_slice() {
[one] => Ok((*one).clone()),
[] => Err(format!(
"no peer called '{name}'. This machine knows: {}",
peers
.iter()
.map(|peer| peer.name.as_str())
.collect::<Vec<_>>()
.join(", ")
)),
many => Err(format!(
"'{name}' matches {} peers: {}. Name one exactly.",
many.len(),
many.iter().map(|peer| peer.name.as_str()).collect::<Vec<_>>().join(", ")
)),
}
}
#[test]
fn test10145_the_usage_states_the_two_things_that_surprise_people() {
assert!(
USAGE.contains("service <peer> <service> <on|off>")
&& USAGE.contains("files, or a plugin's <plugin>.<service>"),
"the service must be switchable by name, and the names said: {USAGE}"
);
assert!(
USAGE.contains("MANUAL mode"),
"the default must be stated, not discovered: {USAGE}"
);
assert!(
USAGE.contains("take") && USAGE.contains("keep") && USAGE.contains("leave"),
"all three answers to a difference must be listed: {USAGE}"
);
for verb in ["services", "service", "mode", "deltas", "take", "keep", "leave", "reconsider"] {
assert_ne!(
dispatch(&args(&["wsb", "peer", verb, "somepeer"])),
2,
"'{verb}' must be a verb this command knows"
);
}
assert_eq!(dispatch(&args(&["wsb", "peer", "reticulate"])), 2);
}
#[test]
fn test10146_service_arguments_parse_through_the_model() {
use crate::peer::model::{Service, Switch, SyncMode};
assert_eq!(Service::parse("files"), Ok(Service::Files));
assert!(Service::parse("secrets").is_err(), "a service wsb does not run is refused");
assert!(Service::parse("file").is_err(), "no near-misses");
assert_eq!(Switch::parse("off"), Ok(Switch::Off));
assert!(Switch::parse("no").is_err());
assert_eq!(SyncMode::parse("auto"), Ok(SyncMode::Auto));
assert_eq!(SyncMode::parse("manual"), Ok(SyncMode::Manual));
assert!(SyncMode::parse("automatic").is_err());
}