use mecha10_cli::dev::lifecycle_adapter::CliLifecycleManager;
use mecha10_cli::types::project::{LifecycleConfig, ModeConfig, NodesConfig, ProjectConfig, RobotConfig};
use std::collections::HashMap;
fn create_test_lifecycle_config() -> LifecycleConfig {
let mut modes = HashMap::new();
modes.insert(
"dev".to_string(),
ModeConfig {
nodes: vec!["listener".to_string(), "speaker".to_string()],
},
);
modes.insert(
"simulation".to_string(),
ModeConfig {
nodes: vec![
"listener".to_string(),
"speaker".to_string(),
"simulation-bridge".to_string(),
],
},
);
modes.insert(
"full".to_string(),
ModeConfig {
nodes: vec![
"listener".to_string(),
"speaker".to_string(),
"imu".to_string(),
"motor".to_string(),
],
},
);
LifecycleConfig {
modes,
default_mode: "dev".to_string(),
}
}
fn create_project_config(lifecycle: Option<LifecycleConfig>) -> ProjectConfig {
ProjectConfig {
name: "test".to_string(),
version: "0.1.0".to_string(),
robot: RobotConfig {
id: "test".to_string(),
platform: None,
description: None,
},
lifecycle,
simulation: None,
nodes: NodesConfig::new(),
targets: None,
behaviors: None,
services: Default::default(),
docker: Default::default(),
environments: Default::default(),
}
}
#[test]
fn test_from_project_config_with_lifecycle() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let manager = CliLifecycleManager::from_project_config(&project_config);
assert!(manager.is_some());
let manager = manager.unwrap();
assert_eq!(manager.current_mode(), "dev");
}
#[test]
fn test_from_project_config_without_lifecycle() {
let project_config = create_project_config(None);
let manager = CliLifecycleManager::from_project_config(&project_config);
assert!(manager.is_none());
}
#[test]
fn test_nodes_for_current_mode() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
let nodes = manager.nodes_for_current_mode();
assert_eq!(nodes.len(), 2);
assert!(nodes.contains(&"listener".to_string()));
assert!(nodes.contains(&"speaker".to_string()));
}
#[test]
fn test_mark_nodes_running() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
manager.mark_nodes_running(&["listener".to_string(), "speaker".to_string()]);
let diff = manager.calculate_mode_diff("dev").unwrap();
assert_eq!(diff.start.len(), 0);
assert_eq!(diff.stop.len(), 0);
}
#[test]
fn test_calculate_mode_diff_start_nodes() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
manager.mark_nodes_running(&["listener".to_string(), "speaker".to_string()]);
let diff = manager.calculate_mode_diff("simulation").unwrap();
assert_eq!(diff.start.len(), 1);
assert!(diff.start.contains(&"simulation-bridge".to_string()));
assert_eq!(diff.stop.len(), 0);
}
#[test]
fn test_calculate_mode_diff_stop_nodes() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
manager.mark_nodes_running(&[
"listener".to_string(),
"speaker".to_string(),
"simulation-bridge".to_string(),
]);
let diff = manager.calculate_mode_diff("dev").unwrap();
assert_eq!(diff.start.len(), 0);
assert_eq!(diff.stop.len(), 1);
assert!(diff.stop.contains(&"simulation-bridge".to_string()));
}
#[test]
fn test_calculate_mode_diff_stops_nodes_not_in_target() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
manager.mark_nodes_running(&[
"listener".to_string(),
"speaker".to_string(),
"simulation-bridge".to_string(),
]);
let diff = manager.calculate_mode_diff("full").unwrap();
assert!(diff.start.contains(&"imu".to_string()));
assert!(diff.start.contains(&"motor".to_string()));
assert!(diff.stop.contains(&"simulation-bridge".to_string()));
}
#[test]
fn test_change_mode() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
assert_eq!(manager.current_mode(), "dev");
let diff = manager.change_mode("simulation").unwrap();
assert_eq!(manager.current_mode(), "simulation");
assert_eq!(diff.start.len(), 3); assert_eq!(diff.stop.len(), 0); }
#[test]
fn test_change_mode_invalid() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
let result = manager.change_mode("invalid-mode");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("not found"));
}
#[test]
fn test_available_modes() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
let modes = manager.available_modes();
assert_eq!(modes.len(), 3);
assert!(modes.contains(&"dev"));
assert!(modes.contains(&"simulation"));
assert!(modes.contains(&"full"));
}
#[test]
fn test_validate_valid_config() {
let config = create_test_lifecycle_config();
let available_nodes = vec![
"listener".to_string(),
"speaker".to_string(),
"simulation-bridge".to_string(),
"imu".to_string(),
"motor".to_string(),
];
let result = CliLifecycleManager::validate(&config, &available_nodes);
assert!(result.is_ok());
}
#[test]
fn test_validate_missing_node() {
let config = create_test_lifecycle_config();
let available_nodes = vec!["listener".to_string(), "speaker".to_string()];
let result = CliLifecycleManager::validate(&config, &available_nodes);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("unknown node"));
}
#[test]
fn test_validate_missing_default_mode() {
let mut config = create_test_lifecycle_config();
config.default_mode = "nonexistent".to_string();
let available_nodes = vec![
"listener".to_string(),
"speaker".to_string(),
"simulation-bridge".to_string(),
];
let result = CliLifecycleManager::validate(&config, &available_nodes);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("not found in modes"));
}
#[test]
fn test_mark_nodes_stopped() {
let config = create_test_lifecycle_config();
let project_config = create_project_config(Some(config));
let mut manager = CliLifecycleManager::from_project_config(&project_config).unwrap();
manager.mark_nodes_running(&["listener".to_string(), "speaker".to_string()]);
manager.mark_nodes_stopped(&["listener".to_string()]);
let diff = manager.calculate_mode_diff("dev").unwrap();
assert_eq!(diff.start.len(), 1);
assert!(diff.start.contains(&"listener".to_string()));
}