mirror of
https://github.com/esphome/esphome.git
synced 2026-10-02 01:10:22 +00:00
Accept precompiled=false, keep same-file copies intact, ungate the empty-match warning
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from unittest.mock import MagicMock, patch
|
||||
@@ -188,6 +189,20 @@ def test_surplus_arguments_error(capsys: pytest.CaptureFixture[str]) -> None:
|
||||
assert "expected 2 arguments, got 3" in capsys.readouterr().err
|
||||
|
||||
|
||||
def test_copy_same_file_keeps_the_input(tmp_path: Path) -> None:
|
||||
"""A same-file copy (dst IS src) must not unlink the input."""
|
||||
src = tmp_path / "firmware.bin"
|
||||
src.write_bytes(b"image")
|
||||
with (
|
||||
patch.object(
|
||||
build_tool.sys, "argv", ["build_tool", "copy", str(src), str(src)]
|
||||
),
|
||||
pytest.raises(shutil.SameFileError),
|
||||
):
|
||||
build_tool.main()
|
||||
assert src.read_bytes() == b"image"
|
||||
|
||||
|
||||
def test_copy_failure_leaves_no_partial_output(tmp_path: Path) -> None:
|
||||
"""A failed copy unlinks the destination; a partial firmware image must
|
||||
never be left on disk."""
|
||||
|
||||
@@ -189,7 +189,7 @@ def test_library_info_declared_filter_matches_nothing_warns(
|
||||
data = {"build": {"srcFilter": ["+<nothing/*>"]}}
|
||||
lib = component._library_info("x", read_path, data)
|
||||
assert not lib.sources
|
||||
assert "declares srcFilter/srcDir but no source files matched" in caplog.text
|
||||
assert "no source files matched" in caplog.text
|
||||
|
||||
|
||||
def test_empty_converted_tree_raises_at_emit(tmp_path: Path) -> None:
|
||||
@@ -606,6 +606,44 @@ def test_library_info_unsupported_link_fields_raise(tmp_path: Path) -> None:
|
||||
component._library_info("x", read_path, {"ldflags": "-lfoo", "build": {}})
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["false", "False", " false ", "", False, None])
|
||||
def test_library_info_precompiled_opt_out_accepted(
|
||||
tmp_path: Path, value: object
|
||||
) -> None:
|
||||
"""Manifest values are strings; precompiled=false is the spec's
|
||||
explicit opt-out, not a declaration."""
|
||||
read_path = tmp_path / "lib"
|
||||
(read_path / "src").mkdir(parents=True)
|
||||
(read_path / "src" / "stub.cpp").write_text("")
|
||||
data = {"build": {}}
|
||||
if value is not None:
|
||||
data["precompiled"] = value
|
||||
component._library_info("x", read_path, data)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["full", True, "weird"])
|
||||
def test_library_info_precompiled_set_raises(tmp_path: Path, value: object) -> None:
|
||||
"""Both full (Arduino's other legal value) and unknown spellings fail safe."""
|
||||
read_path = tmp_path / "lib"
|
||||
(read_path / "src").mkdir(parents=True)
|
||||
(read_path / "src" / "stub.cpp").write_text("")
|
||||
with pytest.raises(EsphomeError, match="declares precompiled"):
|
||||
component._library_info("x", read_path, {"precompiled": value, "build": {}})
|
||||
|
||||
|
||||
def test_library_info_default_filter_matching_nothing_warns(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""The empty-match warning is not gated on a declared srcFilter/srcDir;
|
||||
a default-filter src/ holding only inert files warns too."""
|
||||
read_path = tmp_path / "lib"
|
||||
(read_path / "src").mkdir(parents=True)
|
||||
(read_path / "src" / "keywords.txt").write_text("")
|
||||
lib = component._library_info("x", read_path, {"build": {}})
|
||||
assert not lib.sources
|
||||
assert "no source files matched" in caplog.text
|
||||
|
||||
|
||||
def test_library_info_unmapped_sources_warn(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user