use crate::dev::node_selection::{get_available_node_names, get_enabled_node_names, get_nodes_to_run, NodeToRun};
use crate::types::project::{NodesConfig, ProjectConfig, RobotConfig};
fn create_test_config() -> ProjectConfig {
ProjectConfig {
name: "test-project".to_string(),
version: "0.1.0".to_string(),
robot: RobotConfig {
id: "test-robot".to_string(),
platform: None,
description: None,
},
simulation: None,
lifecycle: None,
nodes: NodesConfig(vec![
"@mecha10/speaker".to_string(),
"@mecha10/listener".to_string(),
"@mecha10/motor".to_string(),
"@local/custom-node".to_string(),
]),
targets: None,
behaviors: None,
services: Default::default(),
docker: Default::default(),
environments: Default::default(),
}
}
#[test]
fn test_get_nodes_to_run_all() {
let config = create_test_config();
let nodes = get_nodes_to_run(&[], &config);
assert_eq!(nodes.len(), 4);
assert!(nodes.iter().any(|n| n.name == "speaker"));
assert!(nodes.iter().any(|n| n.name == "listener"));
assert!(nodes.iter().any(|n| n.name == "motor"));
assert!(nodes.iter().any(|n| n.name == "custom-node"));
}
#[test]
fn test_get_nodes_to_run_specific() {
let config = create_test_config();
let requested = vec!["speaker".to_string(), "motor".to_string()];
let nodes = get_nodes_to_run(&requested, &config);
assert_eq!(nodes.len(), 2);
assert!(nodes.iter().any(|n| n.name == "speaker"));
assert!(nodes.iter().any(|n| n.name == "motor"));
}
#[test]
fn test_get_nodes_to_run_empty_config() {
let config = ProjectConfig {
name: "test".to_string(),
version: "0.1.0".to_string(),
robot: RobotConfig {
id: "test".to_string(),
platform: None,
description: None,
},
simulation: None,
lifecycle: None,
nodes: NodesConfig::new(),
targets: None,
behaviors: None,
services: Default::default(),
docker: Default::default(),
environments: Default::default(),
};
let nodes = get_nodes_to_run(&[], &config);
assert_eq!(nodes.len(), 0);
}
#[test]
fn test_node_to_run_framework() {
let node = NodeToRun {
name: "speaker".to_string(),
identifier: "@mecha10/speaker".to_string(),
path: "mecha10-nodes-speaker".to_string(),
is_framework_node: true,
};
let binary_path = node.binary_path("my-robot");
assert!(binary_path.ends_with("my-robot") || binary_path.ends_with("speaker"));
let args = node.args("my-robot");
assert!(args.is_empty() || args == vec!["node", "speaker"]);
}
#[test]
fn test_node_to_run_project() {
let node = NodeToRun {
name: "custom".to_string(),
identifier: "@local/custom".to_string(),
path: "nodes/custom".to_string(),
is_framework_node: false,
};
assert_eq!(node.binary_path("my-robot"), "target/release/custom");
assert_eq!(node.args("my-robot"), Vec::<String>::new());
}
#[test]
fn test_node_to_run_from_spec_framework() {
use crate::types::project::NodeSpec;
let spec = NodeSpec::parse("@mecha10/speaker").unwrap();
let node = NodeToRun::from_spec(&spec);
assert_eq!(node.name, "speaker");
assert_eq!(node.identifier, "@mecha10/speaker");
assert_eq!(node.path, "mecha10-nodes-speaker");
assert!(node.is_framework_node);
}
#[test]
fn test_node_to_run_from_spec_project() {
use crate::types::project::NodeSpec;
let spec = NodeSpec::parse("@local/custom").unwrap();
let node = NodeToRun::from_spec(&spec);
assert_eq!(node.name, "custom");
assert_eq!(node.identifier, "@local/custom");
assert_eq!(node.path, "nodes/custom");
assert!(!node.is_framework_node);
}
#[test]
fn test_get_available_node_names() {
let config = create_test_config();
let names = get_available_node_names(&config);
assert_eq!(names.len(), 4);
assert!(names.contains(&"speaker".to_string()));
assert!(names.contains(&"listener".to_string()));
assert!(names.contains(&"motor".to_string()));
assert!(names.contains(&"custom-node".to_string()));
}
#[test]
fn test_get_enabled_node_names() {
let config = create_test_config();
let names = get_enabled_node_names(&config);
assert_eq!(names.len(), 4);
assert!(names.contains(&"speaker".to_string()));
assert!(names.contains(&"listener".to_string()));
assert!(names.contains(&"motor".to_string()));
assert!(names.contains(&"custom-node".to_string()));
}
#[test]
fn test_get_available_node_names_empty() {
let config = ProjectConfig {
name: "test".to_string(),
version: "0.1.0".to_string(),
robot: RobotConfig {
id: "test".to_string(),
platform: None,
description: None,
},
simulation: None,
lifecycle: None,
nodes: NodesConfig::new(),
targets: None,
behaviors: None,
services: Default::default(),
docker: Default::default(),
environments: Default::default(),
};
let names = get_available_node_names(&config);
assert_eq!(names.len(), 0);
}
#[test]
fn test_node_spec_parsing() {
use crate::types::project::{NodeSource, NodeSpec};
let spec = NodeSpec::parse("@mecha10/listener").unwrap();
assert_eq!(spec.name, "listener");
assert_eq!(spec.source, NodeSource::Framework);
assert_eq!(spec.package_path(), "mecha10-nodes-listener");
let spec = NodeSpec::parse("@local/my-custom").unwrap();
assert_eq!(spec.name, "my-custom");
assert_eq!(spec.source, NodeSource::Project);
assert_eq!(spec.package_path(), "nodes/my-custom");
let spec = NodeSpec::parse("@someorg/cool-node").unwrap();
assert_eq!(spec.name, "cool-node");
assert_eq!(spec.source, NodeSource::Registry("someorg".to_string()));
assert_eq!(spec.package_path(), "node_modules/@someorg/cool-node");
}
#[test]
fn test_nodes_config_operations() {
let mut nodes = NodesConfig::new();
assert!(nodes.is_empty());
nodes.add_node("@mecha10/listener");
nodes.add_node("@local/custom");
assert_eq!(nodes.len(), 2);
assert!(nodes.contains("listener"));
assert!(nodes.contains("custom"));
assert!(!nodes.contains("nonexistent"));
nodes.remove_node("listener");
assert_eq!(nodes.len(), 1);
assert!(!nodes.contains("listener"));
assert!(nodes.contains("custom"));
}