mod common;
use common::InteractiveTest;
use std::path::PathBuf;
fn augent_bin_path() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_augent"))
}
#[test]
#[cfg_attr(
all(target_arch = "aarch64", target_os = "linux"),
ignore = "PTY spawn runs binary via /bin/sh in cross aarch64 Linux Docker"
)]
#[cfg_attr(
target_os = "windows",
ignore = "PTY reads block indefinitely on Windows conpty, causing test to hang"
)]
fn test_install_with_menu_selects_all_bundles() {
common::run_with_timeout(std::time::Duration::from_secs(15), || {
let workspace = common::TestWorkspace::new();
workspace.init_from_fixture("empty");
workspace.create_agent_dir("cursor");
workspace.create_bundle("bundles");
workspace.create_bundle("bundles/bundle-a");
workspace.create_bundle("bundles/bundle-b");
workspace.write_file(
"bundles/bundle-a/augent.yaml",
"name: \"@test/bundle-a\"\nbundles: []\n",
);
workspace.write_file("bundles/bundle-a/commands/a.md", "# Bundle A\n");
workspace.write_file(
"bundles/bundle-b/augent.yaml",
"name: \"@test/bundle-b\"\nbundles: []\n",
);
workspace.write_file("bundles/bundle-b/commands/b.md", "# Bundle B\n");
let augent_path = augent_bin_path();
let mut test = InteractiveTest::new(
augent_path.to_str().unwrap(),
&["install", "./bundles", "--to", "cursor"],
&workspace.path,
)
.expect("Failed to create interactive test");
test.wait_for_text("Select bundles", std::time::Duration::from_secs(2))
.expect("Menu should appear");
use common::MenuAction;
common::send_menu_actions(
&mut test,
&[
MenuAction::SelectCurrent, MenuAction::MoveDown,
MenuAction::SelectCurrent, MenuAction::Confirm,
],
)
.expect("Failed to send menu actions");
test.wait_for_completion(std::time::Duration::from_secs(3))
.expect("Failed to wait for process completion");
assert!(
workspace.file_exists(".cursor/commands/a.md"),
"Bundle A file should be installed"
);
assert!(
workspace.file_exists(".cursor/commands/b.md"),
"Bundle B file should be installed"
);
let lockfile_path = workspace.path.join(".augent/augent.lock");
let lockfile_content =
std::fs::read_to_string(&lockfile_path).expect("Failed to read lockfile");
let lockfile: serde_json::Value =
serde_json::from_str(&lockfile_content).expect("Failed to parse lockfile");
let bundles = lockfile["bundles"]
.as_array()
.expect("bundles should be an array");
let bundle_names: Vec<&str> = bundles.iter().filter_map(|b| b["name"].as_str()).collect();
assert!(
bundle_names.contains(&"@test/bundle-a"),
"lockfile should contain bundle-a, found: {:?}",
bundle_names
);
assert!(
bundle_names.contains(&"@test/bundle-b"),
"lockfile should contain bundle-b, found: {:?}",
bundle_names
);
});
}
#[test]
#[cfg_attr(
all(target_arch = "aarch64", target_os = "linux"),
ignore = "PTY spawn runs binary via /bin/sh in cross aarch64 Linux Docker"
)]
#[cfg_attr(
target_os = "windows",
ignore = "PTY reads block indefinitely on Windows conpty, causing test to hang"
)]
fn test_install_menu_deselect_all_uninstalls_all() {
common::run_with_timeout(std::time::Duration::from_secs(15), || {
let workspace = common::TestWorkspace::new();
workspace.init_from_fixture("empty");
workspace.create_agent_dir("cursor");
workspace.create_bundle("bundles");
workspace.create_bundle("bundles/bundle-a");
workspace.create_bundle("bundles/bundle-b");
workspace.write_file(
"bundles/bundle-a/augent.yaml",
"name: \"@test/bundle-a\"\nbundles: []\n",
);
workspace.write_file("bundles/bundle-a/commands/a.md", "# Bundle A\n");
workspace.write_file(
"bundles/bundle-b/augent.yaml",
"name: \"@test/bundle-b\"\nbundles: []\n",
);
workspace.write_file("bundles/bundle-b/commands/b.md", "# Bundle B\n");
common::augent_cmd_for_workspace(&workspace.path)
.args(["install", "./bundles", "--to", "cursor", "--all-bundles"])
.assert()
.success();
assert!(workspace.file_exists(".cursor/commands/a.md"));
assert!(workspace.file_exists(".cursor/commands/b.md"));
let augent_path = augent_bin_path();
let mut test = InteractiveTest::new(
augent_path.to_str().unwrap(),
&["install", "./bundles", "--to", "cursor"],
&workspace.path,
)
.expect("Failed to create interactive test");
test.wait_for_text("Select bundles", std::time::Duration::from_secs(2))
.expect("Menu should appear");
use common::MenuAction;
common::send_menu_actions(
&mut test,
&[
MenuAction::SelectCurrent,
MenuAction::MoveDown,
MenuAction::SelectCurrent,
MenuAction::Confirm,
],
)
.expect("Failed to send menu actions");
test.wait_for_completion(std::time::Duration::from_secs(3))
.expect("Failed to wait for process completion");
assert!(
!workspace.file_exists(".cursor/commands/a.md"),
"Bundle A file should be uninstalled when all bundles are deselected"
);
assert!(
!workspace.file_exists(".cursor/commands/b.md"),
"Bundle B file should be uninstalled when all bundles are deselected"
);
});
}