use std::cell::RefCell;
use std::rc::Rc;
use egui_kittest::Harness;
use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state, default_wgpu_setup};
use rsplot::egui::{self, Color32};
use rsplot::{ManagedRoi, PlotWidget, Roi, RoiInteractionMode, YAxis};
const W: usize = 400;
const H: usize = 300;
fn is_red(px: &[u8]) -> bool {
px[0] > 200 && px[1] < 80 && px[2] < 80
}
fn red_columns(raw: &[u8]) -> Vec<u32> {
let mut cols = vec![0u32; W];
for (i, px) in raw.chunks_exact(4).enumerate() {
if is_red(px) {
cols[i % W] += 1;
}
}
cols
}
fn render(mode: RoiInteractionMode) -> (usize, u32) {
let rs = create_render_state(default_wgpu_setup());
rsplot::install(&rs);
let mut plot = PlotWidget::new(&rs, 0);
plot.add_curve(&[0.0, 10.0], &[0.0, 10.0], Color32::from_rgb(0, 0, 255));
plot.set_auto_reset_zoom(false);
plot.set_graph_x_limits(0.0, 10.0);
plot.set_graph_y_limits(0.0, 10.0, YAxis::Left);
let mut managed = ManagedRoi::new(Roi::Band {
begin: (5.0, 5.0),
end: (9.0, 5.0),
width: 2.0,
});
managed.line_width = 4.0;
let idx = plot.add_managed_roi(managed);
assert!(
plot.set_roi_interaction_mode(idx, mode),
"Band must accept {mode:?}"
);
let app = Rc::new(RefCell::new(plot));
let app_ui = app.clone();
let renderer = WgpuTestRenderer::from_render_state(rs);
let mut harness = Harness::builder()
.with_size(egui::vec2(W as f32, H as f32))
.with_pixels_per_point(1.0)
.renderer(renderer)
.build_ui(move |ui| {
app_ui.borrow_mut().show(ui);
});
harness.step();
harness.step();
let image = harness.render().expect("headless wgpu render");
let cols = red_columns(image.as_raw());
let leftmost = cols.iter().position(|&c| c >= 3).unwrap_or(W);
let total: u32 = cols.iter().sum();
(leftmost, total)
}
#[test]
fn band_unbounded_mode_spans_the_view_bounded_mode_does_not() {
let (unbounded_left, unbounded_total) = render(RoiInteractionMode::BandUnbounded);
let (bounded_left, bounded_total) = render(RoiInteractionMode::BandBounded);
assert!(
unbounded_total > 0 && bounded_total > 0,
"both modes must draw the band: unbounded={unbounded_total} bounded={bounded_total} total red px"
);
assert!(
unbounded_left < W && bounded_left < W,
"both modes must paint a real line/edge: unbounded_left={unbounded_left} bounded_left={bounded_left} (W={W})"
);
assert!(
bounded_left > unbounded_left + 80,
"UnboundedMode must reach far left of BoundedMode: unbounded_left={unbounded_left} bounded_left={bounded_left}"
);
}