Skip to main content

anathema_backend/testing/
mod.rs

1use std::time::Duration;
2
3use anathema_geometry::Size;
4use anathema_value_resolver::AttributeStorage;
5use anathema_widgets::components::events::Event;
6use anathema_widgets::paint::{Glyph, paint};
7use anathema_widgets::{GlyphMap, PaintChildren};
8use surface::TestSurface;
9
10use crate::Backend;
11
12mod events;
13mod surface;
14
15#[derive(Debug)]
16/// This is used for testing
17pub struct GlyphRef<'a> {
18    inner: Option<&'a Glyph>,
19}
20
21impl<'a> GlyphRef<'a> {
22    pub fn is_char(&self, rhs: char) -> bool {
23        let Some(glyph) = self.inner else { return false };
24        match glyph {
25            Glyph::Single(lhs, _) => *lhs == rhs,
26            Glyph::Cluster(_glyph_index, _) => todo!(),
27        }
28    }
29}
30
31#[derive(Debug)]
32pub struct TestBackend {
33    surface: TestSurface,
34    events: events::Events,
35}
36
37impl TestBackend {
38    pub fn new(size: impl Into<Size>) -> Self {
39        let size = size.into();
40        Self {
41            surface: TestSurface::new(size),
42            events: events::Events::new(),
43        }
44    }
45
46    pub fn at(&self, x: usize, y: usize) -> GlyphRef<'_> {
47        GlyphRef {
48            inner: self.surface.get(x, y),
49        }
50    }
51
52    pub fn line(&self, index: usize) -> String {
53        let glyphs = self.surface.line(index);
54        glyphs
55            .iter()
56            .filter_map(|g| match g {
57                Glyph::Single(c, _) => Some(c),
58                Glyph::Cluster(_, _) => None,
59            })
60            .collect::<String>()
61            .trim()
62            .to_string()
63    }
64
65    pub fn events(&mut self) -> events::EventsMut<'_> {
66        self.events.mut_ref()
67    }
68}
69
70impl Backend for TestBackend {
71    fn size(&self) -> Size {
72        self.surface.size
73    }
74
75    fn next_event(&mut self, _timeout: Duration) -> Option<Event> {
76        self.events.pop()
77    }
78
79    fn resize(&mut self, new_size: Size, glyph_map: &mut GlyphMap) {
80        self.surface.resize(new_size, glyph_map);
81    }
82
83    fn paint<'bp>(
84        &mut self,
85        glyph_map: &mut GlyphMap,
86        widgets: PaintChildren<'_, 'bp>,
87        attribute_storage: &AttributeStorage<'bp>,
88    ) {
89        self.surface.clear();
90        paint(&mut self.surface, glyph_map, widgets, attribute_storage);
91    }
92
93    fn render(&mut self, _glyph_map: &mut GlyphMap) {
94        // this does nothing here as everything written to the test buffer
95    }
96
97    fn clear(&mut self) {}
98}