use std::fs;
use std::path::Path;
use tempfile::tempdir;
use vkteams_bot_cli::completion::{
CompletionShell, generate_all_completions, generate_completion, get_default_completion_dir,
};
#[test]
fn test_generate_bash_completion_to_stdout() {
let result = generate_completion(CompletionShell::Bash, None);
assert!(result.is_ok(), "Bash completion generation should succeed");
}
#[test]
fn test_generate_zsh_completion_to_stdout() {
let result = generate_completion(CompletionShell::Zsh, None);
assert!(result.is_ok(), "Zsh completion generation should succeed");
}
#[test]
fn test_generate_fish_completion_to_stdout() {
let result = generate_completion(CompletionShell::Fish, None);
assert!(result.is_ok(), "Fish completion generation should succeed");
}
#[test]
fn test_generate_powershell_completion_to_stdout() {
let result = generate_completion(CompletionShell::PowerShell, None);
assert!(
result.is_ok(),
"PowerShell completion generation should succeed"
);
}
#[test]
fn test_generate_completion_to_file() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let output_path = temp_dir.path().join("test_completion.bash");
let result = generate_completion(CompletionShell::Bash, Some(&output_path));
assert!(
result.is_ok(),
"Runtime completion generation to file should succeed"
);
assert!(output_path.exists(), "Completion file should be created");
let content = fs::read_to_string(&output_path).expect("Failed to read completion file");
assert!(!content.is_empty(), "Completion file should not be empty");
assert!(
content.contains("vkteams-bot-cli"),
"Completion should reference the CLI name"
);
}
#[test]
fn test_generate_all_completions() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let result = generate_all_completions(temp_dir.path());
assert!(
result.is_ok(),
"Runtime generating all completions should succeed"
);
let expected_files = [
"vkteams-bot-cli.bash",
"_vkteams-bot-cli",
"vkteams-bot-cli.fish",
"vkteams-bot-cli.ps1",
];
for filename in &expected_files {
let file_path = temp_dir.path().join(filename);
assert!(
file_path.exists(),
"Runtime completion file {filename} should exist"
);
let content =
fs::read_to_string(&file_path).unwrap_or_else(|_| panic!("Failed to read {filename}"));
assert!(
!content.is_empty(),
"Runtime completion file {filename} should not be empty"
);
}
}
#[test]
fn test_generate_completion_nonexistent_directory() {
let nonexistent_path = Path::new("/nonexistent/directory/completion.bash");
let result = generate_completion(CompletionShell::Bash, Some(nonexistent_path));
assert!(
result.is_err(),
"Should fail when parent directory doesn't exist"
);
}
#[test]
fn test_get_default_completion_dir() {
let default_dir = get_default_completion_dir();
if let Some(dir) = default_dir {
assert!(dir.to_string_lossy().contains("vkteams-bot-cli"));
assert!(dir.to_string_lossy().contains("completions"));
}
}
#[test]
fn test_completion_shell_conversion() {
use clap_complete::Shell;
let bash_shell: Shell = CompletionShell::Bash.into();
assert!(matches!(bash_shell, Shell::Bash));
let zsh_shell: Shell = CompletionShell::Zsh.into();
assert!(matches!(zsh_shell, Shell::Zsh));
let fish_shell: Shell = CompletionShell::Fish.into();
assert!(matches!(fish_shell, Shell::Fish));
let powershell_shell: Shell = CompletionShell::PowerShell.into();
assert!(matches!(powershell_shell, Shell::PowerShell));
}
#[test]
fn test_completion_content_quality() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let bash_path = temp_dir.path().join("test.bash");
generate_completion(CompletionShell::Bash, Some(&bash_path)).unwrap();
let bash_content = fs::read_to_string(&bash_path).unwrap();
assert!(
bash_content.contains("vkteams-bot-cli"),
"Should contain CLI name"
);
assert!(
bash_content.contains("complete"),
"Should contain completion setup"
);
let commands = [
"send-text",
"send-file",
"get-chat-info",
"schedule",
"config",
];
for command in &commands {
assert!(
bash_content.contains(command),
"Completion should reference command: {command}"
);
}
}
#[test]
fn test_zsh_completion_content() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let zsh_path = temp_dir.path().join("_test");
generate_completion(CompletionShell::Zsh, Some(&zsh_path)).unwrap();
let zsh_content = fs::read_to_string(&zsh_path).unwrap();
assert!(
zsh_content.contains("#compdef"),
"Should contain zsh compdef"
);
assert!(
zsh_content.contains("vkteams-bot-cli"),
"Should contain CLI name"
);
}
#[test]
fn test_fish_completion_content() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let fish_path = temp_dir.path().join("test.fish");
generate_completion(CompletionShell::Fish, Some(&fish_path)).unwrap();
let fish_content = fs::read_to_string(&fish_path).unwrap();
assert!(
fish_content.contains("complete"),
"Should contain fish complete commands"
);
assert!(
fish_content.contains("vkteams-bot-cli"),
"Should contain CLI name"
);
}
#[test]
fn test_powershell_completion_content() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let ps_path = temp_dir.path().join("test.ps1");
generate_completion(CompletionShell::PowerShell, Some(&ps_path)).unwrap();
let ps_content = fs::read_to_string(&ps_path).unwrap();
assert!(
ps_content.contains("Register-ArgumentCompleter") || ps_content.contains("TabExpansion"),
"Should contain PowerShell completion setup"
);
assert!(
ps_content.contains("vkteams-bot-cli"),
"Should contain CLI name"
);
}
#[test]
fn test_completion_file_permissions() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let completion_path = temp_dir.path().join("test_completion.bash");
generate_completion(CompletionShell::Bash, Some(&completion_path)).unwrap();
assert!(completion_path.exists());
let metadata = fs::metadata(&completion_path).unwrap();
assert!(metadata.is_file());
assert!(metadata.len() > 0);
}
#[cfg(unix)]
#[test]
fn test_completion_file_permissions_unix() {
use std::os::unix::fs::PermissionsExt;
let temp_dir = tempdir().expect("Failed to create temp directory");
let completion_path = temp_dir.path().join("test_completion.bash");
generate_completion(CompletionShell::Bash, Some(&completion_path)).unwrap();
let metadata = fs::metadata(&completion_path).unwrap();
let permissions = metadata.permissions();
assert!(
permissions.mode() & 0o400 != 0,
"File should be readable by owner"
);
}
#[test]
fn test_completion_with_invalid_path() {
#[cfg(unix)]
let invalid_path = Path::new("/root/test_completion.bash");
#[cfg(windows)]
let invalid_path = Path::new("C:\\Windows\\System32\\test_completion.bash");
let result = generate_completion(CompletionShell::Bash, Some(invalid_path));
match result {
Ok(_) => {
let _ = fs::remove_file(invalid_path);
}
Err(_) => {
}
}
}
#[test]
fn test_completion_overwrite_existing_file() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let completion_path = temp_dir.path().join("existing_completion.bash");
fs::write(&completion_path, "# Old completion").unwrap();
assert!(completion_path.exists());
let result = generate_completion(CompletionShell::Bash, Some(&completion_path));
assert!(
result.is_ok(),
"Should be able to overwrite existing file with runtime generation"
);
let content = fs::read_to_string(&completion_path).unwrap();
assert!(!content.contains("# Old completion"));
assert!(content.contains("vkteams-bot-cli"));
}
#[test]
fn test_generate_all_completions_creates_directory() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let subdir = temp_dir.path().join("new_completions_dir");
assert!(!subdir.exists());
let result = generate_all_completions(&subdir);
assert!(
result.is_ok(),
"Should create directory and generate runtime completions"
);
assert!(subdir.exists());
assert!(subdir.is_dir());
}
#[test]
fn test_completion_commands_coverage() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let bash_path = temp_dir.path().join("coverage_test.bash");
generate_completion(CompletionShell::Bash, Some(&bash_path)).unwrap();
let content = fs::read_to_string(&bash_path).unwrap();
let expected_commands = [
"send-text",
"send-file",
"send-voice",
"get-chat-info",
"schedule",
"scheduler",
"task",
"config",
"setup",
"validate",
"completion",
"examples",
];
for command in &expected_commands {
assert!(
content.contains(command),
"Completion should cover command: {command}"
);
}
}