use assert_cmd::prelude::*; use predicates::prelude::*; use std::path::PathBuf;
use std::process::Command; use tempfile::TempDir;
const APP_NAME: &str = "crbrs";
const CONFIG_FILENAME: &str = "config.toml";
fn crbrs_cmd_isolated(temp_dir: &TempDir) -> Result<Command, Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("crbrs-cli")?;
cmd.env("XDG_CONFIG_HOME", temp_dir.path().join("config"));
cmd.env("XDG_DATA_HOME", temp_dir.path().join("data"));
Ok(cmd)
}
fn get_isolated_config_file_path(temp_dir: &TempDir) -> PathBuf {
temp_dir
.path()
.join("config") .join(APP_NAME) .join(CONFIG_FILENAME)
}
#[test]
fn test_config_path_default() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("crbrs-cli")?;
cmd.arg("config").arg("path");
cmd.assert()
.success()
.stdout(
predicate::str::contains(APP_NAME)
.and(predicate::str::contains(CONFIG_FILENAME))
.and(predicate::str::contains("Library/Application Support").or(predicate::str::contains(".config"))) );
Ok(())
}
#[test]
fn test_config_show_defaults_isolated() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?; let mut cmd = crbrs_cmd_isolated(&temp_dir)?; cmd.arg("config").arg("show");
let isolated_config = get_isolated_config_file_path(&temp_dir);
assert!(
!isolated_config.exists(),
"Config file {:?} should not exist in isolated temp dir before running 'show'",
isolated_config
);
cmd.assert()
.success()
.stdout(predicate::str::contains(
"Repository URL: https://example.com/compilers.toml", ))
.stdout(predicate::str::contains(
"Wine Path: (Not Set - using PATH)", ));
assert!(
!isolated_config.exists(),
"Config file {:?} should still not exist after merely showing defaults",
isolated_config
);
Ok(()) }
#[test]
fn test_config_set_and_show_isolated() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
let isolated_config = get_isolated_config_file_path(&temp_dir);
let test_wine_path = "/test/path/to/wine";
let mut cmd_set = crbrs_cmd_isolated(&temp_dir)?;
cmd_set
.arg("config")
.arg("set")
.arg("wine_path")
.arg(test_wine_path);
cmd_set.assert().success().stdout(
predicate::str::contains("Set 'wine_path'")
.and(predicate::str::contains(test_wine_path)),
);
assert!(
isolated_config.exists(),
"Config file {:?} should have been created by 'config set'",
isolated_config
);
let content = std::fs::read_to_string(&isolated_config)?;
println!("DEBUG: Isolated config content:\n{}", content); assert!(
content.contains(&format!("wine_path = \"{}\"", test_wine_path)),
"Config file content mismatch"
);
let mut cmd_show = crbrs_cmd_isolated(&temp_dir)?;
cmd_show.arg("config").arg("show");
cmd_show
.assert()
.success()
.stdout(predicate::str::contains(&format!(
"Wine Path: {}",
test_wine_path
)));
Ok(())
}
#[test]
fn test_config_set_association_isolated() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
let isolated_config = get_isolated_config_file_path(&temp_dir);
let mut cmd_set = crbrs_cmd_isolated(&temp_dir)?;
cmd_set
.arg("config")
.arg("set-association")
.arg("--extension")
.arg("crTest") .arg("--compiler-id")
.arg("test-compiler-v1");
cmd_set.assert().success();
assert!(isolated_config.exists());
let content = std::fs::read_to_string(&isolated_config)?;
assert!(content.contains("[file_associations]"));
assert!(content.contains("crtest = \"test-compiler-v1\""));
let mut cmd_show = crbrs_cmd_isolated(&temp_dir)?;
cmd_show.arg("config").arg("show");
cmd_show
.assert()
.success()
.stdout(predicate::str::contains(".crtest -> test-compiler-v1"));
let mut cmd_unset = crbrs_cmd_isolated(&temp_dir)?;
cmd_unset
.arg("config")
.arg("unset-association")
.arg("--extension")
.arg("crTest"); cmd_unset.assert().success();
let content_after_unset = std::fs::read_to_string(&isolated_config)?;
assert!(!content_after_unset.contains("crtest ="));
let mut cmd_show_after = crbrs_cmd_isolated(&temp_dir)?;
cmd_show_after.arg("config").arg("show");
cmd_show_after
.assert()
.success()
.stdout(predicate::str::contains("File Associations:\n (None)"));
Ok(())
}
#[test]
fn test_config_set_invalid_key() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
let mut cmd = crbrs_cmd_isolated(&temp_dir)?;
cmd.arg("config").arg("set").arg("this_key_is_bad").arg("some_value");
cmd.assert()
.failure() .stderr(predicate::str::contains("Error: Configuration error: Unknown configuration key: this_key_is_bad"));
Ok(())
}