mirror of
https://github.com/esphome/esphome.git
synced 2026-09-30 08:20:21 +00:00
Merge branch 'esp8266-native-library-backend' into esp8266-native-build-spec
This commit is contained in:
@@ -387,8 +387,8 @@ def test_library_info_lib_archive_flag(tmp_path: Path) -> None:
|
||||
def test_resolve_libraries_dep_warnings(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""A nameless dependency entry warns; an owner-without-version entry is
|
||||
left to the shared walk's reconciliation (no local warning)."""
|
||||
"""A nameless dependency entry warns in the shared normalizer; an
|
||||
owner-without-version entry is left to the walk's reconciliation."""
|
||||
framework = _make_framework(tmp_path)
|
||||
converted = _webserver(
|
||||
tmp_path,
|
||||
@@ -402,7 +402,7 @@ def test_resolve_libraries_dep_warnings(
|
||||
)
|
||||
with _emitting_converter(converted):
|
||||
_resolve(framework)
|
||||
assert "malformed dependency entry" in caplog.text
|
||||
assert "Ignoring unrecognized dependency entry" in caplog.text
|
||||
assert "Orphan" not in caplog.text
|
||||
|
||||
|
||||
@@ -735,6 +735,64 @@ def test_transitively_resolved_dependency_does_not_warn(
|
||||
assert "Skipping" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("spec", "expected"),
|
||||
[
|
||||
("owner/Name", "Name"),
|
||||
("Name", "Name"),
|
||||
("Foo=file:///srv/Wire", "Foo"),
|
||||
("Foo=https://github.com/x/Wire", "Foo"),
|
||||
# An "=" without a URL is a registry name, not the custom-name form
|
||||
("FOO=BAR", "FOO=BAR"),
|
||||
("https://github.com/x/Wire", "Wire"),
|
||||
],
|
||||
)
|
||||
def test_external_short_name(spec: str, expected: str) -> None:
|
||||
assert component._external_short_name(spec) == expected
|
||||
|
||||
|
||||
def test_converted_manifest_name_suppresses_bundled_dependency(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""A dependency name a converted library's manifest provides is not
|
||||
also added from the framework tree (a duplicate archive would surface
|
||||
as duplicate-symbol link errors), even when the provider emits later."""
|
||||
framework = _make_framework(tmp_path)
|
||||
_add_library("ESP32Async/ESPAsyncWebServer", "3.9.6")
|
||||
# Requested under a different short name; only the manifest says "Wire"
|
||||
_add_library("Someone/WireLib", "9.9.9")
|
||||
ws_dir = tmp_path / "converted" / "webserver"
|
||||
(ws_dir / "src").mkdir(parents=True)
|
||||
wire_dir = tmp_path / "converted" / "wire"
|
||||
(wire_dir / "src").mkdir(parents=True)
|
||||
ws = _converted(
|
||||
"esp32async__ESPAsyncWebServer",
|
||||
ws_dir,
|
||||
{"build": {}, "dependencies": [{"name": "Wire"}]},
|
||||
)
|
||||
registry_wire = _converted(
|
||||
"someone__WireLib", wire_dir, {"name": "Wire", "build": {}}
|
||||
)
|
||||
with _emitting_converter(ws, registry_wire):
|
||||
libs = _resolve(framework)
|
||||
# The bundled Wire is not added alongside the registry-resolved one
|
||||
assert [lib.name for lib in libs] == [
|
||||
"esp32async__ESPAsyncWebServer",
|
||||
"someone__WireLib",
|
||||
]
|
||||
|
||||
|
||||
def test_bundled_library_root_headers_pass_the_probe(tmp_path: Path) -> None:
|
||||
"""Headers anywhere in the bundled tree (uncommon suffixes and case
|
||||
included) prove the install is intact, even with an empty src dir."""
|
||||
framework = _make_framework(tmp_path)
|
||||
lib_dir = framework / "libraries" / "HeaderOnly"
|
||||
(lib_dir / "src").mkdir(parents=True)
|
||||
(lib_dir / "impl.HXX").write_text("")
|
||||
lib = component._bundled_library(framework, "HeaderOnly")
|
||||
assert lib.sources == []
|
||||
|
||||
|
||||
def test_empty_bundled_library_warns(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
||||
@@ -26,9 +26,13 @@ from esphome.platformio.library import (
|
||||
)
|
||||
|
||||
|
||||
def _backend(emit=lambda component: None) -> LibraryBackend:
|
||||
def _backend(emit=lambda component: None, provides=None) -> LibraryBackend:
|
||||
return LibraryBackend(
|
||||
platform="espressif32", framework="espidf", emit=emit, cache_key="idf"
|
||||
platform="espressif32",
|
||||
framework="espidf",
|
||||
emit=emit,
|
||||
cache_key="idf",
|
||||
provides=provides,
|
||||
)
|
||||
|
||||
|
||||
@@ -596,11 +600,14 @@ def test_normalize_dependencies_forms(caplog) -> None:
|
||||
"""Every PIO-legal spelling normalizes; unrecognizable entries warn."""
|
||||
from esphome.platformio.library import normalize_dependencies
|
||||
|
||||
assert normalize_dependencies(["Wire", {"name": "SPI"}, 5, ""], "libx") == [
|
||||
assert normalize_dependencies(
|
||||
["Wire", {"name": "SPI"}, 5, "", {"version": "1.0"}], "libx"
|
||||
) == [
|
||||
{"name": "Wire"},
|
||||
{"name": "SPI"},
|
||||
]
|
||||
assert caplog.text.count("unrecognized dependency entry") == 2
|
||||
# The int, the empty string, and the nameless dict all warn
|
||||
assert caplog.text.count("unrecognized dependency entry") == 3
|
||||
# A plain string is names, never iterated into characters
|
||||
assert normalize_dependencies("Wire, SPI") == [
|
||||
{"name": "Wire"},
|
||||
@@ -630,12 +637,20 @@ def test_versionless_dependency_without_provider_warns(
|
||||
_patch_download_with_manifests(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
{"esphome/A": {"name": "A", "dependencies": [{"name": "Hash"}]}},
|
||||
{
|
||||
"esphome/A": {
|
||||
"name": "A",
|
||||
# The duplicate entry warns once (reconciliation dedup)
|
||||
"dependencies": [{"name": "Hash"}, {"name": "Hash"}],
|
||||
}
|
||||
},
|
||||
)
|
||||
convert_libraries([Library("esphome/A", None, None)], _backend())
|
||||
assert (
|
||||
"Hash of esphome/A has no version to resolve and nothing provides it"
|
||||
in caplog.text
|
||||
caplog.text.count(
|
||||
"Hash of esphome/A has no version to resolve and nothing provides it"
|
||||
)
|
||||
== 1
|
||||
)
|
||||
|
||||
|
||||
@@ -663,6 +678,46 @@ def test_walk_warns_for_nonplatform_invalid_library(
|
||||
assert "Skipping dependency B of esphome/A: manifest is corrupt" in caplog.text
|
||||
|
||||
|
||||
def test_versionless_owner_qualified_dependency_warns_despite_provides(
|
||||
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""The backend's provides() only covers owner-less names (the walk's
|
||||
backend-provided skip has the same guard), so an owner-qualified
|
||||
version-less dependency that nobody adds must still warn."""
|
||||
_patch_download_with_manifests(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
{
|
||||
"esphome/A": {
|
||||
"name": "A",
|
||||
"dependencies": [{"name": "Wire", "owner": "Foo"}],
|
||||
}
|
||||
},
|
||||
)
|
||||
convert_libraries(
|
||||
[Library("esphome/A", None, None)],
|
||||
_backend(provides=lambda name: name == "Wire"),
|
||||
)
|
||||
assert "Wire of esphome/A has no version to resolve" in caplog.text
|
||||
|
||||
|
||||
def test_versionless_provided_dependency_stays_quiet(
|
||||
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""An owner-less version-less dependency the backend provides is added
|
||||
by the backend after emit; no reconciliation warning."""
|
||||
_patch_download_with_manifests(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
{"esphome/A": {"name": "A", "dependencies": [{"name": "Wire"}]}},
|
||||
)
|
||||
convert_libraries(
|
||||
[Library("esphome/A", None, None)],
|
||||
_backend(provides=lambda name: name == "Wire"),
|
||||
)
|
||||
assert "has no version to resolve" not in caplog.text
|
||||
|
||||
|
||||
def test_versionless_dependency_requested_top_level_stays_quiet(
|
||||
tmp_path, monkeypatch, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user