103 lines
3.2 KiB
Python
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)
|