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

103 lines
3.2 KiB
Python

"""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)