bureaucat / eval /test_grounded.py
ravinsingh15's picture
Bureaucat — Build Small Hackathon submission (Qwen3-VL-8B, ZeroGPU, gr.Server)
6b5e47d
Raw
History Blame Contribute Delete
6.42 kB
"""
Unit tests for eval/grounded.py — shared matching primitives + check_no_invention.
These tests use the same sys.path bootstrap as test_eval_matching.py.
No app import needed — grounded.py is stdlib-only.
Test coverage:
- check_no_invention: returns [] when all deadline values appear verbatim in transcription
- check_no_invention: returns non-empty list when a deadline value is NOT in transcription
- normalize, value_found, extract_values_from_section: return identical results to known
cases from test_eval_matching (regression against moved functions)
- import run_eval still works after refactor (eval-compat regression)
"""
import os
import sys
# Ensure project root and eval/ are on the path regardless of where pytest is run from.
_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_EVAL_DIR = os.path.join(_REPO_ROOT, "eval")
if _REPO_ROOT not in sys.path:
sys.path.insert(0, _REPO_ROOT)
if _EVAL_DIR not in sys.path:
sys.path.insert(0, _EVAL_DIR)
import grounded # direct import (eval/ is on sys.path)
from types import SimpleNamespace as S
# ---------------------------------------------------------------------------
# check_no_invention: no invented values — returns empty list
# ---------------------------------------------------------------------------
def test_check_no_invention_returns_empty_when_all_values_in_transcription():
"""Returns [] when every deadline value appears verbatim in the transcription."""
result = S(
transcription="betala 1 234 kr senast 2026-06-15",
deadlines="- 2026-06-15 — sista dag\n- 1 234 kr — belopp",
)
invented = grounded.check_no_invention(result)
assert invented == []
def test_check_no_invention_returns_nonempty_for_invented_value():
"""Returns a non-empty list when a deadline value is NOT in transcription."""
result = S(
transcription="betala senast 2026-06-15", # "2026-07-99" NOT in transcription
deadlines="- 2026-07-99 — invented date\n- 2026-06-15 — real date",
)
invented = grounded.check_no_invention(result)
assert len(invented) >= 1
assert "2026-07-99" in invented
def test_check_no_invention_empty_deadlines_returns_empty():
"""Empty deadlines section → no values extracted → returns []."""
result = S(
transcription="betala senast 2026-06-15",
deadlines="",
)
invented = grounded.check_no_invention(result)
assert invented == []
def test_check_no_invention_none_found_returns_empty():
"""'None found.' sentinel in deadlines → no values extracted → returns []."""
result = S(
transcription="informational letter",
deadlines="None found.",
)
invented = grounded.check_no_invention(result)
assert invented == []
def test_check_no_invention_all_invented_returns_all():
"""All values invented → all returned in invented list."""
result = S(
transcription="hej det här är ett informationsbrev",
deadlines="- 2099-01-01 — fake\n- 99 999 kr — fake amount",
)
invented = grounded.check_no_invention(result)
assert len(invented) == 2
# ---------------------------------------------------------------------------
# Regression: moved functions return identical results to test_eval_matching cases
# ---------------------------------------------------------------------------
def test_normalize_case_insensitive():
"""normalize lowercases input (regression from test_eval_matching)."""
assert grounded.normalize("1 234,56 KR") == grounded.normalize("1 234,56 kr")
def test_normalize_collapses_multiple_spaces():
"""Multiple spaces collapse to single space."""
assert grounded.normalize("a b") == "a b"
def test_value_found_long_date_in_transcription():
"""An ISO date is found when present."""
haystack = "Du ska betala senast 2026-06-15. Glöm inte."
assert grounded.value_found("2026-06-15", haystack) is True
def test_value_found_short_boundary_inside_longer():
"""A 3-digit ref is NOT found inside a longer run of digits."""
haystack = "ref 1234567 i systemet"
assert grounded.value_found("123", haystack) is False
def test_value_found_short_boundary_standalone():
"""A 3-digit ref IS found when standing alone."""
haystack = "OCR-nummer 123 gäller"
assert grounded.value_found("123", haystack) is True
def test_extract_em_dash_separator():
"""Em-dash separator: verbatim value before ' — '."""
section = "- 15 juni 2026 — last day to file\n- 1 234 kr — amount owed"
vals = grounded.extract_values_from_section(section)
assert vals == ["15 juni 2026", "1 234 kr"]
def test_extract_hyphen_with_spaces_separator():
"""Hyphen-with-spaces separator."""
section = "- 2026-06-15 - sista betalningsdag\n- 1 234 kr - fakturabelopp"
vals = grounded.extract_values_from_section(section)
assert vals == ["2026-06-15", "1 234 kr"]
def test_extract_none_found_yields_empty():
"""'None found.' lines yield no values."""
assert grounded.extract_values_from_section("None found.") == []
def test_extract_date_with_internal_hyphens_preserved():
"""ISO date is not split by internal hyphens."""
section = "- 2026-06-15 — sista dag"
vals = grounded.extract_values_from_section(section)
assert vals == ["2026-06-15"]
# ---------------------------------------------------------------------------
# Eval-compat regression: import run_eval still works after refactor
# ---------------------------------------------------------------------------
def test_import_run_eval_succeeds():
"""import run_eval still works after the grounded.py refactor."""
import run_eval # noqa: F401 — just checking importability
assert hasattr(run_eval, "normalize"), "run_eval.normalize must be re-bound"
assert hasattr(run_eval, "value_found"), "run_eval.value_found must be re-bound"
assert hasattr(run_eval, "extract_values_from_section"), (
"run_eval.extract_values_from_section must be re-bound"
)
def test_run_eval_normalize_still_accessible_via_namespace():
"""import run_eval as e; e.normalize(...) still resolves after refactor."""
import run_eval as e
# Same case as test_eval_matching.py lines 44-45
assert e.normalize("A b") == "a b"
if __name__ == "__main__":
import pytest
pytest.main([__file__, "-v"])