Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_datime/tests/advanced_validation_demo.rs

12.1 KiB, 19 runs

created by r1870400018:8643, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! Comprehensive demonstration of the advanced validation framework features.
2//!
3//! This test showcases all the new advanced validation capabilities including:
4//! - Performance analytics and metrics
5//! - High-performance caching
6//! - Conditional validation rules
7//! - Parallel batch processing
8//! - Validation profiles and registry
9//!
10//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
11//! Anthropic Claude
12
13use oxedyne_fe2o3_datime::prelude::*;
14use oxedyne_fe2o3_core::prelude::*;
15
16
17#[test]
18fn test_validation_analytics() -> Outcome<()> {
19 let zone = CalClockZone::utc();
20 let mut analytics = ValidationAnalytics::new();
21
22 // Create some test data
23 let valid_calclock = res!(CalClock::new(2024, 6, 15, 10, 30, 0, 0, zone.clone()));
24 let validator = CalClockValidator::new();
25
26 // Track some specific validation results
27 analytics.track_validation_result(
28 &validator.validate_calclock(&valid_calclock),
29 "test_rule",
30 std::time::Duration::from_millis(5)
31 );
32
33 // Get analytics metrics
34 let metrics = analytics.get_metrics();
35 assert_eq!(metrics.total_validations, 1);
36 assert!(metrics.success_rate() > 0.0);
37
38 // Generate a report
39 let report = analytics.generate_report();
40 println!("Analytics Report:\n{}", report.format());
41
42 Ok(())
43}
44
45#[test]
46fn test_cached_validation() -> Outcome<()> {
47 let zone = CalClockZone::utc();
48 let base_validator = CalClockValidator::new();
49 let mut cached_validator = CachedValidator::new(base_validator);
50
51 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 0, 0, zone.clone()));
52
53 // First validation - will be computed and cached
54 let result1 = cached_validator.validate_calclock(&calclock);
55 assert!(result1.is_ok());
56
57 // Second validation - should come from cache
58 let result2 = cached_validator.validate_calclock(&calclock);
59 assert!(result2.is_ok());
60
61 // Check cache statistics
62 let stats = cached_validator.cache_stats();
63 assert_eq!(stats.total_operations(), 2);
64 assert!(stats.hit_rate() > 0.0); // Should have at least one cache hit
65
66 println!("Cache Statistics:\n{}", stats.format());
67
68 Ok(())
69}
70
71#[test]
72fn test_conditional_validation() -> Outcome<()> {
73 let zone = CalClockZone::utc();
74
75 // Create a conditional rule: extended hours on weekends, business hours on weekdays
76 let conditional_rule = ConditionalRule::new("weekend_extended_hours")
77 .condition(ValidationCondition::IsWeekend)
78 .if_true(ValidationRules::hour_range(8, 22)) // 8 AM - 10 PM on weekends
79 .if_false(ValidationRules::hour_range(9, 17)) // 9 AM - 5 PM on weekdays
80 .into_rule();
81
82 let mut validator = CalClockValidator::new();
83 validator.add_rule(conditional_rule);
84
85 // Test weekend time (should allow extended hours)
86 let weekend_time = res!(CalClock::new(2024, 6, 16, 20, 0, 0, 0, zone.clone())); // Sunday 8 PM
87 let weekend_result = validator.validate_calclock(&weekend_time);
88 println!("Weekend (Sunday 8 PM) validation result: {:?}", weekend_result);
89 assert!(weekend_result.is_ok(), "Weekend extended hours should be allowed");
90
91 // Test weekday time outside business hours (should fail)
92 let weekday_time = res!(CalClock::new(2024, 6, 17, 20, 0, 0, 0, zone.clone())); // Monday 8 PM
93 let weekday_result = validator.validate_calclock(&weekday_time);
94 println!("Weekday (Monday 8 PM) validation result: {:?}", weekday_result);
95 assert!(weekday_result.is_err(), "Weekday late hours should be rejected");
96
97 Ok(())
98}
99
100#[test]
101fn test_parallel_validation() -> Outcome<()> {
102 let zone = CalClockZone::utc();
103 let validator = CalClockValidator::new();
104 let parallel_validator = ParallelValidator::new(validator, 4); // 4 threads
105
106 // Create a large batch of CalClocks to validate
107 let mut calclocks = Vec::new();
108 for hour in 0..24 {
109 for minute in [0, 15, 30, 45] {
110 calclocks.push(res!(CalClock::new(2024, 6, 15, hour, minute, 0, 0, zone.clone())));
111 }
112 }
113
114 // Validate in parallel
115 let results = parallel_validator.validate_batch(&calclocks);
116
117 assert_eq!(results.total_items, calclocks.len());
118 assert!(results.all_valid(), "All basic CalClocks should be valid");
119 assert!(results.throughput() > 0.0, "Should have positive throughput");
120
121 println!("Parallel Validation Results:\n{}", results.format());
122
123 Ok(())
124}
125
126#[test]
127fn test_validation_profiles() -> Outcome<()> {
128 let zone = CalClockZone::utc();
129
130 // Create a business scheduling profile
131 let business_profile = ProfileBuilder::new("business_scheduling")
132 .description("Standard business scheduling validation")
133 .tag("business")
134 .business_hours_only()
135 .no_weekends()
136 .whole_minutes_only()
137 .build();
138
139 // Create validator from profile
140 let validator = business_profile.create_validator();
141
142 // Test valid business time
143 let business_time = res!(CalClock::new(2024, 6, 17, 10, 30, 0, 0, zone.clone())); // Monday 10:30 AM
144 assert!(validator.validate_calclock(&business_time).is_ok());
145
146 // Test invalid weekend time
147 let weekend_time = res!(CalClock::new(2024, 6, 16, 10, 30, 0, 0, zone.clone())); // Sunday 10:30 AM
148 assert!(validator.validate_calclock(&weekend_time).is_err());
149
150 Ok(())
151}
152
153#[test]
154fn test_profile_registry() -> Outcome<()> {
155 let mut registry = ProfileRegistry::new();
156
157 // Register standard profiles
158 res!(registry.register(StandardProfiles::business_scheduling()));
159 res!(registry.register(StandardProfiles::appointment_booking()));
160 res!(registry.register(StandardProfiles::historical_data()));
161
162 // Check registry contents
163 assert_eq!(registry.len(), 3);
164 assert!(registry.get("business_scheduling").is_some());
165 assert!(registry.get("nonexistent").is_none());
166
167 // Find profiles by tag
168 let business_profiles = registry.find_by_tag("business");
169 assert!(!business_profiles.is_empty());
170
171 println!("Registered profiles: {:?}", registry.list_names());
172
173 Ok(())
174}
175
176#[test]
177fn test_complex_conditional_rules() -> Outcome<()> {
178 let zone = CalClockZone::utc();
179
180 // Create complex conditional logic: maintenance window detection
181 let maintenance_condition = ValidationCondition::And(vec![
182 ValidationCondition::IsDayOfWeek(DayOfWeek::Sunday),
183 ValidationCondition::IsHourInRange(2, 4), // 2-4 AM
184 ]);
185
186 let maintenance_rule = ConditionalRule::new("maintenance_window")
187 .condition(maintenance_condition)
188 .if_true(ValidationRule::new("block_maintenance").with_calclock_validator(|_| {
189 Err(vec![ValidationError::new(
190 "maintenance_window",
191 "System maintenance window - operations blocked"
192 )])
193 }))
194 .into_rule();
195
196 let mut validator = CalClockValidator::new();
197 validator.add_rule(maintenance_rule);
198
199 // Test during maintenance window
200 let maintenance_time = res!(CalClock::new(2024, 6, 16, 3, 0, 0, 0, zone.clone())); // Sunday 3 AM
201 let maintenance_result = validator.validate_calclock(&maintenance_time);
202 assert!(maintenance_result.is_err(), "Maintenance window should block operations");
203
204 // Test outside maintenance window
205 let normal_time = res!(CalClock::new(2024, 6, 16, 10, 0, 0, 0, zone.clone())); // Sunday 10 AM
206 let normal_result = validator.validate_calclock(&normal_time);
207 assert!(normal_result.is_ok(), "Normal hours should be allowed");
208
209 Ok(())
210}
211
212#[test]
213fn test_validation_performance_comparison() -> Outcome<()> {
214 let zone = CalClockZone::utc();
215
216 // Create test data
217 let mut calclocks = Vec::new();
218 for i in 0..1000u32 {
219 let hour = (i % 24) as u8;
220 let minute = ((i * 5) % 60) as u8;
221 calclocks.push(res!(CalClock::new(2024, 6, 15, hour, minute, 0, 0, zone.clone())));
222 }
223
224 // Test regular validation
225 let validator = CalClockValidator::new();
226 let start = std::time::Instant::now();
227 for calclock in &calclocks {
228 let _ = validator.validate_calclock(calclock);
229 }
230 let regular_duration = start.elapsed();
231
232 // Test cached validation
233 let base_validator = CalClockValidator::new();
234 let mut cached_validator = CachedValidator::new(base_validator);
235 let start = std::time::Instant::now();
236 for calclock in &calclocks {
237 let _ = cached_validator.validate_calclock(calclock);
238 }
239 let cached_duration = start.elapsed();
240
241 // Test parallel validation
242 let parallel_validator = ParallelValidator::new(CalClockValidator::new(), 4);
243 let start = std::time::Instant::now();
244 let _results = parallel_validator.validate_batch(&calclocks);
245 let parallel_duration = start.elapsed();
246
247 println!("Performance Comparison:");
248 println!("Regular validation: {:?}", regular_duration);
249 println!("Cached validation: {:?}", cached_duration);
250 println!("Parallel validation: {:?}", parallel_duration);
251
252 // Cache should improve performance for repeated validations
253 let cache_stats = cached_validator.cache_stats();
254 println!("Cache hit rate: {:.1}%", cache_stats.hit_rate() * 100.0);
255
256 Ok(())
257}
258
259#[test]
260fn test_comprehensive_validation_scenario() -> Outcome<()> {
261 let zone = CalClockZone::utc();
262
263 // Create a comprehensive validation setup combining multiple advanced features
264 let mut analytics = ValidationAnalytics::new();
265
266 // Create a sophisticated validation profile
267 let profile = ProfileBuilder::new("enterprise_scheduling")
268 .description("Enterprise-grade scheduling validation")
269 .tag("enterprise")
270 .tag("production")
271 .conditional_business_hours()
272 .seasonal_hours()
273 .whole_minutes_only()
274 .build();
275
276 // Create cached validator from profile
277 let base_validator = profile.create_validator();
278 let mut cached_validator = CachedValidator::new(base_validator);
279
280 // Test data representing various scheduling scenarios
281 let test_scenarios = vec![
282 // Valid business scenarios
283 res!(CalClock::new(2024, 6, 17, 10, 30, 0, 0, zone.clone())), // Monday 10:30 AM
284 res!(CalClock::new(2024, 7, 15, 14, 0, 0, 0, zone.clone())), // Summer business hours
285 res!(CalClock::new(2024, 6, 16, 10, 30, 0, 0, zone.clone())), // Sunday 10:30 AM (weekend hours 10-14)
286
287 // Invalid scenarios
288 res!(CalClock::new(2024, 6, 17, 22, 0, 0, 0, zone.clone())), // Monday 10 PM (too late)
289 res!(CalClock::new(2024, 6, 17, 10, 30, 30, 0, zone.clone())), // Has seconds (not whole minute)
290 ];
291
292 let mut valid_count = 0;
293 let mut invalid_count = 0;
294
295 // Validate each scenario with analytics tracking
296 for (i, calclock) in test_scenarios.iter().enumerate() {
297 let result = analytics.track_validation(|| {
298 cached_validator.validate_calclock(calclock)
299 });
300
301 if result.is_ok() {
302 valid_count += 1;
303 println!("Scenario {}: VALID - {}", i + 1, calclock);
304 } else {
305 invalid_count += 1;
306 println!("Scenario {}: INVALID - {} (errors: {:?})",
307 i + 1, calclock, result.unwrap_err());
308 }
309 }
310
311 // Generate comprehensive report
312 let metrics = analytics.get_metrics();
313 let cache_stats = cached_validator.cache_stats();
314 let report = analytics.generate_report();
315
316 println!("\n=== COMPREHENSIVE VALIDATION REPORT ===");
317 println!("Valid scenarios: {}", valid_count);
318 println!("Invalid scenarios: {}", invalid_count);
319 println!("Success rate: {:.1}%", metrics.success_rate() * 100.0);
320 println!("Average validation time: {:?}", metrics.average_validation_time());
321 println!("Cache hit rate: {:.1}%", cache_stats.hit_rate() * 100.0);
322 println!("\nDetailed Analytics:");
323 println!("{}", report.format());
324
325 // Verify expected results
326 assert_eq!(valid_count, 3, "Should have 3 valid scenarios");
327 assert_eq!(invalid_count, 2, "Should have 2 invalid scenarios");
328 assert_eq!(metrics.total_validations, 5, "Should have processed 5 validations");
329
330 Ok(())
331}