1mod backup;
12mod dir;
13mod grep;
14mod read_write;
15mod search_replace;
16mod util;
17
18pub use backup::{backup_file, prune_oldest_files};
20pub use dir::{
21 copy, create_dir_all, file_exists, list_directory, modified_time, read_dir, remove_file,
22 rename, PathKind,
23};
24pub use grep::{grep_directory, GrepMatch, SKIP_DIRS};
25pub use read_write::{
26 append_file, atomic_write, read_bytes, read_bytes_limit, read_file,
27 search_replace as search_replace_file, write_file,
28};
29pub use search_replace::{
30 apply_replace_fuzzy, apply_replace_normalize_whitespace, apply_search_replace,
31 build_failure_hint, insert_lines_at, line_byte_offsets, safe_excerpt, FuzzyReplaceResult,
32};
33pub use util::{is_likely_binary, matches_glob};
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38 use std::io::Write;
39 use tempfile::{NamedTempFile, TempDir};
40
41 #[test]
42 fn test_file_exists() {
43 let dir = TempDir::new().unwrap();
44 let f = dir.path().join("a.txt");
45 std::fs::write(&f, "x").unwrap();
46 assert!(matches!(file_exists(&f).unwrap(), PathKind::File(1)));
47 assert!(matches!(file_exists(dir.path()).unwrap(), PathKind::Dir));
48 assert!(matches!(
49 file_exists(&dir.path().join("nonexistent")).unwrap(),
50 PathKind::NotFound
51 ));
52 }
53
54 #[test]
55 fn test_list_directory() {
56 let dir = TempDir::new().unwrap();
57 std::fs::write(dir.path().join("a.txt"), "1").unwrap();
58 std::fs::create_dir(dir.path().join("sub")).unwrap();
59 std::fs::write(dir.path().join("sub").join("b.txt"), "2").unwrap();
60 let entries = list_directory(dir.path(), false).unwrap();
61 assert!(entries.iter().any(|e| e.contains("a.txt")));
62 assert!(entries.iter().any(|e| e.contains("sub")));
63 let rec = list_directory(dir.path(), true).unwrap();
64 assert!(rec.iter().any(|e| e.contains("b.txt")));
65 }
66
67 #[test]
68 fn test_apply_search_replace_once() {
69 let content = "hello world\nhello rust";
70 let (new_content, count) = apply_search_replace(content, "hello", "hi", false).unwrap();
71 assert_eq!(new_content, "hi world\nhello rust");
72 assert_eq!(count, 1);
73 }
74
75 #[test]
76 fn test_apply_search_replace_all() {
77 let content = "hello world hello";
78 let (new_content, count) = apply_search_replace(content, "hello", "hi", true).unwrap();
79 assert_eq!(new_content, "hi world hi");
80 assert_eq!(count, 2);
81 }
82
83 #[test]
84 fn test_apply_search_replace_not_found() {
85 let content = "hello world";
86 let r = apply_search_replace(content, "xyz", "a", false);
87 assert!(r.is_err());
88 }
89
90 #[test]
91 fn test_search_replace_file() {
92 let mut f = NamedTempFile::new().unwrap();
93 write!(f, "foo bar foo").unwrap();
94 let path = f.path();
95 let count = search_replace_file(path, "foo", "baz", true).unwrap();
96 assert_eq!(count, 2);
97 let content = read_file(path).unwrap();
98 assert_eq!(content, "baz bar baz");
99 }
100}