test(shell-core): paint-output integration test for multi-select
Codex flagged that `panel.capabilities()` assertions don't actually prove `paint()` uses the result. Closed the loop with a real paint-output test: - Inline `CountingBackend` (RenderBackend impl) records draw_text and fill_round_rect call counts. - `multi_select_paint_diverges_from_full_section_paint` paints a multi-select panel + a single-select Frame panel through it and asserts the op counts differ. If `paint()` regressed to bypass `capabilities()` and call `for_kind(Frame)` for the multi case, the two paints would emit identical ops and the test would fail. Floor sanity: asserts the multi panel still emits ≥ 6 text ops (headers + Position/Size labels) and ≥ 1 round-rect (Size section W/H inputs). Without the multi carve-out the Size section was hidden, so this directly catches the bug codex caught earlier. 135 tests pass; cargo fmt + boundary check clean.
This commit is contained in:
parent
c001bdb41d
commit
48580f613c
|
|
@ -658,6 +658,74 @@ mod tests {
|
|||
.is_none());
|
||||
}
|
||||
|
||||
/// Minimal `RenderBackend` that counts paint ops — used by the
|
||||
/// next test to observe what `paint` actually emits. Mirrors the
|
||||
/// canvas_viewport tests' `RecordingBackend`.
|
||||
#[derive(Default)]
|
||||
struct CountingBackend {
|
||||
text: usize,
|
||||
round_rects: usize,
|
||||
}
|
||||
impl crate::RenderBackend for CountingBackend {
|
||||
fn begin_frame(&mut self) {}
|
||||
fn end_frame(&mut self) {}
|
||||
fn fill_rect(&mut self, _: Rect, _: Color) {}
|
||||
fn stroke_rect(&mut self, _: Rect, _: Color, _: f32) {}
|
||||
fn draw_text(&mut self, _: &crate::TextLayout, _: Point2D) {
|
||||
self.text += 1;
|
||||
}
|
||||
fn clip_rect(&mut self, _: Rect) {}
|
||||
fn save(&mut self) {}
|
||||
fn restore(&mut self) {}
|
||||
fn translate(&mut self, _: Point2D) {}
|
||||
fn stroke_line(&mut self, _: Point2D, _: Point2D, _: Color, _: f32) {}
|
||||
fn fill_round_rect(&mut self, _: Rect, _: f32, _: Color) {
|
||||
self.round_rects += 1;
|
||||
}
|
||||
fn stroke_round_rect(&mut self, _: Rect, _: f32, _: Color, _: f32) {}
|
||||
fn stroke_svg_path(&mut self, _: &str, _: Point2D, _: f32, _: Color, _: f32) {}
|
||||
fn resize(&mut self, _: u32, _: u32) {}
|
||||
fn dpi_scale(&self) -> f32 {
|
||||
1.0
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_select_paint_diverges_from_full_section_paint() {
|
||||
// Paint-output integration test: multi-select hides
|
||||
// fill+stroke+flex via `for_multi`; single-Frame paints all
|
||||
// sections via `for_kind`. If `paint` regressed to bypass
|
||||
// `capabilities()` for the multi panel, the two would emit
|
||||
// identical ops.
|
||||
let mut doc = Document::sample();
|
||||
doc.set_single_selection(NodeId::new(11));
|
||||
doc.toggle_selection(NodeId::new(12));
|
||||
let panel_multi = PropertyPanel::for_selection(&doc).expect("multi");
|
||||
doc.set_single_selection(NodeId::new(10));
|
||||
let panel_frame = PropertyPanel::for_selection(&doc).expect("frame");
|
||||
assert!(!panel_frame.is_multi);
|
||||
|
||||
let rect = Rect {
|
||||
origin: Point2D::new(0.0, 0.0),
|
||||
size: Point2D::new(280.0, 1200.0),
|
||||
};
|
||||
let multi = paint_and_count(&panel_multi, rect);
|
||||
let frame = paint_and_count(&panel_frame, rect);
|
||||
assert_ne!(multi, frame, "multi must paint fewer ops than single-Frame");
|
||||
assert!(multi.0 > 5 && multi.1 > 0, "Size section must paint");
|
||||
}
|
||||
|
||||
fn paint_and_count(panel: &PropertyPanel, rect: Rect) -> (usize, usize) {
|
||||
let mut backend = CountingBackend::default();
|
||||
{
|
||||
let mut cx = PaintCx {
|
||||
backend: &mut backend,
|
||||
};
|
||||
panel.paint(&mut cx, rect);
|
||||
}
|
||||
(backend.text, backend.round_rects)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_select_caps_keep_size_hide_fill_and_stroke() {
|
||||
// Codex CONCERN: asserting `SectionCapabilities::for_multi()`
|
||||
|
|
|
|||
Loading…
Reference in a new issue