dynamisk-rettsstat/tests/conftest.py
Kjell Tore Guttormsen 776325c680
fix: findings from the independent review
Scenario runner: stops when overridden base parameters leave the start out
of balance (new field startlikevekt: krev, kalibrer, ubalanse); stops on
non-finite results; says that models with a court queue drift slowly even
without a shock and prints the drift before the shock; queue in months of
inflow; never deletes files it did not write; stricter limits.
Check: anchored on the note's own checksums for core and reference files,
runs the scenario files too, exact comparison for the diagnosis, honest
wording when parts were skipped or an extension is broken.
Launcher: unknown field names in input are rejected with a suggestion;
unwritable folders give a message, not a traceback.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 15:27:14 +01:00

80 lines
2.5 KiB
Python

# Copyright (c) 2026 Kjell Tore Guttormsen. MIT License, see LICENSE.
"""Felles hjelpere for testene: stier, kjøring av kjor.py og en kopi av pluginens modell."""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
from pathlib import Path
import pytest
ROT = Path(__file__).resolve().parent.parent
MODELL = ROT / "modell"
KJOR = MODELL / "kjor.py"
FASIT = ROT / "fasit"
EKSEMPLER = ROT / "eksempler"
DOMSTOL = EKSEMPLER / "eksempel_domstol.json"
NORGE = EKSEMPLER / "norge_2025.json"
def kjor(
*args: str,
python: list[str] | None = None,
hjem: Path | None = None,
cwd: Path | None = None,
) -> subprocess.CompletedProcess[str]:
"""Kjør kjor.py som brukeren gjør, og fang utskrift og exit-kode.
python: tolken (med valg), standard er den som kjører testene (har numpy og scipy).
hjem: HOME for prosessen, slik at standardmappa ~/.dynamisk-rettsstat aldri er brukerens egen.
"""
miljo = dict(os.environ, PYTHONIOENCODING="utf-8", PYTHONDONTWRITEBYTECODE="1")
miljo.pop("DYNAMISK_RETTSSTAT_VENV", None)
if hjem is not None:
miljo["HOME"] = str(hjem)
return subprocess.run(
[*(python or [sys.executable]), str(KJOR), *args],
capture_output=True, text=True, encoding="utf-8", env=miljo, cwd=str(cwd or ROT), check=False,
)
def fasit(navn: str) -> str:
"""Innholdet i en fasitfil."""
return (FASIT / navn).read_text(encoding="utf-8")
def lag_venv_omvei(data: Path, *python: str) -> Path:
"""Lag en «egen mappe» i data/venv der bin/python er et lite skript som starter en gitt Python.
Testene installerer ingenting: omveien peker på en Python som allerede finnes.
"""
bin_mappe = data / "venv" / "bin"
bin_mappe.mkdir(parents=True)
tolk = bin_mappe / "python"
kommando = " ".join(f'"{p}"' for p in python)
tolk.write_text(f'#!/bin/sh\nexec {kommando} "$@"\n', encoding="utf-8")
tolk.chmod(0o755)
return tolk
@pytest.fixture
def hjem(tmp_path: Path) -> Path:
"""En tom hjemmemappe for prosessen."""
mappe = tmp_path / "hjem"
mappe.mkdir()
return mappe
@pytest.fixture
def kopi(tmp_path: Path) -> Path:
"""En kopi av modell/, fasit/ og eksempler/ som testen kan endre. Returnerer kopiens rot.
Kopien er ikke merket som arbeidskopi (ingen LES-MEG.md), som en klone av repoet.
"""
rot = tmp_path / "kopi"
for navn in ("modell", "fasit", "eksempler"):
shutil.copytree(ROT / navn, rot / navn, ignore=shutil.ignore_patterns("__pycache__"))
return rot