tailwind-rs-core 0.15.4

Core types and utilities for tailwind-rs
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
//! API Stability Testing for tailwind-rs-core
//!
//! This module contains tests to ensure that public APIs maintain
//! backward compatibility and don't break between versions.

use crate::{
    classes::ClassBuilder,
    color::Color as TailwindColor,
    responsive::{Breakpoint, ResponsiveValue},
    theme::{Color as ThemeColor, Spacing, Theme},
    validation::{ClassValidator, ValidationError},
};

/// Test that public API functions maintain their signatures
#[cfg(test)]
mod api_signature_tests {
    use super::*;

    /// Test that ClassBuilder API is stable
    #[test]
    fn test_class_builder_api_stability() {
        // Test that all public methods exist and work as expected
        let builder = ClassBuilder::new();
        let _builder = builder.class("test-class");
        let _class_set = _builder.build();

        // Test that the API hasn't changed
        assert!(true, "ClassBuilder API should be stable");
    }

    /// Test that ClassSet API is stable
    #[test]
    fn test_class_set_api_stability() {
        let builder = ClassBuilder::new().class("test-class");
        let class_set = builder.build();

        // Test that all public methods exist
        let _css = class_set.to_css_classes();

        assert!(true, "ClassSet API should be stable");
    }

    /// Test that Color API is stable
    #[test]
    fn test_color_api_stability() {
        // Test that all public variants exist
        let _color1 = TailwindColor::Blue;
        let _color2 = TailwindColor::Red;
        let _color3 = TailwindColor::Green;
        let _color4 = TailwindColor::Yellow;

        // Test that all public methods exist
        let color = TailwindColor::Blue;
        let _name = color.name();

        assert!(true, "Color API should be stable");
    }

    /// Test that ResponsiveValue API is stable
    #[test]
    fn test_responsive_value_api_stability() {
        let mut responsive = ResponsiveValue::new();
        responsive.set_breakpoint(Breakpoint::Base, 10);

        // Test that all public methods exist
        responsive.set_breakpoint(Breakpoint::Sm, 20);
        let _value = responsive.get_breakpoint(Breakpoint::Sm);

        assert!(true, "ResponsiveValue API should be stable");
    }

    /// Test that Theme API is stable
    #[test]
    fn test_theme_api_stability() {
        let mut theme = Theme::new("test-theme");

        // Test that all public methods exist
        theme.add_color("primary", ThemeColor::hex("#3b82f6"));
        let _color = theme.get_color("primary");

        theme.add_spacing("test", Spacing::px(10.0));
        let _spacing = theme.get_spacing("test");

        assert!(true, "Theme API should be stable");
    }

    /// Test that ClassValidator API is stable
    #[test]
    fn test_class_validator_api_stability() {
        let validator = ClassValidator::new();

        // Test that all public methods exist
        let _result = validator.validate_class("test-class");
        let _result = validator.validate_classes(&["test-class".to_string()]);

        assert!(true, "ClassValidator API should be stable");
    }
}

/// Test that serialization formats are stable
#[cfg(test)]
mod serialization_stability_tests {
    use super::*;

    /// Test that Color serialization is stable
    #[test]
    fn test_color_serialization_stability() {
        let color = TailwindColor::Blue;

        // Test JSON serialization
        let json = serde_json::to_string(&color).expect("Should serialize to JSON");
        let deserialized: TailwindColor =
            serde_json::from_str(&json).expect("Should deserialize from JSON");
        assert_eq!(
            color, deserialized,
            "Color JSON serialization should be stable"
        );

        // Test that the format hasn't changed
        assert!(
            json.contains("Blue"),
            "Color serialization format should be stable"
        );
    }

    /// Test that Spacing serialization is stable
    #[test]
    fn test_spacing_serialization_stability() {
        let spacing = Spacing::px(10.0);

        // Test JSON serialization
        let json = serde_json::to_string(&spacing).expect("Should serialize to JSON");
        let deserialized: Spacing =
            serde_json::from_str(&json).expect("Should deserialize from JSON");
        assert_eq!(
            spacing, deserialized,
            "Spacing JSON serialization should be stable"
        );
    }

    /// Test that Theme serialization is stable
    #[test]
    fn test_theme_serialization_stability() {
        let mut theme = Theme::new("test-theme");
        theme.add_color("primary", ThemeColor::hex("#3b82f6"));
        theme.add_spacing("test", Spacing::px(10.0));

        // Test JSON serialization
        let json = serde_json::to_string(&theme).expect("Should serialize to JSON");
        let deserialized: Theme =
            serde_json::from_str(&json).expect("Should deserialize from JSON");

        assert_eq!(
            theme.get_color("primary").unwrap(),
            deserialized.get_color("primary").unwrap(),
            "Theme JSON serialization should be stable"
        );
    }

    /// Test that ResponsiveValue serialization is stable
    #[test]
    fn test_responsive_value_serialization_stability() {
        let mut responsive = ResponsiveValue::new();
        responsive.set_breakpoint(Breakpoint::Base, 10);
        responsive.set_breakpoint(Breakpoint::Sm, 20);

        // Test JSON serialization
        let json = serde_json::to_string(&responsive).expect("Should serialize to JSON");
        let deserialized: ResponsiveValue<i32> =
            serde_json::from_str(&json).expect("Should deserialize from JSON");

        assert_eq!(
            responsive.get_breakpoint(Breakpoint::Base),
            deserialized.get_breakpoint(Breakpoint::Base)
        );
        assert_eq!(
            responsive.get_breakpoint(Breakpoint::Sm),
            deserialized.get_breakpoint(Breakpoint::Sm)
        );
    }
}

/// Test that error types are stable
#[cfg(test)]
mod error_stability_tests {
    use super::*;

    /// Test that ValidationError variants are stable
    #[test]
    fn test_validation_error_stability() {
        // Test that all error variants exist and work
        let _error1 = ValidationError::InvalidClass("test".to_string());
        let _error2 = ValidationError::ClassConflict("class1".to_string(), "class2".to_string());
        let _error3 = ValidationError::DeprecatedClass("deprecated".to_string());
        let _error4 = ValidationError::UnsupportedClass("unsupported".to_string());

        // Test that error messages are stable
        let error = ValidationError::InvalidClass("test".to_string());
        let message = format!("{}", error);
        assert!(
            message.contains("Invalid class name"),
            "Error message should be stable"
        );
    }

    /// Test that error formatting is stable
    #[test]
    fn test_validation_error_formatting_stability() {
        let error = ValidationError::InvalidClass("test".to_string());

        // Test that error formatting is stable
        let formatted = format!("{}", error);
        assert!(
            formatted.contains("Invalid class name"),
            "Error formatting should be stable"
        );
    }
}

/// Test that default values are stable
#[cfg(test)]
mod default_stability_tests {
    use super::*;

    /// Test that default Color values are stable
    #[test]
    fn test_color_default_stability() {
        // Test that default colors are consistent
        let default_blue = TailwindColor::Blue;
        let default_red = TailwindColor::Red;

        assert_eq!(
            default_blue.name(),
            "blue",
            "Default blue color should be stable"
        );
        assert_eq!(
            default_red.name(),
            "red",
            "Default red color should be stable"
        );
    }

    /// Test that default Spacing values are stable
    #[test]
    fn test_spacing_default_stability() {
        // Test that default spacing values are consistent
        let default_px = Spacing::px(0.0);
        let default_rem = Spacing::rem(0.0);

        assert_eq!(
            default_px.to_css(),
            "0px",
            "Default px spacing should be stable"
        );
        assert_eq!(
            default_rem.to_css(),
            "0rem",
            "Default rem spacing should be stable"
        );
    }

    /// Test that default Theme values are stable
    #[test]
    fn test_theme_default_stability() {
        let theme = Theme::new("test-theme");

        // Test that default theme values are consistent
        assert_eq!(
            theme.name, "test-theme",
            "Default theme name should be stable"
        );
        assert!(
            theme.colors.is_empty(),
            "Default theme should have no colors"
        );
        assert!(
            theme.spacing.is_empty(),
            "Default theme should have no spacing"
        );
    }

    /// Test that default Breakpoint values are stable
    #[test]
    fn test_breakpoint_default_stability() {
        // Test that breakpoint min widths are stable
        assert_eq!(
            Breakpoint::Sm.min_width(),
            640,
            "SM breakpoint should be stable"
        );
        assert_eq!(
            Breakpoint::Md.min_width(),
            768,
            "MD breakpoint should be stable"
        );
        assert_eq!(
            Breakpoint::Lg.min_width(),
            1024,
            "LG breakpoint should be stable"
        );
        assert_eq!(
            Breakpoint::Xl.min_width(),
            1280,
            "XL breakpoint should be stable"
        );
        assert_eq!(
            Breakpoint::Xl2.min_width(),
            1536,
            "2XL breakpoint should be stable"
        );
    }
}

/// Test that performance characteristics are stable
#[cfg(test)]
mod performance_stability_tests {
    use super::*;
    use std::time::Instant;

    /// Test that ClassBuilder performance is stable
    #[test]
    fn test_class_builder_performance_stability() {
        let start = Instant::now();

        let mut builder = ClassBuilder::new();
        for i in 0..100 {
            builder = builder.class(&format!("class-{}", i));
        }
        let _class_set = builder.build();

        let duration = start.elapsed();

        // Performance should be reasonable (less than 5ms for 100 classes)
        assert!(
            duration.as_micros() < 5000,
            "ClassBuilder performance should be stable"
        );
    }

    /// Test that ClassValidator performance is stable
    #[test]
    fn test_class_validator_performance_stability() {
        let validator = ClassValidator::new();
        let classes: Vec<String> = (0..100).map(|i| format!("class-{}", i)).collect();

        let start = Instant::now();
        let _result = validator.validate_classes(&classes);
        let duration = start.elapsed();

        // Performance should be reasonable (less than 20ms for 100 classes)
        assert!(
            duration.as_millis() < 20,
            "ClassValidator performance should be stable"
        );
    }

    /// Test that serialization performance is stable
    #[test]
    fn test_serialization_performance_stability() {
        let theme = Theme::new("test-theme");

        let start = Instant::now();
        let _json = serde_json::to_string(&theme).expect("Should serialize");
        let duration = start.elapsed();

        // Serialization should be fast (less than 2ms)
        assert!(
            duration.as_micros() < 2000,
            "Serialization performance should be stable"
        );
    }
}

/// Test that migration paths are stable
#[cfg(test)]
mod migration_stability_tests {
    use super::*;

    /// Test that old API patterns still work
    #[test]
    fn test_legacy_api_patterns() {
        // Test that old patterns for creating classes still work
        let builder = ClassBuilder::new();
        let _class_set = builder.class("legacy-class").build();

        // Test that old patterns for creating colors still work
        let _color = TailwindColor::Blue;

        // Test that old patterns for creating themes still work
        let mut theme = Theme::new("legacy-theme");
        theme.add_color("primary", ThemeColor::hex("#3b82f6"));

        assert!(true, "Legacy API patterns should still work");
    }

    /// Test that new API patterns are backward compatible
    #[test]
    fn test_new_api_backward_compatibility() {
        // Test that new features don't break old usage
        let builder = ClassBuilder::new();
        let _class_set = builder.class("new-class").build();

        // Test that new color features don't break old usage
        let _color = TailwindColor::Blue;

        // Test that new theme features don't break old usage
        let mut theme = Theme::new("new-theme");
        theme.add_color("primary", ThemeColor::hex("#3b82f6"));

        assert!(true, "New API features should be backward compatible");
    }
}