Every output is a target and every input besides prompt a reading. A targets setting gives descriptions, values, ranges and per-target guards, model takes a trained pack's artifact digest, min_confidence defaults to the model's threshold. A command is applied whole or not at all, and targets the model was not trained on read degraded. The home path (area/kind ports, groups, brightness, temperature answers) is gone.
71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
from collections.abc import Generator
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def db() -> Generator[None, None, None]:
|
|
"""The engine holds no database state, so these tests need no database."""
|
|
yield
|
|
|
|
|
|
@dataclass
|
|
class FakeTarget:
|
|
name: str
|
|
type: str
|
|
value: Any
|
|
values: list[str] | None = None
|
|
range: list[float] | None = None
|
|
description: str = ""
|
|
unit: str | None = None
|
|
readonly: bool = False
|
|
|
|
|
|
@dataclass
|
|
class FakeCall:
|
|
target: str
|
|
value: Any = None
|
|
delay_s: float | None = None
|
|
confidence: float = 1.0
|
|
|
|
|
|
class FakeWren:
|
|
"""The model package's surface: ``act`` answers whatever a test sets
|
|
``answer`` to, and ``load_pack`` returns ``pack``."""
|
|
|
|
Target = FakeTarget
|
|
Call = FakeCall
|
|
runtime = SimpleNamespace(MODEL=Path("demo.bin"))
|
|
|
|
def __init__(self) -> None:
|
|
self.answer: list[FakeCall] = []
|
|
self.pack: dict[str, Any] = {"meta": {"threshold": 0.9, "targets": []}}
|
|
self.loaded: list[Path] = []
|
|
self.commands: list[str] = []
|
|
self.targets: list[list[FakeTarget]] = []
|
|
self.models: list[Any] = []
|
|
|
|
def load_pack(self, path: Path) -> dict[str, Any]:
|
|
self.loaded.append(path)
|
|
return self.pack
|
|
|
|
def act(
|
|
self, command: str, targets: list[FakeTarget], *, model: Any = None
|
|
) -> list[FakeCall]:
|
|
self.commands.append(command)
|
|
self.targets.append(targets)
|
|
self.models.append(model)
|
|
return self.answer
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_wren(monkeypatch: pytest.MonkeyPatch) -> FakeWren:
|
|
"""Stands in for the optional model package the wren node imports."""
|
|
fake = FakeWren()
|
|
monkeypatch.setattr("fluksio.flow.nodes.wren._wren", lambda: fake)
|
|
return fake
|