scenario.py runs all five simulators of the core from a JSON scenario file, with sweeps, and reproduces 20 of the note's data files (14 byte for byte, 6 column-wise). Extensions live outside the core and must reproduce it exactly in a limit case; paadrag_tidsserie is the worked example. arbeidskopi.py gives the user a copy of the model they can change. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
102 lines
4.4 KiB
Python
102 lines
4.4 KiB
Python
# Copyright (c) 2026 Kjell Tore Guttormsen. MIT License, see LICENSE.
|
|
"""arbeidskopi.py: kopien lages, nekter en mappe som ikke er tom, og kan kjøres med --modell."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
import pytest
|
|
from conftest import EKSEMPLER, FASIT, ROT, kjor
|
|
|
|
if TYPE_CHECKING:
|
|
from pathlib import Path
|
|
|
|
KJEDE_S2 = EKSEMPLER / "scenarioer" / "notatet" / "kjede_s2.json"
|
|
|
|
|
|
@pytest.fixture
|
|
def arbeidskopi(tmp_path: Path) -> Path:
|
|
"""En arbeidskopi laget med kjor.py arbeidskopi."""
|
|
mal = tmp_path / "rettsstat-modell"
|
|
prosess = kjor("arbeidskopi", str(mal))
|
|
assert prosess.returncode == 0, prosess.stderr
|
|
assert f"Arbeidskopien er laget i {mal}" in prosess.stdout
|
|
return mal
|
|
|
|
|
|
def test_kopien_har_mappene_og_les_meg(arbeidskopi: Path) -> None:
|
|
for navn in ("modell", "eksempler", "fasit", "tests"):
|
|
assert (arbeidskopi / navn).is_dir(), navn
|
|
for navn in ("modell/kjor.py", "modell/scenario.py", "modell/kjerne/sim.py", "modell/kjerne/KILDE.json",
|
|
"modell/utvidelser/paadrag_tidsserie.py", "fasit/data/p3.dat",
|
|
"eksempler/scenarioer/notatet/p3.json"):
|
|
assert (arbeidskopi / navn).is_file(), navn
|
|
for navn in ("modell/kjerne/sim.py", "fasit/data/endo_ko.dat"):
|
|
assert (arbeidskopi / navn).read_bytes() == (ROT / navn).read_bytes()
|
|
if (ROT / "docs").is_dir():
|
|
assert sorted(p.name for p in (arbeidskopi / "docs").iterdir()) == \
|
|
sorted(p.name for p in (ROT / "docs").iterdir() if p.is_file())
|
|
les_meg = (arbeidskopi / "LES-MEG.md").read_text(encoding="utf-8")
|
|
for tekst in ("Alt i mappa kan endres, også kjernen", f"python3 {arbeidskopi / 'modell' / 'kjor.py'} scenario",
|
|
"kontroll", "«bit for bit som notatet»", "«endret: ...»", "docs/", "BIDRA.md"):
|
|
assert tekst in les_meg, tekst
|
|
|
|
|
|
def test_kopien_har_ikke_mellomlagre_eller_resultater(arbeidskopi: Path) -> None:
|
|
uonsket = {".venv", "venv", "__pycache__", ".pytest_cache", ".mypy_cache", ".ruff_cache", "resultater"}
|
|
funnet = [p for p in arbeidskopi.rglob("*") if p.name in uonsket or p.suffix == ".pyc"]
|
|
assert funnet == []
|
|
|
|
|
|
def test_nekter_mappe_som_ikke_er_tom(tmp_path: Path) -> None:
|
|
mal = tmp_path / "opptatt"
|
|
mal.mkdir()
|
|
(mal / "notat.txt").write_text("mitt", encoding="utf-8")
|
|
prosess = kjor("arbeidskopi", str(mal))
|
|
assert prosess.returncode == 2
|
|
assert "finnes og er ikke tom" in prosess.stderr
|
|
assert sorted(p.name for p in mal.iterdir()) == ["notat.txt"]
|
|
|
|
|
|
def test_tom_mappe_er_greit(tmp_path: Path) -> None:
|
|
mal = tmp_path / "tom"
|
|
mal.mkdir()
|
|
assert kjor("arbeidskopi", str(mal)).returncode == 0
|
|
assert (mal / "LES-MEG.md").is_file()
|
|
|
|
|
|
@pytest.mark.parametrize("args", [[], ["a", "b"]])
|
|
def test_feil_bruk(args: list[str]) -> None:
|
|
prosess = kjor("arbeidskopi", *args)
|
|
assert prosess.returncode == 2
|
|
assert "arbeidskopi <mappe>" in prosess.stderr
|
|
|
|
|
|
def test_nekter_mappe_inne_i_det_som_kopieres(tmp_path: Path, arbeidskopi: Path) -> None:
|
|
mal = arbeidskopi / "eksempler" / "ny"
|
|
prosess = kjor("--modell", str(arbeidskopi), "arbeidskopi", str(mal))
|
|
assert prosess.returncode == 2, prosess.stdout
|
|
assert "ligger inne i" in prosess.stderr
|
|
assert not mal.exists()
|
|
assert not (tmp_path / "ny").exists()
|
|
|
|
|
|
def test_scenario_kjorer_fra_kopien_med_modell(arbeidskopi: Path, tmp_path: Path) -> None:
|
|
ut = tmp_path / "ut"
|
|
prosess = kjor("--modell", str(arbeidskopi), "scenario", str(KJEDE_S2), "--ut", str(ut))
|
|
assert prosess.returncode == 0, prosess.stderr
|
|
assert (ut / "kjede_s2.dat").read_bytes() == (FASIT / "data" / "kjede_s2.dat").read_bytes()
|
|
|
|
|
|
def test_endring_i_kopiens_kjerne_brukes(arbeidskopi: Path, tmp_path: Path) -> None:
|
|
sim = arbeidskopi / "modell" / "kjerne" / "sim.py"
|
|
tekst = sim.read_text(encoding="utf-8")
|
|
assert "shock=1.30," in tekst
|
|
sim.write_text(tekst.replace("shock=1.30,", "shock=1.40,", 1), encoding="utf-8")
|
|
ut = tmp_path / "ut"
|
|
prosess = kjor("--modell", str(arbeidskopi), "scenario", str(KJEDE_S2), "--ut", str(ut))
|
|
assert prosess.returncode == 0, prosess.stderr
|
|
assert (ut / "kjede_s2.dat").read_bytes() != (FASIT / "data" / "kjede_s2.dat").read_bytes()
|
|
plugin = kjor("scenario", str(KJEDE_S2), "--ut", str(tmp_path / "plugin"))
|
|
assert plugin.returncode == 0, plugin.stderr
|
|
assert (tmp_path / "plugin" / "kjede_s2.dat").read_bytes() == (FASIT / "data" / "kjede_s2.dat").read_bytes()
|