aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/kernel/record.ml21
-rw-r--r--test/test_names.ml8
2 files changed, 24 insertions, 5 deletions
diff --git a/lib/kernel/record.ml b/lib/kernel/record.ml
index af55f07..425aad5 100644
--- a/lib/kernel/record.ml
+++ b/lib/kernel/record.ml
@@ -33,8 +33,21 @@ let of_temporal ~rite vocab date (t : ('s, 'r) Temporal.t) =
cel.Celebration.citations;
}
-let headers =
- [ "date"; "rite"; "season"; "week"; "weekday"; "slug"; "rank"; "colour"; "subject" ]
+(* Scalar columns, each with a (name, extractor) pair. Derived from this single
+ source ensures headers and to_row cannot drift apart. Names and citations are
+ excluded: they are variable-arity and belong to richer encoders in Plan 5. *)
+let columns =
+ [ ("date", fun r -> r.date);
+ ("rite", fun r -> r.rite);
+ ("season", fun r -> r.season);
+ ("week", fun r -> r.week);
+ ("weekday", fun r -> r.weekday);
+ ("slug", fun r -> r.slug);
+ ("rank", fun r -> r.rank);
+ ("colour", fun r -> r.colour);
+ ("subject", fun r -> r.subject);
+ ]
-let to_row r =
- [ r.date; r.rite; r.season; r.week; r.weekday; r.slug; r.rank; r.colour; r.subject ]
+let headers = List.map fst columns
+
+let to_row r = List.map (fun (_, get) -> get r) columns
diff --git a/test/test_names.ml b/test/test_names.ml
index 3ddf79c..1649f9e 100644
--- a/test/test_names.ml
+++ b/test/test_names.ml
@@ -130,7 +130,13 @@ let test_record () =
(* 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)
+ (* Schema is pinned: headers and to_row derive from a single columns list,
+ so alignment cannot drift. Assert the column names in order. *)
+ Alcotest.(check (list string)) "headers schema"
+ [ "date"; "rite"; "season"; "week"; "weekday"; "slug"; "rank"; "colour"; "subject" ]
+ Rec.headers;
+ (* Row must be the same length and order as headers. *)
+ Alcotest.(check int) "row matches headers length" (List.length Rec.headers)
(List.length (Rec.to_row r))
let suite =