//! CLI integration tests for empeve //! //! These tests exercise the binary's command-line interface to ensure //! proper user-facing behavior. use assert_cmd::Command; use predicates::prelude::*; use tempfile::TempDir; /// Get a command instance for empeve #[allow(deprecated)] fn empeve() -> Command { Command::cargo_bin("empeve").unwrap() } #[test] fn test_cli_help() { empeve() .arg("--help") .assert() .success() .stdout(predicate::str::contains("Plugin manager for mpv")); } #[test] fn test_cli_version() { empeve() .arg("--version") .assert() .success() .stdout(predicate::str::contains("empeve")); } #[test] fn test_cli_help_add() { empeve() .args(["add", "--help"]) .assert() .success() .stdout(predicate::str::contains("Add a repository")); } #[test] fn test_cli_help_install() { empeve() .args(["install", "--help"]) .assert() .success() .stdout(predicate::str::contains("Install all configured repositories")); } #[test] fn test_cli_help_update() { empeve() .args(["update", "--help"]) .assert() .success() .stdout(predicate::str::contains("Update all repositories")); } /// Test that the add command rejects invalid repo formats #[test] fn test_cli_add_invalid_repo_format() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create minimal config let config_path = config_dir.join("config.toml"); std::fs::write(&config_path, "[settings]\n").unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .args(["add", "invalid_repo_no_slash"]) .assert() .failure() .stderr(predicate::str::contains("invalid repository format")); } /// Test that the add command accepts valid GitHub shorthand #[test] fn test_cli_add_valid_repo_format() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create minimal config let config_path = config_dir.join("config.toml"); std::fs::write(&config_path, "[settings]\n").unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .args(["add", "user/repo"]) .assert() .success() .stdout(predicate::str::contains("Added")); // Verify config was updated let config_content = std::fs::read_to_string(&config_path).unwrap(); assert!(config_content.contains("user/repo")); } /// Test that adding a duplicate repo fails #[test] fn test_cli_add_duplicate_fails() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create config with existing repo let config_path = config_dir.join("config.toml"); std::fs::write( &config_path, r#"[settings] [[repos]] repo = "existing/repo" "#, ) .unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .args(["add", "existing/repo"]) .assert() .failure() .stderr(predicate::str::contains("already exists")); } /// Test that removing a non-existent repo fails #[test] fn test_cli_remove_nonexistent_fails() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create empty config let config_path = config_dir.join("config.toml"); std::fs::write(&config_path, "[settings]\n").unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .args(["remove", "nonexistent/repo"]) .assert() .failure() .stderr(predicate::str::contains("not found")); } /// Test status command with empty config #[test] fn test_cli_status_empty_config() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create empty config let config_path = config_dir.join("config.toml"); std::fs::write(&config_path, "[settings]\n").unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .arg("status") .assert() .success() .stdout(predicate::str::contains("No repositories")); } /// Test that --target flag is recognized #[test] fn test_cli_target_flag() { let temp = TempDir::new().unwrap(); let config_dir = temp.path().join(".config").join("empeve"); std::fs::create_dir_all(&config_dir).unwrap(); // Create config with target let config_path = config_dir.join("config.toml"); let mpv_path = temp.path().join("mpv"); std::fs::create_dir_all(&mpv_path).unwrap(); std::fs::write( &config_path, format!( r#"[settings] [[targets]] name = "mpv" path = "{}" "#, mpv_path.display() ), ) .unwrap(); empeve() .env("XDG_CONFIG_HOME", temp.path().join(".config")) .args(["--target", "mpv", "list"]) .assert() .success(); }