use assert_cmd::assert::OutputAssertExt; use assert_cmd::cargo::cargo_bin; use predicates::prelude::*; use std::fs; use std::process::Command; use tempfile::TempDir; #[test] fn test_help_flag() { let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--help"); cmd.assert() .success() .stdout(predicate::str::contains("Usage: ntu")); } #[test] fn test_version_flag() { let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--version"); cmd.assert() .success() .stdout(predicate::str::contains("NameToUnix")); } #[test] fn test_dry_run_no_changes() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("test file.txt"); fs::write(&file_path, "test content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--dry-run").arg("-r").arg(temp_dir.path()); cmd.assert().success(); // File should still have spaces (not renamed) assert!(file_path.exists()); assert!(!temp_dir.path().join("test_file.txt").exists()); } #[test] fn test_actual_rename() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("test file.txt"); fs::write(&file_path, "test content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // File should be renamed assert!(!file_path.exists()); assert!(temp_dir.path().join("test_file.txt").exists()); } #[test] fn test_hidden_files_preserved() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join(".gitignore"); fs::write(&file_path, "*.tmp").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Hidden file should not be renamed assert!(file_path.exists()); } #[test] fn test_hidden_file_with_spaces() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join(".my config"); fs::write(&file_path, "config content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Hidden file should be renamed but keep leading dot assert!(!file_path.exists()); assert!(temp_dir.path().join(".my_config").exists()); } #[test] fn test_umlaut_conversion() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("Müller.txt"); fs::write(&file_path, "test").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Umlaut should be converted assert!(!file_path.exists()); assert!(temp_dir.path().join("Mueller.txt").exists()); } #[test] fn test_double_extension() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("my archive.tar.gz"); fs::write(&file_path, "archive").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Should keep .tar.gz intact assert!(!file_path.exists()); assert!(temp_dir.path().join("my_archive.tar.gz").exists()); } #[test] fn test_exclude_pattern() { let temp_dir = TempDir::new().unwrap(); let file1 = temp_dir.path().join("test file.txt"); let file2 = temp_dir.path().join("test file.tmp"); fs::write(&file1, "test1").unwrap(); fs::write(&file2, "test2").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--exclude") .arg("*.tmp") .arg("-r") .arg(temp_dir.path()); cmd.assert().success(); // .txt should be renamed, .tmp should not assert!(!file1.exists()); assert!(temp_dir.path().join("test_file.txt").exists()); assert!(file2.exists()); // Excluded } #[test] fn test_quiet_mode() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("test file.txt"); fs::write(&file_path, "test").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--quiet").arg("-r").arg(temp_dir.path()); cmd.assert() .success() .stdout(predicate::str::is_empty()); } #[test] fn test_multiple_paths() { let temp_dir1 = TempDir::new().unwrap(); let temp_dir2 = TempDir::new().unwrap(); let file1 = temp_dir1.path().join("file 1.txt"); let file2 = temp_dir2.path().join("file 2.txt"); fs::write(&file1, "test1").unwrap(); fs::write(&file2, "test2").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir1.path()).arg(temp_dir2.path()); cmd.assert().success(); // Both files should be renamed assert!(temp_dir1.path().join("file_1.txt").exists()); assert!(temp_dir2.path().join("file_2.txt").exists()); } #[test] fn test_parentheses_removed() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("Document (1).txt"); fs::write(&file_path, "test").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Parentheses should be replaced with underscores assert!(!file_path.exists()); assert!(temp_dir.path().join("Document_1.txt").exists()); } #[test] fn test_special_identifiers_preserved() { let temp_dir = TempDir::new().unwrap(); let file_path = temp_dir.path().join("C++ Guide.pdf"); fs::write(&file_path, "test").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // C++ should be preserved assert!(!file_path.exists()); assert!(temp_dir.path().join("C++_Guide.pdf").exists()); } #[test] fn test_non_recursive_default() { let temp_dir = TempDir::new().unwrap(); fs::create_dir(temp_dir.path().join("subdir")).unwrap(); let file1 = temp_dir.path().join("top file.txt"); let file2 = temp_dir.path().join("subdir").join("nested file.txt"); fs::write(&file1, "test1").unwrap(); fs::write(&file2, "test2").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg(temp_dir.path()); cmd.assert().success(); // Top-Level umbenannt assert!(temp_dir.path().join("top_file.txt").exists()); // Nested NICHT umbenannt (non-recursive) assert!(file2.exists()); } #[test] fn test_recursive_flag() { let temp_dir = TempDir::new().unwrap(); fs::create_dir(temp_dir.path().join("subdir")).unwrap(); let file1 = temp_dir.path().join("top file.txt"); let file2 = temp_dir.path().join("subdir").join("nested file.txt"); fs::write(&file1, "test1").unwrap(); fs::write(&file2, "test2").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-r").arg(temp_dir.path()); cmd.assert().success(); // Beide umbenannt assert!(temp_dir.path().join("top_file.txt").exists()); assert!(temp_dir.path().join("subdir").join("nested_file.txt").exists()); } #[test] fn test_conf_option_valid_file() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("custom.toml"); fs::write(&config_file, "[replacements]\n\"test\" = \"xyz\"").unwrap(); let file_path = temp_dir.path().join("test_file.txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf").arg(&config_file).arg(temp_dir.path()); cmd.assert().success(); assert!(temp_dir.path().join("xyz_file.txt").exists()); } #[test] fn test_conf_option_missing_file() { let temp_dir = TempDir::new().unwrap(); let nonexistent = temp_dir.path().join("nonexistent.toml"); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf").arg(&nonexistent).arg(temp_dir.path()); cmd.assert() .failure() .stderr(predicate::str::contains("nicht gefunden")); } #[test] fn test_sequence_lower() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("empty.toml"); fs::write(&config_file, "[replacements]\n").unwrap(); let file_path = temp_dir.path().join("Test File.txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf") .arg(&config_file) .arg("-s") .arg("lower") .arg(temp_dir.path()); cmd.assert().success(); assert!(temp_dir.path().join("test_file.txt").exists()); } #[test] fn test_sequence_upper() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("empty.toml"); fs::write(&config_file, "[replacements]\n").unwrap(); let file_path = temp_dir.path().join("test file.txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf") .arg(&config_file) .arg("-s") .arg("upper") .arg(temp_dir.path()); cmd.assert().success(); assert!(temp_dir.path().join("TEST_FILE.TXT").exists()); } #[test] fn test_sequence_minimal() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("empty.toml"); fs::write(&config_file, "[replacements]\n").unwrap(); let file_path = temp_dir.path().join("Müller Datei.txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf") .arg(&config_file) .arg("-s") .arg("minimal") .arg(temp_dir.path()); cmd.assert().success(); // Umlaute bleiben erhalten, nur Leerzeichen ersetzt assert!(temp_dir.path().join("Müller_Datei.txt").exists()); } #[test] fn test_sequence_utf8() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("empty.toml"); fs::write(&config_file, "[replacements]\n").unwrap(); let file_path = temp_dir.path().join("schön (1).txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf") .arg(&config_file) .arg("-s") .arg("utf-8") .arg(temp_dir.path()); cmd.assert().success(); // Umlaut bleibt, Klammern entfernt assert!(temp_dir.path().join("schön_1.txt").exists()); } #[test] fn test_list_sequences() { let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-L"); cmd.assert() .success() .stdout(predicate::str::contains("default")) .stdout(predicate::str::contains("lower")) .stdout(predicate::str::contains("upper")) .stdout(predicate::str::contains("minimal")) .stdout(predicate::str::contains("utf-8")); } #[test] fn test_list_sequences_verbose() { let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-L").arg("-v"); cmd.assert() .success() .stdout(predicate::str::contains("Umlauts → ASCII")) .stdout(predicate::str::contains("Case transform")); } #[test] fn test_invalid_sequence() { let temp_dir = TempDir::new().unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("-s").arg("invalid_seq").arg(temp_dir.path()); cmd.assert() .failure() .stderr(predicate::str::contains("Unbekannte Sequence")); } #[test] fn test_sequence_default_explicit() { let temp_dir = TempDir::new().unwrap(); let config_file = temp_dir.path().join("empty.toml"); fs::write(&config_file, "[replacements]\n").unwrap(); let file_path = temp_dir.path().join("Müller File.txt"); fs::write(&file_path, "content").unwrap(); let mut cmd = Command::new(cargo_bin!("ntu")); cmd.arg("--conf") .arg(&config_file) .arg("-s") .arg("default") .arg(temp_dir.path()); cmd.assert().success(); // Default: Umlaut → ASCII assert!(temp_dir.path().join("Mueller_File.txt").exists()); }