mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 23:43:44 +08:00
91 lines
4.3 KiB
Python
91 lines
4.3 KiB
Python
import json
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from unittest.mock import patch
|
|
|
|
from openpilot.starpilot.ui import onroad_customization as layout
|
|
from openpilot.starpilot.favorites import layout_actions as favorites
|
|
|
|
|
|
class TestRenderDocumentReuse(unittest.TestCase):
|
|
def setUp(self):
|
|
self.document = layout.default_document()
|
|
self.raw = json.dumps(self.document, separators=(',', ':')).encode()
|
|
|
|
def test_repeated_decode_keeps_independent_nested_values(self):
|
|
first = layout.decode_document(self.raw)
|
|
first['layouts']['compact']['torque_bar']['enabled'] = False
|
|
second = layout.decode_document(self.raw)
|
|
self.assertTrue(second['layouts']['compact']['torque_bar']['enabled'])
|
|
self.assertIsNot(first, second)
|
|
|
|
def test_unchanged_valid_bytes_are_validated_once(self):
|
|
raw = self.raw + b' '
|
|
with patch.object(layout, 'validate_document', wraps=layout.validate_document) as validate:
|
|
self.assertEqual(layout.decode_document(raw), layout.decode_document(raw))
|
|
self.assertEqual(validate.call_count, 1)
|
|
|
|
def test_changed_bytes_are_validated_and_applied(self):
|
|
layout.decode_document(self.raw)
|
|
self.document['layouts']['compact']['torque_bar']['enabled'] = False
|
|
changed = json.dumps(self.document).encode()
|
|
self.assertFalse(layout.decode_document(changed)['layouts']['compact']['torque_bar']['enabled'])
|
|
self.assertTrue(layout.decode_document(self.raw)['layouts']['compact']['torque_bar']['enabled'])
|
|
|
|
def test_large_direct_inputs_do_not_expand_the_cache(self):
|
|
raw = self.raw + b' ' * layout.MAX_BYTES
|
|
with patch.object(layout, 'validate_document', wraps=layout.validate_document) as validate:
|
|
self.assertEqual(layout.decode_document(raw), layout.decode_document(raw))
|
|
self.assertEqual(validate.call_count, 2)
|
|
|
|
def test_invalid_and_duplicate_fields_still_fail(self):
|
|
for raw in (b'bad-json', b'{}', b'{"version":14,"version":14}', b'[]'):
|
|
with self.subTest(raw=raw), self.assertRaises((ValueError, TypeError)):
|
|
layout.decode_document(raw)
|
|
|
|
def test_bytearray_keeps_original_supported_input(self):
|
|
self.assertEqual(layout.decode_document(bytearray(self.raw)), layout.decode_document(self.raw))
|
|
|
|
def test_selected_actions_keep_states_tokens_and_refusals(self):
|
|
with tempfile.TemporaryDirectory() as root:
|
|
path = Path(root) / layout.PARAM_KEY
|
|
path.write_bytes(self.raw)
|
|
params = SimpleNamespace(get_param_path=lambda key: str(Path(root) / key))
|
|
allowed = [True]
|
|
for profile in ('large', 'compact'):
|
|
all_actions = favorites.layout_actions(params, profile, lambda: allowed[0])
|
|
for key in favorites.TOGGLES:
|
|
with self.subTest(profile=profile, key=key):
|
|
selected = favorites.layout_actions(params, profile, lambda: allowed[0], requested_keys={key})
|
|
self.assertEqual(set(selected), {key})
|
|
self.assertEqual(selected[key], all_actions[key])
|
|
allowed[0] = False
|
|
if selected[key].invoke is not None:
|
|
self.assertFalse(selected[key].invoke())
|
|
allowed[0] = True
|
|
saved = favorites.layout_actions(params, profile, lambda: True, requested_keys={'EnableTorqueBarWidget'})
|
|
path.write_bytes(self.raw + b' ')
|
|
self.assertFalse(saved['EnableTorqueBarWidget'].invoke())
|
|
path.write_bytes(self.raw)
|
|
|
|
def test_unrequested_layout_actions_do_not_read_saved_layout(self):
|
|
with patch.object(favorites, 'read_saved', side_effect=AssertionError('No layout actions requested')):
|
|
self.assertEqual(favorites.layout_actions(None, 'compact', lambda: True, requested_keys={'Bookmark'}), {})
|
|
self.assertEqual(favorites.layout_actions(None, 'compact', lambda: True, requested_keys=set()), {})
|
|
|
|
def test_invalid_layout_remains_unavailable(self):
|
|
with tempfile.TemporaryDirectory() as root:
|
|
path = Path(root) / layout.PARAM_KEY
|
|
path.write_bytes(b'bad-json')
|
|
params = SimpleNamespace(get_param_path=lambda key: str(Path(root) / key))
|
|
action = favorites.layout_actions(params, 'compact', lambda: True,
|
|
requested_keys={'EnableTorqueBarWidget'})['EnableTorqueBarWidget']
|
|
self.assertFalse(action.available)
|
|
self.assertIsNone(action.invoke)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|