use super::Engines;
use crate::test_support::window::{own, seated, wall};
use crate::ui::{Aim, Channel, Chunk, Model};
fn names(said: &[&str]) -> Vec<String> {
said.iter().map(|name| (*name).to_owned()).collect()
}
fn engine(name: &str, walls: &[&str]) -> Chunk {
Chunk {
channel: Channel {
name: name.to_owned(),
named_there: None,
dials: None,
},
held: crate::ui::Held::Heard,
walls: walls.iter().map(|wall_name| wall(wall_name)).collect(),
..Chunk::default()
}
}
#[test]
fn the_open_engine_is_first_and_the_rest_follow_the_last_time_each_was_opened() {
let mut engines = Engines::default();
engines.opened.insert("beta".to_owned(), 1);
engines.opened.insert("delta".to_owned(), 2);
let held = names(&["alpha", "beta", "delta", "gamma"]);
assert_eq!(
engines.order(&held, Some("alpha")),
names(&["alpha", "delta", "beta", "gamma"]),
"the open one is hoisted and the never-opened pair fall to the bottom by name"
);
assert_eq!(
engines.order(&held, Some("gamma")),
names(&["gamma", "delta", "beta", "alpha"]),
);
assert_eq!(
engines.order(&held, None),
names(&["delta", "beta", "alpha", "gamma"]),
"with nothing open the order is the openings alone"
);
}
#[test]
fn an_opening_outranks_every_opening_before_it() {
let mut model = Model {
roster: vec![engine("alpha", &["a"]), engine("beta", &["b"])],
..Model::default()
};
model.open_engine("alpha");
model.open_engine("beta");
assert_eq!(model.engines.open.as_deref(), Some("beta"));
assert_eq!(
model.engine_rows()[0].channel.name,
"beta",
"the open one paints first"
);
model.open_engine("alpha");
let order: Vec<String> = model
.engine_rows()
.iter()
.map(|chunk| chunk.channel.name.clone())
.collect();
assert_eq!(order, names(&["alpha", "beta"]));
}
#[test]
fn a_seat_nobody_has_told_opens_the_aims_engine_and_otherwise_the_first_by_name() {
let held = vec![engine("beta", &["b"]), engine("alpha", &["a"])];
let bare = Model {
roster: held.clone(),
..Model::default()
};
assert_eq!(bare.engine_open().as_deref(), Some("alpha"));
let aimed = Model {
aim: Some(Aim {
channel: "beta".to_owned(),
address: "b".to_owned(),
}),
roster: held.clone(),
..Model::default()
};
assert_eq!(aimed.engine_open().as_deref(), Some("beta"));
let said = Model {
engines: Engines {
open: Some("beta".to_owned()),
..Engines::default()
},
..aimed.clone()
};
assert_eq!(said.engine_open().as_deref(), Some("beta"));
let gone = Model {
engines: Engines {
open: Some("a channel this seat gave up".to_owned()),
..Engines::default()
},
..aimed
};
assert_eq!(
gone.engine_open().as_deref(),
Some("beta"),
"a name nothing resolves is inert and the aim answers instead"
);
assert_eq!(Model::default().engine_open(), None, "nothing to open");
}
#[test]
fn opening_aims_the_wall_this_seat_was_last_on_under_it() {
let mut model = Model {
roster: vec![engine("alpha", &["second", "first"])],
..Model::default()
};
model.open_engine("alpha");
assert_eq!(
model.aim.as_ref().map(|aim| aim.address.clone()),
Some("first".to_owned()),
"its first by `ordered`, which is by name here"
);
model.aim_at("alpha", "second");
model.open_engine("alpha");
assert_eq!(
model.aim.as_ref().map(|aim| aim.address.clone()),
Some("second".to_owned()),
"and the one it was left on once there is one"
);
}
#[test]
fn an_opening_aims_nothing_where_there_is_nothing_this_seat_can_address() {
let unreachable = Chunk {
channel: Channel {
name: "elsewhere".to_owned(),
named_there: Some("theirs".to_owned()),
dials: None,
},
walls: vec![wall("not-ours")],
..Chunk::default()
};
let mut model = Model {
roster: vec![unreachable],
engines: Engines {
aimed: [("elsewhere".to_owned(), "gone".to_owned())]
.into_iter()
.collect(),
..Engines::default()
},
..Model::default()
};
model.open_engine("elsewhere");
assert_eq!(model.aim, None);
model.open_engine("a channel this seat gave up");
assert_eq!(model.aim, None);
}
#[test]
fn aiming_writes_the_wall_down_under_its_engine() {
let mut model = seated();
model.standing = Some(own().channel.name.clone());
model.aim_at("(this box's own engine)", "home");
assert_eq!(
model.engines.aimed.get("(this box's own engine)"),
Some(&"home".to_owned())
);
assert_eq!(model.standing, None, "an aim is where the cursor is");
}
#[test]
fn beginning_on_an_engine_opens_it_aims_its_wall_and_asks_for_the_box() {
let mut model = Model {
roster: vec![own(), engine("lab", &["bench"])],
..seated()
};
model.begin_on("lab");
assert_eq!(model.engine_open().as_deref(), Some("lab"));
assert_eq!(
model.engines.opened.get("lab").copied(),
Some(1),
"an opening ranks, whichever control made it"
);
assert_eq!(
model.aim.as_ref().map(|aim| aim.address.clone()),
Some("bench".to_owned())
);
assert_eq!(model.conversation, None);
assert_eq!(model.column, crate::ui::Column::Conversation);
assert_eq!(model.fill, Some(crate::ui::Fill::Goal));
}
#[test]
fn beginning_on_an_engine_with_no_addressable_wall_still_clears_the_selection() {
let aimed = seated().aim.expect("the fixture is aimed");
let mut model = Model {
roster: vec![
own(),
Chunk {
channel: Channel {
name: "lab".to_owned(),
named_there: Some("theirs".to_owned()),
dials: None,
},
walls: vec![wall("not-ours")],
..engine("lab", &[])
},
],
..seated()
};
model.begin_on("lab");
assert_eq!(model.conversation, None, "the selection is cleared");
assert_eq!(model.aim, Some(aimed), "and the aim is left where it was");
assert_eq!(model.fill, Some(crate::ui::Fill::Goal));
}