use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use std::sync::Mutex;
use tempfile::TempDir;
static HOME_MUTEX: Mutex<()> = Mutex::new(());
#[test]
fn test_cli_version() {
let cargo_toml = include_str!("../Cargo.toml");
let version = cargo_toml
.lines()
.find(|line| line.starts_with("version = "))
.and_then(|line| line.split('"').nth(1))
.expect("Version not found in Cargo.toml");
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("--version")
.assert()
.success()
.stdout(predicate::str::contains(version));
}
#[test]
fn test_cli_help() {
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("BioVault"))
.stdout(predicate::str::contains("init"))
.stdout(predicate::str::contains("info"))
.stdout(predicate::str::contains("check"));
}
#[test]
fn test_init_command() {
let _guard = HOME_MUTEX
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let temp_dir = TempDir::new().unwrap();
let config_dir = temp_dir.path().join(".biovault");
let original_home = if cfg!(windows) {
let original_profile = std::env::var("USERPROFILE").ok();
std::env::set_var("USERPROFILE", temp_dir.path());
original_profile
} else {
let original_home = std::env::var("HOME").ok();
std::env::set_var("HOME", temp_dir.path());
original_home
};
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.env("BIOVAULT_TEST_HOME", temp_dir.path());
if cfg!(windows) {
cmd.env("USERPROFILE", temp_dir.path());
cmd.env_remove("HOMEDRIVE");
cmd.env_remove("HOMEPATH");
} else {
cmd.env("HOME", temp_dir.path());
}
cmd.arg("init")
.arg("test@example.com")
.assert()
.success()
.stdout(predicate::str::contains(
"BioVault initialized successfully",
));
let config_file = config_dir.join("config.yaml");
assert!(
config_file.exists(),
"Config file should exist at: {}",
config_file.display()
);
let contents = fs::read_to_string(&config_file).unwrap();
assert!(contents.contains("email: test@example.com"));
if cfg!(windows) {
if let Some(home) = original_home {
std::env::set_var("USERPROFILE", home);
} else {
std::env::remove_var("USERPROFILE");
}
} else if let Some(home) = original_home {
std::env::set_var("HOME", home);
} else {
std::env::remove_var("HOME");
}
}
#[test]
fn test_init_command_existing_config() {
let _guard = HOME_MUTEX
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let temp_dir = TempDir::new().unwrap();
let config_dir = temp_dir.path().join(".biovault");
fs::create_dir_all(&config_dir).unwrap();
let config_file = config_dir.join("config.yaml");
fs::write(&config_file, "email: existing@example.com\n").unwrap();
let original_home = if cfg!(windows) {
let original_profile = std::env::var("USERPROFILE").ok();
std::env::set_var("USERPROFILE", temp_dir.path());
original_profile
} else {
let original_home = std::env::var("HOME").ok();
std::env::set_var("HOME", temp_dir.path());
original_home
};
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.env("BIOVAULT_TEST_HOME", temp_dir.path());
if cfg!(windows) {
cmd.env("USERPROFILE", temp_dir.path());
cmd.env_remove("HOMEDRIVE");
cmd.env_remove("HOMEPATH");
} else {
cmd.env("HOME", temp_dir.path());
}
cmd.arg("init")
.arg("new@example.com")
.assert()
.success()
.stdout(predicate::str::contains("already exists"));
let contents = fs::read_to_string(&config_file).unwrap();
assert!(contents.contains("email: existing@example.com"));
assert!(!contents.contains("email: new@example.com"));
if cfg!(windows) {
if let Some(home) = original_home {
std::env::set_var("USERPROFILE", home);
} else {
std::env::remove_var("USERPROFILE");
}
} else if let Some(home) = original_home {
std::env::set_var("HOME", home);
} else {
std::env::remove_var("HOME");
}
}
#[test]
fn test_info_command() {
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("info")
.assert()
.success()
.stdout(predicate::str::contains("System Information"))
.stdout(predicate::str::contains("OS:"))
.stdout(predicate::str::contains("CPU Arch:"))
.stdout(predicate::str::contains("CPUs:"))
.stdout(predicate::str::contains("RAM:"))
.stdout(predicate::str::contains("DISK FREE:"));
}
#[test]
fn test_check_command() {
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("check")
.assert()
.success()
.stdout(predicate::str::contains("BioVault Dependency Check"))
.stdout(predicate::str::contains("docker"))
.stdout(predicate::str::contains("nextflow"));
}
#[test]
fn test_invalid_command() {
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("invalid-command")
.assert()
.failure()
.stderr(predicate::str::contains("unrecognized subcommand"));
}
#[test]
fn test_init_missing_email() {
let mut cmd = Command::cargo_bin("bv").unwrap();
cmd.arg("init")
.assert()
.failure()
.stderr(predicate::str::contains("required"));
}