1use crate::buffer::Buffer;
4use crate::component::Component;
5use crate::geom::{Rect, Size};
6use crate::render::RenderCx;
7use crate::style::Color;
8
9pub struct TestBuffer {
11 pub buffer: Buffer,
12}
13
14impl TestBuffer {
15 pub fn new(width: u16, height: u16) -> Self {
17 Self { buffer: Buffer::new(Size { width, height }) }
18 }
19
20 pub fn render<C: Component>(&mut self, component: &C) {
22 let rect = Rect { x: 0, y: 0, width: self.buffer.size.width, height: self.buffer.size.height };
23 let style = component.style();
24 let mut cx = RenderCx::new(rect, &mut self.buffer, style);
25 component.render(&mut cx);
26 }
27
28 #[track_caller]
30 pub fn assert_text(&self, x: u16, y: u16, expected: &str) {
31 let index = y as usize * self.buffer.size.width as usize + x as usize;
32 let cell = &self.buffer.cells[index];
33 assert_eq!(cell.symbol, expected,
34 "cell at ({}, {}) expected {:?}, got {:?}", x, y, expected, cell.symbol);
35 }
36
37 #[track_caller]
40 pub fn assert_line(&self, y: u16, expected: &str) {
41 let mut actual = String::new();
42 for x in 0..self.buffer.size.width {
43 let index = y as usize * self.buffer.size.width as usize + x as usize;
44 actual.push_str(&self.buffer.cells[index].symbol);
45 }
46 let actual = actual.trim_end();
47 assert_eq!(actual, expected,
48 "line {} expected {:?}, got {:?}", y, expected, actual);
49 }
50
51 #[track_caller]
53 pub fn assert_lines(&self, expected: &[&str]) {
54 for (y, exp) in expected.iter().enumerate() {
55 self.assert_line(y as u16, exp);
56 }
57 }
58
59 pub fn cell_fg(&self, x: u16, y: u16) -> Option<Color> {
61 let index = y as usize * self.buffer.size.width as usize + x as usize;
62 self.buffer.cells[index].style.fg
63 }
64
65 pub fn cell_bg(&self, x: u16, y: u16) -> Option<Color> {
67 let index = y as usize * self.buffer.size.width as usize + x as usize;
68 self.buffer.cells[index].style.bg
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::widgets::{Checkbox, Label};
76
77 #[test]
78 fn test_label_renders_text() {
79 let mut tb = TestBuffer::new(20, 1);
80 tb.render(&Label::new("hello"));
81 tb.assert_text(0, 0, "h");
82 tb.assert_line(0, "hello");
83 }
84
85 #[test]
86 fn test_checkbox_unchecked() {
87 let mut tb = TestBuffer::new(20, 1);
88 tb.render(&Checkbox::new("opt"));
89 tb.assert_text(1, 0, " "); }
91
92 #[test]
93 fn test_checkbox_checked() {
94 let mut tb = TestBuffer::new(20, 1);
95 tb.render(&Checkbox::new("opt").checked());
96 tb.assert_text(1, 0, "✓");
97 }
98}