feat: introduce device plugin runtime boundary
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def test_mission_core_frontend_has_single_plugin_composition_root() -> None:
|
||||
repository_root = Path(__file__).resolve().parents[1]
|
||||
source_root = repository_root / "apps" / "control-station" / "src"
|
||||
composition = source_root / "composition" / "devicePlugins.ts"
|
||||
forbidden_import = "device-plugins/xgrids-k1"
|
||||
|
||||
imports = [
|
||||
path.relative_to(source_root).as_posix()
|
||||
for path in source_root.rglob("*.ts*")
|
||||
if forbidden_import in path.read_text("utf-8")
|
||||
]
|
||||
|
||||
assert imports == [composition.relative_to(source_root).as_posix()]
|
||||
|
||||
|
||||
def test_mission_core_shell_does_not_know_xgrids_wire_fields() -> None:
|
||||
repository_root = Path(__file__).resolve().parents[1]
|
||||
source_root = repository_root / "apps" / "control-station" / "src"
|
||||
core_paths = [
|
||||
source_root / "App.tsx",
|
||||
source_root / "presentation.ts",
|
||||
source_root / "productModel.ts",
|
||||
source_root / "components",
|
||||
source_root / "core",
|
||||
source_root / "workspaces",
|
||||
]
|
||||
forbidden_tokens = ("k1_ip", "likely_k1", "useK1Console", "rerun_grpc_url")
|
||||
|
||||
checked_files: list[Path] = []
|
||||
for path in core_paths:
|
||||
if path.is_dir():
|
||||
checked_files.extend(path.rglob("*.ts*"))
|
||||
else:
|
||||
checked_files.append(path)
|
||||
|
||||
violations = {
|
||||
path.relative_to(source_root).as_posix(): token
|
||||
for path in checked_files
|
||||
for token in forbidden_tokens
|
||||
if token in path.read_text("utf-8")
|
||||
}
|
||||
|
||||
assert violations == {}
|
||||
|
||||
|
||||
def test_xgrids_client_uses_manifest_identity_and_plugin_scoped_events() -> None:
|
||||
repository_root = Path(__file__).resolve().parents[1]
|
||||
plugin_root = (
|
||||
repository_root / "apps" / "control-station" / "src" / "device-plugins" / "xgrids-k1"
|
||||
)
|
||||
api_source = (plugin_root / "api.ts").read_text("utf-8")
|
||||
manifest_source = (plugin_root / "manifest.ts").read_text("utf-8")
|
||||
|
||||
assert "nodedc.device.xgrids-lixelkity-k1" not in api_source
|
||||
assert 'new URL("/api/events"' not in api_source
|
||||
assert "/api/v1/device-plugins/" in api_source
|
||||
assert "parseDevicePluginManifest" in manifest_source
|
||||
|
||||
|
||||
def test_backend_host_has_no_concrete_xgrids_imports() -> None:
|
||||
repository_root = Path(__file__).resolve().parents[1]
|
||||
app_source = (repository_root / "src" / "k1link" / "web" / "app.py").read_text("utf-8")
|
||||
|
||||
assert "xgrids" not in app_source.lower()
|
||||
assert "k1_ip" not in app_source
|
||||
assert "Bleak" not in app_source
|
||||
|
||||
|
||||
def test_model_switch_is_guarded_by_plugin_deactivation() -> None:
|
||||
repository_root = Path(__file__).resolve().parents[1]
|
||||
frontend_root = repository_root / "apps" / "control-station" / "src"
|
||||
host_source = (frontend_root / "core" / "device-plugins" / "DevicePluginHost.tsx").read_text(
|
||||
"utf-8"
|
||||
)
|
||||
xgrids_runtime = (
|
||||
frontend_root / "device-plugins" / "xgrids-k1" / "runtimeContext.tsx"
|
||||
).read_text("utf-8")
|
||||
|
||||
deactivation_guard = "if (!(await deactivate()))"
|
||||
assert "if (current && !deactivate)" in host_source
|
||||
assert deactivation_guard in host_source
|
||||
assert host_source.index(deactivation_guard) < host_source.index(
|
||||
"setSelectedModelId(nextModelId)"
|
||||
)
|
||||
assert "catch" in host_source
|
||||
assert "selectionTransitionError" in host_source
|
||||
assert "return controller.stop();" in xgrids_runtime
|
||||
Reference in New Issue
Block a user