aboutsummaryrefslogtreecommitdiff
path: root/test/test_emit.ml
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_emit.ml')
-rw-r--r--test/test_emit.ml46
1 files changed, 45 insertions, 1 deletions
diff --git a/test/test_emit.ml b/test/test_emit.ml
index 0a40054..bd9cadc 100644
--- a/test/test_emit.ml
+++ b/test/test_emit.ml
@@ -91,6 +91,20 @@ let test_csv_quotes_commas () =
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)
+(* W5: a day with [[First; Second; Gospel]] MUST NOT widen the CSV's own
+ fixed 16-column header -- see [Emit_csv]'s own comment for why a variable
+ column count is not RFC 4180-legal. Guards the deliberate-drop claim made
+ there with an actual assertion, not only a comment: still exactly 16
+ fields (the [Second] reading genuinely absent from the row, not merely
+ untested), and the header is unchanged. *)
+let test_csv_does_not_widen_for_a_third_citation () =
+ let out = Csv.year (Test_view.three_citation_view ()) in
+ let lines = String.split_on_char '\n' out |> List.filter (fun l -> l <> "") in
+ Alcotest.(check string) "header unchanged"
+ "date,rite,season,season_name,week,slug,name,weekday,rank,rank_name,colour,colour_name,subject,first,gospel,comms"
+ (List.hd lines);
+ Alcotest.(check int) "row still 16 fields" 16 (List.length (parse_csv_row (List.nth lines 1)))
+
let test_json_parses_back () =
let out = Json.year (view_2027 ()) in
Alcotest.(check bool) "starts as an object" true (out.[0] = '{');
@@ -133,6 +147,8 @@ let suite =
( "Emit/csv+json",
[ Alcotest.test_case "csv header and rows" `Quick test_csv_header_and_rows;
Alcotest.test_case "csv quotes commas" `Quick test_csv_quotes_commas;
+ Alcotest.test_case "csv does not widen for a third citation" `Quick
+ test_csv_does_not_widen_for_a_third_citation;
Alcotest.test_case "json parses back" `Quick test_json_parses_back;
Alcotest.test_case "json escapes" `Quick test_json_escapes;
Alcotest.test_case "json passes utf8 through" `Quick test_utf8_passes_through_json ] )
@@ -194,10 +210,38 @@ let test_xml_escapes_live_data () =
String.iteri (fun i c -> if c = '&' && not (is_entity_at out i) then incr bare) out;
Alcotest.(check int) "no bare, unescaped '&' anywhere in the document" 0 !bare
+(* First index [needle] starts at in [hay], or fails the test -- a small,
+ dependency-free substring search (no [Str], per the project's frozen
+ deps), sufficient for the fixed literal tags searched for below. *)
+let index_of ~needle hay =
+ let n = String.length needle and h = String.length hay in
+ let rec go i =
+ if i + n > h then Alcotest.failf "%S not found" needle
+ else if String.sub hay i n = needle then i
+ else go (i + 1)
+ in
+ go 0
+
+(* W5: unlike CSV, XML has no fixed column count -- [<citation>] is a
+ repeated element, so a [Second] reading is a third element, not a
+ breaking schema change. Checks BOTH the presence and the ORDER
+ (first, second, gospel -- reading order, not declaration order in
+ [Emit_xml.day]'s own three [cite] calls). *)
+let test_xml_three_citations () =
+ let out = Xml.year (Test_view.three_citation_view ()) in
+ Alcotest.(check bool) "second citation present" true
+ (contains ~needle:"<citation part=\"second\">1 Cor 1:3-9</citation>" out);
+ let first_at = index_of ~needle:"<citation part=\"first\">" out in
+ let second_at = index_of ~needle:"<citation part=\"second\">" out in
+ let gospel_at = index_of ~needle:"<citation part=\"gospel\">" out in
+ Alcotest.(check bool) "reading order: first < second < gospel" true
+ (first_at < second_at && second_at < gospel_at)
+
let xml_suite =
( "Emit/xml",
[ Alcotest.test_case "shape" `Quick test_xml_shape;
Alcotest.test_case "tags balance" `Quick test_xml_tags_balance;
Alcotest.test_case "escapes data" `Quick test_xml_escapes_data;
Alcotest.test_case "escapes live data (2035, Fabian & Sebastian)" `Quick
- test_xml_escapes_live_data ] )
+ test_xml_escapes_live_data;
+ Alcotest.test_case "three citations, in reading order" `Quick test_xml_three_citations ] )