From 9c0a755767da935dce6bfdaed2f7e11cfd30421a Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Fri, 31 Jul 2026 14:06:33 +0200 Subject: kernel(computus): Gregorian + Julian Easter 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]. --- test/test_colitur.ml | 2 +- test/test_computus.ml | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/test_computus.ml (limited to 'test') diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 734257c..19671ce 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -1,2 +1,2 @@ (* Aggregating test runner. Per-module suites live in test_.ml. *) -let () = Alcotest.run "colitur" [ Test_date.suite ] +let () = Alcotest.run "colitur" [ Test_date.suite; Test_computus.suite ] diff --git a/test/test_computus.ml b/test/test_computus.ml new file mode 100644 index 0000000..1502ad2 --- /dev/null +++ b/test/test_computus.ml @@ -0,0 +1,38 @@ +module D = Colitur_kernel.Date +module C = Colitur_kernel.Computus + +let ymd d = (D.year d, D.month d, D.day d) + +let test_gregorian_known () = + let cases = [ (2024, 3, 31); (2025, 4, 20); (2026, 4, 5); (2027, 3, 28); (2000, 4, 23); (1583, 4, 10) ] in + List.iter + (fun (y, m, d) -> + Alcotest.(check (triple int int int)) (Printf.sprintf "Gregorian Easter %d" y) + (y, m, d) (ymd (C.gregorian_easter y))) + cases + +let test_julian_known () = + (* Orthodox (Julian) Easter, expressed as the equivalent Gregorian date *) + let cases = [ (2023, 4, 16); (2024, 5, 5) ] in + List.iter + (fun (y, m, d) -> + Alcotest.(check (triple int int int)) (Printf.sprintf "Julian Easter %d" y) + (y, m, d) (ymd (C.julian_easter y))) + cases + +let test_gregorian_invariants_exhaustive () = + (* the confidence-to-9999 guarantee: EVERY year's Easter is a Sunday in + [Mar 22, Apr 25] inclusive. *) + for y = 1583 to 9999 do + let e = C.gregorian_easter y in + Alcotest.(check bool) (Printf.sprintf "%d Easter is Sunday" y) true (D.weekday e = D.Sun); + let _, m, d = ymd e in + let ok = (m = 3 && d >= 22) || (m = 4 && d <= 25) in + Alcotest.(check bool) (Printf.sprintf "%d Easter in [Mar22,Apr25]" y) true ok + done + +let suite = + ( "Computus", + [ Alcotest.test_case "Gregorian known dates" `Quick test_gregorian_known; + Alcotest.test_case "Julian known dates" `Quick test_julian_known; + Alcotest.test_case "Gregorian invariants 1583..9999" `Slow test_gregorian_invariants_exhaustive ] ) -- cgit v1.3