48 lines
2.0 KiB
Python
48 lines
2.0 KiB
Python
"""Portable source selection and independently maintained workbook expectations.
|
|
|
|
Ordinary tests may omit external input. Setting ROUND87_REQUIRED=1 makes input
|
|
mandatory; a configured but missing/changed file always fails. CLI tools pass
|
|
required=True and never fall back to another workbook.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
DEFAULT_EXPECTATIONS = Path(__file__).resolve().parent / "fixtures" / "planning-workbook-acceptance.json"
|
|
|
|
|
|
def load_expectations(path: str | Path | None = None) -> dict:
|
|
selected = Path(path or os.environ.get("ROUND87_EXPECTATIONS") or DEFAULT_EXPECTATIONS)
|
|
data = json.loads(selected.read_text(encoding="utf-8"))
|
|
if data.get("schemaVersion") != 1 or not isinstance(data.get("sourceSha256"), str):
|
|
raise ValueError("Invalid workbook acceptance manifest")
|
|
return data
|
|
|
|
|
|
def resolve_source(source: str | Path | None = None, *, required: bool | None = None,
|
|
expectations: dict | None = None) -> Path | None:
|
|
selected = source or os.environ.get("ROUND87_SOURCE")
|
|
required = required if required is not None else os.environ.get("ROUND87_REQUIRED") == "1"
|
|
if not selected:
|
|
if required:
|
|
raise ValueError("Set ROUND87_SOURCE or pass --source for the designated workbook")
|
|
return None
|
|
path = Path(selected).expanduser().resolve(strict=True)
|
|
if not path.is_file():
|
|
raise ValueError("Workbook source must be a file")
|
|
expected = expectations if expectations is not None else load_expectations()
|
|
if hashlib.sha256(path.read_bytes()).hexdigest() != expected["sourceSha256"]:
|
|
raise ValueError("The designated workbook does not match the independently reviewed SHA-256")
|
|
return path
|
|
|
|
|
|
def source_for_test() -> Path:
|
|
source = resolve_source()
|
|
if source is None:
|
|
import pytest
|
|
pytest.skip("External workbook not configured; set ROUND87_SOURCE (ROUND87_REQUIRED=1 for acceptance)")
|
|
return source
|