71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Test plumbing: import path + notebook content served from tagged cells.
|
|
|
|
Content and client data live in the notebook, never in ``.py`` — the cells
|
|
tagged ``topic-bank`` (the feature catalogue) and ``engagement-data`` (the
|
|
client's volumes and commercial terms) in
|
|
``notebooks/genesys_token_calculator.ipynb``. The fixtures below read those
|
|
cells with nbformat and exec them, so pytest pins the exact content the
|
|
deliverable ships (no kernel needed — tagged cells are self-contained by
|
|
contract).
|
|
|
|
The published Genesys rate card is deliberately NOT here: it is a vendor
|
|
record nobody in this repo authors, so it lives in ``genesyscalc/ratecard.py``
|
|
as an immutable anchor and is pinned by ``test_rate_card.py`` (see
|
|
docs/Calculator_Pattern_V1-00.md).
|
|
|
|
The sys.path insert makes genesyscalc importable even without the master
|
|
venv active (the normal setup is ``pip install -e ".[dev]"`` into the
|
|
master-local ``.venv/``).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import sys
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
MASTER_ROOT = pathlib.Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(MASTER_ROOT))
|
|
|
|
NOTEBOOK = MASTER_ROOT / "notebooks" / "genesys_token_calculator.ipynb"
|
|
|
|
|
|
def tagged_cell_ns(tag: str) -> dict[str, Any]:
|
|
"""Exec the single cell carrying ``tag`` and return its namespace."""
|
|
import nbformat
|
|
|
|
nb = nbformat.read(NOTEBOOK, as_version=4)
|
|
cells = [c for c in nb.cells if tag in c.metadata.get("tags", [])]
|
|
assert len(cells) == 1, (
|
|
f"expected exactly one cell tagged {tag!r} in {NOTEBOOK.name}, "
|
|
f"found {len(cells)}"
|
|
)
|
|
ns: dict[str, Any] = {}
|
|
exec(compile(cells[0].source, f"{NOTEBOOK.name} [{tag}]", "exec"), ns)
|
|
return ns
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def catalogue_ns() -> dict[str, Any]:
|
|
"""The executed namespace of the notebook's topic-bank cell."""
|
|
return tagged_cell_ns("topic-bank")
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def features(catalogue_ns: dict[str, Any]) -> tuple[Any, ...]:
|
|
"""The FEATURES tuple as the deliverable defines it."""
|
|
return catalogue_ns["FEATURES"] # type: ignore[no-any-return]
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def feature_by_key(features: tuple[Any, ...]) -> dict[str, Any]:
|
|
return {f.key: f for f in features}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def engagement() -> dict[str, Any]:
|
|
"""The ENGAGEMENT dict as the deliverable's engagement-data cell ships it."""
|
|
return tagged_cell_ns("engagement-data")["ENGAGEMENT"] # type: ignore[no-any-return]
|