1mod color;
2mod color_presets;
3mod gradient;
4mod shimmer;
5mod text_modifier;
6
7pub use color::Color;
8pub use gradient::Gradient;
9pub use shimmer::{Shimmer, ShimmerText};
10pub use text_modifier::TextModifier;
11
12#[cfg(test)]
13mod tests {
14 use super::*;
15
16 #[test]
17 fn test_basic_gradient() {
18 let result = "test".gradient(Color::RED, Color::BLUE, None);
19 assert!(!result.is_empty());
20 assert!(result.contains("\x1b[38;2;"));
21 assert!(result.contains("\x1b[39m")); }
23
24 #[test]
25 fn test_basic_gradient_bg() {
26 let result = "test".gradient_bg(Color::RED, Color::BLUE, None);
27 assert!(!result.is_empty());
28 assert!(result.contains("\x1b[48;2;"));
29 assert!(result.contains("\x1b[49m")); }
31
32 #[test]
33 fn test_empty_string() {
34 let result = "".gradient(Color::RED, Color::BLUE, None);
35 assert!(result.is_empty());
36
37 let result_bg = "".gradient_bg(Color::RED, Color::BLUE, None);
38 assert!(result_bg.is_empty());
39 }
40
41 #[test]
42 fn test_multiline_block_true() {
43 let text = "line1\nline2";
44 let result = text.gradient(Color::RED, Color::BLUE, Some(true));
45 assert!(result.contains("\n"));
46 let lines: Vec<&str> = result.split('\n').collect();
48 assert_eq!(lines.len(), 2);
49 assert!(lines[0].starts_with("\x1b[38;2;"));
50 assert!(lines[1].starts_with("\x1b[38;2;"));
51 }
52
53 #[test]
54 fn test_multiline_block_false() {
55 let text = "line1\nline2";
56 let result = text.gradient(Color::RED, Color::BLUE, Some(false));
57 assert!(result.contains("\n"));
58 let lines: Vec<&str> = result.split('\n').collect();
60 assert_eq!(lines.len(), 2);
61 assert!(lines[0].starts_with("\x1b[38;2;"));
62 assert!(lines[1].contains("\x1b[38;2;")); }
64
65 #[test]
66 fn test_multiline_bg_block_false() {
67 let text = "line1\nline2";
68 let result = text.gradient_bg(Color::RED, Color::BLUE, Some(false));
69 assert!(result.contains("\n"));
70 assert!(result.contains("\x1b[49m\n"));
72 let lines: Vec<&str> = result.split('\n').collect();
74 assert_eq!(lines.len(), 2);
75 assert!(lines[0].contains("\x1b[48;2;"));
76 assert!(lines[0].ends_with("\x1b[49m"));
77 }
78
79 #[test]
80 fn test_gradient_chaining() {
81 let result = "test".gradient(Color::RED, Color::BLUE, None).gradient_bg(
83 Color::GREEN,
84 Color::YELLOW,
85 None,
86 );
87
88 assert!(result.contains("\x1b[38;2;")); assert!(result.contains("\x1b[48;2;")); assert!(result.contains("\x1b[39m")); assert!(result.contains("\x1b[49m")); let result = "test"
97 .gradient_bg(Color::GREEN, Color::YELLOW, None)
98 .gradient(Color::RED, Color::BLUE, None);
99
100 assert!(result.contains("\x1b[38;2;")); assert!(result.contains("\x1b[48;2;")); assert!(result.contains("\x1b[39m")); assert!(result.contains("\x1b[49m")); }
107
108 #[test]
109 fn test_with_existing_ansi() {
110 let bold_text = "test".bold();
112 let result = bold_text.gradient(Color::RED, Color::BLUE, None);
113 assert!(result.contains("\x1b[1m")); assert!(result.contains("\x1b[38;2;")); let colored_text = "test".fg(Color::RED);
118 let result = colored_text.gradient_bg(Color::GREEN, Color::BLUE, None);
119 assert!(result.contains("\x1b[38;2;")); assert!(result.contains("\x1b[48;2;")); }
122
123 #[test]
124 fn test_special_characters() {
125 let text = "test 👍 emoji";
126 let result = text.gradient(Color::RED, Color::BLUE, None);
127 assert!(!result.is_empty());
128 assert!(result.contains("👍"));
129
130 let result_bg = text.gradient_bg(Color::RED, Color::BLUE, None);
131 assert!(!result_bg.is_empty());
132 assert!(result_bg.contains("👍"));
133 }
134
135 #[test]
136 fn test_color_interpolation() {
137 let color1 = Color::new(255, 0, 0);
138 let color2 = Color::new(0, 0, 255);
139 let mid = color1.interpolate(&color2, 0.5);
140 assert_eq!(mid.r, 127);
141 assert_eq!(mid.b, 127);
142 }
143
144 #[test]
145 fn test_shimmer_creation() {
146 let shimmer_text = "Hello World".shimmer(Color::RED, None);
147 let rendered = shimmer_text.static_render();
148 assert!(!rendered.is_empty());
149 assert!(rendered.contains("\x1b[38;2;"));
150 }
151
152 #[test]
153 fn test_shine_creation() {
154 let shine_text = "Shining Text".shine(Color::BLUE);
155 let rendered = shine_text.static_render();
156 assert!(!rendered.is_empty());
157 assert!(rendered.contains("\x1b[38;2;"));
158 }
159
160 #[test]
161 fn test_glow_creation() {
162 let glow_text = "Glowing Text".glow(Color::GREEN, 200);
163 let rendered = glow_text.static_render();
164 assert!(!rendered.is_empty());
165 assert!(rendered.contains("\x1b[38;2;"));
166 }
167
168 #[test]
169 fn test_shimmer_chaining() {
170 let shimmer_text = "Test"
171 .shimmer(Color::RED, None)
172 .speed(50)
173 .background(Color::BLACK)
174 .intensity(180);
175 let rendered = shimmer_text.static_render();
176 assert!(!rendered.is_empty());
177 }
178
179 #[test]
180 fn test_mixed_content() {
181 let text = "line1\nline2";
182 let result = text.gradient_bg(Color::RED, Color::BLUE, Some(false));
183 assert!(result.contains("\x1b[49m\n")); assert!(result.contains("\n")); let lines: Vec<&str> = result.split('\n').collect();
187 assert_eq!(lines.len(), 2);
188 assert!(lines[0].contains("\x1b[48;2;")); }
190}