% Copyright (C) 2026 Mateo Pedersen. Distributed under LPPL 1.3c or later. \input{regression-test.tex} \documentclass{article} \usepackage{calendar-grid} \begin{document} \START \ExplSyntaxOn \msg_new:nnn {calendar-grid-test}{failure}{Test~failed:~#1.} \cs_new_protected:Npn \__cg_test_fail:n #1 {\msg_error:nnn{calendar-grid-test}{failure}{#1}} \msg_redirect_name:nnn {calendar-grid}{bad-date}{none} \cs_new_protected:Npn \__cg_test_leap:nn #1#2 {\__cg_leap:nTF {#1}{\tl_set:Nn\l_tmpa_tl{yes}}{\tl_set:Nn\l_tmpa_tl{no}} \str_if_eq:VnF \l_tmpa_tl {#2}{\__cg_test_fail:n{leap~year~#1}}} \__cg_test_leap:nn {1900}{no} \__cg_test_leap:nn {2000}{yes} \__cg_test_leap:nn {2024}{yes} \__cg_test_leap:nn {2027}{no} \__cg_test_leap:nn {2028}{yes} \__cg_test_leap:nn {2100}{no} \__cg_test_leap:nn {2400}{yes} \TYPE{Gregorian~leap-year~checks~passed} \int_step_inline:nn {12} { \__cg_days_in_month:nnN {2027}{#1}\l__cg_month_days_int \int_compare:nNnF {\l__cg_month_days_int} = {\int_case:nn {#1}{{1}{31}{2}{28}{3}{31}{4}{30}{5}{31}{6}{30}{7}{31}{8}{31}{9}{30}{10}{31}{11}{30}{12}{31}}} {\__cg_test_fail:n{month~length~#1}} } \__cg_days_in_month:nnN {2024}{2}\l__cg_month_days_int \int_compare:nNnF {\l__cg_month_days_int} = {29}{\__cg_test_fail:n{February~2024~has~29~days}} \TYPE{Month-length~checks~passed} \__cg_serial:nnnN {2024}{1}{2}\l__cg_serial_int \int_compare:nNnF {\int_mod:nn{\l__cg_serial_int}{7}+1} = {2}{\__cg_test_fail:n{2024~weekday}} \__cg_serial:nnnN {2000}{1}{2}\l__cg_serial_int \int_compare:nNnF {\int_mod:nn{\l__cg_serial_int}{7}+1} = {7}{\__cg_test_fail:n{2000~weekday}} \__cg_serial:nnnN {1900}{1}{2}\l__cg_serial_int \int_compare:nNnF {\int_mod:nn{\l__cg_serial_int}{7}+1} = {2}{\__cg_test_fail:n{1900~weekday}} \TYPE{Weekday~checks~passed} \keys_set:nn{calendar-grid}{year=2027,month=1,layout=fixed} \int_step_inline:nn {7} { \int_set:Nn\l__cg_week_start_int{#1} \__cg_compute_layout: \int_compare:nNnF{\l__cg_offset_int}={\int_mod:nn{12-#1}{7}} {\__cg_test_fail:n{week-start~offset~#1}} \int_compare:nNnF{\l__cg_rows_int}={6}{\__cg_test_fail:n{fixed~row~count~#1}} \int_compare:nNnF{\l__cg_cells_int}={42}{\__cg_test_fail:n{fixed~cell~count~#1}} } \TYPE{All~seven~week-starts~and~fixed~42-cell~grids~passed} \cs_new_protected:Npn \__cg_test_fixed:nn #1#2 { \keys_set:nn {calendar-grid}{year=#1,month=#2,week-start=monday,layout=fixed} \__cg_compute_layout: \int_compare:nNnF {\l__cg_cells_int} = {42} {\__cg_test_fail:n{fixed~42-cell~invariant~for~#1-#2}} } \__cg_test_fixed:nn {2027}{1} \__cg_test_fixed:nn {2027}{2} \__cg_test_fixed:nn {2028}{2} \__cg_test_fixed:nn {2027}{8} \TYPE{Fixed~42-cell~checks~passed} \keys_set:nn{calendar-grid}{year=2027,month=2,week-start=monday,layout=compact} \__cg_compute_layout: \int_compare:nNnF{\l__cg_rows_int}={4}{\__cg_test_fail:n{compact~February~2027~rows}} \keys_set:nn{calendar-grid}{year=2026,month=2,week-start=monday,layout=compact} \__cg_compute_layout: \int_compare:nNnF{\l__cg_rows_int}={5}{\__cg_test_fail:n{compact~February~2026~rows}} \keys_set:nn{calendar-grid}{year=2027,month=1,week-start=sunday,layout=compact} \__cg_compute_layout: \int_compare:nNnF{\l__cg_rows_int}={6}{\__cg_test_fail:n{compact~January~2027~rows}} \TYPE{Compact~four-,~five-,~and~six-week~grids~passed} \keys_set:nn{calendar-grid}{year=2027,month=1,week-start=monday,layout=fixed,overflow=adjacent} \__cg_compute_layout: \__cg_get_cell:n{0} \int_compare:nNnF{\l__cg_cell_year_int}={2026}{\__cg_test_fail:n{leading~overflow~year}} \int_compare:nNnF{\l__cg_cell_month_int}={12}{\__cg_test_fail:n{leading~overflow~month}} \int_compare:nNnF{\l__cg_cell_day_int}={28}{\__cg_test_fail:n{leading~overflow~day}} \TYPE{Adjacent-month~overflow~passed} \ExplSyntaxOff \TYPE{Calendar arithmetic and grid-layout checks passed} \END \end{document}