aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/cli.t36
-rw-r--r--test/test_lectionary_ef.ml40
-rw-r--r--test/test_lms_ordo.ml15
-rw-r--r--test/test_mass_formulary.ml16
-rw-r--r--test/test_validate.ml2
5 files changed, 82 insertions, 27 deletions
diff --git a/test/cli.t b/test/cli.t
index e2d2eb5..971e442 100644
--- a/test/cli.t
+++ b/test/cli.t
@@ -534,20 +534,32 @@ CSV run rather than one per year:
$ colitur emit --format csv --from 2027 --to 2028 | wc -l
732
-sexp and xml are also available. This line count moved 9010 -> 9011
-(whole-branch review fix round, RG 476(f)): [emit --format sexp] pretty-
-prints with [Sexplib.Sexp.to_string_hum], a column-width wrapping printer,
-not a fixed-shape one -- 2027's All Souls' Day (2 November) record grew a
-single wrapped line when its own [creed] field's value changed from
-[true] to [false] (RG 476(f), the Creed is never said at a Requiem Mass;
-see rubrics_ef.ml), because "false" is one character longer than "true"
-and pushed that one line's rendered width over to_string_hum's own wrap
-threshold. Purely cosmetic -- the record's DATA is unchanged in every
-other field, and this is not a claim that [emit]'s FORMAT changed, only
-that one record's pretty-printed SHAPE did:
+sexp and xml are also available. This line count moved twice in the same
+whole-branch review fix round, for two different reasons, both cosmetic:
+[emit --format sexp] pretty-prints with [Sexplib.Sexp.to_string_hum], a
+column-width wrapping printer, not a fixed-shape one, so any change to a
+value's own rendered WIDTH can shift where it wraps.
+
+9010 -> 9011 (RG 476(f)): 2027's All Souls' Day (2 November) record grew
+a single wrapped line when its own [creed] field's value changed from
+[true] to [false] (the Creed is never said at a Requiem Mass; see
+rubrics_ef.ml), because "false" is one character longer than "true" and
+pushed that one line's rendered width over the wrap threshold.
+
+9011 -> 9025 (Mass_formulary.t.said honesty, Fix 3): [said] gained an
+[option] (its own .mli has the full account) -- every day's formulary
+record now prints [(said (<slug>))] instead of [(said <slug>)], one
+character wider, and a [Votive] day (the RG 78 Saturday Mass of Our
+Lady) prints [(said ())] instead of naming a slug at all, since the
+data genuinely names none for the Mass actually said. Both changes ripple
+across many lines' own wrap points, not just the days whose DATA changed
+-- confirmed directly (diffed the full sexp output line by line): every
+difference is exactly this [said] shape change or a consequent wrap
+shift, nothing else. Not a claim that [emit]'s FORMAT changed, only that
+individual records' pretty-printed SHAPE did:
$ colitur emit --format sexp --from 2027 --to 2027 | wc -l
- 9011
+ 9025
$ colitur emit --format xml --from 2027 --to 2027 | head -2
<?xml version="1.0" encoding="UTF-8"?>
diff --git a/test/test_lectionary_ef.ml b/test/test_lectionary_ef.ml
index 04076c7..3e0880e 100644
--- a/test/test_lectionary_ef.ml
+++ b/test/test_lectionary_ef.ml
@@ -591,22 +591,22 @@ let test_commons_load_rejects_bad_data () =
let formulary_cases =
[ (* step 1: a saint with his own proper -- same date as
[test_step1_proper_beats_any_common_john_of_god]. *)
- (2038, 3, 8, "john-of-god", Colitur_kernel.Mass_formulary.Proper);
+ (2038, 3, 8, Some "john-of-god", Colitur_kernel.Mass_formulary.Proper);
(* step 2: the day's own temporal slug -- same date as
[test_step2_lenten_feria_has_its_own], Monday of Lent I. *)
- (2026, 2, 23, "ef-lent-1-monday", Colitur_kernel.Mass_formulary.Own_slug);
+ (2026, 2, 23, Some "ef-lent-1-monday", Colitur_kernel.Mass_formulary.Own_slug);
(* step 3: a feria resuming the preceding Sunday. The task brief's own
snippet pinned this date against week 9 ("ef-time-after-pentecost-
sunday-9"); running the real resolver against 2026 shows 3 August
2026 is Monday of week 10, resuming 2 August's "...sunday-10" --
corrected per the brief's own "find the dates by running the current
binary if they drift" instruction. *)
- (2026, 8, 3, "ef-time-after-pentecost-sunday-10",
+ (2026, 8, 3, Some "ef-time-after-pentecost-sunday-10",
Colitur_kernel.Mass_formulary.Preceding_sunday);
(* step 4: a saint sent to a Common -- same date as
[test_step4_commons_perpetua_and_felicity]; [said] is the Common's
OWN id (data/ef/commons.sexp), not the saint's slug. *)
- (2038, 3, 6, "common-of-non-virgins-1", Colitur_kernel.Mass_formulary.Common);
+ (2038, 3, 6, Some "common-of-non-virgins-1", Colitur_kernel.Mass_formulary.Common);
(* Fix round 1 (coordinator review): the RG 309(a)/RG 78 Saturday votive
Mass of Our Lady, structurally reached between steps 4 and 2 (see
[readings]' own implementation comment) but tagged [Votive], not
@@ -623,9 +623,16 @@ let formulary_cases =
2026 verified directly against the real resolver (`colitur day
2026`), not trusted from a supplied date, given this session's own
drifted-pin history: a IV-class Saturday, "Officium sanctae Mariae in
- sabbato", temporal slug [ef-time-after-pentecost-9-saturday]. [said]
- is unaffected by the retag and stays that same (reused ferial) slug. *)
- (2026, 8, 1, "ef-time-after-pentecost-9-saturday", Colitur_kernel.Mass_formulary.Votive) ]
+ sabbato", temporal slug [ef-time-after-pentecost-9-saturday].
+ (CORRECTED, whole-branch review fix round: [said] used to be
+ claimed "unaffected by the retag" and pinned to that same reused
+ ferial slug -- that was the defect this round fixed. [said] is
+ [None] here: the shipped data names no slug for the votive Mass
+ actually said, only for the office it replaces. The office slug
+ itself is checked separately, below, via [observed.slug], not
+ through [said] -- see {!Colitur_kernel.Mass_formulary.t}'s own
+ citation for why the two are no longer conflated.) *)
+ (2026, 8, 1, None, Colitur_kernel.Mass_formulary.Votive) ]
let test_formulary_reports_its_source () =
List.iter
@@ -634,10 +641,10 @@ let test_formulary_reports_its_source () =
match day.Colitur_kernel.Liturgical_day.formulary with
| None -> Alcotest.failf "%04d-%02d-%02d: no formulary" y m d
| Some f ->
- Alcotest.(check string)
+ Alcotest.(check (option string))
(Printf.sprintf "%04d-%02d-%02d slug" y m d)
expected_slug
- (Colitur_kernel.Slug.to_string f.Colitur_kernel.Mass_formulary.said);
+ (Option.map Colitur_kernel.Slug.to_string f.Colitur_kernel.Mass_formulary.said);
Alcotest.(check string)
(Printf.sprintf "%04d-%02d-%02d source" y m d)
(Colitur_kernel.Mass_formulary.source_to_string expected_via)
@@ -645,6 +652,17 @@ let test_formulary_reports_its_source () =
f.Colitur_kernel.Mass_formulary.via))
formulary_cases
+(* [said = None] on the Votive day above does not mean the office is lost --
+ {!Colitur_kernel.Mass_formulary.t}'s own citation says a caller reads it
+ off [observed.slug] instead, on the very same {!Colitur_kernel.
+ Liturgical_day.t}. Checked directly, not merely asserted: the same
+ 1 August 2026 date, same expected slug the old (pre-fix) [said] field
+ used to carry. *)
+let test_votive_office_slug_still_available_via_observed () =
+ let d = day 2026 8 1 in
+ Alcotest.(check string) "2026-08-01 observed slug" "ef-time-after-pentecost-9-saturday"
+ (Colitur_kernel.Slug.to_string d.Colitur_kernel.Liturgical_day.observed.Colitur_kernel.Celebration.slug)
+
let suite =
[ ("step 1: sanctoral proper", `Quick, test_step1_sanctoral_proper);
("step 2: own temporal proper", `Quick, test_step2_lenten_feria_has_its_own);
@@ -685,4 +703,6 @@ let suite =
("Commons.load rejects the four silent-degradation defects", `Quick,
test_commons_load_rejects_bad_data);
("the formulary reports its own source, one day per step", `Quick,
- test_formulary_reports_its_source) ]
+ test_formulary_reports_its_source);
+ ("the Votive office slug is still available via observed, not said", `Quick,
+ test_votive_office_slug_still_available_via_observed) ]
diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml
index cff4b3d..a728cbc 100644
--- a/test/test_lms_ordo.ml
+++ b/test/test_lms_ordo.ml
@@ -302,7 +302,9 @@ let describe_creed_mismatch (o : ordo_row) (c : colitur_row) =
Printf.sprintf "%s %S: colitur creed=%b, Ordo creed=%b (formulary=%s)" o.date o.title c.c_creed
(Option.get o.creed)
(match c.c_formulary with
- | Some f -> Colitur_kernel.Slug.to_string f.MF.said
+ | Some { MF.said = Some s; _ } -> Colitur_kernel.Slug.to_string s
+ | Some { MF.said = None; via = MF.Votive } -> "votive (said unnamed in the data)"
+ | Some { MF.said = None; _ } -> "NONE (said, unexpectedly outside Votive)"
| None -> "NONE")
(* The core assertion: every Creed divergence, over all 400 days (Good
@@ -587,7 +589,16 @@ let test_formulary_override_matches () =
:: !bad
| Some { MF.via = MF.Preceding_sunday; said } -> (
bump "preceding_sunday";
- let slug = Colitur_kernel.Slug.to_string said in
+ (* [said] is [Some] for every constructor except [Votive] (see
+ {!Colitur_kernel.Mass_formulary.t}'s own citation) -- a bare
+ [Option.get] here would raise an unhelpful exception if that
+ ever stopped being true; [Alcotest.failf] names the day
+ instead. *)
+ let slug =
+ match said with
+ | Some s -> Colitur_kernel.Slug.to_string s
+ | None -> Alcotest.failf "%s: Preceding_sunday day with said = None (should be impossible)" o.date
+ in
let ordo_says = Printf.sprintf "Mass of %s" in
(* Try the generic [ef-<season>-sunday-<n>] shape first; fall back
to the one NAMED Sunday that also reaches this population
diff --git a/test/test_mass_formulary.ml b/test/test_mass_formulary.ml
index 824e0c7..1316e47 100644
--- a/test/test_mass_formulary.ml
+++ b/test/test_mass_formulary.ml
@@ -4,9 +4,19 @@ module Slug = Colitur_kernel.Slug
let slug s = Slug.of_string_exn s
let test_round_trips_through_sexp () =
- let f = { MF.said = slug "ef-time-after-pentecost-sunday-9"; via = MF.Preceding_sunday } in
+ let f = { MF.said = Some (slug "ef-time-after-pentecost-sunday-9"); via = MF.Preceding_sunday } in
let f' = MF.t_of_sexp (MF.sexp_of_t f) in
- Alcotest.(check string) "slug survives" (Slug.to_string f.MF.said) (Slug.to_string f'.MF.said);
+ Alcotest.(check (option string)) "slug survives"
+ (Option.map Slug.to_string f.MF.said) (Option.map Slug.to_string f'.MF.said);
+ Alcotest.(check bool) "source survives" true (f.MF.via = f'.MF.via)
+
+(* [said] is [None] exactly for {!MF.Votive} -- see the .mli's own citation.
+ Round-tripped separately so the [None] case has its own witness, not only
+ inferred from the [Some] case above. *)
+let test_none_said_round_trips_through_sexp () =
+ let f = { MF.said = None; via = MF.Votive } in
+ let f' = MF.t_of_sexp (MF.sexp_of_t f) in
+ Alcotest.(check bool) "said stays None" true (f'.MF.said = None);
Alcotest.(check bool) "source survives" true (f.MF.via = f'.MF.via)
(* [to_string] is what an ordo line shows. It names the SOURCE, not the slug,
@@ -25,5 +35,7 @@ let test_to_string_names_the_source () =
let suite =
( "Mass_formulary",
[ Alcotest.test_case "sexp round-trips" `Quick test_round_trips_through_sexp;
+ Alcotest.test_case "sexp round-trips, said = None (Votive)" `Quick
+ test_none_said_round_trips_through_sexp;
Alcotest.test_case "source_to_string names each source" `Quick
test_to_string_names_the_source ] )
diff --git a/test/test_validate.ml b/test/test_validate.ml
index ea8fc0f..1ceaca2 100644
--- a/test/test_validate.ml
+++ b/test/test_validate.ml
@@ -321,7 +321,7 @@ module Synthetic = struct
(* The formulary equivalent of [well_formed_citations] above -- shape only,
never rubrically meaningful content. *)
let well_formed_formulary =
- { Colitur_kernel.Mass_formulary.said = Slug.of_string_exn "syn-formulary";
+ { Colitur_kernel.Mass_formulary.said = Some (Slug.of_string_exn "syn-formulary");
via = Colitur_kernel.Mass_formulary.Own_slug }
(* No fixture here exercises the Creed rubric -- a rite that has not