aboutsummaryrefslogtreecommitdiff
path: root/test/test_lang_coverage.ml
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_lang_coverage.ml')
-rw-r--r--test/test_lang_coverage.ml53
1 files changed, 53 insertions, 0 deletions
diff --git a/test/test_lang_coverage.ml b/test/test_lang_coverage.ml
index b4de5be..0271a59 100644
--- a/test/test_lang_coverage.ml
+++ b/test/test_lang_coverage.ml
@@ -95,6 +95,56 @@ let test_every_rite_has_a_latin_name () =
(fun id -> if L.rite t id = id then Alcotest.failf "no Latin display name for rite %S" id)
[ Rite_ef.Temporal_ef.id ]
+(* Task 10: every id Colitur_citation.Book.all knows must have BOTH a
+ `.full` and an `.abbr` row in lang/la.ini's own [bible] section -- this is
+ the check that would have caught a forgotten tradition target (the seven
+ ids in book.ml's own `tradition_targets`, never cited by the data itself,
+ so nothing else here would ever notice one missing -- see book.mli's own
+ note on why `default_spelling` falls back to the bare id for exactly
+ this case). The total-lookup contract makes this a one-line miss test:
+ `Lang.bible la key = key` IS "no entry", the same pattern
+ `test_every_slug_has_a_latin_name` above already uses for [celebration]. *)
+let test_every_book_named () =
+ let la = la () in
+ let missing =
+ List.concat_map
+ (fun id ->
+ let n = Colitur_citation.Book.to_string id in
+ List.filter_map
+ (fun form ->
+ let key = n ^ "." ^ form in
+ if L.bible la key = key then Some key else None)
+ [ "full"; "abbr" ])
+ Colitur_citation.Book.all
+ in
+ Alcotest.(check (list string)) "every book named, both forms" [] missing
+
+(* A name must not BE the internal id. The check above compares the value
+ against the KEY ("kings_1.full"), so a row reading `kings_1.full = kings_1`
+ passes it -- the two strings differ. That is exactly what shipped: all seven
+ tradition targets carried their own id as their name, and
+ `--sigla-tradition modern` printed "kings_1 19:3-8", leaking a key that
+ book.mli states is never shown to a reader.
+
+ The two checks are complementary and neither subsumes the other: that one
+ catches a MISSING row, this one catches a row present but filled with the
+ wrong thing. *)
+let test_no_book_name_is_an_internal_id () =
+ let la = la () in
+ let leaked =
+ List.concat_map
+ (fun id ->
+ let n = Colitur_citation.Book.to_string id in
+ List.filter_map
+ (fun form ->
+ let v = L.bible la (n ^ "." ^ form) in
+ if v = n then Some (n ^ "." ^ form) else None)
+ [ "full"; "abbr" ])
+ Colitur_citation.Book.all
+ in
+ Alcotest.(check (list string)) "no book name is its own internal id" []
+ leaked
+
(* lang/en.ini is DELIBERATELY partial (see its own header note): it declares
[meta] fallback = la, so a slug it does not carry itself should still
resolve through the chain to la.ini's name rather than degrade to the bare
@@ -136,4 +186,7 @@ let suite =
[ Alcotest.test_case "every slug has a Latin name" `Slow test_every_slug_has_a_latin_name;
Alcotest.test_case "vocabularies complete" `Quick test_vocabularies_are_complete;
Alcotest.test_case "every rite has a Latin name" `Quick test_every_rite_has_a_latin_name;
+ Alcotest.test_case "every book named, both forms" `Quick test_every_book_named;
+ Alcotest.test_case "no book name is an internal id" `Quick
+ test_no_book_name_is_an_internal_id;
Alcotest.test_case "en.ini falls back to Latin" `Quick test_en_falls_back_to_latin ] )