@@ -107,6 +107,28 @@ module DisallowBeltRule =
107107 end )
108108 (TestingLinterOptions )
109109
110+ module DisallowBeltListRule =
111+ DisallowModuleRule. Make
112+ (struct
113+ type options = DisallowModuleRule.Options .options
114+
115+ let options =
116+ { DisallowModuleRule.Options. disallowed_module= " Belt.List"
117+ ; DisallowModuleRule.Options. suggested_module= Some " List" }
118+ end )
119+ (TestingLinterOptions )
120+
121+ module DisallowBeltArrayRule =
122+ DisallowModuleRule. Make
123+ (struct
124+ type options = DisallowModuleRule.Options .options
125+
126+ let options =
127+ { DisallowModuleRule.Options. disallowed_module= " Belt.Array"
128+ ; DisallowModuleRule.Options. suggested_module= Some " Array" }
129+ end )
130+ (TestingLinterOptions )
131+
110132module DisallowedEmbeddedRegexLiteralRule =
111133 DisallowedEmbeddedRegexLiteralRule. Make
112134 (struct
@@ -317,6 +339,48 @@ module Tests = struct
317339 ^ string_of_int (List. length errors)
318340 ^ " errors" )
319341
342+ (* Issue #15: pipe with no extra arguments bypasses DisallowModule lint *)
343+ let disallow_module_pipe_no_args_test () =
344+ let parseResult = parseAst " testData/disallow_module_test_6.res" in
345+ let errors, _warnings =
346+ Linter. lint [(module DisallowBeltListRule : Rule.HASRULE )] parseResult.ast parseResult.comments
347+ in
348+ match errors with
349+ | [_; _; _; _] -> Alcotest. (check pass) " Same error message" [] []
350+ | errors ->
351+ Alcotest. fail
352+ ( " Should have four lint errors (direct call, pipe+args, pipe no-args toArray, pipe no-args \
353+ length), but got "
354+ ^ string_of_int (List. length errors)
355+ ^ " errors" )
356+
357+ (* Issue #15: verify Pexp_apply scenarios still caught after Pexp_ident fix *)
358+ let disallow_module_pexp_apply_test () =
359+ let parseResult = parseAst " testData/disallow_module_test_7.res" in
360+ let errors, _warnings =
361+ Linter. lint
362+ [(module DisallowBeltListRule : Rule.HASRULE ); (module DisallowBeltArrayRule : Rule.HASRULE )]
363+ parseResult.ast parseResult.comments
364+ in
365+ (* Expected errors:
366+ 1. Belt.List.toArray — direct call, single arg
367+ 2. Belt.List.has — direct call, multiple args
368+ 3. Belt.List.map — pipe with extra args
369+ 4. Belt.List.toArray — pipe with no extra args (was the bug)
370+ 5. Belt.List.toArray — chained pipe, no-args (was the bug)
371+ 6. Belt.Array.map — chained pipe, with args
372+ 7. Belt.List.toArray — nested outer call
373+ 8. Belt.List.map — nested inner call
374+ *)
375+ match errors with
376+ | [_; _; _; _; _; _; _; _] -> Alcotest. (check pass) " Same error message" [] []
377+ | errors ->
378+ Alcotest. fail
379+ ( " Should have eight lint errors (6 Belt.List + 2 Belt.Array... wait, 7 Belt.List + 1 Belt.Array), \
380+ but got "
381+ ^ string_of_int (List. length errors)
382+ ^ " errors" )
383+
320384 let disallowed_embedded_regex_literal_test () =
321385 let parseResult = parseAst " testData/disallowed_embedded_regex_literal_test.res" in
322386 let errors, _warnings =
@@ -441,7 +505,9 @@ let () =
441505 ; test_case " alias module" `Quick Tests. disallow_module_test_2
442506 ; test_case " direct access module" `Quick Tests. disallow_module_test_3
443507 ; test_case " qualified module with constructors (Belt.Result)" `Quick Tests. disallow_module_test_4
444- ; test_case " module prefix matching (Belt.*)" `Quick Tests. disallow_module_test_5 ] )
508+ ; test_case " module prefix matching (Belt.*)" `Quick Tests. disallow_module_test_5
509+ ; test_case " pipe with no extra args (Issue #15)" `Quick Tests. disallow_module_pipe_no_args_test
510+ ; test_case " Pexp_apply still caught (Issue #15)" `Quick Tests. disallow_module_pexp_apply_test ] )
445511 ; ( " Disallowed embedded regex literal"
446512 , [test_case " Disallowed embedded regex literal" `Quick Tests. disallowed_embedded_regex_literal_test] )
447513 ; (" Disallowed dead code" , [test_case " Disallowed dead code" `Quick Tests. disallowed_dead_code_test])
0 commit comments