- Providers réels livrés dans le catalogue par défaut (anthropic★/openai/deepseek/google) + hints provider sur claude-code/deepseek-harness - Suppression par null dans l'overlay : am providers remove écrit <nom>: null (merge traite null comme suppression, set_path remplace le null avant de descendre) - Cascade @secret (#89) : le provider déclaré de l'agent prime sur default_provider
89 lines
2.9 KiB
Rust
89 lines
2.9 KiB
Rust
//! Dry-run behaviour: no directories created, no state written, but the
|
|
//! commands that would run are announced.
|
|
|
|
mod common;
|
|
|
|
use agent_manager::commands::install_cmd;
|
|
use agent_manager::commands::uninstall_cmd;
|
|
use agent_manager::state::InstalledEntry;
|
|
|
|
#[test]
|
|
fn install_dry_run_creates_nothing() {
|
|
let app = common::test_app(
|
|
"dryinstall",
|
|
&["install", "smelt", "--dry-run", "--yes"],
|
|
);
|
|
assert!(app.dry_run());
|
|
let code = install_cmd::run(&app, "smelt", None, false, None, None, false).unwrap();
|
|
assert_eq!(code, 0);
|
|
// Nothing was written.
|
|
assert!(!app.paths.install_dir.join("smelt").exists());
|
|
assert!(app.state.all().unwrap().is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn install_without_dry_run_but_mock_is_not_supported() {
|
|
// Guard: install command requires a real runner; ensure the API surface
|
|
// used by the previous test is stable.
|
|
let app = common::test_app("dryguard", &["install", "smelt", "--dry-run", "--yes"]);
|
|
assert!(app.dry_run());
|
|
}
|
|
|
|
#[test]
|
|
fn uninstall_dry_run_keeps_everything() {
|
|
let app = common::test_app(
|
|
"dryuninstall",
|
|
&["uninstall", "smelt", "--dry-run", "--yes"],
|
|
);
|
|
// Simulate an installed agent.
|
|
let dir = app.paths.install_dir.join("smelt");
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
let marker = dir.join("bin");
|
|
std::fs::write(&marker, "x").unwrap();
|
|
let entry = InstalledEntry {
|
|
name: "smelt".to_string(),
|
|
version: Some("0.5.0".to_string()),
|
|
method: "cargo".to_string(),
|
|
install_dir: dir.display().to_string(),
|
|
bins: vec![],
|
|
run: "smelt".to_string(),
|
|
installed_at: "2026-01-01T00:00:00Z".to_string(),
|
|
updated_at: None,
|
|
pid: None,
|
|
started_at: None,
|
|
};
|
|
app.state.set(&entry).unwrap();
|
|
|
|
let code = uninstall_cmd::run(&app, "smelt", true).unwrap();
|
|
assert_eq!(code, 0);
|
|
// Directory and state entry survive a dry run.
|
|
assert!(dir.exists());
|
|
assert!(app.state.get("smelt").unwrap().is_some());
|
|
}
|
|
|
|
#[test]
|
|
fn real_uninstall_removes_files_and_state() {
|
|
let app = common::test_app("uninstall", &["uninstall", "smelt", "--yes"]);
|
|
let dir = app.paths.install_dir.join("smelt");
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
std::fs::write(dir.join("bin"), "x").unwrap();
|
|
let entry = InstalledEntry {
|
|
name: "smelt".to_string(),
|
|
version: Some("0.5.0".to_string()),
|
|
method: "cargo".to_string(),
|
|
install_dir: dir.display().to_string(),
|
|
bins: vec![],
|
|
run: "smelt".to_string(),
|
|
installed_at: "2026-01-01T00:00:00Z".to_string(),
|
|
updated_at: None,
|
|
pid: None,
|
|
started_at: None,
|
|
};
|
|
app.state.set(&entry).unwrap();
|
|
|
|
let code = uninstall_cmd::run(&app, "smelt", false).unwrap();
|
|
assert_eq!(code, 0);
|
|
assert!(!dir.exists());
|
|
assert!(app.state.get("smelt").unwrap().is_none());
|
|
}
|