use slate_framework::{Div, HeadlessApp, Image, IntoAny};
fn generate_quadrant_pattern() -> Vec<u8> {
let mut pixels = Vec::with_capacity(4 * 4 * 4);
for y in 0..4 {
for x in 0..4 {
let color = match (x < 2, y < 2) {
(true, true) => [255, 0, 0, 255], (false, true) => [0, 255, 0, 255], (true, false) => [0, 0, 255, 255], (false, false) => [255, 255, 255, 255], };
pixels.extend_from_slice(&color);
}
}
pixels
}
fn sample_pixel(img: &image::RgbaImage, x: u32, y: u32) -> [u8; 4] {
let p = img.get_pixel(x, y);
[p[0], p[1], p[2], p[3]]
}
fn colors_match(a: [u8; 4], b: [u8; 4], tolerance: u8) -> bool {
a.iter()
.zip(b.iter())
.all(|(av, bv)| (*av as i16 - *bv as i16).unsigned_abs() <= tolerance as u16)
}
#[test]
fn image_element_renders_to_headless() {
let _ = env_logger::builder().is_test(true).try_init();
let mut app = HeadlessApp::new(64, 64).expect("HeadlessApp creation failed");
let pattern = generate_quadrant_pattern();
let img = Image::new(4, 4, pattern);
let ui = Div::new().child(img).into_any();
let output = app.render(ui).expect("render failed");
let tolerance = 8;
let top_left = sample_pixel(&output, 0, 0);
let top_right = sample_pixel(&output, 2, 0);
let bottom_left = sample_pixel(&output, 0, 2);
let bottom_right = sample_pixel(&output, 2, 2);
assert!(
colors_match(top_left, [255, 0, 0, 255], tolerance),
"top-left expected red, got {:?}",
top_left
);
assert!(
colors_match(top_right, [0, 255, 0, 255], tolerance),
"top-right expected green, got {:?}",
top_right
);
assert!(
colors_match(bottom_left, [0, 0, 255, 255], tolerance),
"bottom-left expected blue, got {:?}",
bottom_left
);
assert!(
colors_match(bottom_right, [255, 255, 255, 255], tolerance),
"bottom-right expected white, got {:?}",
bottom_right
);
}
#[test]
fn image_element_with_style_override() {
let _ = env_logger::builder().is_test(true).try_init();
let mut app = HeadlessApp::new(64, 64).expect("HeadlessApp creation failed");
let pixels = vec![
255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
];
let img = Image::new(2, 2, pixels);
let ui = Div::new().child(img).into_any();
let output = app.render(ui).expect("render failed");
let p = sample_pixel(&output, 0, 0);
assert!(
colors_match(p, [255, 0, 0, 255], 8),
"expected red at origin, got {:?}",
p
);
}
#[test]
fn empty_image_does_not_crash() {
let _ = env_logger::builder().is_test(true).try_init();
let mut app = HeadlessApp::new(32, 32).expect("HeadlessApp creation failed");
let img = Image::default();
let ui = Div::new().child(img).into_any();
let output = app.render(ui);
assert!(output.is_ok(), "empty image render should not fail");
}
#[test]
fn oversized_image_degrades_gracefully() {
let _ = env_logger::builder().is_test(true).try_init();
let mut app = HeadlessApp::new(32, 32).expect("HeadlessApp creation failed");
let pixels = vec![255u8; 3000 * 100 * 4];
let img = Image::new(3000, 100, pixels);
assert_eq!(img.width(), 0, "oversized image should have width 0");
assert_eq!(img.height(), 0, "oversized image should have height 0");
let ui = Div::new().child(img).into_any();
let output = app.render(ui);
assert!(output.is_ok(), "oversized image render should not fail");
}