diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-03 21:13:38 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-03 21:13:38 +0200 |
| commit | 81a9df4bab615abdd8ef0e2fe7322219ce00ee6d (patch) | |
| tree | 82e358bc2e7f95c7133481e6a5f6a347dbc605c5 /test/test_lectionary_of.ml | |
| parent | d0807440309e2357d51cd56c72a443072b0ba57f (diff) | |
| parent | fe136f0952284b9a339252926dfd4675c4a7c3c6 (diff) | |
| download | colitur-81a9df4bab615abdd8ef0e2fe7322219ce00ee6d.tar.gz colitur-81a9df4bab615abdd8ef0e2fe7322219ce00ee6d.zip | |
The OF's readings had never been validated against anything but the lineage
they arrived on. Pointing a second lineage at them found ten corrupt
references on the first run.
Diffstat (limited to 'test/test_lectionary_of.ml')
| -rw-r--r-- | test/test_lectionary_of.ml | 80 |
1 files changed, 77 insertions, 3 deletions
diff --git a/test/test_lectionary_of.ml b/test/test_lectionary_of.ml index dc02176..cbffdd2 100644 --- a/test/test_lectionary_of.ml +++ b/test/test_lectionary_of.ml @@ -201,7 +201,7 @@ let test_sha256_pinned () = and test_citation_coverage_of.ml), and the header's "Epistle" wording is fixed to "First". Re-derived the same way, same discipline. *) Alcotest.(check string) "data/of/lectionary.sexp SHA-256" - "788ddc6d2d783286b6e64882a5372ae213cd5462c887e68aa2bea22388cdb4f7" (sha256_of_file lectionary_path) + "aaa57bd7229bbd1fb3372fb9467251419885af6f02dbd19d328a6c410030868d" (sha256_of_file lectionary_path) (* lectio's OWN of-lectionary.ini SHA-256, pinned inside data/of/ lectionary.sexp's own provenance header (tools/bootstrap_lectionary_of @@ -216,7 +216,7 @@ let test_source_sha256_pinned_in_header () = let n = in_channel_length ic in let content = really_input_string ic n in close_in ic; - let needle = "SHA-256: f0b527aef58b93e6ccdfbeafe52b340ed2a9d7d72805bf5083e3da04b080123c" in + let needle = "SHA-256: 7b6c6a26abf222312c3000aeaae131887bbb1e2af3863c68a3e5ad005cd07ba9" in let contains haystack needle = let hl = String.length haystack and nl = String.length needle in let rec go i = i + nl <= hl && (String.sub haystack i nl = needle || go (i + 1)) in @@ -488,6 +488,77 @@ let test_christmas_date_keyed_no_drift () = check_year 2024; check_year 2025 +(* ------------------------------------------------------------------ *) +(* In ORDINARY TIME the OF weekday Gospel does not depend on which year of + the two-year cycle is running: OLM n. 69 point 4 alternates the FIRST + reading between Year I and Year II and leaves the Gospel a single + one-year series. So for every [of-ordinary-time-<n>-<day>-i] there is an + [...-ii] whose Gospel reference is the SAME STRING, and a pair that + disagrees is a data defect rather than a liturgical fact. + + This is deliberately scoped to Ordinary Time. The same sweep over the + whole file reports 17 further disagreeing pairs in [of-advent-3/4-*] and + [of-christmas-*] -- all of them CORRECT: those weekdays are keyed to the + calendar DATE (17-24 December, and the Christmas octave, OLM n. 69 + point 3, the rule [date_keyed_slug] above implements), so their -i/-ii + entries describe two different dates rather than two years of one cycle. + An unscoped version of this test would report seventeen false positives + and would, correctly, be switched off by whoever next read it. + + CLOSED (2026-08-28, same day it was opened). Six pairs violated this when + the test was written, every one the same transcription fault: a Year II + Gospel ending at verse 22 where the OLM ends it at 20. All six are now + corrected upstream in lectio's own internal/caldata/of-lectionary.ini and + this file regenerated from it, so the expected violation set is EMPTY and + the test asserts the invariant outright rather than pinning exceptions to + it. Four further corruptions the same exercise found -- three First + readings and of-advent-2-saturday's "Matthew 17:9a,10-135", a verse + Matthew 17 does not have -- are fixed in the same upstream commit but are + invisible to THIS check by construction: no I/II symmetry constrains a + First reading, and Advent has no year cycle. They were caught by comparing + against litcal instead, and the two SHA-256 pins above are what stop the + data regressing underneath either. + + Corrections confirmed verbatim in the Latin OLM 1981: "Mc 1, 14-20", + "Mc 4, 1-20", "Mc 5, 1-20", "Mt 7, 15-20", "Mt 17, 14-20", + "Mt 18, 15-20". *) +let known_year_ii_gospel_defects = [] + +let test_ordinary_time_gospel_is_year_independent () = + let entries = Lectionary.entries (real_lectionary ()) in + let gospel_of cits = + match List.find_opt (fun c -> c.Colitur_kernel.Citation.part = Colitur_kernel.Citation.Gospel) cits with + | Some c -> Some c.Colitur_kernel.Citation.reference + | None -> None + in + let by_slug = List.map (fun (s, c) -> (Slug.to_string s, gospel_of c)) entries in + let find s = match List.assoc_opt s by_slug with Some g -> g | None -> None in + let has_prefix p s = String.length s >= String.length p && String.sub s 0 (String.length p) = p in + let has_suffix suf s = + String.length s >= String.length suf && String.sub s (String.length s - String.length suf) (String.length suf) = suf + in + let ordinary_time_stems = + List.filter_map + (fun (s, _) -> + if has_prefix "of-ordinary-time-" s && has_suffix "-i" s && not (has_suffix "-ii" s) then + Some (String.sub s 0 (String.length s - 2)) + else None) + by_slug + in + let stems = List.sort_uniq compare ordinary_time_stems in + let violations = + List.filter + (fun stem -> + match (find (stem ^ "-i"), find (stem ^ "-ii")) with + | Some a, Some b -> a <> b + | _ -> false) + stems + in + Alcotest.(check bool) "the sweep actually found Ordinary Time pairs to check" true (List.length stems > 100); + Alcotest.(check (list string)) + "Ordinary Time: Year I and Year II share one Gospel, with no exceptions" + known_year_ii_gospel_defects (List.sort compare violations) + let suite = [ Alcotest.test_case "Sunday cycle table (OLM n.66, straddles Advent I)" `Quick test_sunday_cycle_table; Alcotest.test_case "weekday cycle table (OLM n.69.4, straddles Advent I)" `Quick test_weekday_cycle_table; @@ -504,5 +575,8 @@ let suite = Alcotest.test_case "O-Antiphon date-keyed reading does not drift (17 December)" `Quick test_o_antiphon_no_drift; Alcotest.test_case "Christmas-season date-keyed reading does not drift (2 January)" `Quick - test_christmas_date_keyed_no_drift + test_christmas_date_keyed_no_drift; + Alcotest.test_case + "Ordinary Time Gospel is year-independent (OLM n. 69.4)" `Quick + test_ordinary_time_gospel_is_year_independent ] |
