use std::ffi::{OsStr, OsString};
use super::{App, Command, Harness, OpenOutcome};
use crate::widget::View;
mod links {
use crate::runtime::{Command, Open, OpenOutcome};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Msg {
Guide,
SignIn,
Opened(OpenOutcome),
Draw,
}
#[derive(Default)]
pub struct State {
pub heard: Vec<String>,
}
pub fn update(state: &mut State, msg: Msg) -> Command<Msg> {
match msg {
Msg::Guide => Command::open("https://quvyta.com/guide"),
Msg::SignIn => Command::open_with(Open::new("https://example.com/sign-in").answer(Msg::Opened)),
Msg::Draw => Command::open_with(Open::program("gimp").arg("--new-instance").dir("/tmp")),
Msg::Opened(outcome) => {
state.heard.push(match outcome {
OpenOutcome::Opened => "opened".to_owned(),
OpenOutcome::Failed(reason) => format!("failed {reason}"),
});
Command::none()
}
}
}
}
#[derive(Default)]
struct Host {
links: links::State,
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum Msg {
Links(links::Msg),
}
impl App for Host {
type Msg = Msg;
fn update(&mut self, msg: Msg) -> Command<Msg> {
match msg {
Msg::Links(msg) => links::update(&mut self.links, msg).map(Msg::Links),
}
}
fn view(&self, _ui: &mut View<'_, Msg>) {}
}
fn send(msg: links::Msg) -> Msg {
Msg::Links(msg)
}
#[test]
fn an_opening_is_recorded_with_what_it_was_asked_to_open_and_no_screen_is_given_away() {
let mut h = Harness::new(Host::default(), 20, 2);
assert!(h.opens().is_empty());
h.send(send(links::Msg::Guide));
let asked = h.opens();
assert_eq!(asked.len(), 1);
assert_eq!(asked[0].target.as_deref(), Some(OsStr::new("https://quvyta.com/guide")));
assert_eq!(asked[0].args, [OsString::from("https://quvyta.com/guide")]);
assert!(h.handoffs().is_empty(), "no handoff waits for it");
assert!(h.detached_handoffs().is_empty(), "and none detaches either");
assert!(h.app().links.heard.is_empty(), "this opening asked for no message");
}
#[test]
fn the_outcome_the_test_sets_reaches_the_application_through_a_mapped_message() {
let mut h = Harness::new(Host::default(), 20, 2);
h.send(send(links::Msg::SignIn));
assert_eq!(h.app().links.heard, ["opened"], "without an outcome the opening simply works");
h.set_open_outcome(OpenOutcome::Failed("no opener on this desktop".to_owned()));
h.send(send(links::Msg::SignIn));
assert_eq!(h.app().links.heard[1..], ["failed no opener on this desktop"]);
assert_eq!(h.opens().len(), 2);
assert_eq!(h.opens()[1].target.as_deref(), Some(OsStr::new("https://example.com/sign-in")));
}
#[test]
fn a_program_of_its_own_is_recorded_with_its_arguments_and_no_target() {
let mut h = Harness::new(Host::default(), 20, 2);
h.send(send(links::Msg::Draw));
let asked = h.opens();
assert_eq!(asked.len(), 1);
assert_eq!(asked[0].program, OsString::from("gimp"));
assert_eq!(asked[0].args, [OsString::from("--new-instance")]);
assert_eq!(asked[0].target, None, "nothing was handed to an opener");
}