66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
"""Guard tests keeping the live-settings schema and the config builder in lock-step.
|
|
|
|
`_live_processing_config` builds ProcessingLiveConfig by reading every widget through
|
|
`_WEB_LIVE_SCHEMA` (the same map the embedded web form renders from), plus a small set
|
|
of fields set explicitly (`_NON_WIDGET_LIVE_FIELDS`). These tests fail the moment a new
|
|
config field is added without being placed in one of those two sets — which is exactly
|
|
the drift that previously hid GPR settings from the web form.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import dataclasses as dc
|
|
import unittest
|
|
|
|
from python_app.gui.controllers.app_window_config.live_processing_mixin import (
|
|
_NON_WIDGET_LIVE_FIELDS,
|
|
_WEB_DISPLAY_SCHEMA,
|
|
_WEB_LIVE_GETTERS,
|
|
_WEB_STABLE_SCHEMA,
|
|
web_apply_field_names,
|
|
)
|
|
from python_app.orchestration.live_processing_config import ProcessingLiveConfig
|
|
|
|
|
|
class LiveSettingsSchemaCoverageTest(unittest.TestCase):
|
|
@staticmethod
|
|
def _config_fields() -> set[str]:
|
|
return {field.name for field in dc.fields(ProcessingLiveConfig)}
|
|
|
|
def test_schema_plus_non_widget_covers_every_config_field(self) -> None:
|
|
schema_fields = set(_WEB_LIVE_GETTERS)
|
|
covered = schema_fields | _NON_WIDGET_LIVE_FIELDS
|
|
config_fields = self._config_fields()
|
|
self.assertEqual(
|
|
covered,
|
|
config_fields,
|
|
msg=(
|
|
f"uncovered config fields: {sorted(config_fields - covered)}; "
|
|
f"stray names: {sorted(covered - config_fields)}"
|
|
),
|
|
)
|
|
|
|
def test_widget_and_non_widget_sets_are_disjoint(self) -> None:
|
|
# A field is either widget-backed (in the schema) or explicitly non-widget — never both.
|
|
self.assertEqual(set(_WEB_LIVE_GETTERS) & _NON_WIDGET_LIVE_FIELDS, set())
|
|
|
|
def test_display_and_stable_fields_are_not_live_config(self) -> None:
|
|
# Display toggles (GUI profile) and stable fields (run_config) must never collide
|
|
# with live ProcessingLiveConfig fields — they take different write paths.
|
|
extra = {f for f, *_ in _WEB_DISPLAY_SCHEMA} | {f for f, *_ in _WEB_STABLE_SCHEMA}
|
|
self.assertEqual(extra & self._config_fields(), set())
|
|
self.assertEqual(extra & set(_WEB_LIVE_GETTERS), set())
|
|
|
|
def test_web_apply_names_cover_the_whole_form(self) -> None:
|
|
form_fields = (
|
|
set(_WEB_LIVE_GETTERS)
|
|
| {f for f, *_ in _WEB_DISPLAY_SCHEMA}
|
|
| {f for f, *_ in _WEB_STABLE_SCHEMA}
|
|
)
|
|
# The web may apply every form field plus the history command, and nothing else.
|
|
self.assertEqual(web_apply_field_names(), form_fields | {"history_command"})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|