emdashes begone (#10847)

This commit is contained in:
Tom
2026-07-01 19:01:27 -05:00
committed by GitHub
parent dee94e0758
commit 3becaf2d95
276 changed files with 1795 additions and 1793 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
"""`boards.py` filter and enumeration correctness.
Runs against the real `pio project config` output of this firmware repo —
Runs against the real `pio project config` output of this firmware repo -
validates that filter predicates match expected envs and don't drift if
variants get reorganized.
"""
+1 -1
View File
@@ -1,6 +1,6 @@
"""Unit tests for the `build_flags` injection on `flash.build()`.
We don't actually run pio here — too slow, requires hardware-aware envs.
We don't actually run pio here - too slow, requires hardware-aware envs.
We test the translation layer (`_build_flags_env`) and that the env vars
are threaded through pio.run correctly via mock.
"""
+7 -7
View File
@@ -1,6 +1,6 @@
"""TCP transport plumbing in connection.py + devices.py.
Pure-Python tests — no real device or daemon required. Mocks `TCPInterface`
Pure-Python tests - no real device or daemon required. Mocks `TCPInterface`
when exercising `connect()`.
"""
@@ -171,7 +171,7 @@ class TestResolvePort:
self, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("MESHTASTIC_MCP_TCP_HOST", "localhost")
# Don't patch list_devices — let the real env-var path run, but stub
# Don't patch list_devices - let the real env-var path run, but stub
# the USB enumeration to keep the test hermetic.
with patch("meshtastic_mcp.devices.list_ports.comports", return_value=[]):
assert connection.resolve_port(None) == "tcp://localhost:4403"
@@ -208,7 +208,7 @@ class TestDevicesTcpEntry:
self, monkeypatch: pytest.MonkeyPatch
) -> None:
# `list_devices` is the diagnostic tool reached for when an env var
# isn't working — it must not throw on misconfiguration.
# isn't working - it must not throw on misconfiguration.
monkeypatch.setenv("MESHTASTIC_MCP_TCP_HOST", "host:notaport")
with patch("meshtastic_mcp.devices.list_ports.comports", return_value=[]):
ds = devices.list_devices(include_unknown=True)
@@ -222,7 +222,7 @@ class TestDevicesTcpEntry:
self, monkeypatch: pytest.MonkeyPatch
) -> None:
# `likely_meshtastic=False` keeps the bad TCP entry out of the
# auto-select path — `resolve_port(None)` should still report
# auto-select path - `resolve_port(None)` should still report
# "no Meshtastic devices" rather than picking a broken endpoint.
monkeypatch.setenv("MESHTASTIC_MCP_TCP_HOST", "host:notaport")
with patch("meshtastic_mcp.devices.list_ports.comports", return_value=[]):
@@ -274,7 +274,7 @@ class TestDevicesTcpEntry:
ds = devices.list_devices(include_unknown=True)
assert ds, "expected at least the USB + TCP entries"
# Real USB candidate must be at position 0 — it's likely_meshtastic.
# Real USB candidate must be at position 0 - it's likely_meshtastic.
assert ds[0]["port"] == "/dev/cu.usbmodem4201"
assert ds[0]["likely_meshtastic"] is True
# The malformed TCP entry exists but lands among the unlikely entries.
@@ -287,7 +287,7 @@ class TestDevicesTcpEntry:
self, monkeypatch: pytest.MonkeyPatch
) -> None:
# Conversely, a *valid* TCP env var should sort ahead of USB
# candidates of equal likely_meshtastic rank — explicit env-var
# candidates of equal likely_meshtastic rank - explicit env-var
# configuration is a precedence signal.
monkeypatch.setenv("MESHTASTIC_MCP_TCP_HOST", "localhost:4403")
@@ -375,7 +375,7 @@ class TestConnectRoutesTcp:
with connection.connect(port="tcp://locktest:4403"):
pass
# Lock should be released — a second connect attempt must not fail
# Lock should be released - a second connect attempt must not fail
# with "busy".
with patch("meshtastic.tcp_interface.TCPInterface") as mock_tcp:
mock_tcp.return_value.close.return_value = None
@@ -1,7 +1,7 @@
"""Tests for the fake-NodeDB fixture pipeline (bin/gen-fake-nodedb-seed.py
+ bin/seed-json-to-proto.py + mcp-server fixtures.push_fake_nodedb).
Lives under tests/unit/ because none of these touch real hardware — they
Lives under tests/unit/ because none of these touch real hardware - they
shell out to the bin/ scripts and decode the resulting protobufs in-process.
"""
@@ -42,7 +42,7 @@ def _require_v25_bindings() -> None:
)
if "positions" not in NodeDatabase.DESCRIPTOR.fields_by_name:
pytest.skip(
"Loaded NodeDatabase predates v25 — run `./bin/regen-py-protos.sh`."
"Loaded NodeDatabase predates v25 - run `./bin/regen-py-protos.sh`."
)
@@ -170,7 +170,7 @@ def test_committed_seed_compiles_and_decodes(size: int, tmp_path: pathlib.Path)
proto = tmp_path / "out.proto"
jsonl = FIXTURES_DIR / f"seed_v25_{size:04d}.jsonl"
if not jsonl.is_file():
pytest.skip(f"{jsonl} not present — run ./bin/regen-fake-nodedbs.sh")
pytest.skip(f"{jsonl} not present - run ./bin/regen-fake-nodedbs.sh")
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(proto)])
db = NodeDatabase()
@@ -199,7 +199,7 @@ def test_compile_freshens_timestamps(tmp_path: pathlib.Path) -> None:
_require_v25_bindings()
jsonl = FIXTURES_DIR / "seed_v25_0250.jsonl"
if not jsonl.is_file():
pytest.skip("250-node seed not present — run ./bin/regen-fake-nodedbs.sh")
pytest.skip("250-node seed not present - run ./bin/regen-fake-nodedbs.sh")
a = tmp_path / "a.proto"
b = tmp_path / "b.proto"
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(a)])
@@ -1,7 +1,7 @@
"""Pin `InputEventCode` values to the firmware `input_broker_event` enum.
If this test fails, someone changed the firmware enum (or this Python
mirror) and they must stay in sync — the admin RPC sends these as u8
mirror) and they must stay in sync - the admin RPC sends these as u8
wire values directly.
Also exercises `coerce_event_code` for the happy + error paths.
+7 -7
View File
@@ -75,7 +75,7 @@ class TestParseLogLine:
assert out["msg"] == "raw message body"
def test_bare_message(self) -> None:
# LogRecord.message path — no level prefix at all.
# LogRecord.message path - no level prefix at all.
out = parse_log_line("just a bare message")
assert "level" not in out or out.get("level") is None
assert out["line"] == "just a bare message"
@@ -155,7 +155,7 @@ class TestRecorderDebugHeapSynthesis:
assert synth[-1]["fields"]["heap_total_bytes"] == 200000
def test_no_heap_no_synthesis(self, recorder: "Recorder") -> None:
# Plain log line (no [heap N], no Heap status) — telemetry.jsonl
# Plain log line (no [heap N], no Heap status) - telemetry.jsonl
# should NOT gain a synth row.
before = (recorder.base_dir / "telemetry.jsonl").read_text().count("\n")
recorder._on_log_line("INFO | 00:00:00 1 [Main] just a message", _FakeIface())
@@ -234,7 +234,7 @@ class TestSerialTap:
def test_serial_line_handler_swallows_exceptions(
self, recorder: "Recorder"
) -> None:
# Hostile input — should not raise.
# Hostile input - should not raise.
recorder._on_serial_line(None, port="/dev/cu.tap") # type: ignore[arg-type]
recorder._on_serial_line(b"\x00\x01\x02\x03", port="/dev/cu.tap") # type: ignore[arg-type]
# Survived.
@@ -320,11 +320,11 @@ class TestRecorderWrites:
recorder._on_log_line("INFO | 12:34:56 99 [T] hi", _FakeIface())
path = recorder.base_dir / "logs.jsonl"
rows = [json.loads(line) for line in path.read_text().splitlines() if line]
# First row is recorder_start_event mirror? No — that's events.jsonl only.
# First row is recorder_start_event mirror? No - that's events.jsonl only.
assert any(r.get("level") == "INFO" and r.get("tag") == "T" for r in rows)
def test_telemetry_recorded_and_packet_double(self, recorder: Recorder) -> None:
# _on_telemetry alone — only telemetry.jsonl
# _on_telemetry alone - only telemetry.jsonl
recorder._on_telemetry(
{
"fromId": "!abc",
@@ -367,13 +367,13 @@ class TestRecorderWrites:
assert "kept" in post_resume
def test_pubsub_handler_swallows_exceptions(self, recorder: Recorder) -> None:
# If the writer dies, the pubsub callback must NOT raise — that
# If the writer dies, the pubsub callback must NOT raise - that
# would crash the meshtastic receive thread.
bad_packet = object() # not a dict
recorder._on_receive(bad_packet, _FakeIface()) # type: ignore[arg-type]
recorder._on_telemetry(bad_packet, _FakeIface()) # type: ignore[arg-type]
recorder._on_log_line(None, _FakeIface()) # type: ignore[arg-type]
# No assertion needed — survival is the test.
# No assertion needed - survival is the test.
# -- log_query read side ---------------------------------------------
@@ -113,7 +113,7 @@ def test_owner_names_included_when_provided() -> None:
def test_psk_seed_isolation_across_ci_runs() -> None:
"""The core claim: two test labs running concurrently with different
session seeds produce different PSKs — their meshes cannot decode each
session seeds produce different PSKs - their meshes cannot decode each
other's traffic."""
lab_a = userprefs.build_testing_profile(psk_seed="lab-A-nightly")
lab_b = userprefs.build_testing_profile(psk_seed="lab-B-nightly")
+2 -2
View File
@@ -5,9 +5,9 @@ new hub-descriptor fields (e.g. the `, ppps` marker). The parser uses loose
regexes to tolerate additions; this test keeps us honest.
Samples captured from:
- v2.6.0 on macOS (Homebrew) — two USB2 hubs, one populated with an
- v2.6.0 on macOS (Homebrew) - two USB2 hubs, one populated with an
nRF52 and a CP2102, plus chained USB3 hubs.
- v2.5.0 on Linux (hypothetical — reconstructed from the project README).
- v2.5.0 on Linux (hypothetical - reconstructed from the project README).
"""
from __future__ import annotations
+3 -3
View File
@@ -1,8 +1,8 @@
"""Pin the `Screen: frame N/M name=X reason=Y` regex + FrameEvent dataclass.
The firmware-side format lives in `src/graphics/Screen.cpp::logFrameChange`;
if the format string changes, this test — and the parser in
`tests/ui/_screen_log.py` — have to be updated together.
if the format string changes, this test - and the parser in
`tests/ui/_screen_log.py` - have to be updated together.
"""
from __future__ import annotations
@@ -23,7 +23,7 @@ class TestFrameEventParse:
def test_with_log_prefix(self) -> None:
"""Log lines may be preamble-wrapped by the firmware LOG_INFO macro
(timestamp, severity, etc.) — the regex uses .search() not .match()
(timestamp, severity, etc.) - the regex uses .search() not .match()
so prefixes are fine."""
raw = "[INFO] 00:12:34 567 Screen: frame 4/12 name=nodelist_nodes reason=fn_f3 "
evt = FrameEvent.parse(raw)
@@ -2,7 +2,7 @@
write, and the `temporary_overrides` context manager's byte-for-byte restore.
None of these require hardware. They validate the contract that the flash/
testing-profile tools rely on — if these fail, the provisioning tier will
testing-profile tools rely on - if these fail, the provisioning tier will
produce confusing mismatches.
"""
@@ -63,7 +63,7 @@ def test_infer_type_matches_platformio_custom_py() -> None:
def test_temporary_overrides_restores_byte_for_byte(sample_jsonc: Path) -> None:
"""The context manager MUST leave the file bit-identical on exit, even on
exception — this is the safety guarantee build/flash tools rely on."""
exception - this is the safety guarantee build/flash tools rely on."""
original = sample_jsonc.read_bytes()
with userprefs.temporary_overrides({"USERPREFS_CHANNEL_0_NAME": "OverrideTest"}):
@@ -104,7 +104,7 @@ def test_build_manifest_surfaces_all_keys(sample_jsonc: Path) -> None:
"""Manifest should union the jsonc set with firmware-src consumers.
In the sample tmpdir there's no `src/` so `consumed_by` is empty for all
entries; that's fine — the manifest still lists every jsonc key.
entries; that's fine - the manifest still lists every jsonc key.
"""
manifest = userprefs.build_manifest()
keys = {e["key"] for e in manifest["entries"]}