Rework radar system
This commit is contained in:
@@ -1,60 +1,33 @@
|
||||
"""Guard tests keeping the live-settings schema and the config builder in lock-step.
|
||||
"""Every native live setting has one declaration or an explicit runtime source."""
|
||||
|
||||
`_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
|
||||
from dataclasses import fields
|
||||
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_apply_field_names,
|
||||
)
|
||||
from python_app.models.setting_fields import GUI_FIELDS, active_live_fields, active_web_fields
|
||||
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_fields_are_not_live_config(self) -> None:
|
||||
extra = {f for f, *_ in _WEB_DISPLAY_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}
|
||||
)
|
||||
# The web may apply every form field plus the history command, and nothing else.
|
||||
self.assertEqual(web_apply_field_names(), form_fields | {"history_command"})
|
||||
def test_bindings_cover_live_config_and_select_each_page_once(self) -> None:
|
||||
config_names = {field.name for field in fields(ProcessingLiveConfig)}
|
||||
runtime = {"reprocess_current_result", "history_clear_before_ns", "history_removed", "settings_revision"}
|
||||
geometry = {"relative_permittivity", "tx_geometry", "rx_geometry"}
|
||||
modes = next(binding.spec.choices for binding in GUI_FIELDS if binding.spec.live == "processor_mode")
|
||||
widget_names = [binding.spec.widget for binding in GUI_FIELDS if binding.spec.widget]
|
||||
self.assertEqual(len(widget_names), len(set(widget_names)))
|
||||
for mode in modes:
|
||||
with self.subTest(mode=mode):
|
||||
live = active_live_fields(mode)
|
||||
live_names = {binding.spec.live for binding in live}
|
||||
self.assertEqual(len(live), len(live_names))
|
||||
self.assertEqual(live_names | geometry | runtime, config_names)
|
||||
self.assertFalse(live_names & (geometry | runtime))
|
||||
web = active_web_fields(mode)
|
||||
web_names = {binding.spec.web for binding in web}
|
||||
self.assertEqual(len(web), len(web_names))
|
||||
self.assertIn("processor_mode", web_names)
|
||||
self.assertTrue(all(binding.mode in (None, mode) for binding in web))
|
||||
self.assertFalse({binding.spec.web for binding in web if not binding.spec.live} & config_names)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user