[core] Expose IIFE_MAX_STATEMENTS constant and derive test sizes from it

Tests were hardcoding 120 statements and expecting 3 sub-chunks from a 50-cap. Extract the cap as a named module constant and compute the test-input size from it, so bumping the cap doesn't silently invalidate the tests.
This commit is contained in:
J. Nick Koston
2026-04-17 18:50:41 -05:00
parent bb0067f517
commit 3ab935bebb
2 changed files with 26 additions and 13 deletions
+9 -1
View File
@@ -531,6 +531,14 @@ class Library:
return self
# Cap on the number of statements in a single IIFE chunk when a
# component's to_code body is sub-split. Picks a frame-size sweet spot
# on esp32-s3 — large enough that most components fit in one chunk and
# small enough that heavy sensor platforms (many filter registrations)
# don't produce a chunk with a very large spill frame.
IIFE_MAX_STATEMENTS = 50
def _emits_bare_local(exp: "Statement") -> bool:
"""True if ``exp`` emits a scope brace or bare-raw construct that may
declare a function-local whose lifetime extends past the current
@@ -1134,7 +1142,7 @@ class EsphomeCore:
# declarations must stay in one IIFE so the declarations
# remain visible to subsequent uses. ``max_statements=None``
# disables sub-splitting for the group.
cap = None if group_no_split[0] else 50
cap = None if group_no_split[0] else IIFE_MAX_STATEMENTS
pieces.extend(_wrap_in_iifes(body, max_statements=cap))
return "\n".join(pieces) + "\n\n"
+17 -12
View File
@@ -1020,13 +1020,19 @@ def test_cpp_main_section_component_marker_wraps_in_iife() -> None:
assert "component-marker" not in out
_CHUNK_COUNT = 3 # number of sub-chunks to force when testing splitting
# Statement count that produces exactly _CHUNK_COUNT IIFEs when sub-split
# at IIFE_MAX_STATEMENTS (full chunks at the cap, no partial).
_STATEMENTS_OVER_CAP = core.IIFE_MAX_STATEMENTS * _CHUNK_COUNT
def test_cpp_main_section_scope_brace_raw_disables_sub_split() -> None:
# A group containing scope-brace RawStatements (e.g. `{` / `}` from
# with_local_variable) must stay in one IIFE regardless of size so
# the scope bounds and any locals between them stay together.
target = core.EsphomeCore()
stmts: list = [ComponentMarker("wifi"), RawStatement("{")]
stmts.extend(RawStatement(f"s{i}();") for i in range(100))
stmts.extend(RawStatement(f"s{i}();") for i in range(_STATEMENTS_OVER_CAP))
stmts.append(RawStatement("}"))
target.main_statements = stmts
out = target.cpp_main_section
@@ -1040,11 +1046,12 @@ def test_cpp_main_section_inline_comment_raw_still_sub_splits() -> None:
# content-aware check only triggers on bare `{` / `}`.
target = core.EsphomeCore()
stmts: list = [ComponentMarker("sensor")]
stmts.extend(RawStatement(f"s{i}(); // flags") for i in range(120))
stmts.extend(
RawStatement(f"s{i}(); // flags") for i in range(_STATEMENTS_OVER_CAP)
)
target.main_statements = stmts
out = target.cpp_main_section
# 120 statements / 50-cap = 3 sub-chunks expected.
assert out.count("[]() {") == 3
assert out.count("[]() {") == _CHUNK_COUNT
def test_cpp_main_section_raw_expression_disables_sub_split() -> None:
@@ -1057,7 +1064,8 @@ def test_cpp_main_section_raw_expression_disables_sub_split() -> None:
ExpressionStatement(RawExpression("time::ParsedTimezone tz{}")),
]
stmts.extend(
ExpressionStatement(RawExpression(f"tz.field_{i} = {i}")) for i in range(100)
ExpressionStatement(RawExpression(f"tz.field_{i} = {i}"))
for i in range(_STATEMENTS_OVER_CAP)
)
target.main_statements = stmts
out = target.cpp_main_section
@@ -1069,21 +1077,18 @@ def test_cpp_main_section_raw_expression_as_call_arg_still_sub_splits() -> None:
# `var.set_program(RawExpression("&foo"))`) produces
# `ExpressionStatement(CallExpression(..., RawExpression))` — the
# outer expression is a CallExpression, not a RawExpression, so
# the group is still sub-splittable. Exercise this with actual
# CallExpression-wrapping-RawExpression statements filling the
# group past the 50-statement cap.
# the group is still sub-splittable.
target = core.EsphomeCore()
stmts: list = [ComponentMarker("rp2040_pio_led_strip")]
stmts.extend(
ExpressionStatement(
CallExpression(MockObj(f"var_{i}.set_program"), RawExpression("&foo"))
)
for i in range(120)
for i in range(_STATEMENTS_OVER_CAP)
)
target.main_statements = stmts
out = target.cpp_main_section
# 120 statements / 50-cap -> 3 sub-chunks.
assert out.count("[]() {") == 3
assert out.count("[]() {") == _CHUNK_COUNT
def test_cpp_main_section_typed_assignment_disables_sub_split() -> None:
@@ -1096,7 +1101,7 @@ def test_cpp_main_section_typed_assignment_disables_sub_split() -> None:
AssignmentExpression(MockObj("int"), "", MockObj("x"), MockObj("42"))
)
stmts: list = [ComponentMarker("custom"), typed_assign]
stmts.extend(RawStatement(f"use_x_{i}();") for i in range(100))
stmts.extend(RawStatement(f"use_x_{i}();") for i in range(_STATEMENTS_OVER_CAP))
target.main_statements = stmts
out = target.cpp_main_section
assert out.count("[]() {") == 1