use oxiui_core::Color;
use oxiui_render_soft::{
render_headless_once, render_headless_scene, Framebuffer, LinearGradient, SoftRenderer,
};
#[test]
fn soft_renderer_constructs() {
let _r = SoftRenderer::default();
}
#[test]
fn clear_frame_correct_length() {
let r = SoftRenderer::default();
let frame = r
.clear_frame(4, 4, Color(0, 0, 0, 255))
.expect("clear failed");
assert_eq!(frame.len(), 16);
}
#[test]
fn clear_frame_zero_dimensions() {
let r = SoftRenderer::default();
let frame = r
.clear_frame(0, 0, Color(255, 0, 0, 255))
.expect("clear zero-size failed");
assert_eq!(frame.len(), 0);
}
#[test]
fn clear_frame_large_buffer() {
let r = SoftRenderer::default();
let frame = r
.clear_frame(100, 80, Color(122, 162, 247, 255))
.expect("clear failed");
assert_eq!(frame.len(), 8000);
}
#[test]
fn headless_buffer_dimensions() {
let buf = render_headless_once(800, 600);
assert_eq!(buf.width, 800);
assert_eq!(buf.height, 600);
assert_eq!(buf.data.len(), 800 * 600 * 4);
}
#[test]
fn headless_buffer_has_content() {
let buf = render_headless_once(800, 600);
assert!(
buf.has_content(),
"headless buffer must not be fully transparent/zero"
);
}
#[test]
fn headless_buffer_zero_dimensions() {
let buf = render_headless_once(0, 0);
assert_eq!(buf.data.len(), 0);
assert!(!buf.has_content());
}
#[test]
fn headless_buffer_single_pixel() {
let buf = render_headless_once(1, 1);
assert_eq!(buf.data.len(), 4);
assert!(buf.has_content());
}
#[test]
fn headless_buffer_bg_is_tokyo_night_dark() {
let buf = render_headless_once(2, 2);
assert_eq!(buf.data[0], 26, "R should be 26 (#1A)");
assert_eq!(buf.data[1], 27, "G should be 27 (#1B)");
assert_eq!(buf.data[2], 38, "B should be 38 (#26)");
assert_eq!(buf.data[3], 255, "A should be 255 (fully opaque)");
}
#[test]
fn headless_png_roundtrip() {
let buf = render_headless_once(16, 8);
let tmp = std::env::temp_dir().join("oxiui_headless_test.png");
buf.save_png(&tmp).expect("PNG save failed");
let file = std::fs::File::open(&tmp).expect("could not open saved PNG");
let decoder = png::Decoder::new(std::io::BufReader::new(file));
let reader = decoder.read_info().expect("png read_info failed");
let info = reader.info();
assert_eq!(info.width, 16, "PNG width mismatch");
assert_eq!(info.height, 8, "PNG height mismatch");
assert_eq!(info.color_type, png::ColorType::Rgba);
let _ = std::fs::remove_file(&tmp);
}
#[test]
fn clear_frame_actually_fills_color() {
let r = SoftRenderer::default();
let frame = r
.clear_frame(2, 2, Color(122, 162, 247, 255))
.expect("clear");
assert!(
frame.iter().all(|&px| px == 0xFF7AA2F7),
"all pixels filled"
);
}
#[test]
fn render_scene_draws_rect() {
let r = SoftRenderer::default();
let fb = r.render(20, 20, Color(0, 0, 0, 255), |c| {
c.fill_rect(5.0, 5.0, 10.0, 10.0, Color(255, 0, 0, 255));
});
assert_eq!(fb.get_rgba(10, 10), Some((255, 0, 0, 255)));
assert_eq!(fb.get_rgba(0, 0), Some((0, 0, 0, 255)));
}
#[test]
fn headless_scene_has_drawn_content() {
let buf = render_headless_scene(32, 32, |c| {
c.fill_circle(16.0, 16.0, 8.0, Color(255, 255, 255, 255));
});
assert_eq!(buf.width, 32);
assert!(buf.has_content());
let idx = ((16 * 32 + 16) * 4) as usize;
assert_eq!(buf.data[idx], 255, "circle centre should be white");
}
#[test]
fn gradient_fill_then_png_roundtrip_preserves_pixels() {
let mut fb = Framebuffer::with_fill(8, 1, Color(0, 0, 0, 255));
let clip = oxiui_render_soft::ClipRect::full(8, 1);
let g = LinearGradient::two_stop(
(0.0, 0.0),
(8.0, 0.0),
Color(255, 0, 0, 255),
Color(0, 0, 255, 255),
);
g.fill_rect(&mut fb, &clip, 0.0, 0.0, 8.0, 1.0);
let before = fb.to_rgba_buffer();
let tmp = std::env::temp_dir().join("oxiui_gradient_roundtrip.png");
before.save_png(&tmp).expect("save png");
let file = std::fs::File::open(&tmp).expect("open png");
let decoder = png::Decoder::new(std::io::BufReader::new(file));
let mut reader = decoder.read_info().expect("read_info");
let out_size = reader.output_buffer_size().expect("output buffer size");
let mut decoded = vec![0u8; out_size];
let frame = reader.next_frame(&mut decoded).expect("next_frame");
decoded.truncate(frame.buffer_size());
assert_eq!(decoded, before.data, "PNG round-trip must preserve pixels");
let _ = std::fs::remove_file(&tmp);
}