(** Tests for the functional Sonority module *) open Sorsyl (** Test fixture - create the sonority calculator once *) let sonority_calc = let data_dir = if Sys.file_exists "./data" then "./data" else if Sys.file_exists "../data" then "../data" else if Sys.file_exists "../../../data" then "../../../data" else ( Printf.eprintf "Current directory: %s\n" (Sys.getcwd ()); failwith "Cannot find data directory") in Sonority.create data_dir (** Test sonority value 9 - Low vowels *) let test_sonority_nine () = let segments = [ "a"; "ɑ"; "æ"; "ɒ"; "e"; "o̥" ] in let expected = [ 9; 9; 9; 9; 9; 9 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_nine: PASSED\n" (** Test sonority value 8 - High vowels *) let test_sonority_eight () = let segments = [ "i"; "y"; "ɨ"; "ʉ"; "ɯ"; "u" ] in let expected = [ 8; 8; 8; 8; 8; 8 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_eight: PASSED\n" (** Test sonority value 7 - Glides/approximants *) let test_sonority_seven () = let segments = [ "j"; "w"; "ʋ"; "ɰ"; "ɹ"; "e̯" ] in let expected = [ 7; 7; 7; 7; 7; 7 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_seven: PASSED\n" (** Test sonority value 6 - Liquids *) let test_sonority_six () = let segments = [ "l"; "ɭ"; "r"; "ɾ" ] in let expected = [ 6; 6; 6; 6 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_six: PASSED\n" (** Test sonority value 5 - Nasals *) let test_sonority_five () = let segments = [ "n"; "m"; "ŋ"; "ɴ" ] in let expected = [ 5; 5; 5; 5 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_five: PASSED\n" (** Test sonority value 4 - Voiced fricatives *) let test_sonority_four () = let segments = [ "v"; "z"; "ʒ"; "ɣ" ] in let expected = [ 4; 4; 4; 4 ] in let results = List.map (Sonority.sonority sonority_calc) segments in let results_string = List.fold_left (fun acc item -> Printf.sprintf "%s-%d" acc item) "" results in assert (results = expected); Printf.printf "test_sonority_four: %s\nPASSED\n" results_string (** Test sonority value 3 - Voiceless fricatives *) let test_sonority_three () = let segments = [ "f"; "s"; "x"; "ħ"; "ʃ" ] in let expected = [ 3; 3; 3; 3; 3 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_three: PASSED\n" (** Test sonority value 2 - Voiced stops *) let test_sonority_two () = let segments = [ "b"; "ɡ"; "d"; "ɢ" ] in let expected = [ 2; 2; 2; 2 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_two: PASSED\n" (** Test sonority value 1 - Voiceless stops *) let test_sonority_one () = let segments = [ "p"; "k"; "c"; "q" ] in let expected = [ 1; 1; 1; 1 ] in let results = List.map (Sonority.sonority sonority_calc) segments in assert (results = expected); Printf.printf "test_sonority_one: PASSED\n" (** Test unknown segment handling *) let test_unknown_segment () = try let _ = Sonority.sonority sonority_calc "🦆" in assert false (* Should not reach here *) with | Failure msg when String.sub msg 0 20 = "Unknown IPA segment:" -> Printf.printf "test_unknown_segment: PASSED\n" | _ -> assert false (** Test feature-based sonority calculation *) let test_sonority_from_features () = (* Test a simple voiceless stop: -syl, +cons, -son, -cont, -voi *) let segment = [ (Feature.Syllabic, Feature.Minus); (Feature.Consonantal, Feature.Plus); (Feature.Sonorant, Feature.Minus); (Feature.Continuant, Feature.Minus); (Feature.Voiced, Feature.Minus); ] in let result = Sonority.sonority_from_features sonority_calc segment in assert (result = 1); Printf.printf "test_sonority_from_features: PASSED\n" (** Test that we can create multiple calculators (no global state) *) let test_multiple_calculators () = let data_dir = if Sys.file_exists "./data" then "./data" else if Sys.file_exists "../data" then "../data" else if Sys.file_exists "../../../data" then "../../../data" else failwith "Cannot find data directory" in let calc1 = Sonority.create data_dir in let calc2 = Sonority.create data_dir in (* Both should work independently *) assert (Sonority.sonority calc1 "a" = 9); assert (Sonority.sonority calc2 "a" = 9); Printf.printf "test_multiple_calculators: PASSED\n" (** Run all tests *) let () = Printf.printf "Running Sonority module tests...\n"; Printf.printf "===================================\n"; test_sonority_nine (); test_sonority_eight (); test_sonority_seven (); test_sonority_six (); test_sonority_five (); test_sonority_four (); test_sonority_three (); test_sonority_two (); test_sonority_one (); test_unknown_segment (); test_sonority_from_features (); test_multiple_calculators (); Printf.printf "===================================\n"; Printf.printf "All Sonority tests passed!\n"