Merge branch 'esp8266-native-library-converter' into esp8266-native-shared-helpers

This commit is contained in:
J. Nick Koston
2026-08-23 18:15:04 -05:00
35 changed files with 987 additions and 270 deletions
+13
View File
@@ -294,6 +294,19 @@ def test_generate_cmakelists_txt_multi_token_flag(tmp_component):
assert ' "-include"\n "cp_custom_alloc.h"\n' in content
def test_generate_cmakelists_txt_escapes_embedded_quotes(tmp_component):
"""A define value carrying a literal quote survives into CMake as an
escaped quote, not a prematurely-terminated string."""
src_dir = tmp_component.path / "src"
src_dir.mkdir()
(src_dir / "main.c").write_text("int main() {}")
# shlex keeps the backslash-escaped quotes as literal characters
tmp_component.data = {"build": {"flags": ['-DMSG=\\"hi\\"']}}
content = generate_cmakelists_txt(tmp_component)
assert '"-DMSG=\\"hi\\""' in content
def test_generate_cmakelists_txt_extra_script_link_flags(tmp_component):
"""Captured extra-script LINKFLAGS come out as target_link_options, not
compile options where they would be silently ineffective."""
@@ -461,6 +461,27 @@ def test_prepend_inserts_ahead_of_existing(method: str) -> None:
assert env.result.libs == ["algobsec", "bsec", "m"]
def test_env_membership_and_iteration(tmp_path) -> None:
"""Membership tests and for-loops must use the mapping protocol; the
legacy sequence fallback through __getitem__ would loop forever."""
env = _FakeSConsEnv(
board_mcu="esp8266", pio_env="esphome_esp8266", pio_platform="espressif8266"
)
assert "BOARD_MCU" in env
assert "NOPE" not in env
assert sorted(env) == ["BOARD_MCU", "PIOENV", "PIOPLATFORM"]
def test_apply_extra_script_non_string_falsey_raises(tmp_path) -> None:
"""A falsey non-string extraScript (false, 0, []) is a malformed
manifest, not an absent script."""
c = IDFComponent("owner/name", "1.0", source=URLSource("http://dummy"))
c.path = tmp_path
c.data = {"build": {"extraScript": False}}
with pytest.raises(EsphomeError, match="must be a string"):
apply_extra_script(c, board_mcu=lambda: "esp8266", pio_platform="espressif8266")
def test_env_get_unknown_key_warns_once(caplog) -> None:
"""A script branching on an unmodelled env var is diagnosable."""
env = _FakeSConsEnv(
+19 -1
View File
@@ -800,10 +800,28 @@ def test_normalize_dependencies_forms(caplog) -> None:
assert normalize_dependencies({"Foo": ["1.0", "2.0"]}, "libx") == []
assert normalize_dependencies([{"name": "Foo", "version": 1}], "libx") == []
assert caplog.text.count("unrecognized dependency entry") == 7
# A non-string owner would stringify into a malformed registry name
assert (
normalize_dependencies(
[{"name": "Foo", "owner": {"bad": 1}, "version": "1.0"}], "libx"
)
== []
)
# A falsey scalar (0, false) is malformed, not an empty list
assert normalize_dependencies(0, "libx") == []
assert "Ignoring unrecognized dependencies 0 of libx" in caplog.text
@pytest.mark.parametrize(
"manifest", [["not", "a", "manifest"], {"name": "A", "build": "src"}]
"manifest",
[
["not", "a", "manifest"],
{"name": "A", "build": "src"},
{"name": "A", "ESPHOME": "yes"},
{"name": "A", "build": {"srcDir": 123}},
{"name": "A", "build": {"includeDir": ["inc"]}},
{"name": "A", "build": {"srcFilter": {"+": "src"}}},
],
)
def test_convert_libraries_malformed_manifest_raises(
tmp_path, monkeypatch, manifest
+16
View File
@@ -66,6 +66,22 @@ def test_generate_cmakelists_txt_flags_and_includes(tmp_path):
assert "-lm" in out
def test_generate_cmakelists_txt_lexes_spaced_flags(tmp_path):
"""A spaced -I entry routes to include dirs instead of landing verbatim
in compile options; same shared lexer as the espidf emitter."""
c = _make_component(tmp_path)
(tmp_path / "src").mkdir()
(tmp_path / "src" / "a.c").write_text("")
(tmp_path / "include").mkdir()
c.data = {"build": {"flags": "-I include -DBAR=1"}}
out = generate_cmakelists_txt(c)
assert str((tmp_path / "include").resolve()).replace("\\", "\\\\") in out
assert "-DBAR=1" in out
assert "-I include" not in out
def test_generate_zephyr_modules_collects_all_dirs_and_writes(tmp_path, monkeypatch):
# Two converted libraries: one top-level, one transitive dependency. The
# converter calls backend.emit for both; generate_zephyr_modules must return