\input regression-test.tex
\documentclass{article}
\usepackage[startdate=18.07.2026]{kanban-board}
\newcount\kbitem
% Invalid replacements must warn and preserve the valid package value.
\kbset{startdate=31.02.2026}
\def\kbmacrodate{18.07.2026}
\def\kbrobustdate{\textsc{soon}}
\begin{document}
\sbox0{\scriptsize $x$}% Load math font sizes outside captured output.
\START
\begingroup
\makeatletter
\year=2026 \month=7 \day=18
\newcommand\kbexpectneutral[2]{%
  \kb@evaloverdue{#1}%
  \ifboolexpr{not bool {kb@overdue} and not bool {kb@duenow}}
    {\TYPE{#2 OK}}
    {\TYPE{#2 FAILED}}}
\newcommand\kbexpectoverdue[2]{%
  \kb@evaloverdue{#1}%
  \ifbool{kb@overdue}
    {\TYPE{#2 OK}}
    {\TYPE{#2 FAILED}}}
\newcommand\kbexpectcurrent[2]{%
  \kb@evaloverdue{#1}%
  \ifbool{kb@duenow}
    {\TYPE{#2 OK}}
    {\TYPE{#2 FAILED}}}

\ifdefstring{\kanban@startdate}{2026-07-18}
  {\TYPE{KANBAN INVALID STARTDATE PRESERVES VALUE OK}}
  {\TYPE{KANBAN INVALID STARTDATE PRESERVES VALUE FAILED}}
\def\kanban@thestart{18.07.2026}
\kbexpectcurrent{\number\day.\number\month.\number\year}
  {KANBAN EXPANDED CURRENT DATE}
\kbexpectoverdue{29.02.2024}{KANBAN VALID LEAP DATE}
\kbexpectneutral{29.02.2025}{KANBAN INVALID LEAP DATE NEUTRAL}
\kbexpectneutral{2025-02-29}{KANBAN INVALID ISO LEAP DATE NEUTRAL}
\kbexpectneutral{31.04.2026}{KANBAN INVALID MONTH DAY NEUTRAL}
\kbexpectneutral{18.07.26}{KANBAN TWO-DIGIT YEAR NEUTRAL}
\kbexpectneutral{7/8/26}{KANBAN TWO-DIGIT SLASH YEAR NEUTRAL}
\kbexpectoverdue{2026-7-8}{KANBAN LOOSE ISO DATE CLASSIFIED}
\kbexpectoverdue{2026/7/8}{KANBAN LOOSE YEAR-FIRST DATE CLASSIFIED}
\kbexpectneutral{Milestone}{KANBAN M LABEL NEUTRAL}
\kbexpectneutral{Editorial review.}{KANBAN PUNCTUATED LABEL NEUTRAL}
\kbexpectneutral{M0}{KANBAN ZERO PROJECT MONTH NEUTRAL}
\kbexpectneutral{M1000000}{KANBAN OUT-OF-RANGE PROJECT MONTH NEUTRAL}
\kbexpectneutral{M999999999999999999999999999999999999}
  {KANBAN HUGE PROJECT MONTH NEUTRAL}
\kbexpectcurrent{M1}{KANBAN PROJECT MONTH CURRENT}
\kbexpectneutral{M2}{KANBAN PROJECT MONTH FUTURE}
\kbexpectcurrent{M01}{KANBAN LEADING ZERO PROJECT MONTH CURRENT}
\kbexpectneutral{M000}{KANBAN ALL ZERO PROJECT MONTH NEUTRAL}
\kbexpectoverdue{01.01.0001}{KANBAN YEAR ONE OVERDUE}
\kbexpectneutral{31.12.9999}{KANBAN YEAR 9999 FUTURE}
\kbexpectneutral{01.01.0000}{KANBAN YEAR ZERO NEUTRAL}
\kbexpectcurrent{\kbmacrodate}{KANBAN MACRO DATE CLASSIFIED}
\kbexpectneutral{\emph{soon}}{KANBAN ROBUST DEADLINE NEUTRAL}
\kbexpectneutral{\textbf{2026-07-18}}{KANBAN WRAPPED DATE NEUTRAL}
\kbexpectneutral{\kbrobustdate}{KANBAN MACRO TO ROBUST COMMAND NEUTRAL}
\ExplSyntaxOn
\cs_new_protected:Npn \kb_expect_valid:nn #1#2
  {
    \__kanban_parse_date:nn {#1} {us}
    \bool_if:NTF \l__kanban_valid_date_bool
      {\TYPE{#2~OK}} {\TYPE{#2~FAILED}}
  }
\cs_new_protected:Npn \kb_expect_invalid:nn #1#2
  {
    \__kanban_parse_date:nn {#1} {us}
    \bool_if:NTF \l__kanban_valid_date_bool
      {\TYPE{#2~FAILED}} {\TYPE{#2~OK}}
  }
\kb_expect_valid:nn {01.01.0001} {KANBAN~YEAR~ONE~VALID}
\kb_expect_valid:nn {31.12.9999} {KANBAN~YEAR~9999~VALID}
\kb_expect_invalid:nn {01.01.0000} {KANBAN~YEAR~ZERO~INVALID}
\ExplSyntaxOff
\makeatother
\endgroup
\begingroup
  % Deadline diagnostics are issued when a task is declared. Capture them
  % semantically, because the console rendering of l3msg varies across TeX
  % Live releases.
  \ExplSyntaxOn
  \cs_set_protected:Npn \msg_warning:nnn #1#2#3
    {\TYPE{KANBAN~WARNING:~#2~'#3'}}
  \ExplSyntaxOff
  \begin{kanban}[columns={Queue}]
    \kanbantask[due=29.02.2025]{Queue}{An invalid leap date}
    \kanbantask[due=2025-02-29]{Queue}{An invalid ISO leap date}
    \kanbantask[due=31.04.2026]{Queue}{An invalid month day}
    \kanbantask[due=18.07.26]{Queue}{A two-digit year}
    \kanbantask[due=7/8/26]{Queue}{A two-digit slash year}
    \kanbantask[due=M0]{Queue}{A zero project month}
    \kanbantask[due=M1000000]{Queue}{An out-of-range project month}
    \kanbantask[due=Milestone]{Queue}{A descriptive label}
    \kanbantask[due=2026-7-8]{Queue}{A loose ISO date}
    \kanbantask[due=12/31/2099]{Queue}{A valid date}
    \TYPE{KANBAN DEADLINE DIAGNOSTICS AT DECLARATION OK}
  \end{kanban}
\endgroup
\begin{kanban}[columns={Queue}]
  \kbitem=0
  \loop
    \advance\kbitem by 1
    \kanbantask{Queue}{Collected task \the\kbitem}
  \ifnum\kbitem<25
  \repeat
  \makeatletter
  \ifnum\csuse{kanban@count@\kanban@boardgroup @1}=25\relax
    \TYPE{KANBAN LARGE COLLECTION COUNT OK}
  \else
    \TYPE{KANBAN LARGE COLLECTION COUNT FAILED}
  \fi
  \makeatother
\end{kanban}
\END
\end{document}
