Find and remove dead code and unused APIs in OCaml projects
at main 272 lines 8.1 kB view raw
1(* Tests for the cache module *) 2open Alcotest 3open Prune 4 5let temp_file_fn content = 6 let file = Filename.temp_file "cache_test" ".txt" in 7 let oc = open_out file in 8 output_string oc content; 9 close_out oc; 10 file 11 12let read_file file = 13 let ic = open_in file in 14 let content = really_input_string ic (in_channel_length ic) in 15 close_in ic; 16 content 17 18let test_create_and_clear () = 19 let cache = Cache.v () in 20 let make_temp_file = temp_file_fn "line1\nline2\nline3" in 21 22 (* Load file into cache *) 23 (match Cache.load cache make_temp_file with 24 | Ok () -> () 25 | Error (`Msg msg) -> fail msg); 26 27 (* Verify file is loaded *) 28 check (option string) "line 1" (Some "line1") 29 (Cache.line cache make_temp_file 1); 30 check (option string) "line 2" (Some "line2") 31 (Cache.line cache make_temp_file 2); 32 33 (* Clear cache *) 34 Cache.clear cache; 35 36 (* Verify cache is empty *) 37 check (option string) "after clear" None (Cache.line cache make_temp_file 1); 38 39 Sys.remove make_temp_file 40 41let test_load_and_get_line () = 42 let cache = Cache.v () in 43 let content = "first line\nsecond line\nthird line" in 44 let make_temp_file = temp_file_fn content in 45 46 (* Test get_line before loading *) 47 check (option string) "before load" None (Cache.line cache make_temp_file 1); 48 49 (* Load file *) 50 (match Cache.load cache make_temp_file with 51 | Ok () -> () 52 | Error (`Msg msg) -> fail msg); 53 54 (* Test get_line after loading *) 55 check (option string) "line 1" (Some "first line") 56 (Cache.line cache make_temp_file 1); 57 check (option string) "line 2" (Some "second line") 58 (Cache.line cache make_temp_file 2); 59 check (option string) "line 3" (Some "third line") 60 (Cache.line cache make_temp_file 3); 61 62 (* Test out of bounds *) 63 check (option string) "line 0" None (Cache.line cache make_temp_file 0); 64 check (option string) "line 4" None (Cache.line cache make_temp_file 4); 65 66 Sys.remove make_temp_file 67 68let test_replace_line () = 69 let cache = Cache.v () in 70 let content = "AAA\nBBB\nCCC" in 71 let make_temp_file = temp_file_fn content in 72 73 (* Load file *) 74 (match Cache.load cache make_temp_file with 75 | Ok () -> () 76 | Error (`Msg msg) -> fail msg); 77 78 (* Replace line 2 *) 79 Cache.replace_line cache make_temp_file 2 "XXX"; 80 81 (* Verify replacement *) 82 check (option string) "line 1 unchanged" (Some "AAA") 83 (Cache.line cache make_temp_file 1); 84 check (option string) "line 2 replaced" (Some "XXX") 85 (Cache.line cache make_temp_file 2); 86 check (option string) "line 3 unchanged" (Some "CCC") 87 (Cache.line cache make_temp_file 3); 88 89 (* Test out of bounds replace *) 90 Cache.replace_line cache make_temp_file 0 "invalid"; 91 Cache.replace_line cache make_temp_file 4 "invalid"; 92 93 (* Lines should be unchanged *) 94 check (option string) "after invalid replace" (Some "XXX") 95 (Cache.line cache make_temp_file 2); 96 97 Sys.remove make_temp_file 98 99let test_clear_line () = 100 let cache = Cache.v () in 101 let content = "line1\nline2\nline3" in 102 let make_temp_file = temp_file_fn content in 103 104 (* Load file *) 105 (match Cache.load cache make_temp_file with 106 | Ok () -> () 107 | Error (`Msg msg) -> fail msg); 108 109 (* Clear line 2 *) 110 Cache.clear_line cache make_temp_file 2; 111 112 (* Verify clearing *) 113 check (option string) "line 1 unchanged" (Some "line1") 114 (Cache.line cache make_temp_file 1); 115 check (option string) "line 2 cleared" (Some "") 116 (Cache.line cache make_temp_file 2); 117 check (option string) "line 3 unchanged" (Some "line3") 118 (Cache.line cache make_temp_file 3); 119 120 Sys.remove make_temp_file 121 122let test_get_line_count () = 123 let cache = Cache.v () in 124 125 (* Test non-existent file *) 126 check (option int) "non-existent file" None 127 (Cache.line_count cache "nonexistent.txt"); 128 129 let content = "one\ntwo\nthree\nfour" in 130 let make_temp_file = temp_file_fn content in 131 132 (* Load file *) 133 (match Cache.load cache make_temp_file with 134 | Ok () -> () 135 | Error (`Msg msg) -> fail msg); 136 137 (* Check line count *) 138 check (option int) "line count" (Some 4) 139 (Cache.line_count cache make_temp_file); 140 141 (* Test empty file *) 142 let empty_file = temp_file_fn "" in 143 (match Cache.load cache empty_file with 144 | Ok () -> () 145 | Error (`Msg msg) -> fail msg); 146 check (option int) "empty file" (Some 1) (Cache.line_count cache empty_file); 147 148 Sys.remove make_temp_file; 149 Sys.remove empty_file 150 151let test_write_with_changes () = 152 let cache = Cache.v () in 153 let content = "original1\noriginal2\noriginal3" in 154 let make_temp_file = temp_file_fn content in 155 156 (* Load file *) 157 (match Cache.load cache make_temp_file with 158 | Ok () -> () 159 | Error (`Msg msg) -> fail msg); 160 161 (* Make changes *) 162 Cache.replace_line cache make_temp_file 1 "modified1"; 163 Cache.clear_line cache make_temp_file 2; 164 Cache.replace_line cache make_temp_file 3 "modified3"; 165 166 (* Write to disk *) 167 (match Cache.write cache make_temp_file with 168 | Ok () -> () 169 | Error (`Msg msg) -> fail msg); 170 171 (* Read file and verify *) 172 let new_content = read_file make_temp_file in 173 check string "written content" "modified1\n\nmodified3" new_content; 174 175 Sys.remove make_temp_file 176 177let test_write_without_changes_fails () = 178 let cache = Cache.v () in 179 let content = "line1\nline2" in 180 let make_temp_file = temp_file_fn content in 181 182 (* Load file *) 183 (match Cache.load cache make_temp_file with 184 | Ok () -> () 185 | Error (`Msg msg) -> fail msg); 186 187 (* Try to write without making changes - should fail *) 188 let write_result = 189 try 190 let _ = Cache.write cache make_temp_file in 191 false 192 with Failure msg -> 193 (* Check the error message *) 194 check bool "error message contains BUG" true 195 (String.starts_with ~prefix:"BUG: Attempted to write file" msg); 196 true 197 in 198 199 check bool "write without changes fails" true write_result; 200 201 Sys.remove make_temp_file 202 203let test_no_change_tracking () = 204 let cache = Cache.v () in 205 let content = "AAA\nBBB\nCCC" in 206 let make_temp_file = temp_file_fn content in 207 208 (* Load file *) 209 (match Cache.load cache make_temp_file with 210 | Ok () -> () 211 | Error (`Msg msg) -> fail msg); 212 213 (* Replace with same content - should not track as diff *) 214 Cache.replace_line cache make_temp_file 2 "BBB"; 215 216 (* Try to write - should fail since no actual changes *) 217 let write_result = 218 try 219 let _ = Cache.write cache make_temp_file in 220 false 221 with Failure _ -> true 222 in 223 224 check bool "write with no-op change fails" true write_result; 225 226 Sys.remove make_temp_file 227 228let test_multiple_files () = 229 let cache = Cache.v () in 230 let file1 = temp_file_fn "file1_line1\nfile1_line2" in 231 let file2 = temp_file_fn "file2_line1\nfile2_line2" in 232 233 (* Load both files *) 234 (match Cache.load cache file1 with 235 | Ok () -> () 236 | Error (`Msg msg) -> fail msg); 237 238 (match Cache.load cache file2 with 239 | Ok () -> () 240 | Error (`Msg msg) -> fail msg); 241 242 (* Modify different files *) 243 Cache.replace_line cache file1 1 "modified_file1"; 244 Cache.replace_line cache file2 2 "modified_file2"; 245 246 (* Check independence *) 247 check (option string) "file1 line 1" (Some "modified_file1") 248 (Cache.line cache file1 1); 249 check (option string) "file1 line 2" (Some "file1_line2") 250 (Cache.line cache file1 2); 251 check (option string) "file2 line 1" (Some "file2_line1") 252 (Cache.line cache file2 1); 253 check (option string) "file2 line 2" (Some "modified_file2") 254 (Cache.line cache file2 2); 255 256 Sys.remove file1; 257 Sys.remove file2 258 259let suite = 260 ( "cache", 261 [ 262 test_case "create and clear" `Quick test_create_and_clear; 263 test_case "load and get_line" `Quick test_load_and_get_line; 264 test_case "replace_line" `Quick test_replace_line; 265 test_case "clear_line" `Quick test_clear_line; 266 test_case "get_line_count" `Quick test_get_line_count; 267 test_case "write with changes" `Quick test_write_with_changes; 268 test_case "write without changes fails" `Quick 269 test_write_without_changes_fails; 270 test_case "no change tracking" `Quick test_no_change_tracking; 271 test_case "multiple files" `Quick test_multiple_files; 272 ] )