aboutsummaryrefslogtreecommitdiff
path: root/test
Commit message (Collapse)AuthorAgeFilesLines
* rite(ef): season and rank vocabulary per RG 71-77 and RG 8Lukasz Kasprzak2026-08-113-2/+30
| | | | | | | Eight seasons in canonical liturgical-year order, each carrying its RG citation, and the four classes. season_slug_word is deliberately distinct from season_to_string: slugs are lectionary keys adopted verbatim from lectio, which calls Paschaltide 'easter' and Christmastide 'christmas'.
* fix(record): derive headers and to_row from a single columns listLukasz Kasprzak2026-08-111-1/+7
| | | | | | | | | Make alignment impossible: both headers and to_row are derived from a single list of (name, extractor) pairs, so reordering one without the other is impossible. CSV schema cannot silently mislabel columns. Add a meaningful test that pins the header names in order, not just length. This catches column reordering regressions.
* kernel(record): flat all-string canonical output viewLukasz Kasprzak2026-08-111-1/+42
| | | | | | | 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(overlay): close review gaps in the merge-algebra test suiteLukasz Kasprzak2026-08-111-6/+97
| | | | | | | | | | | | | | | | | | | | | | | | | Five review findings, all in the test suite the task designates as the algebra's specification: - test_diagnostics's headline assertion was vacuous: it checked slug presence after an add-over-existing, but hilary was already present before the Add ran, so a broken implementation that recorded the diagnostic and skipped applying the entry would still pass. Add now carries a rank that genuinely differs from base()'s default, and the assertion checks the field actually changed. - Set_subject, Set_name, Remove_name, Set_citation and Remove_citation were implemented but never exercised. Added coverage for all five, including the case that matters most for Set_citation: setting a part that already exists must replace it, not append a duplicate. - Replace had zero coverage. Added tests for both its existing-slug path (entry swapped, no diagnostic) and its absent-slug path (diagnostic recorded, entry still added). - merge's diagnostic accumulation was untested; test_merge_order discarded the diagnostics it got back. Added a test asserting two overlays' each producing one diagnostic come back in application order. Extended the cel/entry test helpers with optional subject/names/citations so the new tests can build fixtures with those fields populated.
* kernel(overlay): ordered layer-merge algebra with diagnosticsLukasz Kasprzak2026-08-111-1/+100
| | | | | | | add/suppress/replace/field-edit folded in order, last writer wins per field, empty the identity. A directive naming an unknown slug, or adding one that already exists, yields a diagnostic rather than silence or a hard failure: overlays must survive a shifted base while still surfacing authoring errors.
* test(layer): cover load's failure modes and same-date index orderingLukasz Kasprzak2026-08-111-1/+80
| | | | | | | | | | | | | load previously had zero coverage despite being the module's only fallible- I/O function and the one place the brief's literal code would have let an exception escape on this sexplib version (Failure instead of Parse_error). Add cases for a missing file, a malformed/unterminated sexp, an invalid slug embedded in an otherwise well-formed layer, and a success round-trip. Also add a same-date index case with three entries inserted out of slug order, pinning that the by-date index accumulates rather than overwrites and returns buckets in canonical order regardless of insertion order -- the previous two-entry fixture only ever touched bucket sizes 0 and 1.
* kernel(layer): sanctoral layer with canonical order and date indexLukasz Kasprzak2026-08-112-1/+47
| | | | | | | Entries sort by slug so equal layers serialise identically. The by-date index is built once per layer rather than per year, since fixed dates are year-independent; a full-domain sweep would otherwise rescan every entry for every day. load turns parse and validation failures into result.
* kernel: Vocab, Celebration and Temporal parametric typesLukasz Kasprzak2026-08-112-2/+24
| | | | | | | | Rite specificity is carried by type parameters plus a vocab record of operations rather than by functors: the same guarantee that a rite cannot name another rite's season, without threading module plumbing through every kernel module. Celebration takes only the rank parameter, since it has no season field and OCaml rejects a type variable that appears in no field.
* kernel: fix sexp deriving, add missing tests, canonicalize removeLukasz Kasprzak2026-08-111-1/+31
| | | | | | | | | | | | | Use [@@deriving sexp] with open Sexplib0.Sexp_conv instead of hand-rolling converters (fixes non-standard Citation shape and missing field validation). Names.t_of_sexp wraps derived version to enforce canonical sort on load. Add tests: - Names of_list duplicate handling - Names sexp canonical sort guarantee (identical serialization) - Names and Date_spec sexp roundtrips Fix Names.remove to canonicalize output (defensive against non-canonical input).
* kernel: Names, Citation and Date_specLukasz Kasprzak2026-08-112-1/+57
| | | | | | | Names is an open language-keyed assoc kept in canonical order so equal name sets serialise identically. Citation carries references only, never text. Date_spec ships the one form the EF sanctoral needs; 29 February is constructible and resolves to None in common years.
* test(kernel): cover Lang's sexp validation pathLukasz Kasprzak2026-08-111-1/+14
| | | | | | | | test_lang exercised only of_string. Add a sexp round-trip plus a check_raises proving a malformed-but-plausible code ("e1": right length, fails the lowercase rule) is rejected by t_of_sexp rather than silently accepted -- mirrors test_slug_sexp's guard against a future regression to [@@deriving sexp].
* kernel: Slug and Lang validated private stringsLukasz Kasprzak2026-08-112-1/+42
| | | | | | Both parse through a smart constructor returning result, and both hand-write t_of_sexp so a malformed value in a data file is rejected at load rather than silently accepted -- deriving the converter would have bypassed validation.
* kernel: Colour and Subject shared vocabularyLukasz Kasprzak2026-08-112-1/+33
| | | | | | The six liturgical colours and the Lord/BVM/saint/temporal distinction are common to both Roman forms, so they are shared closed variants rather than rite-parametric. Subject is so named because class is an OCaml keyword.
* kernel(date): ISO-8601 rendering, validating parse, sexp convertersLukasz Kasprzak2026-08-112-2/+19
| | | | | | | Adds sexplib and ppx_sexp_conv to the project and wires the ppx into the kernel library. Date's sexp form is an ISO-8601 atom rather than the opaque rata die, so data files stay human-editable and parsing revalidates the 1583..9999 domain.
* cli: colitur easter <year> prints Easter and its anchorsLukasz Kasprzak2026-07-312-0/+24
| | | | | Argv-parsed subcommand; validates the 1583..9999 domain (exit 2 otherwise); prints 'name YYYY-MM-DD' lines. Cram test covers the output and the exit codes.
* kernel(computus): Easter-relative movable-feast anchorsLukasz Kasprzak2026-07-311-1/+19
| | | | | | Ash Wednesday/Palm Sunday/Ascension/Pentecost/Corpus Christi as Easter+/-N. Verified vs 2026 dates; exhaustive weekday invariants 1583..9999 (Ash Wed=Wed, Ascension/Corpus Christi=Thu, Palm/Pentecost=Sun).
* kernel(computus): Gregorian + Julian EasterLukasz Kasprzak2026-07-312-1/+39
| | | | | | | Anonymous Gregorian (Meeus/Jones/Butcher) for OF+EF; Meeus Julian mapped to the proleptic-Gregorian date for future eastern rites. Verified vs known dates (2000/2024-27, 1583; Orthodox 2023/24) and EXHAUSTIVELY over 1583..9999: every Easter is a Sunday in [Mar22,Apr25].
* kernel(date): proleptic Gregorian date, validated make + arithmeticLukasz Kasprzak2026-07-312-5/+64
| | | | | | | Hinnant civil<->days rep (1970-epoch rata die); make validates month/day and the 1583..9999 domain; of_rata/add_days are total arithmetic. Weekday, compare. Tested: known weekdays, leap boundaries, rejects; qcheck round-trip / add-inverse / weekday-cycle properties over random in-range dates.
* chore: scaffold dune project (kernel lib + cli + tests)Lukasz Kasprzak2026-07-312-0/+8
OCaml 5.2.0 local switch; colitur_kernel library, a colitur executable stub, and an alcotest+qcheck test runner. AGPL LICENSE, README, generated colitur.opam.