xacli_testing/testing/
ctx.rs1use std::{
9 cell::RefCell,
10 collections::VecDeque,
11 io::{self, Write},
12 rc::Rc,
13};
14
15use xacli_core::{Context, ContextInfo, InputEvent, Output, OutputCommand, ReadEvent};
16
17pub struct MockContext {
22 #[allow(dead_code)]
24 pub is_tty: bool,
25 pub info: ContextInfo,
27 pub input_events: VecDeque<InputEvent>,
29 pub stdout_buffer: Rc<RefCell<Vec<u8>>>,
31 pub stderr_buffer: Rc<RefCell<Vec<u8>>>,
33 #[allow(dead_code)]
35 pub queued_commands: Vec<OutputCommand>,
36}
37
38impl MockContext {
39 pub fn new(info: ContextInfo, input_events: VecDeque<InputEvent>, is_tty: bool) -> Self {
41 Self {
42 is_tty,
43 info,
44 input_events,
45 stdout_buffer: Rc::new(RefCell::new(Vec::new())),
46 stderr_buffer: Rc::new(RefCell::new(Vec::new())),
47 queued_commands: Vec::new(),
48 }
49 }
50
51 pub fn stdout_plain(&self) -> String {
53 String::from_utf8_lossy(&self.stdout_buffer.borrow()).to_string()
54 }
55
56 pub fn stderr_plain(&self) -> String {
58 String::from_utf8_lossy(&self.stderr_buffer.borrow()).to_string()
59 }
60}
61
62impl Context for MockContext {
63 fn info(&self) -> &ContextInfo {
64 &self.info
65 }
66
67 fn stdout(&mut self) -> Output {
68 Output::new(Box::new(SharedWriter(self.stdout_buffer.clone())))
69 }
70
71 fn stderr(&mut self) -> Output {
72 Output::new(Box::new(SharedWriter(self.stderr_buffer.clone())))
73 }
74}
75
76struct SharedWriter(Rc<RefCell<Vec<u8>>>);
77
78impl Write for SharedWriter {
79 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
80 self.0.borrow_mut().extend_from_slice(buf);
81 Ok(buf.len())
82 }
83
84 fn flush(&mut self) -> io::Result<()> {
85 Ok(())
86 }
87}
88
89impl ReadEvent for MockContext {
90 fn read_event(&mut self) -> xacli_core::Result<InputEvent> {
91 self.input_events.pop_front().ok_or_else(|| {
92 xacli_core::Error::IoError(io::Error::new(
93 io::ErrorKind::UnexpectedEof,
94 "No more input events in queue",
95 ))
96 })
97 }
98}