aura-gui 0.3.5

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Cliente MCP contra un servidor falso en Python (el mismo que usan las pruebas del LSP necesita `python3`).

use aura_ui::ai::mcp::McpConfig;
use aura_ui::ai::mcp_hub::McpHub;
use serde_json::json;
use std::collections::BTreeMap;

fn fake() -> McpConfig {
    let script = format!("{}/tests/mcp_fake.py", env!("CARGO_MANIFEST_DIR"));
    McpConfig { command: "python3".into(), args: vec![script], env: BTreeMap::new() }
}

#[test]
fn lista_herramientas_con_nombre_unico_y_las_llama() {
    let configs = BTreeMap::from([("demo".to_owned(), fake())]);
    let (hub, errors) = McpHub::start(&configs);
    assert!(errors.is_empty(), "{errors:?}");
    let names: Vec<String> = hub.specs().into_iter().map(|spec| spec.name).collect();
    assert_eq!(names, ["mcp__demo__echo", "mcp__demo__falla"]);
    assert_eq!(hub.call("mcp__demo__echo", &json!({"text": "hola"})).unwrap(), "eco: hola");
}

#[test]
fn error_de_herramienta_vuelve_como_error_para_el_modelo() {
    let configs = BTreeMap::from([("demo".to_owned(), fake())]);
    let (hub, _) = McpHub::start(&configs);
    assert_eq!(hub.call("mcp__demo__falla", &json!({})).unwrap_err(), "no funciona");
    assert!(hub.call("mcp__otro__x", &json!({})).unwrap_err().contains("no está activo"));
}

#[test]
fn servidor_que_no_existe_se_informa_sin_romper_a_los_demas() {
    let configs = BTreeMap::from([
        ("bueno".to_owned(), fake()),
        ("roto".to_owned(), McpConfig { command: "aura-no-existe-xyz".into(), ..Default::default() }),
    ]);
    let (hub, errors) = McpHub::start(&configs);
    assert_eq!(errors.len(), 1);
    assert!(errors[0].contains("roto"));
    assert!(!hub.is_empty());
}