mecha10-cli 0.7.0

Mecha10 CLI tool
Documentation
//! Tests for node_selection module

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(),
        template_version: None,
        robot: RobotConfig {
            id: "test-robot".to_string(),
            name: "test-robot".to_string(),
            platform: None,
            description: None,
        },
        simulation: None,
        nodes: {
            let mut nodes = NodesConfig::new();
            nodes.add_node("@mecha10/speaker", "0.1.0");
            nodes.add_node("@mecha10/listener", "0.1.0");
            nodes.add_node("@mecha10/motor", "0.1.0");
            nodes.add_node("custom-node", "0.1.0");
            nodes
        },
        targets: Default::default(),
        behaviors: None,
        docker: Default::default(),
        environments: Default::default(),
        actuator: 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(),
        template_version: None,
        robot: RobotConfig {
            id: "test".to_string(),
            name: "test".to_string(),
            platform: None,
            description: None,
        },
        simulation: None,
        nodes: NodesConfig::new(),
        targets: Default::default(),
        behaviors: None,
        docker: Default::default(),
        environments: Default::default(),
        actuator: Default::default(),
    };

    let nodes = get_nodes_to_run(&[], &config);
    assert_eq!(nodes.len(), 0);
}

#[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("custom").unwrap();
    let node = NodeToRun::from_spec(&spec);

    assert_eq!(node.name, "custom");
    assert_eq!(node.identifier, "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(),
        template_version: None,
        robot: RobotConfig {
            id: "test".to_string(),
            name: "test".to_string(),
            platform: None,
            description: None,
        },
        simulation: None,
        nodes: NodesConfig::new(),
        targets: Default::default(),
        behaviors: None,
        docker: Default::default(),
        environments: Default::default(),
        actuator: 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("my-custom").unwrap();
    assert_eq!(spec.name, "my-custom");
    assert_eq!(spec.source, NodeSource::Project);
    assert_eq!(spec.package_path(), "nodes/my-custom");

    assert!(NodeSpec::parse("@local/my-custom").is_err());

    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", "0.1.48");
    nodes.add_node("custom", "0.1.0");
    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"));
}