diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/cli.t | 23 | ||||
| -rw-r--r-- | test/test_emit.ml | 6 | ||||
| -rw-r--r-- | test/test_view.ml | 92 |
3 files changed, 110 insertions, 11 deletions
@@ -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 ] ) |
