fischer-agentkit/tests/unit/bitable/test_functions_datetime.py

127 lines
3.0 KiB
Python

"""Tests for datetime formula functions (R1)."""
from __future__ import annotations
from agentkit.bitable.formula.functions.datetime import (
DATETIME_FUNCTIONS,
_date,
_dateadd,
_datedif,
_day,
_eomonth,
_hour,
_minute,
_month,
_networkdays,
_now,
_second,
_today,
_weekday,
_year,
)
def test_registry_has_15_functions() -> None:
assert len(DATETIME_FUNCTIONS) == 15
assert "DATE" in DATETIME_FUNCTIONS
assert "NETWORKDAYS" in DATETIME_FUNCTIONS
def test_date_constructor() -> None:
result = _date(2026, 7, 6)
assert result == "2026-07-06T00:00:00"
def test_year_month_day() -> None:
d = _date(2026, 7, 6)
assert _year(d) == 2026
assert _month(d) == 7
assert _day(d) == 6
def test_hour_minute_second() -> None:
dt = "2026-07-06T14:30:45"
assert _hour(dt) == 14
assert _minute(dt) == 30
assert _second(dt) == 45
def test_weekday() -> None:
# 2026-07-06 is a Monday → ISO weekday 1
assert _weekday("2026-07-06") == 1
# 2026-07-12 is a Sunday → ISO weekday 7
assert _weekday("2026-07-12") == 7
def test_datedif_days() -> None:
assert _datedif("2026-07-01", "2026-07-06", "days") == 5
def test_datedif_months() -> None:
assert _datedif("2026-01-15", "2026-07-15", "months") == 6
def test_datedif_years() -> None:
assert _datedif("2020-01-01", "2026-01-01", "years") == 6
def test_dateadd_days() -> None:
assert _dateadd("2026-07-06", 5, "days") == "2026-07-11T00:00:00"
def test_dateadd_months() -> None:
assert _dateadd("2026-01-15", 1, "months") == "2026-02-15T00:00:00"
def test_dateadd_months_clamps_day() -> None:
# Jan 31 + 1 month → Feb 28 (2026 is not a leap year)
assert _dateadd("2026-01-31", 1, "months") == "2026-02-28T00:00:00"
def test_networkdays() -> None:
# 2026-07-06 (Mon) to 2026-07-10 (Fri) = 5 working days
assert _networkdays("2026-07-06", "2026-07-10") == 5
def test_networkdays_includes_weekend() -> None:
# 2026-07-06 (Mon) to 2026-07-12 (Sun) = 5 working days (weekend excluded)
assert _networkdays("2026-07-06", "2026-07-12") == 5
def test_networkdays_reversed_args() -> None:
# Should swap if start > end
assert _networkdays("2026-07-10", "2026-07-06") == 5
def test_eomonth() -> None:
# End of July 2026
assert _eomonth("2026-07-06", 0) == "2026-07-31T00:00:00"
def test_eomonth_next_month() -> None:
# End of August 2026
assert _eomonth("2026-07-06", 1) == "2026-08-31T00:00:00"
def test_today_returns_iso_string() -> None:
result = _today()
assert isinstance(result, str)
assert "T00:00:00" in result
def test_now_returns_iso_string() -> None:
result = _now()
assert isinstance(result, str)
assert "T" in result
def test_none_input_returns_none_for_accessors() -> None:
assert _year(None) is None
assert _month(None) is None
assert _day(None) is None
def test_empty_string_returns_none_for_accessors() -> None:
assert _year("") is None
assert _datedif("", "2026-07-06") is None