[uart] Keep debug delimiters and event patterns in flash (#20109)

This commit is contained in:
J. Nick Koston authored and GitHub committed 2026-10-26 12:05:06 -04:00
1 parent 5cceddfbf4
commit 9ea4d35a50
8 files changed
+160 -49

No files matched your search

@@ -0,0 +1,34 @@
esphome:
name: test
esp8266:
board: esp01_1m
uart:
- id: uart_a
tx_pin: GPIO1
rx_pin: GPIO3
baud_rate: 9600
debug:
after:
delimiter: "\r\n"
- id: uart_b
tx_pin: GPIO2
baud_rate: 9600
debug:
after:
delimiter: [0x0D, 0x0A]
event:
- platform: uart
uart_id: uart_a
name: Event A
event_types:
- "start": "*A#"
- "stop": [0x2A, 0x42, 0x23]
- platform: uart
uart_id: uart_a
name: Event B
event_types:
- "start": "*A#"
- "stop": [0x2A, 0x42, 0x23]
@@ -0,0 +1,41 @@
"""uart debug delimiters and uart event patterns live in shared PROGMEM tables."""
from collections.abc import Callable
from pathlib import Path
import re
import pytest
from esphome.components.uart.event import validate_event_types
import esphome.config_validation as cv
def test_debug_delimiter_and_event_matchers_use_shared_tables(
generate_main: Callable[[str | Path], str],
component_config_path: Callable[[str], Path],
) -> None:
main_cpp = generate_main(component_config_path("debug_event_tables.yaml"))
# "\r\n" and [0x0D, 0x0A] are the same bytes, so both debuggers share one table
delimiters = re.findall(r"->set_after_delimiter\((\w+), 2\);", main_cpp)
assert len(delimiters) == 2
assert delimiters[0] == delimiters[1]
assert "add_delimiter_byte" not in main_cpp
# Both events have the same patterns, so they share the byte tables and the matcher table
patterns = re.findall(r"static constexpr uint8_t uart_event_match\w*\[\]", main_cpp)
assert len(patterns) == 2
calls = re.findall(r"->set_matchers\((\w+), 2, 3\);", main_cpp)
assert len(calls) == 2
assert calls[0] == calls[1]
assert main_cpp.count("static constexpr uart::UARTEventMatcher") == 1
assert "add_event_matcher" not in main_cpp
def test_event_string_patterns_are_utf8_bytes() -> None:
assert validate_event_types([{"euro": "€"}]) == [("euro", [0xE2, 0x82, 0xAC])]
def test_event_types_count_is_capped() -> None:
with pytest.raises(cv.Invalid, match="at most 65535 entries"):
validate_event_types([{f"e{i}": "x"} for i in range(0x10000)])