Files
pf1e-simulator/tests/test_format_llm_report.py
T
ctan 98985ee6fc feat(phase2): llm report writer (P5.3)
- New module src/pf1e_simulator/report.py with ReportContext, build_report_context,
  LLMReportPolicy, ReportBudget, format_llm_report, build_report_prompt
- Prompt pack fixture: tests/fixtures/prompt_pack_fs/report.md (FR narrator)
- CLI integration: --llm-report + --output flags, mutually exclusive with --transcript
- Budget enforcement: ReportBudget integrates with CostBudget, allows max_retries+1 calls
- Tests: test_report_context, test_report_prompt_pack, test_llm_report_policy,
  test_format_llm_report, test_cli_llm_report, test_report_budget (27 new tests)
2026-09-26 10:40:58 +02:00

64 lines
2.4 KiB
Python

"""Tests for format_llm_report (P5.3 T4)."""
from __future__ import annotations
from pf1e_simulator.report import build_report_context, format_llm_report
from pf1e_simulator.runner import CombatantAttrition, EncounterReport
def _make_encounter() -> EncounterReport:
return EncounterReport(
runs=100,
seed=1,
wins={"players": 65, "monsters": 33},
draws=2,
avg_rounds=7.2,
attrition={
"goblin": CombatantAttrition(2.45, 0.12, 18.30, 4.20, 0.00),
"orc": CombatantAttrition(3.20, 0.25, 28.40, 15.60, 0.00),
},
)
def test_format_llm_report_empty_narrative() -> None:
"""Empty LLM text returns only the factual report."""
ctx = build_report_context(encounter=_make_encounter(), spec_name="test")
result = format_llm_report(ctx, "")
assert "=== Rapport d'équilibrage ===" in result
assert "Victoires players : 65.0%" in result
assert "Récit d'équilibrage" not in result
def test_format_llm_report_whitespace_only_narrative() -> None:
"""Whitespace-only LLM text returns only the factual report."""
ctx = build_report_context(encounter=_make_encounter(), spec_name="test")
result = format_llm_report(ctx, " \n \t ")
assert "=== Rapport d'équilibrage ===" in result
assert "Récit d'équilibrage" not in result
def test_format_llm_report_with_narrative() -> None:
"""Non-empty LLM text appends narrative section after factual report."""
ctx = build_report_context(encounter=_make_encounter(), spec_name="test")
narrative = "Le gobelin a surpris l'orc par sa vitesse."
result = format_llm_report(ctx, narrative)
assert "=== Rapport d'équilibrage ===" in result
assert "Victoires players : 65.0%" in result
assert "=== Récit d'équilibrage (LLM) ===" in result
assert narrative in result
# factual comes before narrative
factual_end = result.index("=== Récit d'équilibrage (LLM) ===")
assert "Victoires players" in result[:factual_end]
def test_format_llm_report_strips_narrative_whitespace() -> None:
"""Leading/trailing whitespace in narrative is stripped."""
ctx = build_report_context(encounter=_make_encounter(), spec_name="test")
result = format_llm_report(ctx, " \n Texte narratif. \n ")
assert result.endswith("Texte narratif.")
assert "=== Récit d'équilibrage (LLM) ===\nTexte narratif." in result