Skip to main content

glyph_core/
lib.rs

1mod error;
2mod format;
3
4pub use error::{GlyphError, Result};
5pub use format::{Frame, Glyph};
6
7#[cfg(test)]
8mod tests {
9    use super::*;
10    use std::io::Cursor;
11
12    fn create_test_frame(content: &str) -> Frame {
13        Frame::new(content.to_string())
14    }
15
16    fn create_test_frame_with_duration(content: &str, duration: u32) -> Frame {
17        Frame::with_duration(content.to_string(), duration)
18    }
19
20    #[test]
21    fn test_frame_creation() {
22        let frame = create_test_frame("abc\ndef");
23        assert_eq!(frame.content, "abc\ndef");
24        assert_eq!(frame.duration_ms, None);
25
26        let frame_with_duration = create_test_frame_with_duration("abc\ndef", 200);
27        assert_eq!(frame_with_duration.content, "abc\ndef");
28        assert_eq!(frame_with_duration.duration_ms, Some(200));
29    }
30
31    #[test]
32    fn test_single_frame() {
33        let mut glyph = Glyph::new(3, 2, 100);
34        let frame = create_test_frame("abc\ndef");
35        glyph.add_frame(frame).unwrap();
36
37        let mut buffer = Vec::new();
38        glyph.write(&mut buffer).unwrap();
39
40        let mut cursor = Cursor::new(buffer);
41        let read_glyph = Glyph::read(&mut cursor).unwrap();
42
43        assert_eq!(read_glyph.width, 3);
44        assert_eq!(read_glyph.height, 2);
45        assert_eq!(read_glyph.default_duration_ms, 100);
46        assert_eq!(read_glyph.frames.len(), 1);
47        assert_eq!(read_glyph.frames[0].content, "abc\ndef");
48    }
49
50    #[test]
51    fn test_multiple_frames() {
52        let mut glyph = Glyph::new(3, 2, 100);
53
54        let frame1 = create_test_frame("abc\ndef");
55        glyph.add_frame(frame1).unwrap();
56
57        let frame2 = create_test_frame_with_duration("abc\ndEf", 200);
58        glyph.add_frame(frame2).unwrap();
59
60        let mut buffer = Vec::new();
61        glyph.write(&mut buffer).unwrap();
62
63        let mut cursor = Cursor::new(buffer);
64        let read_glyph = Glyph::read(&mut cursor).unwrap();
65
66        assert_eq!(read_glyph.frames.len(), 2);
67        assert_eq!(read_glyph.frames[0].content, "abc\ndef");
68        assert_eq!(read_glyph.frames[1].content, "abc\ndEf");
69        assert_eq!(read_glyph.frames[1].duration_ms, Some(200));
70    }
71
72    #[test]
73    fn test_invalid_dimensions() {
74        let mut glyph = Glyph::new(3, 2, 100);
75
76        // Wrong height
77        let frame1 = create_test_frame("abc");
78        assert!(matches!(
79            glyph.add_frame(frame1),
80            Err(GlyphError::InvalidDimensions {
81                width: 3,
82                height: 1
83            })
84        ));
85
86        // Wrong width
87        let frame2 = create_test_frame("abcd\ndef");
88        assert!(matches!(
89            glyph.add_frame(frame2),
90            Err(GlyphError::InvalidDimensions {
91                width: 4,
92                height: 2
93            })
94        ));
95    }
96
97    #[test]
98    fn test_delta_encoding() {
99        let mut glyph = Glyph::new(3, 2, 100);
100
101        // First frame
102        glyph.add_frame(create_test_frame("abc\ndef")).unwrap();
103
104        // Second frame with one character changed
105        glyph.add_frame(create_test_frame("abC\ndef")).unwrap();
106
107        let mut buffer = Vec::new();
108        glyph.write(&mut buffer).unwrap();
109
110        // Verify we can read back the frames correctly
111        let mut cursor = Cursor::new(buffer);
112        let read_glyph = Glyph::read(&mut cursor).unwrap();
113
114        assert_eq!(read_glyph.frames[0].content, "abc\ndef");
115        assert_eq!(read_glyph.frames[1].content, "abC\ndef");
116
117        // Verify the frames have the expected differences
118        let different_chars: Vec<_> = read_glyph.frames[0]
119            .content
120            .chars()
121            .zip(read_glyph.frames[1].content.chars())
122            .enumerate()
123            .filter(|(_, (a, b))| a != b)
124            .map(|(i, _)| i)
125            .collect();
126
127        assert_eq!(different_chars.len(), 1); // Only one character should be different
128        assert_eq!(different_chars[0], 2); // The third character (index 2) should be different
129    }
130
131    #[test]
132    fn test_invalid_magic_number() {
133        let mut buffer = Vec::new();
134        buffer.extend_from_slice(b"INVALID"); // Wrong magic number
135        let mut cursor = Cursor::new(buffer);
136        assert!(matches!(
137            Glyph::read(&mut cursor),
138            Err(GlyphError::InvalidMagic)
139        ));
140    }
141
142    #[test]
143    fn test_invalid_version() {
144        let mut buffer = Vec::new();
145        buffer.extend_from_slice(b"GLYF");
146        buffer.extend_from_slice(&99u32.to_le_bytes()); // Wrong version
147        let mut cursor = Cursor::new(buffer);
148        assert!(matches!(
149            Glyph::read(&mut cursor),
150            Err(GlyphError::InvalidVersion)
151        ));
152    }
153
154    #[test]
155    fn test_empty_glyph() {
156        let glyph = Glyph::new(10, 5, 100);
157        assert_eq!(glyph.width, 10);
158        assert_eq!(glyph.height, 5);
159        assert_eq!(glyph.default_duration_ms, 100);
160        assert!(glyph.frames.is_empty());
161    }
162
163    #[test]
164    fn test_large_frame_sequence() {
165        let mut glyph = Glyph::new(3, 2, 100);
166        let base_frame = "abc\ndef";
167
168        // Add 100 frames with slight modifications
169        for i in 0..100 {
170            let content = if i == 0 {
171                base_frame.to_string()
172            } else {
173                format!("ab{}\ndef", (b'c' + (i % 26) as u8) as char)
174            };
175            glyph.add_frame(create_test_frame(&content)).unwrap();
176        }
177
178        let mut buffer = Vec::new();
179        glyph.write(&mut buffer).unwrap();
180
181        let mut cursor = Cursor::new(buffer);
182        let read_glyph = Glyph::read(&mut cursor).unwrap();
183
184        assert_eq!(read_glyph.frames.len(), 100);
185        for i in 0..100 {
186            let expected = if i == 0 {
187                base_frame.to_string()
188            } else {
189                format!("ab{}\ndef", (b'c' + (i % 26) as u8) as char)
190            };
191            assert_eq!(read_glyph.frames[i].content, expected);
192        }
193    }
194}