aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/cli.t23
-rw-r--r--test/test_emit.ml6
-rw-r--r--test/test_view.ml92
3 files changed, 110 insertions, 11 deletions
diff --git a/test/cli.t b/test/cli.t
index 80c8078..dfe5caa 100644
--- a/test/cli.t
+++ b/test/cli.t
@@ -419,8 +419,8 @@ displaced silently.
CSV emits a header and one row per day:
$ colitur emit --format csv --from 2027 --to 2027 | head -2
- date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms
- 2027-01-01,ef,christmastide,,ef-circumcision,class-1,white,temporal,,,Titus 2:11-15,Luke 2:21,
+ date,rite,season,season_name,week,slug,name,weekday,rank,rank_name,colour,colour_name,subject,first,gospel,comms
+ 2027-01-01,ef,christmastide,Tempus Nativitatis,,ef-circumcision,In Octava Nativitatis Domini,Feria VI,class-1,I classis,white,albus,temporal,Titus 2:11-15,Luke 2:21,
$ colitur emit --format csv --from 2027 --to 2027 | wc -l
366
@@ -522,12 +522,21 @@ render is the same operation under the name the design used:
2027-01-01 ef-circumcision
2027-01-02 ef-christmas-1-saturday
-Flavour is inferred from the extension and escapes data -- Sts. Peter &
-Paul (29 June) and its vigil are the only two 2035 entries whose English
-name needs LaTeX escaping:
+Flavour is inferred from the extension. `name` is the RESOLVED display
+string now (view.ml), not the old lang-keyed object -- there is no more
+`.en`/`.la` to reach, so a plain `{{name}}` is the only correct form; the
+old `{{name.en}}` dotted lookup on today's plain string simply finds
+nothing, on purpose (this is the change that also removes the shadowing
+hazard: a miss on a plain string has no dotted path left to fall back
+through). Names are Latin here (no --lang until the CLI wiring task), and
+the Missal's own Latin spells Peter and Paul's feast with "et", never an
+ampersand, so this no longer doubles as an escaping demonstration --
+that property is proved live on 2035 data in test_emit.ml instead
+(test_xml_escapes_live_data), where the English table both name sources
+still share does carry one:
- $ printf '{{#days}}{{name.en}}\n{{/days}}' > /tmp/t.tex
- $ colitur table --year 2035 --template /tmp/t.tex | grep -c 'Peter \\& Paul'
+ $ printf '{{#days}}{{name}}\n{{/days}}' > /tmp/t.tex
+ $ colitur table --year 2035 --template /tmp/t.tex | grep -c 'Ss\. Petri et Pauli'
2
An unknown extension with no --flavour is an error, not a silent fallback:
diff --git a/test/test_emit.ml b/test/test_emit.ml
index a22eaaf..0a40054 100644
--- a/test/test_emit.ml
+++ b/test/test_emit.ml
@@ -61,7 +61,7 @@ let test_csv_header_and_rows () =
let lines = String.split_on_char '\n' out |> List.filter (fun l -> l <> "") in
Alcotest.(check int) "366 lines: header + 365 days" 366 (List.length lines);
Alcotest.(check string) "header"
- "date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms"
+ "date,rite,season,season_name,week,slug,name,weekday,rank,rank_name,colour,colour_name,subject,first,gospel,comms"
(List.hd lines);
Alcotest.(check bool) "first row is 1 January" true
(String.length (List.nth lines 1) > 10 && String.sub (List.nth lines 1) 0 10 = "2027-01-01")
@@ -86,8 +86,8 @@ let test_csv_quotes_commas () =
that escapes its quoting produces 14 fields, not 13. Also assert the
quoted substring appears literally, byte for byte -- belt and braces,
and closer to what a human reviewing the CSV would actually look for. *)
- Alcotest.(check int) "the row has exactly 13 fields, same as the header"
- 13 (List.length (parse_csv_row joseph));
+ Alcotest.(check int) "the row has exactly 16 fields, same as the header"
+ 16 (List.length (parse_csv_row joseph));
Alcotest.(check bool) "Joseph's comma-bearing name is quoted whole, not split" true
(contains ~needle:"\"St. Joseph, Spouse of the Bl. Virgin Mary\"" joseph)
diff --git a/test/test_view.ml b/test/test_view.ml
index e595357..b49b090 100644
--- a/test/test_view.ml
+++ b/test/test_view.ml
@@ -24,8 +24,29 @@ let days_of_year y =
done;
List.rev !out
+(* Shared across this file and test_emit.ml: the ENGLISH table, chained to
+ Latin (en.ini's own [meta] fallback = la), so a slug en.ini does not name
+ directly still resolves through the chain rather than degrading to its
+ slug. English (not Latin, and not Lang.raw) is deliberate: it keeps the
+ emitter tests' own literal expectations -- "St. Joseph, Spouse of the Bl.
+ Virgin Mary" (a comma, for CSV quoting), "Sts. Fabian & Sebastian" (an
+ ampersand, for XML escaping) -- byte-identical to lang/en.ini's own
+ [celebration] entries, verified by grep against the shipped file rather
+ than assumed. *)
+let read_lang path =
+ let ic = open_in_bin path in
+ let s = really_input_string ic (in_channel_length ic) in
+ close_in ic;
+ match Colitur_naming.Lang.of_string s with
+ | Ok t -> t
+ | Error e -> Alcotest.failf "%s: %s" path e
+
+let default_lang =
+ lazy (Colitur_naming.Lang.with_fallback (read_lang "../lang/en.ini") (read_lang "../lang/la.ini"))
+
let view_of y =
- V.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y (days_of_year y)
+ V.of_days ~lang:(Lazy.force default_lang) ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y
+ (days_of_year y)
let get path v =
let rec go v = function
@@ -110,10 +131,79 @@ let test_exactly_one_colour_flag () =
if n <> 1 then Alcotest.failf "%s has %d colour flags set" (as_str (get [ "iso" ] d)) n)
(as_list (get [ "days" ] v))
+(* Padding cells and real days must carry the SAME key set: a template that
+ walks a grid row must never hit a missing key on a padding cell. Compares
+ the sorted key lists of a real day and a padding cell (the first cell of
+ January 2027's first week -- 1 Jan 2027 is a Friday, so that cell IS a
+ padding cell, see test_padding_cells_are_flagged above). *)
+let keys_of = function
+ | T.Obj kvs -> List.sort compare (List.map fst kvs)
+ | _ -> Alcotest.fail "expected an object"
+
+let test_padding_and_real_share_key_set () =
+ let v = view_of 2027 in
+ let jan = List.hd (as_list (get [ "months" ] v)) in
+ let first_week = List.hd (as_list (get [ "weeks" ] jan)) in
+ let cells = as_list (get [ "days" ] first_week) in
+ let padding = List.find (fun c -> not (as_bool (get [ "in_month" ] c))) cells in
+ let real = List.find (fun c -> as_bool (get [ "in_month" ] c)) cells in
+ Alcotest.(check (list string)) "padding and real days have the same key set" (keys_of real)
+ (keys_of padding)
+
+let latin () =
+ let ic = open_in_bin "../lang/la.ini" in
+ let s = really_input_string ic (in_channel_length ic) in
+ close_in ic;
+ match Colitur_naming.Lang.of_string s with
+ | Ok t -> t | Error e -> Alcotest.failf "la.ini: %s" e
+
+let view_named y = V.of_days ~lang:(latin ()) ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y (days_of_year y)
+
+(* The defect this whole branch exists to fix: no rendered day may show a slug
+ where a name exists. Asserted over a whole year, not a sample. *)
+let test_no_day_shows_a_slug () =
+ let v = view_named 2027 in
+ List.iter
+ (fun d ->
+ let name = as_str (get [ "name" ] d) and slug = as_str (get [ "slug" ] d) in
+ if name = slug then Alcotest.failf "%s renders its slug as its name" (as_str (get [ "iso" ] d));
+ if name = "" then Alcotest.failf "%s has an empty name" (as_str (get [ "iso" ] d)))
+ (as_list (get [ "days" ] v))
+
+let test_slug_is_unchanged_by_naming () =
+ let raw = V.of_days ~lang:Colitur_naming.Lang.raw ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:2027 (days_of_year 2027) in
+ let named = view_named 2027 in
+ List.iter2
+ (fun a b -> Alcotest.(check string) "slug identical" (as_str (get [ "slug" ] a)) (as_str (get [ "slug" ] b)))
+ (as_list (get [ "days" ] raw)) (as_list (get [ "days" ] named))
+
+(* Under --raw the name IS the slug: that is what makes raw output byte-stable. *)
+let test_raw_name_equals_slug () =
+ let raw = V.of_days ~lang:Colitur_naming.Lang.raw ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:2027 (days_of_year 2027) in
+ List.iter
+ (fun d -> Alcotest.(check string) "raw" (as_str (get [ "slug" ] d)) (as_str (get [ "name" ] d)))
+ (as_list (get [ "days" ] raw))
+
+(* Weekday, month, season, rank and colour must localise too -- a calendar in a
+ language needs more than feast names. *)
+let test_vocabularies_localise () =
+ let v = view_named 2027 in
+ let jan = List.hd (as_list (get [ "months" ] v)) in
+ Alcotest.(check string) "month name" "Ianuarius" (as_str (get [ "name" ] jan));
+ let d1 = List.hd (as_list (get [ "days" ] v)) in
+ Alcotest.(check string) "weekday" "Feria VI" (as_str (get [ "weekday" ] d1));
+ Alcotest.(check string) "rank" "I classis" (as_str (get [ "rank_name" ] d1));
+ Alcotest.(check string) "colour" "albus" (as_str (get [ "colour_name" ] d1))
+
let suite =
( "View",
[ Alcotest.test_case "year shape" `Quick test_year_shape;
Alcotest.test_case "weeks flatten to days" `Quick test_weeks_flatten_to_days;
Alcotest.test_case "padding cells flagged" `Quick test_padding_cells_are_flagged;
+ Alcotest.test_case "padding and real days share key set" `Quick test_padding_and_real_share_key_set;
+ Alcotest.test_case "no day shows a slug" `Quick test_no_day_shows_a_slug;
+ Alcotest.test_case "slug unchanged by naming" `Quick test_slug_is_unchanged_by_naming;
+ Alcotest.test_case "raw name equals slug" `Quick test_raw_name_equals_slug;
+ Alcotest.test_case "vocabularies localise" `Quick test_vocabularies_localise;
Alcotest.test_case "day fields" `Quick test_day_fields;
Alcotest.test_case "exactly one colour flag" `Quick test_exactly_one_colour_flag ] )