Merge branch 'esp8266-native-ninja-emission' into esp8266-arduino-toolchain

This commit is contained in:
J. Nick Koston
2026-08-22 11:49:37 -05:00
4 changed files with 110 additions and 35 deletions
+25 -18
View File
@@ -441,28 +441,32 @@ def test_library_info_falsy_declared_src_dir_raises(
@pytest.mark.parametrize(
("value", "expected", "warns"),
("value", "expected"),
[
(False, False, False),
("false", False, False),
("False", False, False),
("true", True, False),
("archive-me", True, True),
(False, False),
("false", False),
("False", False),
("true", True),
],
)
def test_library_info_lib_archive_parse(
tmp_path: Path,
value: object,
expected: bool,
warns: bool,
caplog: pytest.LogCaptureFixture,
) -> None:
"""bool("false") is True; the string forms must parse, not coerce."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
lib = component._library_info("x", read_path, {"build": {"libArchive": value}})
assert lib.lib_archive is expected
assert ("unrecognized libArchive" in caplog.text) is warns
def test_library_info_lib_archive_malformed_raises(tmp_path: Path) -> None:
"""A typo'd libArchive fails by name like the other build fields."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
with pytest.raises(EsphomeError, match="malformed libArchive value 'archive-me'"):
component._library_info("x", read_path, {"build": {"libArchive": "archive-me"}})
def test_bundled_dependency_dict_shorthand_prefers_bundled(tmp_path: Path) -> None:
@@ -535,27 +539,30 @@ def test_library_info_malformed_build_fields_are_named(
@pytest.mark.parametrize(
("value", "expected", "warns"),
("value", "expected"),
[
("true", True, False),
("False", False, False),
("yes", True, True),
("true", True),
("False", False),
],
)
def test_library_info_dot_a_linkage_parses_strictly(
tmp_path: Path,
value: str,
expected: bool,
warns: bool,
caplog: pytest.LogCaptureFixture,
) -> None:
"""The dot_a_linkage property uses the same strict table as libArchive; a typo warns
and keeps the archive default instead of silently flipping linkage."""
"""The dot_a_linkage property uses the same strict table as libArchive."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
lib = component._library_info("x", read_path, {"dot_a_linkage": value, "build": {}})
assert lib.lib_archive is expected
assert ("unrecognized dot_a_linkage" in caplog.text) is warns
def test_library_info_dot_a_linkage_malformed_raises(tmp_path: Path) -> None:
"""A typo'd dot_a_linkage must not silently flip link semantics."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
with pytest.raises(EsphomeError, match="malformed dot_a_linkage value 'yes'"):
component._library_info("x", read_path, {"dot_a_linkage": "yes", "build": {}})
def test_bundled_library_properties_depends_warns(
+55 -1
View File
@@ -10,7 +10,7 @@ from pathlib import Path
import pytest
from esphome.core import EsphomeError, Library
from esphome.core import CORE, EsphomeError, Library
import esphome.platformio.library as lib
from esphome.platformio.library import (
SOURCE_KIND_FOR_SUFFIX,
@@ -540,6 +540,36 @@ def test_convert_libraries_skips_incompatible_dependency(tmp_path, monkeypatch):
assert top[0].dependencies == []
def test_convert_libraries_warns_for_nonplatform_invalid_dependency_component(
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
) -> None:
"""A dependency component dropped for any cause other than the platform
filter warns; only the routine cross-platform skip stays at debug."""
_patch_download_with_manifests(
monkeypatch,
tmp_path,
{
"esphome/A": {
"name": "A",
"dependencies": [{"name": "C", "owner": "esphome", "version": "1.0"}],
},
"esphome/C": {"name": "C"},
},
)
real = lib.check_library_data
def flaky(data, platform, framework):
# Fail only on C's resolved manifest, not on A's dependency entry
if data.get("name") == "C" and "version" not in data:
raise InvalidLibrary("manifest is corrupt")
return real(data, platform, framework)
monkeypatch.setattr(lib, "check_library_data", flaky)
convert_libraries([Library("esphome/A", "1.0.0", None)], _backend())
assert "manifest is corrupt" in caplog.text
assert "Skipping dependency" in caplog.text
def test_split_flag_entry_unbalanced_quote_is_clean() -> None:
"""A malformed flags entry raises EsphomeError, not a raw ValueError."""
@@ -592,6 +622,9 @@ def test_source_kind_map_shape() -> None:
assert SOURCE_KIND_FOR_SUFFIX[".S"] == "asm"
assert SOURCE_KIND_FOR_SUFFIX[".c"] == "c"
assert SOURCE_KIND_FOR_SUFFIX[".cpp"] == "cxx"
# SCons's case-sensitive C++ suffixes: PIO compiles .C as C++
assert SOURCE_KIND_FOR_SUFFIX[".C"] == "cxx"
assert SOURCE_KIND_FOR_SUFFIX[".C++"] == "cxx"
def test_normalize_dependencies_forms(caplog) -> None:
@@ -612,6 +645,12 @@ def test_normalize_dependencies_forms(caplog) -> None:
{"name": "SPI"},
]
assert normalize_dependencies("Wire") == [{"name": "Wire"}]
# The dict-shorthand form validates names like the list form: an empty
# key and a spec overriding name with a non-string both warn and drop
assert normalize_dependencies(
{"": "1.0", "Wire": {"name": 123, "version": "1.0"}, "SPI": "*"}, "libx"
) == [{"name": "SPI", "owner": None, "version": "*"}]
assert caplog.text.count("unrecognized dependency entry") == 5
@pytest.mark.parametrize(
@@ -627,6 +666,21 @@ def test_convert_libraries_malformed_manifest_raises(
convert_libraries([Library("esphome/A", None, None)], _backend())
def test_versionless_ignored_dependency_stays_quiet(
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
) -> None:
"""A lib_ignore'd version-less dependency is deliberately excluded, not
a drop; no reconciliation warning."""
_patch_download_with_manifests(
monkeypatch,
tmp_path,
{"esphome/A": {"name": "A", "dependencies": [{"name": "Hash"}]}},
)
CORE.platformio_options = {"lib_ignore": ["Hash"]}
convert_libraries([Library("esphome/A", None, None)], _backend())
assert "has no version to resolve" not in caplog.text
def test_versionless_dependency_without_provider_warns(
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
) -> None: