Opinionated OCaml linter with Merlin integration for code quality, naming conventions, and style checks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

merlint E605: fix expected test path for nested lib dirs

The path computation now finds the first lib/ or src/ component and
mirrors everything after it under test/. Before this fix,
ocaml-atp/atp/lib/atp_mst.ml would expect the test at
ocaml-atp/test/atp/lib/test_atp_mst.ml (wrong nesting). Now it
correctly expects ocaml-atp/atp/test/test_atp_mst.ml.

+24 -23
+24 -23
lib/rules/e605.ml
··· 52 52 - [proj/foo/sub/bar.ml] -> [proj/test/foo/sub/test_bar.ml] *) 53 53 let expected_test_path source_file = 54 54 let parts = String.split_on_char '/' source_file in 55 - (* Given [project :: source_dir :: rest], compute the test path. 56 - [lib] and [src] are conventional source dirs that get replaced by [test]. 57 - Any other directory (proto, foo, etc.) is kept under [test/]. *) 58 - let compute_test_path prefix dir rest = 59 - let after = String.concat "/" rest in 60 - let dirname = Filename.dirname after in 61 - let basename = Filename.basename after |> String.lowercase_ascii in 62 - let test_name = "test_" ^ basename in 63 - let test_after = 64 - if dir = "lib" || dir = "src" then 55 + (* Find the first [lib] or [src] component and split the path there. 56 + Everything before it is the project prefix; everything after is the 57 + module path within the library. The test file mirrors that structure 58 + under [test/]. 59 + 60 + - [proj/lib/foo.ml] → [proj/test/test_foo.ml] 61 + - [proj/atp/lib/atp_mst.ml] → [proj/atp/test/test_atp_mst.ml] 62 + - [proj/lib/sub/bar.ml] → [proj/test/sub/test_bar.ml] *) 63 + let rec find_lib_dir prefix = function 64 + | [] -> None 65 + | dir :: rest when dir = "lib" || dir = "src" -> 66 + Some (String.concat "/" (List.rev prefix), dir, rest) 67 + | part :: rest -> find_lib_dir (part :: prefix) rest 68 + in 69 + match find_lib_dir [] parts with 70 + | Some (project_prefix, _lib_or_src, rest) -> 71 + let after = String.concat "/" rest in 72 + let dirname = Filename.dirname after in 73 + let basename = Filename.basename after |> String.lowercase_ascii in 74 + let test_name = "test_" ^ basename in 75 + let test_after = 65 76 if dirname = "." then test_name else Filename.concat dirname test_name 66 - else 67 - let with_dir = 68 - if dirname = "." then Filename.concat dir test_name 69 - else Filename.concat dir (Filename.concat dirname test_name) 70 - in 71 - with_dir 72 - in 73 - Fmt.str "%s/test/%s" prefix test_after 74 - in 75 - match parts with 76 - | project :: dir :: rest when dir <> "test" && dir <> "bin" && rest <> [] -> 77 - compute_test_path project dir rest 78 - | _ -> 77 + in 78 + Fmt.str "%s/test/%s" project_prefix test_after 79 + | None -> 79 80 let dir = Filename.dirname source_file in 80 81 let base = Filename.basename source_file in 81 82 Filename.concat (Filename.concat dir "test") ("test_" ^ base)