"""Tests for aggregate and math formula functions (R1).""" from __future__ import annotations from agentkit.bitable.formula.functions.aggregate import ( AGGREGATE_FUNCTIONS_DICT, AGGREGATE_FUNCTIONS_LIST, ) def test_registry_has_12_functions() -> None: assert len(AGGREGATE_FUNCTIONS_DICT) == 12 def test_aggregate_set_has_10_functions() -> None: assert len(AGGREGATE_FUNCTIONS_LIST) == 10 assert "SUM" in AGGREGATE_FUNCTIONS_LIST assert "SUMIF" in AGGREGATE_FUNCTIONS_LIST assert "ABS" not in AGGREGATE_FUNCTIONS_LIST # ABS is scalar, not aggregate assert "ROUND" not in AGGREGATE_FUNCTIONS_LIST # ── migrated aggregate functions ──────────────────────── def test_sum() -> None: assert AGGREGATE_FUNCTIONS_DICT["SUM"]([1, 2, 3, 4, 5]) == 15 assert AGGREGATE_FUNCTIONS_DICT["SUM"]([1, None, "", "3"]) == 4.0 def test_avg() -> None: assert AGGREGATE_FUNCTIONS_DICT["AVG"]([1, 2, 3, 4, 5]) == 3.0 assert AGGREGATE_FUNCTIONS_DICT["AVG"]([]) == 0.0 def test_count() -> None: assert AGGREGATE_FUNCTIONS_DICT["COUNT"]([1, 2, None, "", "x"]) == 3 def test_min() -> None: assert AGGREGATE_FUNCTIONS_DICT["MIN"]([3, 1, 4, 1, 5]) == 1.0 assert AGGREGATE_FUNCTIONS_DICT["MIN"]([]) == 0 def test_max() -> None: assert AGGREGATE_FUNCTIONS_DICT["MAX"]([3, 1, 4, 1, 5]) == 5.0 assert AGGREGATE_FUNCTIONS_DICT["MAX"]([]) == 0 # ── migrated scalar math ──────────────────────────────── def test_abs() -> None: assert AGGREGATE_FUNCTIONS_DICT["ABS"](-5) == 5.0 assert AGGREGATE_FUNCTIONS_DICT["ABS"](5) == 5.0 assert AGGREGATE_FUNCTIONS_DICT["ABS"](None) is None def test_round() -> None: assert AGGREGATE_FUNCTIONS_DICT["ROUND"](3.14159, 2) == 3.14 assert AGGREGATE_FUNCTIONS_DICT["ROUND"](3.14159) == 3.0 assert AGGREGATE_FUNCTIONS_DICT["ROUND"](None) is None # ── conditional aggregates ────────────────────────────── def test_sumif_equality() -> None: assert AGGREGATE_FUNCTIONS_DICT["SUMIF"]([1, 2, 3, 4, 5], 3) == 3.0 def test_sumif_greater_than() -> None: assert AGGREGATE_FUNCTIONS_DICT["SUMIF"]([1, 2, 3, 4, 5], ">3") == 9.0 # 4+5 def test_countif_greater_than() -> None: assert AGGREGATE_FUNCTIONS_DICT["COUNTIF"]([1, 2, 3, 4, 5], ">3") == 2 def test_averageif() -> None: assert AGGREGATE_FUNCTIONS_DICT["AVERAGEIF"]([1, 2, 3, 4, 5], ">=3") == 4.0 # (3+4+5)/3 def test_sumifs() -> None: values = [10, 20, 30, 40] criteria_range = [1, 2, 1, 2] # Sum values where criteria_range == 2 → 20 + 40 = 60 assert AGGREGATE_FUNCTIONS_DICT["SUMIFS"](values, criteria_range, 2) == 60.0 def test_countifs() -> None: values = [10, 20, 30, 40] criteria_range = [1, 2, 1, 2] # Count values where criteria_range == 1 → 2 assert AGGREGATE_FUNCTIONS_DICT["COUNTIFS"](values, criteria_range, 1) == 2 def test_sumifs_length_mismatch() -> None: import pytest with pytest.raises(ValueError, match="equal length"): AGGREGATE_FUNCTIONS_DICT["SUMIFS"]([1, 2, 3], [1, 2], 1)