#[doc(inline)]
pub use iced_test::selector;
use crate::Theme;
use iced::{window, Element};
use iced_test::Simulator;
use std::env;
use std::path::PathBuf;
use std::str::FromStr;
pub const TEST_KIND_ENV_VAR: &str = "TEST_KIND";
pub const SCREENSHOTS_DIR: &str = "screenshots";
pub const PREVIEW_DIR: &str = "preview";
pub const WINDOW_SIZE: iced::Size = iced::Size {
width: 1024.0,
height: 768.0,
};
#[derive(Debug, Default, strum::EnumString)]
#[strum(ascii_case_insensitive)]
pub enum TestKind {
#[default]
Compare,
Preview,
Accept,
}
#[derive(Debug)]
pub struct TestViewResult<'a> {
pub name: &'a str,
pub succeeded: bool,
}
#[derive(Debug, Clone, Copy)]
pub enum Size {
Fullscreen,
Specific { width: f32, height: f32 },
}
pub fn test_view<'a, 'b, Message, Renderer>(
results: &mut Vec<TestViewResult<'b>>,
uniq_name: &'b str,
element: impl Into<Element<'a, Message, Theme, Renderer>>,
size: Size,
) where
Renderer: iced::advanced::Renderer + iced::advanced::renderer::Headless,
{
test_view_change_sim(results, uniq_name, element, size, |_sim| {})
}
pub fn test_view_change_sim<'a, 'b, Message, Renderer, F>(
results: &mut Vec<TestViewResult<'b>>,
uniq_name: &'b str,
element: impl Into<Element<'a, Message, Theme, Renderer>>,
size: Size,
change_sim: F,
) where
Renderer: iced::advanced::Renderer + iced::advanced::renderer::Headless,
F: Fn(&mut Simulator<Message, Theme, Renderer>),
{
let test_kind = test_kind();
let size = match size {
Size::Fullscreen => WINDOW_SIZE,
Size::Specific { width, height } => iced::Size { width, height },
};
let mut sim = Simulator::<_, Theme, _>::with_size(
iced::Settings::default(),
size,
element,
);
change_sim(&mut sim);
let snapshot = sim.snapshot(&theme()).unwrap();
let file_name = format!("{uniq_name}.png");
match test_kind {
TestKind::Compare => {
let dir = PathBuf::from(PREVIEW_DIR);
let matched = snapshot.matches_image(dir.join(&file_name)).unwrap();
results.push(TestViewResult {
name: uniq_name,
succeeded: matched,
})
}
TestKind::Preview => {
let dir = PathBuf::from(PREVIEW_DIR);
let matched = snapshot.matches_image(dir.join(&file_name)).unwrap();
assert!(matched, "The view {uniq_name} doesn't have a unique name");
}
TestKind::Accept => {
let dir = PathBuf::from(SCREENSHOTS_DIR);
let matched = snapshot.matches_image(dir.join(&file_name)).unwrap();
assert!(matched, "The view {uniq_name} doesn't have a unique name");
}
}
}
pub fn test_kind() -> TestKind {
if let Ok(val) = env::var(TEST_KIND_ENV_VAR) {
let val = val.trim();
if !val.is_empty() {
return TestKind::from_str(val).unwrap_or_else(|err| {
panic!("Unexpected test kind: {val}, failed parsing with {err}")
});
}
}
TestKind::default()
}
pub fn report_results(results: Vec<TestViewResult<'_>>) {
let failed: Vec<_> = results
.into_iter()
.filter_map(
|TestViewResult { name, succeeded }| {
if succeeded {
None
} else {
Some(name)
}
},
)
.collect();
if !failed.is_empty() {
panic!("Changed views: {failed:#?}");
}
}
fn theme() -> Theme {
crate::theme(&(), window::Id::unique())
}