Files
stack/tests/aco/test_express_base.py
kert 8f99eeb154
Some checks failed
ci/woodpecker/push/deploy Pipeline failed
ci/woodpecker/push/ci Pipeline failed
add comprehensive test suite, CI/CD quality gates, and package publishing
- 5519 unit tests covering all modules (aco, bcda, bls, cms, pfs, rex, bib)
- ruff lint + format enforcement across entire codebase (377 files reformatted)
- pre-commit hook: ruff check, ruff format, pytest
- Woodpecker CI split into ci.yml (quality gate) and deploy.yml (package + images)
- ci.yml: lint → test → validate-compose, runs on every push/PR
- deploy.yml: build + publish Python package to Gitea PyPI registry, then
  container image builds, Trivy scans, and registry push (main branch only)
- Gitea branch protection on main: requires CI status checks to pass
- .gitignore updated for .coverage, dist/, *.egg-info/
- grafana config moved to dev/grafana/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:58:48 -05:00

98 lines
3.4 KiB
Python

"""Tests for aco.express.base — Expr DSL primitive model."""
from __future__ import annotations
import pytest
from aco.express.base import Expr
from bib.tag import Tag
# ── fixtures ─────────────────────────────────────────────────────────────────
def _dummy_fn(core__encounter):
"""A dummy narwhalify function for Expr tests."""
return core__encounter
def _multi_input_fn(core__encounter, core__patient):
"""A function with multiple inputs."""
return core__encounter
# ── Expr model ───────────────────────────────────────────────────────────────
class TestExpr:
def test_create_minimal(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert expr.name == "core.encounter"
assert expr.fn is _dummy_fn
def test_create_with_all_fields(self) -> None:
expr = Expr(
name="readmissions._int_encounter",
fn=_dummy_fn,
output=None,
after=["core.encounter"],
refs=[Tag.module("aco")],
description="Test expression",
)
assert expr.after == ["core.encounter"]
assert len(expr.refs) == 1
assert expr.description == "Test expression"
def test_name_must_be_qualified(self) -> None:
with pytest.raises(ValueError, match="qualified"):
Expr(name="encounter", fn=_dummy_fn)
def test_doc_returns_description(self) -> None:
expr = Expr(
name="core.encounter",
fn=_dummy_fn,
description="My description",
)
assert expr.doc == "My description"
def test_doc_falls_back_to_docstring(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert "dummy narwhalify" in expr.doc
def test_inputs_from_signature(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert "core.encounter" in expr.inputs
def test_multi_inputs(self) -> None:
expr = Expr(name="core.test", fn=_multi_input_fn)
inputs = expr.inputs
assert "core.encounter" in inputs
assert "core.patient" in inputs
def test_qualified_refs_includes_auto_tag(self) -> None:
tag = Tag.module("aco")
expr = Expr(name="core.encounter", fn=_dummy_fn, refs=[tag])
qrefs = expr.qualified_refs
# First ref should be auto-generated table tag
assert qrefs[0].namespace == "table"
assert qrefs[0].value == "core.encounter"
# Second should be the user-provided tag
assert qrefs[1] == tag
def test_repr(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
r = repr(expr)
assert "core.encounter" in r
assert "_dummy_fn" in r
def test_default_after_is_empty(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert expr.after == []
def test_default_refs_is_empty(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert expr.refs == []
def test_default_description_is_empty(self) -> None:
expr = Expr(name="core.encounter", fn=_dummy_fn)
assert expr.description == ""