- Updated the nutrition import logic to utilize a new row processing specification, improving data aggregation and validation. - Refactored the template rendering process in the workflow executor to use Jinja2's Environment with ChainableUndefined for better handling of missing attributes. - Added backward-compatible shortcuts for accessing decision signals in node contexts, enhancing flexibility in template usage. - Introduced import row processing options in CSV templates, allowing for more customizable data handling during imports.
68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
"""Tests für CSV-Zeilenaggregation (import_row_processing)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import datetime as dt
|
|
|
|
import pytest
|
|
|
|
from csv_parser.import_row_processing import (
|
|
aggregate_mapped_rows,
|
|
resolve_import_row_processing,
|
|
validate_import_row_processing,
|
|
)
|
|
|
|
|
|
def test_validate_rejects_unknown_aggregate():
|
|
with pytest.raises(ValueError, match="ungültige Operation"):
|
|
validate_import_row_processing(
|
|
"nutrition",
|
|
{"group_by": ["date"], "aggregates": {"kcal": "bogus"}},
|
|
{"Kal": "date", "E": "kcal"},
|
|
)
|
|
|
|
|
|
def test_validate_group_by_must_be_mapped():
|
|
with pytest.raises(ValueError, match="keiner CSV-Spalte zugeordnet"):
|
|
validate_import_row_processing(
|
|
"nutrition",
|
|
{"group_by": ["date"], "aggregates": {"kcal": "sum"}},
|
|
{"Kal": "kcal"}, # date nicht gemappt
|
|
)
|
|
|
|
|
|
def test_aggregate_mapped_rows_sums_same_group():
|
|
d = dt.date(2024, 1, 15)
|
|
rows = [
|
|
{"date": d, "kcal": 500.0, "protein_g": 20},
|
|
{"date": d, "kcal": 300.0, "protein_g": 15},
|
|
]
|
|
spec = {"group_by": ["date"], "aggregates": {"kcal": "sum", "protein_g": "sum"}}
|
|
out = aggregate_mapped_rows(rows, spec)
|
|
assert len(out) == 1
|
|
assert out[0]["kcal"] == 800.0
|
|
assert out[0]["protein_g"] == 35
|
|
|
|
|
|
def test_resolve_explicit_overrides_default():
|
|
m = {
|
|
"import_row_processing": {"group_by": ["date"], "aggregates": {"kcal": "mean"}},
|
|
}
|
|
spec = resolve_import_row_processing("nutrition", m)
|
|
assert spec is not None
|
|
assert spec["aggregates"]["kcal"] == "mean"
|
|
|
|
|
|
def test_resolve_empty_dict_falls_back_to_module_default():
|
|
m: dict = {"import_row_processing": {}}
|
|
spec = resolve_import_row_processing("nutrition", m)
|
|
assert spec is not None
|
|
assert spec["group_by"] == ["date"]
|
|
assert spec["aggregates"]["kcal"] == "sum"
|
|
|
|
|
|
def test_resolve_none_uses_nutrition_default():
|
|
spec = resolve_import_row_processing("nutrition", {})
|
|
assert spec is not None
|
|
assert "date" in (spec.get("group_by") or [])
|