aboutsummaryrefslogtreecommitdiff
path: root/test/test_precedence.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-24 16:29:23 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-24 16:29:23 +0200
commit8a5da8756cf6b57aa36c01b71ce893f7967d3a29 (patch)
tree10873a692400fa25ce54c67ac9fc34d46af86272 /test/test_precedence.ml
parent4f87cbde4ee79ac96aa7ebfed105b3a5ec02be43 (diff)
parent73b15551804bb63ee0081005e2869d36afb54be2 (diff)
downloadcolitur-8a5da8756cf6b57aa36c01b71ce893f7967d3a29.tar.gz
colitur-8a5da8756cf6b57aa36c01b71ce893f7967d3a29.zip
merge: celebrant Mass rubrics, and four rubrical corrections
colitur now prints what a real ordo prints for the Mass: which formulary is said and how it was reached, the Gloria, the Creed, the preface, and the commemorations with their Low-Mass/sung distinction. colitur rubrics joins day and readings. Four defects were found and fixed on the way, each by an external witness rather than by inspection: the Creed said at Requiem Masses (RG 476(f)), the missing bissextile shift of St Matthias and St Gabriel (2 041 leap years), Rogation Monday and Tuesday coloured violet in Paschaltide (RG 119(b)), and the ferias after the Ascension resuming the wrong Sunday's Mass rather than the Ascension's. Validation gained a sixth layer and then some: the preface is checked against three independent publishers over seven witness-years (FIUV, three LMS editions, three extraordinaryform.org editions), none of which shares the Divinum Officium -> missalemeum -> lectio lineage the older layers all descend from.
Diffstat (limited to 'test/test_precedence.ml')
-rw-r--r--test/test_precedence.ml55
1 files changed, 54 insertions, 1 deletions
diff --git a/test/test_precedence.ml b/test/test_precedence.ml
index acc89fc..54ab3f9 100644
--- a/test/test_precedence.ml
+++ b/test/test_precedence.ml
@@ -98,6 +98,49 @@ let test_temporal_only_day () =
Alcotest.(check int) "nothing deferred" 0 (List.length r.P.deferred);
Alcotest.(check int) "nothing omitted" 0 (List.length r.P.omitted)
+(* RG 111(a): sung_mass_commemorations -- see precedence.mli's own citation.
+ Pure function, no {!resolve} needed: exercised directly against
+ hand-built Low-Mass admitted lists, the same shape {!P.resolve} would
+ produce, rather than through a full resolution. *)
+let sung_test_cand rank slug = cand ~rank slug
+
+let test_sung_mass_no_privileged () =
+ let low_mass = [ (sung_test_cand Lo "a", P.Ordinary); (sung_test_cand Lo "b", P.Ordinary) ] in
+ Alcotest.(check (list string)) "no privileged commemoration -> sung Mass keeps none" []
+ (List.map (fun (c, _) -> slug_of c) (P.sung_mass_commemorations low_mass))
+
+let test_sung_mass_one_privileged () =
+ let low_mass =
+ [ (sung_test_cand Lo "ordinary-one", P.Ordinary); (sung_test_cand Hi "privileged-one", P.Privileged) ]
+ in
+ Alcotest.(check (list string)) "the ordinary commemoration is dropped, the privileged one kept"
+ [ "privileged-one" ]
+ (List.map (fun (c, _) -> slug_of c) (P.sung_mass_commemorations low_mass))
+
+let test_sung_mass_privileged_first_already () =
+ let low_mass =
+ [ (sung_test_cand Hi "privileged-one", P.Privileged); (sung_test_cand Lo "ordinary-one", P.Ordinary) ]
+ in
+ Alcotest.(check (list string)) "a privileged commemoration already first is kept alone" [ "privileged-one" ]
+ (List.map (fun (c, _) -> slug_of c) (P.sung_mass_commemorations low_mass))
+
+let test_sung_mass_empty_low_mass_set () =
+ Alcotest.(check (list string)) "an empty Low-Mass set stays empty at Sung Mass" []
+ (List.map (fun (c, _) -> slug_of c) (P.sung_mass_commemorations []))
+
+(* If two privileged commemorations were ever admitted together (not known
+ to occur on any shipped rite's data -- precedence.mli's own citation),
+ [sung_mass_commemorations] keeps only the FIRST -- input order is
+ already RG 113 precedence order, so this is "the highest-precedence
+ privileged entry survives", not an arbitrary truncation. *)
+let test_sung_mass_two_privileged_keeps_first () =
+ let low_mass =
+ [ (sung_test_cand Hi "first-privileged", P.Privileged); (sung_test_cand Hi "second-privileged", P.Privileged) ]
+ in
+ Alcotest.(check (list string)) "only the first (higher-precedence) privileged commemoration survives"
+ [ "first-privileged" ]
+ (List.map (fun (c, _) -> slug_of c) (P.sung_mass_commemorations low_mass))
+
let suite =
( "Precedence",
[ Alcotest.test_case "highest band wins" `Quick test_highest_band_wins;
@@ -107,4 +150,14 @@ let suite =
test_commemoration_only_never_observed;
Alcotest.test_case "nothing silently lost" `Quick test_nothing_silently_lost;
Alcotest.test_case "order independent" `Quick test_order_independent;
- Alcotest.test_case "temporal-only day" `Quick test_temporal_only_day ] )
+ Alcotest.test_case "temporal-only day" `Quick test_temporal_only_day;
+ Alcotest.test_case "RG 111(a): sung Mass, no privileged commemoration" `Quick
+ test_sung_mass_no_privileged;
+ Alcotest.test_case "RG 111(a): sung Mass keeps the one privileged commemoration" `Quick
+ test_sung_mass_one_privileged;
+ Alcotest.test_case "RG 111(a): sung Mass, privileged already first" `Quick
+ test_sung_mass_privileged_first_already;
+ Alcotest.test_case "RG 111(a): sung Mass, empty Low-Mass set" `Quick
+ test_sung_mass_empty_low_mass_set;
+ Alcotest.test_case "RG 111(a): sung Mass keeps only the first of two privileged" `Quick
+ test_sung_mass_two_privileged_keeps_first ] )