From f00f7a66d073815249e94cec1b6ef10539d773e7 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Wed, 19 Aug 2026 14:12:52 +0200 Subject: feat(lang): Latin temporal names from the Missal Every entry is transcribed from the 1962 Missal's own propers headings in docs/research/LT.txt and cites where it came from; names constructed by following a neighbouring pattern are marked as such, so a reader can tell transcription from inference. The coverage test is the point of this commit. It walks every day of 2020-2045 and fails naming any slug with no Latin name -- the test that would have caught the original defect, where a printed booklet said ef-septuagesima-sunday-2 because nothing asserted that names exist. The three Triduum names reuse the exact strings temporal_ef.ml already carries, so the engine and the language file cannot disagree. --- test/test_lang_coverage.ml | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/test_lang_coverage.ml (limited to 'test/test_lang_coverage.ml') diff --git a/test/test_lang_coverage.ml b/test/test_lang_coverage.ml new file mode 100644 index 0000000..d72484f --- /dev/null +++ b/test/test_lang_coverage.ml @@ -0,0 +1,73 @@ +module L = Colitur_naming.Lang + +let read path = + let ic = open_in_bin path in + let s = really_input_string ic (in_channel_length ic) in + close_in ic; + s + +let la () = + match L.of_string (read "../lang/la.ini") with + | Ok t -> t + | Error e -> Alcotest.failf "lang/la.ini: %s" e + +(* Every TEMPORAL slug the engine can emit must have a Latin name. THIS IS THE + TEST THAT WOULD HAVE CAUGHT THE ORIGINAL DEFECT -- a booklet printed + "ef-septuagesima-sunday-2" because nothing asserted coverage. It must fail + loudly the moment a new slug appears without a name. + + RESTRICTED TO "^ef-" SLUGS FOR NOW (Task 3's own scope: la.ini's + [celebration] table currently carries the temporal half only). Task 4 adds + the sanctoral names and REMOVES this filter -- see this file's own + [is_temporal_slug] below, kept as one clearly-named, easy-to-find place to + change, rather than an inline condition. *) +let is_temporal_slug slug = String.length slug >= 3 && String.sub slug 0 3 = "ef-" + +let test_every_temporal_slug_has_a_latin_name () = + let t = la () in + let layer = match Test_support.load_ef_layer () with Ok l -> l | Error e -> Alcotest.failf "%s" e in + let ctx = Test_support.ef_context () in + let missing = ref [] in + for y = 2020 to 2045 do + Array.iter + (fun (d : (Rite_ef.Vocab_ef.season, Rite_ef.Vocab_ef.rank) Colitur_kernel.Liturgical_day.t) -> + let slug = + Colitur_kernel.Slug.to_string + d.Colitur_kernel.Liturgical_day.observed.Colitur_kernel.Celebration.slug + in + (* A miss returns the key itself, so name = slug means "no entry". *) + if + is_temporal_slug slug + && L.celebration t slug = slug + && not (List.mem slug !missing) + then missing := slug :: !missing) + (Colitur_kernel.Calendar.year ctx layer y) + done; + if !missing <> [] then + Alcotest.failf "%d slugs have no Latin name, e.g. %s" (List.length !missing) + (String.concat ", " (List.filteri (fun i _ -> i < 5) !missing)) + +let test_vocabularies_are_complete () = + let t = la () in + List.iter + (fun s -> if L.season t s = s then Alcotest.failf "no Latin season name for %S" s) + [ "advent"; "christmastide"; "time-after-epiphany"; "septuagesima"; "lent"; + "passiontide"; "paschaltide"; "time-after-pentecost" ]; + List.iter + (fun r -> if L.rank t r = r then Alcotest.failf "no Latin rank name for %S" r) + [ "class-1"; "class-2"; "class-3"; "class-4" ]; + List.iter + (fun c -> if L.colour t c = c then Alcotest.failf "no Latin colour name for %S" c) + [ "white"; "red"; "green"; "violet"; "rose"; "black" ]; + for n = 0 to 6 do + if L.weekday t n = string_of_int n then Alcotest.failf "no Latin weekday for %d" n + done; + for n = 1 to 12 do + if L.month t n = string_of_int n then Alcotest.failf "no Latin month for %d" n + done + +let suite = + ( "Lang/coverage", + [ Alcotest.test_case "every temporal slug has a Latin name" `Slow + test_every_temporal_slug_has_a_latin_name; + Alcotest.test_case "vocabularies complete" `Quick test_vocabularies_are_complete ] ) -- cgit v1.3