1#[cfg(test)]
8mod tests {
9 use crate::reflection::{
10 rag_synthesis::{RagDataSynthesizer, RagSynthesisConfig},
11 schema_graph::SchemaGraph,
12 smart_mock_generator::{SmartMockConfig, SmartMockGenerator},
13 validation_framework::{
14 CustomValidationRule, GeneratedEntity, ValidationConfig, ValidationFramework,
15 ValidationRuleType,
16 },
17 };
18
19 use std::collections::HashMap;
20 use std::time::SystemTime;
21
22 #[tokio::test]
24 async fn test_complete_data_synthesis_pipeline() {
25 let config = SmartMockConfig {
27 field_name_inference: true,
28 use_faker: true,
29 field_overrides: HashMap::new(),
30 service_profiles: HashMap::new(),
31 max_depth: 3,
32 seed: Some(12345),
33 deterministic: true,
34 };
35
36 let _generator = SmartMockGenerator::new_with_seed(config, 12345);
37
38 let rag_config = RagSynthesisConfig {
40 enabled: false, rag_config: None,
42 context_sources: vec![],
43 prompt_templates: HashMap::new(),
44 max_context_length: 2000,
45 cache_contexts: true,
46 };
47
48 let _rag_synthesizer = RagDataSynthesizer::new(rag_config);
49
50 let validation_config = ValidationConfig {
52 enabled: true,
53 strict_mode: false,
54 max_validation_depth: 3,
55 custom_rules: vec![CustomValidationRule {
56 name: "email_format".to_string(),
57 applies_to_entities: vec!["User".to_string()],
58 validates_fields: vec!["email".to_string()],
59 rule_type: ValidationRuleType::FieldFormat,
60 parameters: HashMap::from([(
61 "pattern".to_string(),
62 r"^[^@\s]+@[^@\s]+\.[^@\s]+$".to_string(),
63 )]),
64 error_message: "Invalid email format".to_string(),
65 }],
66 cache_results: true,
67 };
68
69 let mut validator = ValidationFramework::new(validation_config);
70
71 let entities = vec![
73 GeneratedEntity {
74 entity_type: "User".to_string(),
75 primary_key: Some("user_1".to_string()),
76 field_values: HashMap::from([
77 ("id".to_string(), "user_1".to_string()),
78 ("name".to_string(), "John Doe".to_string()),
79 ("email".to_string(), "john@example.com".to_string()),
80 ]),
81 endpoint: "/users".to_string(),
82 generated_at: SystemTime::now(),
83 },
84 GeneratedEntity {
85 entity_type: "Order".to_string(),
86 primary_key: Some("order_1".to_string()),
87 field_values: HashMap::from([
88 ("id".to_string(), "order_1".to_string()),
89 ("user_id".to_string(), "user_1".to_string()),
90 ("total".to_string(), "99.99".to_string()),
91 ]),
92 endpoint: "/orders".to_string(),
93 generated_at: SystemTime::now(),
94 },
95 ];
96
97 for entity in entities {
99 validator.register_entity(entity).expect("Should register entity");
100 }
101
102 let validation_result = validator.validate_all_entities();
104
105 assert!(validation_result.is_valid, "Validation should pass");
107 assert!(validation_result.errors.is_empty(), "Should have no validation errors");
108
109 let stats = validator.get_statistics();
110 assert_eq!(stats.total_entities, 2);
111 assert_eq!(stats.entity_type_count, 2);
112 }
113
114 #[test]
115 fn test_deterministic_data_generation() {
116 let config = SmartMockConfig {
118 seed: Some(999),
119 deterministic: true,
120 ..Default::default()
121 };
122
123 let mut gen1 = SmartMockGenerator::new(config.clone());
124 let mut gen2 = SmartMockGenerator::new(config);
125
126 let uuid1 = gen1.generate_uuid();
128 let uuid2 = gen2.generate_uuid();
129 assert_eq!(uuid1, uuid2, "Deterministic generators should produce identical UUIDs");
130
131 let str1 = gen1.generate_random_string(10);
133 let str2 = gen2.generate_random_string(10);
134 assert_eq!(str1, str2, "Deterministic generators should produce identical strings");
135 }
136
137 #[test]
138 fn test_validation_with_foreign_key_violations() {
139 let mut validator = ValidationFramework::new(ValidationConfig::default());
140
141 let schema_graph = SchemaGraph {
143 entities: HashMap::new(),
144 relationships: vec![],
145 foreign_keys: HashMap::from([(
146 "Order".to_string(),
147 vec![crate::reflection::schema_graph::ForeignKeyMapping {
148 field_name: "user_id".to_string(),
149 target_entity: "User".to_string(),
150 confidence: 0.9,
151 detection_method:
152 crate::reflection::schema_graph::ForeignKeyDetectionMethod::NamingConvention,
153 }],
154 )]),
155 };
156
157 validator.set_schema_graph(schema_graph);
158
159 let order_entity = GeneratedEntity {
161 entity_type: "Order".to_string(),
162 primary_key: Some("order_1".to_string()),
163 field_values: HashMap::from([
164 ("id".to_string(), "order_1".to_string()),
165 ("user_id".to_string(), "nonexistent_user".to_string()),
166 ]),
167 endpoint: "/orders".to_string(),
168 generated_at: SystemTime::now(),
169 };
170
171 validator.register_entity(order_entity).unwrap();
172
173 let result = validator.validate_all_entities();
174
175 assert!(!result.errors.is_empty(), "Should have foreign key validation errors");
177 assert!(result.errors.iter().any(|e| matches!(
178 e.error_type,
179 crate::reflection::validation_framework::ValidationErrorType::ForeignKeyNotFound
180 )));
181 }
182
183 #[test]
184 fn test_rag_synthesizer_deterministic_behavior() {
185 let config = RagSynthesisConfig::default();
186 let synthesizer = RagDataSynthesizer::new(config);
187
188 let hash1 = synthesizer.hash_field_name("user_id");
190 let hash2 = synthesizer.hash_field_name("user_id");
191 assert_eq!(hash1, hash2, "Field name hashing should be deterministic");
192
193 let hash3 = synthesizer.hash_field_name("different_field");
194 assert_ne!(hash1, hash3, "Different field names should have different hashes");
195 }
196
197 #[cfg(feature = "data-faker")]
198 #[test]
199 fn test_faker_integration_with_deterministic_seeding() {
200 let config = SmartMockConfig {
201 use_faker: true,
202 seed: Some(777),
203 deterministic: true,
204 ..Default::default()
205 };
206
207 let generator = SmartMockGenerator::new(config);
208
209 assert!(generator.is_faker_enabled(), "Faker should be initialized");
211
212 assert!(generator.config().deterministic);
214 assert_eq!(generator.config().seed, Some(777));
215 }
216
217 #[test]
218 fn test_validation_custom_rules_comprehensive() {
219 let config = ValidationConfig {
220 enabled: true,
221 strict_mode: true,
222 max_validation_depth: 3,
223 custom_rules: vec![
224 CustomValidationRule {
225 name: "age_range".to_string(),
226 applies_to_entities: vec!["User".to_string()],
227 validates_fields: vec!["age".to_string()],
228 rule_type: ValidationRuleType::Range,
229 parameters: HashMap::from([
230 ("min".to_string(), "0".to_string()),
231 ("max".to_string(), "120".to_string()),
232 ]),
233 error_message: "Age must be between 0 and 120".to_string(),
234 },
235 CustomValidationRule {
236 name: "unique_email".to_string(),
237 applies_to_entities: vec!["User".to_string()],
238 validates_fields: vec!["email".to_string()],
239 rule_type: ValidationRuleType::Unique,
240 parameters: HashMap::new(),
241 error_message: "Email must be unique".to_string(),
242 },
243 ],
244 cache_results: true,
245 };
246
247 let mut validator = ValidationFramework::new(config);
248
249 let entities = vec![
251 GeneratedEntity {
252 entity_type: "User".to_string(),
253 primary_key: Some("user_1".to_string()),
254 field_values: HashMap::from([
255 ("id".to_string(), "user_1".to_string()),
256 ("age".to_string(), "150".to_string()), ("email".to_string(), "test@example.com".to_string()),
258 ]),
259 endpoint: "/users".to_string(),
260 generated_at: SystemTime::now(),
261 },
262 GeneratedEntity {
263 entity_type: "User".to_string(),
264 primary_key: Some("user_2".to_string()),
265 field_values: HashMap::from([
266 ("id".to_string(), "user_2".to_string()),
267 ("age".to_string(), "25".to_string()),
268 ("email".to_string(), "test@example.com".to_string()), ]),
270 endpoint: "/users".to_string(),
271 generated_at: SystemTime::now(),
272 },
273 ];
274
275 for entity in entities {
276 validator.register_entity(entity).unwrap();
277 }
278
279 let result = validator.validate_all_entities();
280
281 assert!(!result.is_valid, "Validation should fail in strict mode");
283 assert!(result.errors.len() >= 2, "Should have age range and duplicate email errors");
284
285 assert!(result.errors.iter().any(|e| matches!(
287 e.error_type,
288 crate::reflection::validation_framework::ValidationErrorType::OutOfRange
289 )));
290 assert!(result.errors.iter().any(|e| matches!(
291 e.error_type,
292 crate::reflection::validation_framework::ValidationErrorType::DuplicateValue
293 )));
294 }
295
296 #[test]
297 fn test_generator_reset_functionality() {
298 let config = SmartMockConfig {
299 seed: Some(555),
300 deterministic: true,
301 ..Default::default()
302 };
303
304 let mut generator = SmartMockGenerator::new(config);
305
306 let uuid1 = generator.generate_uuid();
308 let seq1 = generator.next_sequence();
309 let str1 = generator.generate_random_string(8);
310
311 assert_eq!(seq1, 1);
312
313 let seq2 = generator.next_sequence();
315 assert_eq!(seq2, 2);
316
317 generator.reset();
319
320 let uuid2 = generator.generate_uuid();
322 let seq3 = generator.next_sequence();
323 let str2 = generator.generate_random_string(8);
324
325 assert_eq!(uuid1, uuid2, "UUID should be same after reset");
326 assert_eq!(seq3, 1, "Sequence should reset to 1");
327 assert_eq!(str1, str2, "Random string should be same after reset");
328 }
329
330 #[test]
331 fn test_comprehensive_validation_statistics() {
332 let config = ValidationConfig::default();
333 let mut validator = ValidationFramework::new(config);
334
335 for i in 1..=10 {
337 let user = GeneratedEntity {
338 entity_type: "User".to_string(),
339 primary_key: Some(format!("user_{}", i)),
340 field_values: HashMap::from([
341 ("id".to_string(), format!("user_{}", i)),
342 ("name".to_string(), format!("User {}", i)),
343 ]),
344 endpoint: "/users".to_string(),
345 generated_at: SystemTime::now(),
346 };
347 validator.register_entity(user).unwrap();
348 }
349
350 for i in 1..=5 {
351 let order = GeneratedEntity {
352 entity_type: "Order".to_string(),
353 primary_key: Some(format!("order_{}", i)),
354 field_values: HashMap::from([
355 ("id".to_string(), format!("order_{}", i)),
356 ("user_id".to_string(), format!("user_{}", i)),
357 ]),
358 endpoint: "/orders".to_string(),
359 generated_at: SystemTime::now(),
360 };
361 validator.register_entity(order).unwrap();
362 }
363
364 let stats = validator.get_statistics();
365 assert_eq!(stats.total_entities, 15);
366 assert_eq!(stats.entity_type_count, 2);
367 assert_eq!(stats.indexed_foreign_keys, 15); validator.clear();
371 let stats_after_clear = validator.get_statistics();
372 assert_eq!(stats_after_clear.total_entities, 0);
373 assert_eq!(stats_after_clear.entity_type_count, 0);
374 assert_eq!(stats_after_clear.indexed_foreign_keys, 0);
375 }
376
377 #[tokio::test]
378 async fn test_end_to_end_synthesis_workflow() {
379 let mut generator = SmartMockGenerator::new_with_seed(SmartMockConfig::default(), 99999);
383
384 let users_data: Vec<_> = (1..=3)
386 .map(|i| {
387 HashMap::from([
388 ("id".to_string(), format!("user_{}", i)),
389 ("name".to_string(), format!("User {}", i)),
390 ("email".to_string(), format!("user{}@example.com", i)),
391 ])
392 })
393 .collect();
394
395 let orders_data: Vec<_> = (1..=5)
396 .map(|i| {
397 HashMap::from([
398 ("id".to_string(), format!("order_{}", i)),
399 ("user_id".to_string(), format!("user_{}", (i % 3) + 1)),
400 ("total".to_string(), format!("{}.99", 10 + i * 10)),
401 ])
402 })
403 .collect();
404
405 let validation_config = ValidationConfig {
407 enabled: true,
408 strict_mode: false,
409 max_validation_depth: 5,
410 custom_rules: vec![CustomValidationRule {
411 name: "positive_total".to_string(),
412 applies_to_entities: vec!["Order".to_string()],
413 validates_fields: vec!["total".to_string()],
414 rule_type: ValidationRuleType::Range,
415 parameters: HashMap::from([
416 ("min".to_string(), "0.01".to_string()),
417 ("max".to_string(), "10000.00".to_string()),
418 ]),
419 error_message: "Order total must be positive".to_string(),
420 }],
421 cache_results: true,
422 };
423
424 let mut validator = ValidationFramework::new(validation_config);
425
426 for user_data in users_data.iter() {
428 let entity = GeneratedEntity {
429 entity_type: "User".to_string(),
430 primary_key: Some(user_data.get("id").unwrap().clone()),
431 field_values: user_data.clone(),
432 endpoint: "/users".to_string(),
433 generated_at: SystemTime::now(),
434 };
435 validator.register_entity(entity).unwrap();
436 }
437
438 for order_data in orders_data.iter() {
439 let entity = GeneratedEntity {
440 entity_type: "Order".to_string(),
441 primary_key: Some(order_data.get("id").unwrap().clone()),
442 field_values: order_data.clone(),
443 endpoint: "/orders".to_string(),
444 generated_at: SystemTime::now(),
445 };
446 validator.register_entity(entity).unwrap();
447 }
448
449 let result = validator.validate_all_entities();
451
452 assert!(result.is_valid, "End-to-end workflow should produce valid data");
454
455 let stats = validator.get_statistics();
456 assert_eq!(stats.total_entities, 8); assert_eq!(stats.entity_type_count, 2);
458
459 generator.reset();
461 let uuid_after_reset = generator.generate_uuid();
462 let string_after_reset = generator.generate_random_string(12);
463
464 generator.reset();
466 let uuid_again = generator.generate_uuid();
467 let string_again = generator.generate_random_string(12);
468
469 assert_eq!(uuid_after_reset, uuid_again);
470 assert_eq!(string_after_reset, string_again);
471
472 println!("✓ End-to-end synthesis workflow completed successfully");
473 println!(" - Generated {} users and {} orders", users_data.len(), orders_data.len());
474 println!(
475 " - Validation: {} errors, {} warnings",
476 result.errors.len(),
477 result.warnings.len()
478 );
479 println!(" - Deterministic generation verified");
480 }
481}