1use crate::workspace::core::{EntityId, Environment, EnvironmentColor};
7use chrono::Utc;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone)]
13pub struct EnvironmentManager {
14 environments: HashMap<EntityId, Environment>,
16 active_environment_id: Option<EntityId>,
18}
19
20#[derive(Debug, Clone)]
22pub struct VariableSubstitution {
23 pub value: String,
25 pub success: bool,
27 pub errors: Vec<String>,
29}
30
31#[derive(Debug, Clone)]
33pub struct EnvironmentValidationResult {
34 pub is_valid: bool,
36 pub errors: Vec<String>,
38 pub warnings: Vec<String>,
40}
41
42#[derive(Debug, Clone)]
44pub enum EnvironmentExportFormat {
45 Json,
47 Yaml,
49 DotEnv,
51 Custom(String),
53}
54
55impl EnvironmentManager {
56 pub fn new() -> Self {
58 Self {
59 environments: HashMap::new(),
60 active_environment_id: None,
61 }
62 }
63
64 pub fn add_environment(&mut self, environment: Environment) -> EntityId {
66 let id = environment.id.clone();
67 self.environments.insert(id.clone(), environment);
68
69 if self.environments.len() == 1 {
71 self.active_environment_id = Some(id.clone());
72 if let Some(env) = self.environments.get_mut(&id) {
73 env.active = true;
74 }
75 }
76
77 id
78 }
79
80 pub fn get_environment(&self, id: &EntityId) -> Option<&Environment> {
82 self.environments.get(id)
83 }
84
85 pub fn get_environment_mut(&mut self, id: &EntityId) -> Option<&mut Environment> {
87 self.environments.get_mut(id)
88 }
89
90 pub fn remove_environment(&mut self, id: &EntityId) -> Result<Environment, String> {
92 if let Some(environment) = self.environments.remove(id) {
93 if self.active_environment_id.as_ref() == Some(id) {
95 self.active_environment_id = self.environments.keys().next().cloned();
96 if let Some(active_id) = &self.active_environment_id {
97 if let Some(env) = self.environments.get_mut(active_id) {
98 env.active = true;
99 }
100 }
101 }
102
103 Ok(environment)
104 } else {
105 Err(format!("Environment with ID {} not found", id))
106 }
107 }
108
109 pub fn get_all_environments(&self) -> Vec<&Environment> {
111 self.environments.values().collect()
112 }
113
114 pub fn get_active_environment(&self) -> Option<&Environment> {
116 self.active_environment_id.as_ref().and_then(|id| self.environments.get(id))
117 }
118
119 pub fn set_active_environment(&mut self, id: EntityId) -> Result<(), String> {
121 if self.environments.contains_key(&id) {
122 for environment in self.environments.values_mut() {
124 environment.active = false;
125 }
126
127 if let Some(env) = self.environments.get_mut(&id) {
129 env.active = true;
130 self.active_environment_id = Some(id);
131 }
132
133 Ok(())
134 } else {
135 Err(format!("Environment with ID {} not found", id))
136 }
137 }
138
139 pub fn substitute_variables(&self, template: &str) -> VariableSubstitution {
141 let mut result = String::new();
142 let mut success = true;
143 let mut errors = Vec::new();
144
145 let variables = if let Some(active_env) = self.get_active_environment() {
147 &active_env.variables
148 } else {
149 &std::collections::HashMap::new()
151 };
152
153 let mut chars = template.chars().peekable();
154 while let Some(ch) = chars.next() {
155 if ch == '{' && chars.peek() == Some(&'{') {
156 chars.next(); if let Some(var_name) = self.parse_variable_name(&mut chars) {
159 if let Some(value) = variables.get(&var_name) {
160 result.push_str(value);
161 } else {
162 success = false;
163 errors.push(format!("Variable '{}' not found", var_name));
164 result.push_str(&format!("{{{{{}}}}}", var_name));
165 }
166 } else {
167 result.push_str("{{");
168 }
169 } else {
170 result.push(ch);
171 }
172 }
173
174 VariableSubstitution {
175 value: result,
176 success,
177 errors,
178 }
179 }
180
181 fn parse_variable_name(
183 &self,
184 chars: &mut std::iter::Peekable<std::str::Chars>,
185 ) -> Option<String> {
186 let mut var_name = String::new();
187
188 while let Some(ch) = chars.peek() {
189 if *ch == '}' {
190 if let Some(next_ch) = chars.clone().nth(1) {
191 if next_ch == '}' {
192 chars.next(); chars.next(); break;
196 }
197 }
198 } else if ch.is_alphanumeric() || *ch == '_' || *ch == '-' || *ch == '.' {
199 var_name.push(*ch);
200 chars.next();
201 } else {
202 return None; }
204 }
205
206 if var_name.is_empty() {
207 None
208 } else {
209 Some(var_name)
210 }
211 }
212
213 pub fn validate_environment(&self, environment: &Environment) -> EnvironmentValidationResult {
215 let mut errors = Vec::new();
216 let mut warnings = Vec::new();
217
218 if environment.name.trim().is_empty() {
220 errors.push("Environment name cannot be empty".to_string());
221 }
222
223 let mut seen_variables = std::collections::HashSet::new();
225 for (key, value) in &environment.variables {
226 if !seen_variables.insert(key.clone()) {
227 errors.push(format!("Duplicate variable name: {}", key));
228 }
229
230 if key.trim().is_empty() {
232 errors.push("Variable key cannot be empty".to_string());
233 }
234
235 if value.trim().is_empty() {
237 warnings.push(format!("Variable '{}' has empty value", key));
238 }
239 }
240
241 EnvironmentValidationResult {
244 is_valid: errors.is_empty(),
245 errors,
246 warnings,
247 }
248 }
249
250 pub fn export_environment(
252 &self,
253 environment_id: &EntityId,
254 format: EnvironmentExportFormat,
255 ) -> Result<String, String> {
256 let environment = self
257 .environments
258 .get(environment_id)
259 .ok_or_else(|| format!("Environment with ID {} not found", environment_id))?;
260
261 match format {
262 EnvironmentExportFormat::Json => serde_json::to_string_pretty(environment)
263 .map_err(|e| format!("Failed to serialize environment: {}", e)),
264 EnvironmentExportFormat::Yaml => serde_yaml::to_string(environment)
265 .map_err(|e| format!("Failed to serialize environment: {}", e)),
266 EnvironmentExportFormat::DotEnv => {
267 let mut result = String::new();
268 for (key, value) in &environment.variables {
269 result.push_str(&format!("{}={}\n", key, value));
270 }
271 Ok(result)
272 }
273 EnvironmentExportFormat::Custom(template) => {
274 let mut result = template.clone();
275 for (key, value) in &environment.variables {
276 let placeholder = format!("{{{{{}}}}}", key);
277 result = result.replace(&placeholder, value);
278 }
279 Ok(result)
280 }
281 }
282 }
283
284 pub fn import_environment(&mut self, json_data: &str) -> Result<EntityId, String> {
286 let environment: Environment = serde_json::from_str(json_data)
287 .map_err(|e| format!("Failed to deserialize environment: {}", e))?;
288
289 let validation = self.validate_environment(&environment);
291 if !validation.is_valid {
292 return Err(format!("Environment validation failed: {:?}", validation.errors));
293 }
294
295 Ok(self.add_environment(environment))
296 }
297
298 pub fn get_stats(&self) -> EnvironmentStats {
300 let total_variables =
301 self.environments.values().map(|env| env.variables.len()).sum::<usize>();
302
303 let active_count = self.environments.values().filter(|env| env.active).count();
304
305 EnvironmentStats {
306 total_environments: self.environments.len(),
307 total_variables,
308 active_environments: active_count,
309 }
310 }
311
312 pub fn find_environments_by_name(&self, name_query: &str) -> Vec<&Environment> {
314 let query_lower = name_query.to_lowercase();
315 self.environments
316 .values()
317 .filter(|env| env.name.to_lowercase().contains(&query_lower))
318 .collect()
319 }
320
321 pub fn get_all_variables(&self) -> HashMap<String, String> {
323 let mut all_vars = HashMap::new();
324
325 for environment in self.environments.values() {
326 for (key, value) in &environment.variables {
327 all_vars.insert(key.clone(), value.clone());
328 }
329 }
330
331 all_vars
332 }
333
334 pub fn clone_environment(
336 &mut self,
337 source_id: &EntityId,
338 new_name: String,
339 ) -> Result<EntityId, String> {
340 let source_env = self
341 .environments
342 .get(source_id)
343 .ok_or_else(|| format!("Environment with ID {} not found", source_id))?;
344
345 let mut new_env = source_env.clone();
346 new_env.id = uuid::Uuid::new_v4().to_string();
347 new_env.name = new_name;
348 new_env.active = false;
349 new_env.created_at = Utc::now();
350 new_env.updated_at = Utc::now();
351
352 Ok(self.add_environment(new_env))
353 }
354
355 pub fn merge_environments(
357 &mut self,
358 environment_ids: &[EntityId],
359 merged_name: String,
360 ) -> Result<EntityId, String> {
361 let mut merged_variables = HashMap::new();
362
363 for env_id in environment_ids {
364 let env = self
365 .environments
366 .get(env_id)
367 .ok_or_else(|| format!("Environment with ID {} not found", env_id))?;
368
369 for (key, value) in &env.variables {
370 merged_variables.insert(key.clone(), value.clone());
371 }
372 }
373
374 let mut merged_env = Environment::new(merged_name);
375 merged_env.variables = merged_variables;
376
377 Ok(self.add_environment(merged_env))
378 }
379}
380
381#[derive(Debug, Clone, Serialize, Deserialize)]
383pub struct EnvironmentStats {
384 pub total_environments: usize,
386 pub total_variables: usize,
388 pub active_environments: usize,
390}
391
392impl Default for EnvironmentManager {
393 fn default() -> Self {
394 Self::new()
395 }
396}
397
398pub struct EnvironmentValidator;
400
401impl EnvironmentValidator {
402 pub fn validate_variable_name(name: &str) -> Result<(), String> {
404 if name.is_empty() {
405 return Err("Variable name cannot be empty".to_string());
406 }
407
408 if !name.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') {
409 return Err(
410 "Variable name can only contain letters, numbers, underscores, and hyphens"
411 .to_string(),
412 );
413 }
414
415 if name.starts_with('-') || name.ends_with('-') {
416 return Err("Variable name cannot start or end with hyphens".to_string());
417 }
418
419 Ok(())
420 }
421
422 pub fn validate_variable_value(value: &str) -> Result<(), String> {
424 if value.contains('\0') {
425 return Err("Variable value cannot contain null characters".to_string());
426 }
427
428 Ok(())
429 }
430
431 pub fn validate_color(_color: &EnvironmentColor) -> Result<(), String> {
433 Ok(())
435 }
436}
437
438#[cfg(test)]
439mod tests {
440 use super::*;
441
442 #[test]
443 fn test_variable_substitution() {
444 let mut manager = EnvironmentManager::new();
445 let mut env = Environment::new("test".to_string());
446 env.set_variable("API_URL".to_string(), "https://api.example.com".to_string());
447 env.set_variable("VERSION".to_string(), "1.0.0".to_string());
448 manager.add_environment(env);
449
450 let result = manager.substitute_variables("API: {{API_URL}}, Version: {{VERSION}}");
451 assert!(result.success);
452 assert_eq!(result.value, "API: https://api.example.com, Version: 1.0.0");
453 }
454
455 #[test]
456 fn test_missing_variable_substitution() {
457 let manager = EnvironmentManager::new();
458 let result = manager.substitute_variables("Missing: {{MISSING_VAR}}");
459
460 assert!(!result.success);
461 assert!(result.errors.contains(&"Variable 'MISSING_VAR' not found".to_string()));
462 }
463
464 #[test]
465 fn test_environment_manager_new() {
466 let manager = EnvironmentManager::new();
467 assert!(manager.environments.is_empty());
468 assert!(manager.active_environment_id.is_none());
469 }
470
471 #[test]
472 fn test_environment_manager_default() {
473 let manager = EnvironmentManager::default();
474 assert!(manager.environments.is_empty());
475 }
476
477 #[test]
478 fn test_add_environment_first_becomes_active() {
479 let mut manager = EnvironmentManager::new();
481 let mut env = Environment::new("Dev".to_string());
482 env.set_variable("API_URL".to_string(), "http://localhost".to_string());
483 let id = manager.add_environment(env);
484
485 assert_eq!(manager.active_environment_id, Some(id.clone()));
486 assert!(manager.get_environment(&id).unwrap().active);
487 }
488
489 #[test]
490 fn test_add_environment_multiple() {
491 let mut manager = EnvironmentManager::new();
493 let env1 = Environment::new("Dev".to_string());
494 let env2 = Environment::new("Prod".to_string());
495
496 let id1 = manager.add_environment(env1);
497 let id2 = manager.add_environment(env2);
498
499 assert_eq!(manager.active_environment_id, Some(id1.clone()));
500 assert!(manager.get_environment(&id1).unwrap().active);
501 assert!(!manager.get_environment(&id2).unwrap().active);
502 }
503
504 #[test]
505 fn test_get_environment() {
506 let mut manager = EnvironmentManager::new();
507 let env = Environment::new("Test".to_string());
508 let id = manager.add_environment(env);
509
510 assert!(manager.get_environment(&id).is_some());
511 assert_eq!(manager.get_environment(&id).unwrap().name, "Test");
512 assert!(manager.get_environment(&"nonexistent".to_string()).is_none());
513 }
514
515 #[test]
516 fn test_get_environment_mut() {
517 let mut manager = EnvironmentManager::new();
518 let env = Environment::new("Test".to_string());
519 let id = manager.add_environment(env);
520
521 if let Some(env_mut) = manager.get_environment_mut(&id) {
522 env_mut.set_variable("KEY".to_string(), "VALUE".to_string());
523 }
524
525 assert_eq!(
526 manager.get_environment(&id).unwrap().get_variable("KEY"),
527 Some(&"VALUE".to_string())
528 );
529 }
530
531 #[test]
532 fn test_remove_environment_not_active() {
533 let mut manager = EnvironmentManager::new();
535 let env1 = Environment::new("Dev".to_string());
536 let env2 = Environment::new("Prod".to_string());
537
538 let id1 = manager.add_environment(env1);
539 let id2 = manager.add_environment(env2);
540
541 let removed = manager.remove_environment(&id2).unwrap();
542 assert_eq!(removed.name, "Prod");
543 assert!(manager.get_environment(&id2).is_none());
544 assert_eq!(manager.active_environment_id, Some(id1)); }
546
547 #[test]
548 fn test_remove_environment_active() {
549 let mut manager = EnvironmentManager::new();
551 let env1 = Environment::new("Dev".to_string());
552 let env2 = Environment::new("Prod".to_string());
553
554 let id1 = manager.add_environment(env1);
555 let id2 = manager.add_environment(env2);
556
557 let removed = manager.remove_environment(&id1).unwrap();
559 assert_eq!(removed.name, "Dev");
560 assert_eq!(manager.active_environment_id, Some(id2.clone())); assert!(manager.get_environment(&id2).unwrap().active);
562 }
563
564 #[test]
565 fn test_remove_environment_not_found() {
566 let mut manager = EnvironmentManager::new();
567 let result = manager.remove_environment(&"nonexistent".to_string());
568 assert!(result.is_err());
569 assert!(result.unwrap_err().contains("not found"));
570 }
571
572 #[test]
573 fn test_get_all_environments() {
574 let mut manager = EnvironmentManager::new();
575 manager.add_environment(Environment::new("Dev".to_string()));
576 manager.add_environment(Environment::new("Prod".to_string()));
577
578 let all = manager.get_all_environments();
579 assert_eq!(all.len(), 2);
580 }
581
582 #[test]
583 fn test_get_active_environment() {
584 let mut manager = EnvironmentManager::new();
585 let env = Environment::new("Dev".to_string());
586 let id = manager.add_environment(env);
587
588 let active = manager.get_active_environment();
589 assert!(active.is_some());
590 assert_eq!(active.unwrap().id, id);
591 }
592
593 #[test]
594 fn test_get_active_environment_none() {
595 let manager = EnvironmentManager::new();
596 assert!(manager.get_active_environment().is_none());
597 }
598
599 #[test]
600 fn test_set_active_environment() {
601 let mut manager = EnvironmentManager::new();
603 let env1 = Environment::new("Dev".to_string());
604 let env2 = Environment::new("Prod".to_string());
605
606 let id1 = manager.add_environment(env1);
607 let id2 = manager.add_environment(env2);
608
609 manager.set_active_environment(id2.clone()).unwrap();
611
612 assert_eq!(manager.active_environment_id, Some(id2.clone()));
613 assert!(!manager.get_environment(&id1).unwrap().active);
614 assert!(manager.get_environment(&id2).unwrap().active);
615 }
616
617 #[test]
618 fn test_set_active_environment_not_found() {
619 let mut manager = EnvironmentManager::new();
620 let result = manager.set_active_environment("nonexistent".to_string());
621 assert!(result.is_err());
622 assert!(result.unwrap_err().contains("not found"));
623 }
624
625 #[test]
626 fn test_substitute_variables_no_active() {
627 let manager = EnvironmentManager::new();
629 let result = manager.substitute_variables("{{VAR}}");
630 assert!(!result.success);
631 assert!(result.errors.contains(&"Variable 'VAR' not found".to_string()));
632 }
633
634 #[test]
635 fn test_substitute_variables_invalid_syntax() {
636 let mut manager = EnvironmentManager::new();
638 let mut env = Environment::new("Test".to_string());
639 env.set_variable("VAR".to_string(), "value".to_string());
640 manager.add_environment(env);
641
642 let result = manager.substitute_variables("Text {{VAR");
645 assert_eq!(result.value, "Text value");
647 }
648
649 #[test]
650 fn test_substitute_variables_invalid_characters() {
651 let mut manager = EnvironmentManager::new();
653 let mut env = Environment::new("Test".to_string());
654 env.set_variable("VAR".to_string(), "value".to_string());
655 manager.add_environment(env);
656
657 let result = manager.substitute_variables("{{VAR@INVALID}}");
659 assert!(result.value.contains("{{"));
660 }
661
662 #[test]
663 fn test_substitute_variables_empty_name() {
664 let mut manager = EnvironmentManager::new();
666 let mut env = Environment::new("Test".to_string());
667 env.set_variable("VAR".to_string(), "value".to_string());
668 manager.add_environment(env);
669
670 let result = manager.substitute_variables("{{}}");
671 assert!(result.value.contains("{{"));
672 }
673
674 #[test]
675 fn test_validate_environment_empty_name() {
676 let manager = EnvironmentManager::new();
678 let mut env = Environment::new(" ".to_string()); env.set_variable("VAR".to_string(), "value".to_string());
680
681 let result = manager.validate_environment(&env);
682 assert!(!result.is_valid);
683 assert!(result.errors.contains(&"Environment name cannot be empty".to_string()));
684 }
685
686 #[test]
687 fn test_validate_environment_duplicate_variables() {
688 let manager = EnvironmentManager::new();
690 let mut env = Environment::new("Test".to_string());
691 env.set_variable("VAR".to_string(), "value1".to_string());
692 env.set_variable("VAR".to_string(), "value2".to_string()); let result = manager.validate_environment(&env);
695 assert!(result.is_valid || !result.errors.is_empty());
698 }
699
700 #[test]
701 fn test_validate_environment_empty_key() {
702 let manager = EnvironmentManager::new();
704 let mut env = Environment::new("Test".to_string());
705 env.set_variable(" ".to_string(), "value".to_string()); let result = manager.validate_environment(&env);
708 assert!(!result.is_valid);
709 assert!(result.errors.iter().any(|e| e.contains("empty")));
710 }
711
712 #[test]
713 fn test_validate_environment_empty_value_warning() {
714 let manager = EnvironmentManager::new();
716 let mut env = Environment::new("Test".to_string());
717 env.set_variable("VAR".to_string(), " ".to_string()); let result = manager.validate_environment(&env);
720 assert!(result.is_valid); assert!(result.warnings.iter().any(|w| w.contains("empty value")));
722 }
723
724 #[test]
725 fn test_validate_environment_valid() {
726 let manager = EnvironmentManager::new();
728 let mut env = Environment::new("Test".to_string());
729 env.set_variable("VAR1".to_string(), "value1".to_string());
730 env.set_variable("VAR2".to_string(), "value2".to_string());
731
732 let result = manager.validate_environment(&env);
733 assert!(result.is_valid);
734 assert!(result.errors.is_empty());
735 }
736
737 #[test]
738 fn test_export_environment_json() {
739 let mut manager = EnvironmentManager::new();
741 let mut env = Environment::new("Test".to_string());
742 env.set_variable("VAR".to_string(), "value".to_string());
743 let id = manager.add_environment(env);
744
745 let result = manager.export_environment(&id, EnvironmentExportFormat::Json);
746 assert!(result.is_ok());
747 assert!(result.unwrap().contains("Test"));
748 }
749
750 #[test]
751 fn test_export_environment_yaml() {
752 let mut manager = EnvironmentManager::new();
754 let env = Environment::new("Test".to_string());
755 let id = manager.add_environment(env);
756
757 let result = manager.export_environment(&id, EnvironmentExportFormat::Yaml);
758 assert!(result.is_ok());
759 }
760
761 #[test]
762 fn test_export_environment_dotenv() {
763 let mut manager = EnvironmentManager::new();
765 let mut env = Environment::new("Test".to_string());
766 env.set_variable("VAR1".to_string(), "value1".to_string());
767 env.set_variable("VAR2".to_string(), "value2".to_string());
768 let id = manager.add_environment(env);
769
770 let result = manager.export_environment(&id, EnvironmentExportFormat::DotEnv);
771 assert!(result.is_ok());
772 let content = result.unwrap();
773 assert!(content.contains("VAR1=value1"));
774 assert!(content.contains("VAR2=value2"));
775 }
776
777 #[test]
778 fn test_export_environment_custom() {
779 let mut manager = EnvironmentManager::new();
781 let mut env = Environment::new("Test".to_string());
782 env.set_variable("VAR".to_string(), "value".to_string());
783 let id = manager.add_environment(env);
784
785 let template = "Config: {{VAR}}";
786 let result =
787 manager.export_environment(&id, EnvironmentExportFormat::Custom(template.to_string()));
788 assert!(result.is_ok());
789 assert_eq!(result.unwrap(), "Config: value");
790 }
791
792 #[test]
793 fn test_export_environment_not_found() {
794 let manager = EnvironmentManager::new();
795 let result =
796 manager.export_environment(&"nonexistent".to_string(), EnvironmentExportFormat::Json);
797 assert!(result.is_err());
798 assert!(result.unwrap_err().contains("not found"));
799 }
800
801 #[test]
802 fn test_import_environment() {
803 let mut manager = EnvironmentManager::new();
805 let env = Environment::new("Test".to_string());
806 let json = serde_json::to_string(&env).unwrap();
807
808 let result = manager.import_environment(&json);
809 assert!(result.is_ok());
810 assert_eq!(manager.get_all_environments().len(), 1);
811 }
812
813 #[test]
814 fn test_import_environment_invalid_json() {
815 let mut manager = EnvironmentManager::new();
816 let result = manager.import_environment("invalid json");
817 assert!(result.is_err());
818 }
819
820 #[test]
821 fn test_get_stats() {
822 let mut manager = EnvironmentManager::new();
824 let mut env1 = Environment::new("Dev".to_string());
825 env1.set_variable("VAR1".to_string(), "value1".to_string());
826 let mut env2 = Environment::new("Prod".to_string());
827 env2.set_variable("VAR2".to_string(), "value2".to_string());
828
829 manager.add_environment(env1);
830 manager.add_environment(env2);
831
832 let stats = manager.get_stats();
833 assert_eq!(stats.total_environments, 2);
834 assert_eq!(stats.total_variables, 2);
835 assert_eq!(stats.active_environments, 1); }
837
838 #[test]
839 fn test_find_environments_by_name() {
840 let mut manager = EnvironmentManager::new();
842 manager.add_environment(Environment::new("Development".to_string()));
843 manager.add_environment(Environment::new("Production".to_string()));
844 manager.add_environment(Environment::new("Staging".to_string()));
845
846 let results = manager.find_environments_by_name("dev");
847 assert_eq!(results.len(), 1);
848 assert_eq!(results[0].name, "Development");
849 }
850
851 #[test]
852 fn test_get_all_variables() {
853 let mut manager = EnvironmentManager::new();
855 let mut env1 = Environment::new("Dev".to_string());
856 env1.set_variable("VAR1".to_string(), "value1".to_string());
857 let mut env2 = Environment::new("Prod".to_string());
858 env2.set_variable("VAR2".to_string(), "value2".to_string());
859
860 manager.add_environment(env1);
861 manager.add_environment(env2);
862
863 let all_vars = manager.get_all_variables();
864 assert_eq!(all_vars.len(), 2);
865 assert_eq!(all_vars.get("VAR1"), Some(&"value1".to_string()));
866 assert_eq!(all_vars.get("VAR2"), Some(&"value2".to_string()));
867 }
868
869 #[test]
870 fn test_clone_environment() {
871 let mut manager = EnvironmentManager::new();
873 let mut env = Environment::new("Source".to_string());
874 env.set_variable("VAR".to_string(), "value".to_string());
875 let source_id = manager.add_environment(env);
876
877 let cloned_id = manager.clone_environment(&source_id, "Cloned".to_string()).unwrap();
878
879 assert_ne!(cloned_id, source_id);
880 let cloned = manager.get_environment(&cloned_id).unwrap();
881 assert_eq!(cloned.name, "Cloned");
882 assert_eq!(cloned.get_variable("VAR"), Some(&"value".to_string()));
883 assert!(!cloned.active); }
885
886 #[test]
887 fn test_clone_environment_not_found() {
888 let mut manager = EnvironmentManager::new();
889 let result = manager.clone_environment(&"nonexistent".to_string(), "New".to_string());
890 assert!(result.is_err());
891 }
892
893 #[test]
894 fn test_merge_environments() {
895 let mut manager = EnvironmentManager::new();
897 let mut env1 = Environment::new("Dev".to_string());
898 env1.set_variable("VAR1".to_string(), "value1".to_string());
899 let mut env2 = Environment::new("Prod".to_string());
900 env2.set_variable("VAR2".to_string(), "value2".to_string());
901
902 let id1 = manager.add_environment(env1);
903 let id2 = manager.add_environment(env2);
904
905 let merged_id = manager.merge_environments(&[id1, id2], "Merged".to_string()).unwrap();
906 let merged = manager.get_environment(&merged_id).unwrap();
907
908 assert_eq!(merged.name, "Merged");
909 assert_eq!(merged.get_variable("VAR1"), Some(&"value1".to_string()));
910 assert_eq!(merged.get_variable("VAR2"), Some(&"value2".to_string()));
911 }
912
913 #[test]
914 fn test_merge_environments_not_found() {
915 let mut manager = EnvironmentManager::new();
916 let result = manager.merge_environments(&["nonexistent".to_string()], "Merged".to_string());
917 assert!(result.is_err());
918 }
919
920 #[test]
921 fn test_environment_validator_validate_variable_name() {
922 assert!(EnvironmentValidator::validate_variable_name("VALID_NAME").is_ok());
924 assert!(EnvironmentValidator::validate_variable_name("VALID_NAME_123").is_ok());
925 assert!(EnvironmentValidator::validate_variable_name("valid-name").is_ok());
926
927 assert!(EnvironmentValidator::validate_variable_name("").is_err());
928 assert!(EnvironmentValidator::validate_variable_name("INVALID@NAME").is_err());
929 assert!(EnvironmentValidator::validate_variable_name("-INVALID").is_err());
930 assert!(EnvironmentValidator::validate_variable_name("INVALID-").is_err());
931 }
932
933 #[test]
934 fn test_environment_validator_validate_variable_value() {
935 assert!(EnvironmentValidator::validate_variable_value("valid value").is_ok());
937 assert!(EnvironmentValidator::validate_variable_value("").is_ok());
938
939 let mut invalid_value = String::from("valid");
940 invalid_value.push('\0');
941 assert!(EnvironmentValidator::validate_variable_value(&invalid_value).is_err());
942 }
943
944 #[test]
945 fn test_environment_validator_validate_color() {
946 let color = EnvironmentColor::new(255, 128, 64);
948 assert!(EnvironmentValidator::validate_color(&color).is_ok());
949 }
950}