use std::any::Any;
use anyhow::Context as _;
use crate::output::SuperConsoleOutput;
use crate::superconsole::SuperConsole;
use crate::Dimensions;
pub struct TestOutput {
pub should_render: bool,
pub terminal_size: Dimensions,
pub frames: Vec<Vec<u8>>,
}
impl SuperConsoleOutput for TestOutput {
fn should_render(&mut self) -> bool {
self.should_render
}
fn output(&mut self, buffer: Vec<u8>) -> anyhow::Result<()> {
self.frames.push(buffer);
Ok(())
}
fn terminal_size(&self) -> anyhow::Result<Dimensions> {
Ok(self.terminal_size)
}
fn finalize(self: Box<Self>) -> anyhow::Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
pub trait SuperConsoleTestingExt {
fn test_output(&self) -> anyhow::Result<&TestOutput>;
fn test_output_mut(&mut self) -> anyhow::Result<&mut TestOutput>;
}
impl SuperConsoleTestingExt for SuperConsole {
fn test_output(&self) -> anyhow::Result<&TestOutput> {
self.output
.as_any()
.downcast_ref()
.context("Downcast failed")
}
fn test_output_mut(&mut self) -> anyhow::Result<&mut TestOutput> {
self.output
.as_any_mut()
.downcast_mut()
.context("Downcast failed")
}
}
pub fn test_console() -> SuperConsole {
let size = Dimensions {
width: 80,
height: 80,
};
SuperConsole::new_internal(
Some(size),
Box::new(TestOutput {
should_render: true,
terminal_size: size,
frames: Vec::new(),
}),
)
}
pub fn frame_contains(frame: &[u8], needle: impl AsRef<[u8]>) -> bool {
let needle = needle.as_ref();
for w in frame.windows(needle.len()) {
if w == needle {
return true;
}
}
false
}