From 5046defebb8e04d00489a6be070b1b7e7a49ce84 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 11 Aug 2026 13:00:51 +0200 Subject: kernel(record): flat all-string canonical output view The boundary where rite-parametric types stop. CSV, JSON and the template engine all render from this one schema, so they never see a type variable. headers/to_row cover the scalar columns; names and citations are variable-arity and wait for the richer encoders in Plan 5. --- test/test_names.ml | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_names.ml b/test/test_names.ml index f340c62..3ddf79c 100644 --- a/test/test_names.ml +++ b/test/test_names.ml @@ -93,6 +93,46 @@ let test_celebration () = let sexp = Cel.sexp_of_t sexp_of_demo_rank c in Alcotest.(check bool) "sexp roundtrip" true (Cel.t_of_sexp demo_rank_of_sexp sexp = c) +module Rec = Colitur_kernel.Record +module Voc = Colitur_kernel.Vocab +module Tmp = Colitur_kernel.Temporal + +type demo_season = Ordinary [@@deriving sexp] + +let demo_vocab : (demo_season, demo_rank) Voc.t = + { seasons = [ Ordinary ]; + season_to_string = (fun Ordinary -> "ordinary"); + season_of_string = (function "ordinary" -> Some Ordinary | _ -> None); + ranks = [ High; Low ]; + rank_to_string = (function High -> "high" | Low -> "low"); + rank_of_string = (function "high" -> Some High | "low" -> Some Low | _ -> None) } + +let test_record () = + let date = match D.make ~year:2026 ~month:4 ~day:5 with + | Ok d -> d | Error e -> Alcotest.failf "%s" e + in + let office = + Cel.make ~slug:(S.of_string_exn "ef-easter-sunday") + ~names:(N.of_list [ (lang "la", "Dominica Resurrectionis") ]) + ~rank:High ~colour:Col.White ~subject:Sub.Lord ~layer:"temporal" () + in + let t = { Tmp.season = Ordinary; week = Some 1; weekday = D.Sun; office } in + let r = Rec.of_temporal ~rite:"ef" demo_vocab date t in + Alcotest.(check string) "date" "2026-04-05" r.Rec.date; + Alcotest.(check string) "season" "ordinary" r.Rec.season; + Alcotest.(check string) "week" "1" r.Rec.week; + Alcotest.(check string) "weekday" "sunday" r.Rec.weekday; + Alcotest.(check string) "rank" "high" r.Rec.rank; + Alcotest.(check string) "colour" "white" r.Rec.colour; + Alcotest.(check string) "subject" "lord" r.Rec.subject; + Alcotest.(check (list string)) "names flattened" [ "la" ] + (List.map fst r.Rec.names); + (* A day outside a numbered week renders week as the empty string, not "0". *) + let r' = Rec.of_temporal ~rite:"ef" demo_vocab date { t with Tmp.week = None } in + Alcotest.(check string) "no week" "" r'.Rec.week; + Alcotest.(check int) "row matches headers" (List.length Rec.headers) + (List.length (Rec.to_row r)) + let suite = ( "Names/Citation/DateSpec", [ Alcotest.test_case "names basics" `Quick test_names_basics; @@ -103,4 +143,5 @@ let suite = Alcotest.test_case "citation" `Quick test_citation; Alcotest.test_case "date_spec" `Quick test_date_spec; Alcotest.test_case "date_spec sexp roundtrip" `Quick test_date_spec_sexp_roundtrip; - Alcotest.test_case "celebration" `Quick test_celebration ] ) + Alcotest.test_case "celebration" `Quick test_celebration; + Alcotest.test_case "record" `Quick test_record ] ) -- cgit v1.3