summaryrefslogtreecommitdiff
path: root/test/test_computus.ml
blob: cbb8cab50806999db5a87b2847353dd6ca04bf3f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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 test_anchors_2026 () =
  (* Easter 2026 = Apr 5 *)
  Alcotest.(check (triple int int int)) "Ash Wednesday 2026" (2026, 2, 18) (ymd (C.ash_wednesday 2026));
  Alcotest.(check (triple int int int)) "Palm Sunday 2026" (2026, 3, 29) (ymd (C.palm_sunday 2026));
  Alcotest.(check (triple int int int)) "Ascension 2026" (2026, 5, 14) (ymd (C.ascension 2026));
  Alcotest.(check (triple int int int)) "Pentecost 2026" (2026, 5, 24) (ymd (C.pentecost 2026))

let test_anchor_weekdays_exhaustive () =
  for y = 1583 to 9999 do
    Alcotest.(check bool) (Printf.sprintf "%d Ash Wed = Wed" y) true (D.weekday (C.ash_wednesday y) = D.Wed);
    Alcotest.(check bool) (Printf.sprintf "%d Palm Sun = Sun" y) true (D.weekday (C.palm_sunday y) = D.Sun);
    Alcotest.(check bool) (Printf.sprintf "%d Ascension = Thu" y) true (D.weekday (C.ascension y) = D.Thu);
    Alcotest.(check bool) (Printf.sprintf "%d Pentecost = Sun" y) true (D.weekday (C.pentecost y) = D.Sun);
    Alcotest.(check bool) (Printf.sprintf "%d Corpus Christi = Thu" y) true (D.weekday (C.corpus_christi y) = D.Thu)
  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;
      Alcotest.test_case "anchors 2026" `Quick test_anchors_2026;
      Alcotest.test_case "anchor weekdays 1583..9999" `Slow test_anchor_weekdays_exhaustive ] )