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

This commit is contained in:
J. Nick Koston
2026-08-22 12:26:39 -05:00
6 changed files with 118 additions and 25 deletions
@@ -124,3 +124,48 @@ def test_ar_empty_object_list_fails(
rc = build_tool.main()
assert rc == 1
assert "no objects listed" in capsys.readouterr().err
def test_ar_batches_long_object_lists(tmp_path: Path) -> None:
"""The expanded argv must stay under the Windows 32767-char limit: a
long object list creates with rc, then appends with q."""
archive = tmp_path / "lib.a"
rsp = tmp_path / "lib.a.rsp"
objects = [f"dir/{'x' * 120}_{i}.o" for i in range(400)]
rsp.write_text("\n".join(objects) + "\n")
with (
patch.object(
build_tool.sys,
"argv",
["build_tool", "ar", "ar-bin", str(archive), str(rsp)],
),
patch.object(
build_tool.subprocess, "run", return_value=MagicMock(returncode=0)
) as mock_run,
):
assert build_tool.main() == 0
calls = [c[0][0] for c in mock_run.call_args_list]
assert len(calls) > 1
assert calls[0][1] == "rc"
assert all(c[1] == "q" for c in calls[1:])
assert [o for c in calls for o in c[3:]] == objects
assert all(sum(len(a) + 1 for a in c) < 32000 for c in calls)
def test_ar_batch_failure_stops(tmp_path: Path) -> None:
"""A failing batch propagates its exit code without running the rest."""
archive = tmp_path / "lib.a"
rsp = tmp_path / "lib.a.rsp"
rsp.write_text("\n".join(f"{'y' * 200}_{i}.o" for i in range(300)) + "\n")
with (
patch.object(
build_tool.sys,
"argv",
["build_tool", "ar", "ar-bin", str(archive), str(rsp)],
),
patch.object(
build_tool.subprocess, "run", return_value=MagicMock(returncode=3)
) as mock_run,
):
assert build_tool.main() == 3
assert mock_run.call_count == 1
+23 -4
View File
@@ -477,13 +477,32 @@ def test_library_info_dropped_link_fields_warn(
def test_library_info_unmapped_sources_warn(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""Matched files that all fall through the suffix map are visible; an
empty archive would fail far away at link."""
"""Source-like files the case-sensitive suffix map rejects are named,
even when other sources compiled (a partial drop links with undefined
symbols far from the cause)."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
(read_path / "src" / "impl.CPP").write_text("")
component._library_info("x", read_path, {"build": {}})
assert "no matched file has a recognized source suffix" in caplog.text
(read_path / "src" / "sketch.ino").write_text("")
(read_path / "src" / "ok.cpp").write_text("")
lib = component._library_info("x", read_path, {"build": {}})
assert [s.name for s in lib.sources] == ["ok.cpp"]
assert "not compiled: impl.CPP, sketch.ino" in caplog.text
def test_library_info_header_only_src_stays_quiet(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""A header-only library (real headers in src/) is routine, not a
warning (the default +<*> filter matches the headers too)."""
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
(read_path / "src" / "ArduinoJson.h").write_text("")
(read_path / "keywords.txt").write_text("")
lib = component._library_info("x", read_path, {"build": {}})
assert lib.sources == []
assert "not compiled" not in caplog.text
assert "srcFilter" not in caplog.text
def test_library_info_lib_archive_malformed_raises(tmp_path: Path) -> None:
@@ -645,6 +645,9 @@ def test_normalize_dependencies_forms(caplog) -> None:
{"name": "SPI"},
]
assert normalize_dependencies("Wire") == [{"name": "Wire"}]
# A non-iterable value fails by manifest name, never a bare TypeError
assert normalize_dependencies(5, "libx") == []
assert "Ignoring unrecognized dependencies 5 of libx" in caplog.text
# 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(