tests.rs raw

use super::*;
use guiduck_scene::paint::color::palette::css;
use guiduck_scene::paint::{Blob, ImageAlphaType, ImageData, ImageFormat};

fn image(w: u32, h: u32) -> Graphic {
    Graphic::Image(ImageBrush::from(ImageData {
        data: Blob::new(std::sync::Arc::new(vec![0u8; (w * h * 4) as usize])),
        format: ImageFormat::Rgba8,
        alpha_type: ImageAlphaType::Alpha,
        width: w,
        height: h,
    }))
}

fn unit_square() -> Graphic {
    Graphic::from_path_cmds(&[
        PathCmd::Move(0.0, 0.0),
        PathCmd::Line(1.0, 0.0),
        PathCmd::Line(1.0, 1.0),
        PathCmd::Close,
    ])
}

#[test]
fn only_an_image_has_a_natural_size() {
    assert_eq!(image(40, 20).natural_size(), Some(Size::new(40.0, 20.0)));
    // Scale-free geometry has no size to report; inventing one would be a
    // lie, so a path must be given a box.
    assert_eq!(unit_square().natural_size(), None);
}

#[test]
fn a_path_scales_into_its_target_rect() {
    let mut fragment = Fragment::default();
    unit_square().paint_into(
        &mut fragment,
        Rect::new(10.0, 20.0, 30.0, 60.0),
        &GraphicPaint::Fill(css::BLACK.into()),
    );
    let items = &fragment.items;
    assert_eq!(items.len(), 1);
    let guiduck_scene::DisplayItem::Fill { shape, .. } = &items[0] else {
        panic!("expected a fill, got {:?}", items[0]);
    };
    // The unit square lands exactly on the rect: translated to its origin and
    // scaled non-uniformly to its extent.
    let bounds = shape.bounding_box();
    assert_eq!((bounds.x0, bounds.y0), (10.0, 20.0));
    assert_eq!((bounds.x1, bounds.y1), (30.0, 60.0));
}

#[test]
fn an_image_fills_its_target_rect() {
    let mut fragment = Fragment::default();
    let rect = Rect::new(0.0, 0.0, 32.0, 32.0);
    // The paint is a path's business; an image carries its own pixels and
    // must ignore it rather than tint or refuse.
    image(16, 16).paint_into(
        &mut fragment,
        rect,
        &GraphicPaint::Stroke(css::RED.into(), 4.0),
    );
    let items = &fragment.items;
    assert_eq!(items.len(), 1);
    let guiduck_scene::DisplayItem::Image { dest, .. } = &items[0] else {
        panic!("expected an image, got {:?}", items[0]);
    };
    assert_eq!(dest, &rect, "a 16x16 image scales into a 32x32 box");
}

#[test]
fn an_empty_rect_draws_nothing() {
    let mut fragment = Fragment::default();
    let empty = Rect::new(5.0, 5.0, 5.0, 5.0);
    unit_square().paint_into(&mut fragment, empty, &GraphicPaint::Fill(css::BLACK.into()));
    image(16, 16).paint_into(&mut fragment, empty, &GraphicPaint::Fill(css::BLACK.into()));
    assert!(fragment.items.is_empty());
}