- CLI Rust (am) : list/install/uninstall/update/start/stop/restart/run/status/search/info/config/doctor/completion/export/import/self-update + shell interactif (Tab, historique) - 9 methodes d'installation (npm, pip, uv, cargo, go, bun, curl, binary, git) - catalogue de 72 agents, dependances, processus, securite (dry-run, checksums) - sondes de version paralleles + cache (am list ~25 ms a chaud) - installateurs one-liner : install.sh, install.ps1
92 lines
2.4 KiB
Rust
92 lines
2.4 KiB
Rust
//! Integration tests for configuration loading, overriding and validation.
|
|
|
|
mod common;
|
|
|
|
use agent_manager::app::App;
|
|
use agent_manager::cli::Cli;
|
|
use clap::Parser;
|
|
|
|
#[test]
|
|
fn user_config_overrides_embedded_catalog() {
|
|
let dir = std::env::temp_dir().join(format!("am-cfg-{}", std::process::id()));
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
let cfg = dir.join("config.yaml");
|
|
std::fs::write(
|
|
&cfg,
|
|
r#"
|
|
version: "1.0"
|
|
agents:
|
|
- name: claude-code
|
|
display_name: "Mon Claude Custom"
|
|
install: { type: npm, package: "@anthropic-ai/claude-code" }
|
|
run: claude
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
let cli = Cli::parse_from([
|
|
"am".to_string(),
|
|
"--config".to_string(),
|
|
cfg.display().to_string(),
|
|
"list".to_string(),
|
|
]);
|
|
let app = App::from_cli(cli).unwrap();
|
|
let cc = app.catalog.get("claude-code").unwrap();
|
|
assert_eq!(cc.display_name.as_deref(), Some("Mon Claude Custom"));
|
|
// The rest of the embedded catalog is still there.
|
|
assert!(app.catalog.len() >= 60);
|
|
assert_eq!(app.config_origin.as_deref(), Some(cfg.as_path()));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_user_config_fails_to_load() {
|
|
let dir = std::env::temp_dir().join(format!("am-badcfg-{}", std::process::id()));
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
let cfg = dir.join("config.yaml");
|
|
std::fs::write(
|
|
&cfg,
|
|
r#"
|
|
version: "1.0"
|
|
agents:
|
|
- name: broken
|
|
installable: true
|
|
run: ""
|
|
install: { type: npm, package: x }
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
let cli = Cli::parse_from([
|
|
"am".to_string(),
|
|
"--config".to_string(),
|
|
cfg.display().to_string(),
|
|
"list".to_string(),
|
|
]);
|
|
let err = App::from_cli(cli).unwrap_err().to_string();
|
|
assert!(err.contains("'run' is required"), "unexpected error: {err}");
|
|
}
|
|
|
|
#[test]
|
|
fn unknown_field_is_rejected() {
|
|
let dir = std::env::temp_dir().join(format!("am-badfield-{}", std::process::id()));
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
let cfg = dir.join("config.yaml");
|
|
std::fs::write(
|
|
&cfg,
|
|
r#"
|
|
version: "1.0"
|
|
agents:
|
|
- name: my-agent
|
|
install: { type: npm, package: pkg, typo_field: true }
|
|
run: my-agent
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
let cli = Cli::parse_from([
|
|
"am".to_string(),
|
|
"--config".to_string(),
|
|
cfg.display().to_string(),
|
|
"list".to_string(),
|
|
]);
|
|
let err = App::from_cli(cli).unwrap_err().to_string();
|
|
assert!(err.contains("typo_field"), "unexpected error: {err}");
|
|
}
|