Rename the reference-project helpers and test names (_reference_k, test_reference_path_*) and the cost-baseline helper (_kontor_it_baseline, which already returned KONTOR-IT-E1). Names only; no assertion changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
108 lines
4.5 KiB
Python
108 lines
4.5 KiB
Python
"""P18/C1 — ``--docs-dir`` is optional once ``--bundle-dir`` is given.
|
|
|
|
P16 FUNN 2: the documented stress command names the same directory twice
|
|
(``--docs-dir <base> --bundle-dir <base>``), because single-project mode demanded ``--docs-dir``
|
|
even on the bundle path — where it is never read. Retrieval, the chunk tool and the "no citable
|
|
content" check all live in the REFERENCE branch (``run.py``); the bundle branch builds its citations
|
|
from the navigated base. So the flag was required for a path that ignores it, and the published
|
|
command had to satisfy the requirement by repeating itself.
|
|
|
|
**This is not the "--docs-dir omvei"** (feeding project documents through retrieval INSTEAD of
|
|
ingesting them into a knowledge base), which STATE forbids and this order forbids again. No such
|
|
path is opened: the reference branch still refuses without a real ``--docs-dir``, and the value is
|
|
bound ONCE from ``--bundle-dir`` — byte-identically what the README already tells an operator to
|
|
type by hand, so every existing invocation, the two-flag form included, is unchanged.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import shutil
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from portfolio_optimiser import run
|
|
|
|
_FIXTURES = Path(__file__).parent / "fixtures"
|
|
_PRICED = _FIXTURES / "k2-prisskjema-SYNTETISK"
|
|
_IR_PROJECTION = {
|
|
"project_id": "K2",
|
|
"measure": "energy_efficiency",
|
|
"claimed_saving_nok": 1000.0,
|
|
"affected_codes": ["01.1"],
|
|
}
|
|
|
|
|
|
def _runnable(tmp_path: Path) -> str:
|
|
root = tmp_path / "base"
|
|
shutil.copytree(_PRICED, root)
|
|
(root / "validator-input.json").write_text(json.dumps(_IR_PROJECTION), encoding="utf-8")
|
|
return str(root)
|
|
|
|
|
|
def test_a_bundle_run_needs_no_docs_dir(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
|
|
"""(a) The fix. A free dry run on ``--bundle-dir`` alone is ACCEPTED and reaches the bundle
|
|
path — asserted on the run-config the dry run prints, not on rc alone, since rc 0 is also what
|
|
a run that silently took the reference path would return."""
|
|
rc = run.main(["K2", "--bundle-dir", _runnable(tmp_path), "--live-dry-run"])
|
|
|
|
assert rc == 0
|
|
assert "LIVE-DRY-RUN OK" in capsys.readouterr().out
|
|
|
|
|
|
def test_the_documented_two_flag_form_still_works(
|
|
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
"""(b) The CONTROL that this is a widening, not a change. The README's form — the same
|
|
directory twice — must be byte-for-byte as accepted as it was before."""
|
|
base = _runnable(tmp_path)
|
|
rc = run.main(["K2", "--docs-dir", base, "--bundle-dir", base, "--live-dry-run"])
|
|
|
|
assert rc == 0
|
|
assert "LIVE-DRY-RUN OK" in capsys.readouterr().out
|
|
|
|
|
|
def test_neither_flag_is_still_refused_by_name(capsys: pytest.CaptureFixture[str]) -> None:
|
|
"""(c) The half that must NOT be relaxed: the reference path has no base to fall back to, so an
|
|
argv naming neither is refused, and the refusal names BOTH doors rather than only the one it
|
|
used to name."""
|
|
rc = run.main(["K2", "--live-dry-run"])
|
|
|
|
assert rc == 1
|
|
err = capsys.readouterr().err
|
|
assert "run refused" in err and "--docs-dir" in err and "--bundle-dir" in err
|
|
|
|
|
|
def test_the_reference_path_still_requires_a_real_docs_dir(
|
|
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
"""(d) The anti-omvei arm. With no bundle, ``--docs-dir`` is still the only door AND it is
|
|
still read: a directory holding nothing citable is refused by the reference branch's own check, so
|
|
nothing here turns retrieval into a substitute for ingestion."""
|
|
empty = tmp_path / "tomt"
|
|
empty.mkdir()
|
|
rc = run.main(["P1", "--docs-dir", str(empty), "--live-dry-run"])
|
|
|
|
assert rc == 1
|
|
assert capsys.readouterr().err.strip(), "the reference path must say why, not fail silently"
|
|
|
|
|
|
def test_the_bundle_value_is_bound_once_and_reaches_run_project(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""(e) The SEAM. rc 0 above would also be satisfied by a CLI that never forwarded the value, so
|
|
the argument ``run_project`` actually receives is recorded — one binding, both dispatch sites."""
|
|
base = _runnable(tmp_path)
|
|
seen: dict[str, Any] = {}
|
|
|
|
async def _record(project_id: str, profile: Any, **kw: Any) -> Any:
|
|
seen.update(kw)
|
|
raise SystemExit(0)
|
|
|
|
monkeypatch.setattr("portfolio_optimiser.run.run_project", _record)
|
|
with pytest.raises(SystemExit):
|
|
run.main(["K2", "--bundle-dir", base, "--live-dry-run"])
|
|
|
|
assert seen["docs_dir"] == base == seen["bundle_dir"]
|