Skip to main content

saorsa_core/terminal/
test_backend.rs

1//! In-memory terminal backend for testing.
2
3use crate::error::Result;
4use crate::geometry::Size;
5
6use super::traits::{Terminal, TerminalCapabilities};
7
8/// In-memory terminal backend for testing.
9///
10/// All output is captured in a buffer that can be inspected.
11pub struct TestBackend {
12    size: Size,
13    capabilities: TerminalCapabilities,
14    buffer: Vec<u8>,
15    raw_mode: bool,
16    mouse_enabled: bool,
17}
18
19impl TestBackend {
20    /// Create a new test backend with the given size.
21    pub fn new(width: u16, height: u16) -> Self {
22        Self {
23            size: Size::new(width, height),
24            capabilities: TerminalCapabilities::default(),
25            buffer: Vec::new(),
26            raw_mode: false,
27            mouse_enabled: false,
28        }
29    }
30
31    /// Get the bytes written to this backend.
32    pub fn buffer(&self) -> &[u8] {
33        &self.buffer
34    }
35
36    /// Clear the output buffer.
37    pub fn clear_buffer(&mut self) {
38        self.buffer.clear();
39    }
40
41    /// Check if raw mode is active.
42    pub fn is_raw_mode(&self) -> bool {
43        self.raw_mode
44    }
45
46    /// Check if mouse capture is active.
47    pub fn is_mouse_enabled(&self) -> bool {
48        self.mouse_enabled
49    }
50
51    /// Set the terminal size (simulates a resize).
52    pub fn set_size(&mut self, width: u16, height: u16) {
53        self.size = Size::new(width, height);
54    }
55}
56
57impl Terminal for TestBackend {
58    fn size(&self) -> Result<Size> {
59        Ok(self.size)
60    }
61
62    fn capabilities(&self) -> &TerminalCapabilities {
63        &self.capabilities
64    }
65
66    fn enter_raw_mode(&mut self) -> Result<()> {
67        self.raw_mode = true;
68        Ok(())
69    }
70
71    fn exit_raw_mode(&mut self) -> Result<()> {
72        self.raw_mode = false;
73        Ok(())
74    }
75
76    fn write_raw(&mut self, data: &[u8]) -> Result<()> {
77        self.buffer.extend_from_slice(data);
78        Ok(())
79    }
80
81    fn flush(&mut self) -> Result<()> {
82        Ok(())
83    }
84
85    fn enable_mouse(&mut self) -> Result<()> {
86        self.mouse_enabled = true;
87        Ok(())
88    }
89
90    fn disable_mouse(&mut self) -> Result<()> {
91        self.mouse_enabled = false;
92        Ok(())
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn test_backend_size() {
102        let tb = TestBackend::new(80, 24);
103        let size = tb.size().ok();
104        assert_eq!(size, Some(Size::new(80, 24)));
105    }
106
107    #[test]
108    fn test_backend_write() {
109        let mut tb = TestBackend::new(80, 24);
110        tb.write_raw(b"hello").ok();
111        assert_eq!(tb.buffer(), b"hello");
112    }
113
114    #[test]
115    fn test_backend_clear() {
116        let mut tb = TestBackend::new(80, 24);
117        tb.write_raw(b"data").ok();
118        tb.clear_buffer();
119        assert!(tb.buffer().is_empty());
120    }
121
122    #[test]
123    fn test_backend_raw_mode() {
124        let mut tb = TestBackend::new(80, 24);
125        assert!(!tb.is_raw_mode());
126        tb.enter_raw_mode().ok();
127        assert!(tb.is_raw_mode());
128        tb.exit_raw_mode().ok();
129        assert!(!tb.is_raw_mode());
130    }
131
132    #[test]
133    fn test_backend_mouse() {
134        let mut tb = TestBackend::new(80, 24);
135        assert!(!tb.is_mouse_enabled());
136        tb.enable_mouse().ok();
137        assert!(tb.is_mouse_enabled());
138        tb.disable_mouse().ok();
139        assert!(!tb.is_mouse_enabled());
140    }
141
142    #[test]
143    fn test_backend_resize() {
144        let mut tb = TestBackend::new(80, 24);
145        tb.set_size(120, 40);
146        let size = tb.size().ok();
147        assert_eq!(size, Some(Size::new(120, 40)));
148    }
149}