module Val = Colitur_kernel.Validate module V = Rite_ef.Vocab_ef module T = Rite_ef.Temporal_ef let run year = Val.run V.vocab ~year_start:T.year_start ~temporal:T.temporal ~year let check_year year = match run year with | [] -> () | fs -> Alcotest.failf "%d: %s" year (String.concat "; " (List.map Val.failure_to_string (List.filteri (fun i _ -> i < 5) fs))) let test_landmark_years () = List.iter check_year [ 1583; 2026; 2035; 9998 ] (* Easter extremes: the earliest possible date is 22 March and the latest is 25 April. Find one of each inside the domain and validate those years. *) let extreme_years () = let module C = Colitur_kernel.Computus in let module D = Colitur_kernel.Date in let earliest = ref None and latest = ref None in for y = 1583 to 2500 do let e = C.gregorian_easter y in if D.month e = 3 && D.day e = 22 && !earliest = None then earliest := Some y; if D.month e = 4 && D.day e = 25 && !latest = None then latest := Some y done; List.filter_map Fun.id [ !earliest; !latest ] let test_easter_extremes () = let ys = extreme_years () in Alcotest.(check bool) "found at least one extreme year" true (ys <> []); List.iter check_year ys (* The confidence-to-9999 core: random years across the whole domain. *) let prop_invariants = QCheck.Test.make ~count:200 ~name:"EF temporal invariants hold across 1583..9998" (QCheck.int_range 1583 9998) (fun y -> run y = []) let suite = ( "Validate", [ Alcotest.test_case "landmark years" `Quick test_landmark_years; Alcotest.test_case "easter extremes" `Quick test_easter_extremes ] @ List.map QCheck_alcotest.to_alcotest [ prop_invariants ] )