···146146 let prob = init_prob n_langs in
147147 let alpha = t.config.alpha +. (random_gaussian () *. alpha_width) in
148148 let converged = ref false in
149149- let i = ref 0 in
150150- while (not !converged) && !i < iteration_limit do
149149+ let iter_count = ref 0 in
150150+ while (not !converged) && !iter_count < iteration_limit do
151151 let r = random_int (Array.length ngrams) in
152152 let (_ : bool) = update_lang_prob prob ngrams.(r) t.word_lang_prob alpha in
153153- if !i mod 5 = 0 then
153153+ if !iter_count mod 5 = 0 then begin
154154 let max_p = normalize_prob prob in
155155- if max_p > t.config.conv_threshold then converged := true;
156156- incr i
155155+ if max_p > t.config.conv_threshold then converged := true
156156+ end;
157157+ incr iter_count
157158 done;
158159 for j = 0 to n_langs - 1 do
159160 lang_prob.(j) <- lang_prob.(j) +. (prob.(j) /. float_of_int t.config.n_trial)
+36
test/test_langdetect.ml
···538538 with exn ->
539539 Alcotest.fail (Printf.sprintf "Exception testing profiles: %s" (Printexc.to_string exn))
540540541541+(* Regression test: ensure detection loop completes in reasonable time.
542542+ This catches bugs like the iter_count variable name mismatch that caused infinite loops. *)
543543+let test_detection_completes_quickly () =
544544+ let d = get_detector () in
545545+ let start_time = Unix.gettimeofday () in
546546+ (* Run detection on several texts to ensure it completes *)
547547+ List.iter (fun (_, _, text) ->
548548+ let _ = Langdetect.detect_best d text in ()
549549+ ) all_test_corpus;
550550+ let elapsed = Unix.gettimeofday () -. start_time in
551551+ (* All detections should complete within 5 seconds total *)
552552+ if elapsed > 5.0 then
553553+ Alcotest.fail (Printf.sprintf "Detection took too long: %.2f seconds (expected < 5s)" elapsed)
554554+ else
555555+ Printf.printf "Detection completed in %.2f seconds\n" elapsed
556556+557557+(* Regression test: verify iteration_limit is respected in detect_block *)
558558+let test_iteration_limit_respected () =
559559+ let d = get_detector () in
560560+ (* Use a text that might not converge quickly *)
561561+ let mixed_text = String.concat " " (List.init 100 (fun i ->
562562+ if i mod 3 = 0 then "hello"
563563+ else if i mod 3 = 1 then "bonjour"
564564+ else "hallo"
565565+ )) in
566566+ let start_time = Unix.gettimeofday () in
567567+ let _ = Langdetect.detect d mixed_text in
568568+ let elapsed = Unix.gettimeofday () -. start_time in
569569+ (* Single detection should complete within 1 second *)
570570+ if elapsed > 1.0 then
571571+ Alcotest.fail (Printf.sprintf "Single detection took too long: %.2f seconds (expected < 1s)" elapsed)
572572+541573(* Main test suite *)
542574let () =
543575 Alcotest.run "Langdetect" [
···583615 Alcotest.test_case "very long text" `Quick test_very_long_text;
584616 Alcotest.test_case "repeated detection consistency" `Quick test_repeated_detection_consistency;
585617 Alcotest.test_case "all profiles functional" `Quick test_all_profiles_functional;
618618+ ]);
619619+ ("Regression tests", [
620620+ Alcotest.test_case "detection completes quickly" `Quick test_detection_completes_quickly;
621621+ Alcotest.test_case "iteration limit respected" `Quick test_iteration_limit_respected;
586622 ]);
587623 ]