Skip to content

Commit a5b014a

Browse files
committed
[red] bind public docs to qualified firmware 0.6.0
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
1 parent 10d6ff1 commit a5b014a

1 file changed

Lines changed: 77 additions & 25 deletions

File tree

‎tests/publication/test_public_claims.py‎

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,28 +83,27 @@ def setUpClass(cls) -> None:
8383
REPO_ROOT / "tools" / "web" / "README.md"
8484
).read_text(encoding="utf-8")
8585

86-
def test_readme_identifies_the_exact_hardware_tested_public_beta(self) -> None:
86+
def test_readme_identifies_the_qualified_v060_release(self) -> None:
8787
firmware = markdown_section(self.readme, "What works")
8888
normalized = " ".join(firmware.split())
8989

9090
self.assertIn(
91-
"public browser installer currently offers the exact v0.4.2 hardware-tested beta",
91+
"qualified public v0.6.0 release",
9292
normalized,
9393
)
94-
self.assertIn("Production Chrome erase/install", firmware)
95-
self.assertIn("interrupted-flash recovery passed", firmware)
96-
self.assertIn("Complete release qualification continues", firmware)
94+
self.assertIn("all five exact release profiles", normalized)
95+
self.assertIn("four ESP profiles use Web Serial", normalized)
96+
self.assertIn("verified UF2", firmware)
97+
self.assertIn("BOOTSEL", firmware)
9798
self.assertIn("`esp32-4mb`", firmware)
98-
self.assertIn("Classic ESP32, 4 MiB external SPI flash", firmware)
9999
self.assertIn("`esp32-s3-n16r8`", firmware)
100-
self.assertIn("16 MiB flash / 8 MiB Octal PSRAM", firmware)
101-
self.assertIn(
102-
"v0.4.2 hardware-tested beta; browser install/recovery passed",
103-
firmware,
104-
)
105-
self.assertIn("Planned; unavailable", firmware)
106-
self.assertNotIn("currently offers qualified images", firmware)
107-
self.assertNotIn("full HIL pending", firmware)
100+
self.assertIn("`waveshare-esp32-s3-lcd-147b`", firmware)
101+
self.assertIn("`esp32-c3-4mb`", firmware)
102+
self.assertIn("`rpi-pico2-w`", firmware)
103+
self.assertEqual(firmware.count("Qualified v0.6.0"), 5)
104+
self.assertNotIn("v0.4.2 hardware-tested beta", firmware)
105+
self.assertNotIn("Planned; unavailable", firmware)
106+
self.assertNotIn("in-progress `0.6.0`", firmware)
108107

109108
def test_readme_caption_describes_only_the_visible_app(self) -> None:
110109
caption_start = self.readme.index("<em>Actual PyBLE app")
@@ -116,23 +115,22 @@ def test_readme_caption_describes_only_the_visible_app(self) -> None:
116115
self.assertIn("generated MicroPython", caption)
117116
self.assertNotRegex(caption, r"(?i)pictured|board|module")
118117

119-
def test_readme_try_steps_use_the_hardware_tested_beta_safely(self) -> None:
118+
def test_readme_try_steps_use_the_qualified_v060_release_safely(self) -> None:
120119
try_section = markdown_section(self.readme, "Try PyBLE")
121120
normalized = " ".join(try_section.split())
122121

123-
self.assertIn("v0.4.2 hardware-tested beta", normalized)
124-
self.assertIn(
125-
"Browser installation and interrupted-flash recovery passed",
126-
normalized,
127-
)
128-
self.assertIn("complete release qualification continues", normalized)
129-
self.assertNotIn("full HIL pending", try_section)
122+
self.assertIn("qualified v0.6.0 release", normalized)
123+
self.assertIn("four ESP profiles", normalized)
124+
self.assertIn("Web Serial", try_section)
125+
self.assertIn("Pico 2 W", try_section)
126+
self.assertIn("verified UF2", try_section)
127+
self.assertIn("BOOTSEL", try_section)
128+
self.assertIn("iPadOS cannot perform", normalized)
130129
self.assertNotIn("use it at your own risk", try_section)
131130
self.assertIn("exact profile", try_section)
132131
self.assertIn("back up", try_section)
133-
self.assertIn("enabled install action", try_section)
134132
self.assertIn("Flashing erases the board", try_section)
135-
self.assertNotIn("wait for that page", try_section.lower())
133+
self.assertNotIn("v0.4.2 hardware-tested beta", try_section)
136134

137135
def test_current_public_surfaces_agree_on_beta_and_c3_state(self) -> None:
138136
combined = "\n".join(
@@ -232,7 +230,31 @@ def test_post_release_attestation_bounds_the_completed_hil_scope(self) -> None:
232230

233231
def test_public_surfaces_link_the_release_evidence_and_changelog(self) -> None:
234232
self.assertIn(
235-
"(docs/validation/browser-flashing/v0.4.2-production.md)",
233+
"https://pyble.dev/firmware/v0.6.0/release.json",
234+
self.readme,
235+
)
236+
self.assertIn(
237+
"https://pyble.dev/firmware/v0.6.0/RELEASE_NOTES.md",
238+
self.readme,
239+
)
240+
self.assertIn(
241+
"https://pyble.dev/firmware/v0.6.0/SHA256SUMS",
242+
self.readme,
243+
)
244+
self.assertIn(
245+
"https://pyble.dev/firmware/v0.6.0/RECOVERY.md",
246+
self.readme,
247+
)
248+
self.assertIn(
249+
"https://github.com/PyBLE-dev/PyBLE/tree/firmware-v0.6.0",
250+
self.readme,
251+
)
252+
self.assertIn(
253+
"c2940281a14feddb55c48de15ac18087e9317d1b7130e514fab5a209b046a1e6",
254+
self.readme,
255+
)
256+
self.assertIn(
257+
"0c7230d6708797c241160ba71fbd37e6b22f180a",
236258
self.readme,
237259
)
238260
self.assertIn(
@@ -249,6 +271,36 @@ def test_public_surfaces_link_the_release_evidence_and_changelog(self) -> None:
249271
self.assertIn("complete release qualification remains pending", release)
250272
self.assertNotIn("qualified release", release)
251273

274+
v060 = markdown_section(
275+
self.changelog, "Firmware 0.6.0 — 2026-08-21"
276+
)
277+
for wording in (
278+
"qualified five-profile release",
279+
"`esp32-4mb`",
280+
"`esp32-s3-n16r8`",
281+
"`waveshare-esp32-s3-lcd-147b`",
282+
"`esp32-c3-4mb`",
283+
"`rpi-pico2-w`",
284+
"firmware-v0.6.0",
285+
"0c7230d6708797c241160ba71fbd37e6b22f180a",
286+
"MicroPython v1.28.0",
287+
"ESP-IDF v5.5.1",
288+
"four ESP profiles",
289+
"verified UF2",
290+
"BOOTSEL",
291+
"all five HIL rows passed",
292+
"https://pyble.dev/flash",
293+
):
294+
self.assertIn(wording, v060)
295+
296+
unreleased = markdown_section(self.changelog, "Unreleased")
297+
for stale in (
298+
"Abandoned the unpublished local `firmware-v0.6.0` candidate",
299+
"Pico remains absent from public release metadata",
300+
"all candidate/HIL gates restart",
301+
):
302+
self.assertNotIn(stale, unreleased)
303+
252304
def test_public_specifications_describe_the_exact_beta_without_overclaim(
253305
self,
254306
) -> None:

0 commit comments

Comments
 (0)