Files
mckero 2667e046e8 Emulator: multiboot slots from the page, flash controller, portable tests
flash controller: store ACR/OPTKEYR instead of swallowing them, which is what stopped the factory bootloader from starting

slots over the firmware's own serial protocol (0x0720 family); uvk5_socket/uvk5_testenv so a fresh checkout skips instead of failing; web UI slot table and Multiboot button; quick start, CONTRIBUTING, and stop tracking firmware images and radio dumps
2026-10-01 14:54:34 +08:00

56 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Unit tests for key-name validation."""
import os
import re
import unittest
from uvk5_keys import KEYS, is_valid, normalise
class TestKeys(unittest.TestCase):
def test_matches_the_model_key_list(self):
# keypad_key_names in qemu/py32f071.c
self.assertEqual(set(KEYS), {
"MENU", "UP", "DOWN", "EXIT", "F", "STAR",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"SIDE1", "SIDE2",
})
def test_stays_in_sync_with_the_machine_model(self):
"""Read the real list out of py32f071.c so the two cannot drift.
If someone adds a key to the model, this fails until KEYS is updated --
which beats discovering it as a QMP error at runtime.
"""
src = os.path.join(os.path.dirname(os.path.abspath(__file__)),
os.pardir, "qemu", "py32f071.c")
# Explicit UTF-8: the default is the locale codec, and on Windows that is
# GBK, which cannot decode this file once it contains any non-ASCII byte.
text = open(src, encoding="utf-8").read()
block = re.search(
r"keypad_key_names\[[^\]]*\]\s*=\s*\{(.*?)\};", text, re.S)
self.assertIsNotNone(block, "could not find keypad_key_names in the model")
names = set(re.findall(r'"([^"]+)"', block.group(1)))
self.assertEqual(names, set(KEYS))
def test_ptt_is_not_offered_as_a_key(self):
# PTT works, but not through the key table: the firmware reads its own pin, so
# it is a separate boolean property. Setting "press" to PTT would error.
self.assertFalse(is_valid("PTT"))
def test_normalise_is_case_insensitive_and_strips(self):
self.assertEqual(normalise("menu"), "MENU")
self.assertEqual(normalise(" up "), "UP")
self.assertTrue(is_valid("menu"))
def test_rejects_unknown(self):
self.assertFalse(is_valid("BANANA"))
def test_rejects_empty_and_none(self):
self.assertFalse(is_valid(""))
self.assertFalse(is_valid(None))
if __name__ == "__main__":
unittest.main()