1use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
2
3use crate::rendering::frame::Cursor;
4use crate::rendering::frame::Frame;
5use crate::rendering::renderer::Renderer;
6use crate::{SelectOption, ViewContext};
7
8use super::TestTerminal;
9
10fn frame_from_lines(lines: &[crate::line::Line], _width: u16, _rows: u16) -> Frame {
11 Frame::new(lines.to_vec())
12 .with_cursor(Cursor {
13 row: lines.len().saturating_sub(1),
14 col: 0,
15 is_visible: true,
16 })
17 .clamp_cursor()
18}
19
20pub fn render_component(
21 mut render: impl FnMut(&ViewContext) -> Frame,
22 width: u16,
23 rows: u16,
24) -> TestTerminal {
25 let ctx = ViewContext::new((width, rows));
26 let frame = render(&ctx);
27 let terminal = TestTerminal::new(width, rows);
28 let mut renderer = Renderer::new(terminal, crate::theme::Theme::default(), (width, rows));
29 renderer.render_frame(|_| frame).unwrap();
30 renderer.writer().clone()
31}
32
33pub fn render_component_with_renderer(
34 mut render: impl FnMut(&ViewContext) -> Frame,
35 renderer: &mut Renderer<TestTerminal>,
36 width: u16,
37 rows: u16,
38) {
39 let ctx = ViewContext::new((width, rows));
40 let frame = render(&ctx);
41 renderer.render_frame(|_| frame).unwrap();
42}
43
44pub fn render_lines(lines: &[crate::line::Line], width: u16, rows: u16) -> TestTerminal {
45 render_component(|_| frame_from_lines(lines, width, rows), width, rows)
46}
47
48pub fn key(code: KeyCode) -> KeyEvent {
49 KeyEvent::new(code, KeyModifiers::NONE)
50}
51
52pub fn sample_options() -> Vec<SelectOption> {
53 vec![
54 SelectOption {
55 value: "a".into(),
56 title: "Alpha".into(),
57 description: None,
58 },
59 SelectOption {
60 value: "b".into(),
61 title: "Beta".into(),
62 description: None,
63 },
64 SelectOption {
65 value: "c".into(),
66 title: "Gamma".into(),
67 description: None,
68 },
69 ]
70}