mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-14 22:13:47 -06:00
chore: merge origin/main
This commit is contained in:
commit
45cf1accfb
28 files changed
+1084
-600
No files matched your search
@@ -56,8 +56,8 @@ class ReadmeRegressions(unittest.TestCase):
|
||||
|
||||
def _quick_install(self) -> str:
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
return readme.split("## Quick install", 1)[1].split(
|
||||
"## Download BIOS packs", 1
|
||||
return readme.split("## Install in one line", 1)[1].split(
|
||||
"## Or download a ZIP", 1
|
||||
)[0]
|
||||
|
||||
def test_advertised_bootstrap_urls_are_the_shipped_ones(self):
|
||||
@@ -1121,7 +1121,10 @@ class CatalogRatioRegressions(unittest.TestCase):
|
||||
match = re.search(
|
||||
r"\*\*([\d,]+) of ([\d,]+) system files\*\* matched to", readme
|
||||
)
|
||||
self.assertIsNotNone(match, "README no longer states the catalog ratio")
|
||||
if match is None:
|
||||
# The README states no ratio since it leads to the site: a ratio
|
||||
# it states must still be the database's.
|
||||
return
|
||||
matched, total = (int(g.replace(",", "")) for g in match.groups())
|
||||
self.assertEqual(matched, count_catalog_matched(db))
|
||||
self.assertEqual(total, compute_composition(db)["systems"]["files"])
|
||||
|
||||
+10
-13
@@ -340,7 +340,7 @@ class FilesColumnParagraph(unittest.TestCase):
|
||||
paragraph = next(p for p in readme.split("\n\n") if "The Files column" in p)
|
||||
self.assertNotIn("\n", paragraph.strip())
|
||||
after = readme.split(paragraph, 1)[1].lstrip("\n")
|
||||
self.assertTrue(after.startswith("| Platform | Files |"))
|
||||
self.assertTrue(after.startswith("| Setup | Files |"))
|
||||
|
||||
|
||||
class PageOpenings(unittest.TestCase):
|
||||
@@ -769,14 +769,12 @@ class ReadmeInstallerOptions(unittest.TestCase):
|
||||
import generate_readme
|
||||
|
||||
source = inspect.getsource(generate_readme.generate_readme)
|
||||
self.assertIn('install_command("powershell", "--check")', source)
|
||||
self.assertIn("wiki/installer/#passing-options", source)
|
||||
self.assertIn("## Passing options", _page("installer.md"))
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
quick = _section(readme, "Quick install")
|
||||
from siteguides import INSTALL_PS1
|
||||
|
||||
self.assertIn(f"&([scriptblock]::Create((irm {INSTALL_PS1}))) --check", quick)
|
||||
quick = _section(readme, "Install in one line")
|
||||
# The README gives the bare line and sends options to the page that
|
||||
# writes their PowerShell form: an option after `| iex` reaches iex.
|
||||
self.assertIn("wiki/installer/#passing-options", quick)
|
||||
self.assertNotRegex(readme, r"(?m)^irm \S+ \| iex \S")
|
||||
|
||||
@@ -791,7 +789,7 @@ class PublishedNumbersShareOneFormat(unittest.TestCase):
|
||||
|
||||
readme_source = inspect.getsource(generate_readme.generate_readme)
|
||||
self.assertNotIn("size_mb", readme_source)
|
||||
self.assertIn("format_size(total_size)", readme_source)
|
||||
self.assertIn("format_size(size)", readme_source)
|
||||
self.assertIn("{total_files:,}", inspect.getsource(generate_site))
|
||||
self.assertEqual(generate_readme.format_size(16011 * 1024 * 1024), "15.6 GB")
|
||||
|
||||
@@ -1713,9 +1711,7 @@ class ReadmeKeepsItsPointers(unittest.TestCase):
|
||||
"""The README sent a reader to 'build your own pack below' for a bare
|
||||
minimum, and the block below never named --required-only."""
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
self.assertIn("For a bare minimum, build your own pack below.", readme)
|
||||
block = readme[readme.index("## Build your own pack"):]
|
||||
block = block[:block.index("\n## ", 1)]
|
||||
block = readme[readme.index("<summary><strong>For developers"):readme.index("</details>")]
|
||||
self.assertIn("--required-only", block)
|
||||
|
||||
def test_unsourceable_files_are_not_said_to_exist_nowhere(self):
|
||||
@@ -1725,7 +1721,8 @@ class ReadmeKeepsItsPointers(unittest.TestCase):
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
self.assertNotIn("sourced at all", readme)
|
||||
self.assertNotIn("nobody has made", readme)
|
||||
self.assertRegex(readme, r"more the collection does not hold and does not serve by name")
|
||||
# The README names no count: the gap analysis it links does, by reason.
|
||||
self.assertIn("gaps/", readme)
|
||||
|
||||
|
||||
class ArchitectureStatesTheArbitration(unittest.TestCase):
|
||||
@@ -2041,8 +2038,8 @@ class BuildYourOwnPackSaysWhatTheCloneCosts(unittest.TestCase):
|
||||
line = generate_readme.clone_line(db)
|
||||
self.assertIn("git clone --depth 1", line)
|
||||
self.assertRegex(line, r"over \d+(\.\d)? GB")
|
||||
section = _section((ROOT / "README.md").read_text(encoding="utf-8"),
|
||||
"Build your own pack")
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
section = readme[readme.index("<summary><strong>For developers"):readme.index("</details>")]
|
||||
self.assertIn("git clone --depth 1", section)
|
||||
|
||||
def test_advanced_usage_names_the_shallow_clone(self):
|
||||
|
||||
@@ -191,16 +191,17 @@ class DownloadLinksKeepTheirAddress(unittest.TestCase):
|
||||
from common import list_registered_platforms, list_release_pack_platforms
|
||||
|
||||
readme = _read("README.md")
|
||||
table = _section(readme, "## Download BIOS packs")
|
||||
table = _section(readme, "## Or download a ZIP")
|
||||
self.assertNotIn("/releases/download/", table)
|
||||
released = set(list_release_pack_platforms("platforms"))
|
||||
rows = [line for line in table.splitlines() if line.startswith("| ")]
|
||||
for key in list_registered_platforms("platforms"):
|
||||
with self.subTest(platform=key):
|
||||
# Every setup's lasting page is linked: a ZIP's from its row,
|
||||
# the others from the line that says they install by command.
|
||||
self.assertIn(f"]({SITE_URL}get/{key}/)", table)
|
||||
row = next(line for line in table.splitlines()
|
||||
if f"get/{key}/)" in line)
|
||||
if key not in released:
|
||||
self.assertIn("[Use the command]", row)
|
||||
in_rows = any(f"get/{key}/)" in row for row in rows)
|
||||
self.assertEqual(in_rows, key in released)
|
||||
|
||||
def test_the_download_page_rows_link_get_pages(self):
|
||||
page = _which_pack()
|
||||
@@ -258,7 +259,7 @@ class TheReadmeLeadsBeginnersToTheirPages(unittest.TestCase):
|
||||
def test_quick_install_links_the_start_pages(self):
|
||||
# The code block holds `#` comment lines, so the section runs to
|
||||
# the next level-two heading.
|
||||
section = _read("README.md").split("## Quick install", 1)[1].split("\n## ", 1)[0]
|
||||
section = _read("README.md").split("## Install in one line", 1)[1].split("\n## ", 1)[0]
|
||||
for page in ("first-install", "troubleshooting", "faq"):
|
||||
with self.subTest(page=page):
|
||||
self.assertIn(f"wiki/{page}/)", section)
|
||||
|
||||
@@ -284,9 +284,9 @@ class EverySurfaceSaysWhy(unittest.TestCase):
|
||||
|
||||
def test_the_readme_rows_read_use_the_command(self):
|
||||
readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
row = next(line for line in readme.splitlines() if line.startswith("| KNULLI |"))
|
||||
self.assertIn(f"[Use the command]({SITE}get/knulli/)", row)
|
||||
self.assertIn("ZIPs are made for the setups most people download.", readme)
|
||||
line = next(text for text in readme.split("\n\n") if "ZIPs are made for the setups most people download." in text)
|
||||
self.assertIn(f"[KNULLI]({SITE}get/knulli/)", line)
|
||||
self.assertIn("install with the line above", line)
|
||||
|
||||
def test_the_faq_answers_why(self):
|
||||
faq = (REPO_ROOT / "wiki" / "faq.md").read_text(encoding="utf-8")
|
||||
|
||||
@@ -271,7 +271,7 @@ class GeneratedSurfaces(unittest.TestCase):
|
||||
|
||||
def test_the_readme_shows_the_short_form(self):
|
||||
readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
quick = readme.split("## Quick install", 1)[1].split("\n## ", 1)[0]
|
||||
quick = readme.split("## Install in one line", 1)[1].split("\n## ", 1)[0]
|
||||
self.assertIn(f"\n{install_command('sh')}\n", quick)
|
||||
self.assertIn(f"\n{install_command('powershell')}\n", quick)
|
||||
self.assertNotIn("raw.githubusercontent.com", quick)
|
||||
|
||||
+145
-40
@@ -1,9 +1,12 @@
|
||||
"""The installer demo of the README and the site (scripts/make_demo.py).
|
||||
"""The installer demos of the README and the site (scripts/make_demo.py).
|
||||
|
||||
The home page and Get your files score 98 to 100 on a phone: the video must
|
||||
The home page and Get your files score 98 to 100 on a phone: a video must
|
||||
cost nothing before it is on screen, keep still under reduced motion, and say
|
||||
in words what it shows. The files are committed, so their sizes are held
|
||||
here, and the words come from what the recording measured.
|
||||
here, and the words come from what each recording measured. Get your files
|
||||
shows one recording per tab of its install box: the handheld's under "On the
|
||||
device", none under Windows (no Windows recording is published), the
|
||||
terminal recording under the others.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -29,43 +32,90 @@ COMPONENT = ROOT / "website" / "src" / "components" / "InstallDemo.astro"
|
||||
DIST = ROOT / "website" / "dist"
|
||||
|
||||
|
||||
def _facts() -> dict:
|
||||
def _all_facts() -> dict:
|
||||
return json.loads((DEMO / "demo.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def _facts(variant: str = "default") -> dict:
|
||||
return _all_facts()[variant]
|
||||
|
||||
|
||||
class TheFilesAreThereAndSmall(unittest.TestCase):
|
||||
def test_each_output_is_under_its_target(self):
|
||||
for name, limit in make_demo.LIMITS.items():
|
||||
with self.subTest(name=name):
|
||||
self.assertLessEqual((DEMO / name).stat().st_size, limit)
|
||||
for variant in make_demo.VARIANTS.values():
|
||||
for name, limit in make_demo.limits(variant).items():
|
||||
with self.subTest(name=name):
|
||||
self.assertLessEqual((DEMO / name).stat().st_size, limit)
|
||||
|
||||
def test_the_gif_and_the_poster_have_the_recorded_size(self):
|
||||
def test_only_the_readme_variant_has_a_gif(self):
|
||||
gifs = sorted(p.name for p in DEMO.glob("*.gif"))
|
||||
self.assertEqual(gifs, [Path(generate_readme.DEMO_GIF).name])
|
||||
self.assertEqual([v.name for v in make_demo.VARIANTS.values() if v.gif], ["default"])
|
||||
|
||||
def test_the_gif_and_the_posters_have_the_recorded_size(self):
|
||||
facts = _facts()
|
||||
head = (DEMO / "install.gif").read_bytes()[:10]
|
||||
self.assertEqual(head[:6], b"GIF89a")
|
||||
self.assertEqual(struct.unpack("<HH", head[6:10]), (facts["width"], facts["height"]))
|
||||
png = (DEMO / "install.png").read_bytes()[:24]
|
||||
self.assertEqual(png[:8], b"\x89PNG\r\n\x1a\n")
|
||||
self.assertEqual(struct.unpack(">II", png[16:24]), (facts["width"], facts["height"]))
|
||||
for variant in make_demo.VARIANTS.values():
|
||||
facts = _facts(variant.name)
|
||||
png = (DEMO / f"{variant.stem}.png").read_bytes()[:24]
|
||||
with self.subTest(variant=variant.name):
|
||||
self.assertEqual(png[:8], b"\x89PNG\r\n\x1a\n")
|
||||
self.assertEqual(struct.unpack(">II", png[16:24]),
|
||||
(facts["width"], facts["height"]))
|
||||
|
||||
def test_the_videos_are_webm_and_mp4(self):
|
||||
self.assertEqual((DEMO / "install.webm").read_bytes()[:4], b"\x1a\x45\xdf\xa3")
|
||||
self.assertEqual((DEMO / "install.mp4").read_bytes()[4:8], b"ftyp")
|
||||
for variant in make_demo.VARIANTS.values():
|
||||
with self.subTest(variant=variant.name):
|
||||
self.assertEqual((DEMO / f"{variant.stem}.webm").read_bytes()[:4],
|
||||
b"\x1a\x45\xdf\xa3")
|
||||
self.assertEqual((DEMO / f"{variant.stem}.mp4").read_bytes()[4:8], b"ftyp")
|
||||
|
||||
def test_demo_json_holds_each_variant_and_its_alt_text(self):
|
||||
facts = _all_facts()
|
||||
self.assertEqual(list(facts), list(make_demo.VARIANTS))
|
||||
for name, entry in facts.items():
|
||||
with self.subTest(variant=name):
|
||||
self.assertEqual(entry["alt"], make_demo.describe(name, entry))
|
||||
# Written into an MDX attribute: no quote of either kind.
|
||||
self.assertNotRegex(entry["alt"], "[\"']")
|
||||
|
||||
|
||||
class TheTapeAndTheDriverAgree(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tape = make_demo.TAPE.read_text(encoding="utf-8")
|
||||
|
||||
def test_the_tape_writes_what_the_driver_encodes(self):
|
||||
self.assertIn(f"Output {make_demo.RECORDED.relative_to(ROOT).as_posix()}\n", self.tape)
|
||||
self.assertIn(f"Screenshot {make_demo.POSTER_SHOT.relative_to(ROOT).as_posix()}\n",
|
||||
self.tape)
|
||||
def test_each_tape_writes_what_the_driver_encodes(self):
|
||||
for variant in make_demo.VARIANTS.values():
|
||||
tape = variant.tape.read_text(encoding="utf-8")
|
||||
with self.subTest(variant=variant.name):
|
||||
self.assertIn(f"Output {variant.recorded.relative_to(ROOT).as_posix()}\n", tape)
|
||||
self.assertIn(
|
||||
f"Screenshot {variant.poster_shot.relative_to(ROOT).as_posix()}\n", tape)
|
||||
|
||||
def test_the_size_in_demo_json_is_the_tapes(self):
|
||||
facts = _facts()
|
||||
self.assertIn(f"Set Width {facts['width']}\n", self.tape)
|
||||
self.assertIn(f"Set Height {facts['height']}\n", self.tape)
|
||||
def test_the_size_in_demo_json_is_each_tapes(self):
|
||||
for variant in make_demo.VARIANTS.values():
|
||||
facts, tape = _facts(variant.name), variant.tape.read_text(encoding="utf-8")
|
||||
with self.subTest(variant=variant.name):
|
||||
self.assertIn(f"Set Width {facts['width']}\n", tape)
|
||||
self.assertIn(f"Set Height {facts['height']}\n", tape)
|
||||
|
||||
def test_the_handheld_is_an_r36s_screen_driven_by_its_buttons(self):
|
||||
variant = make_demo.VARIANTS["handheld"]
|
||||
tape = variant.tape.read_text(encoding="utf-8")
|
||||
self.assertIn("Set Width 640\n", tape)
|
||||
self.assertIn("Set Height 480\n", tape)
|
||||
# Nothing typed but the hidden start of the session: the buttons
|
||||
# gptokeyb maps (ports/shared/retrobios.gptk: a = enter) do the rest.
|
||||
self.assertEqual(re.findall(r"^Type (.*)$", tape, re.M),
|
||||
["'exec \"$RETROBIOS_DEMO_SESSION\"'"])
|
||||
gptk = (ROOT / "ports" / "shared" / "retrobios.gptk").read_text(encoding="utf-8")
|
||||
self.assertRegex(gptk, r"(?m)^a = enter$")
|
||||
env = make_demo.session_env("http://127.0.0.1:1", ROOT / "tmp", ROOT / "tmp", variant)
|
||||
self.assertEqual(env["RETROBIOS_PAD"], "gptokeyb")
|
||||
self.assertEqual(env["RETROBIOS_OS"], "linux")
|
||||
self.assertEqual(variant.mount, "/roms")
|
||||
|
||||
def test_the_command_typed_is_the_one_the_pages_give(self):
|
||||
from siteguides import install_command # noqa: PLC0415
|
||||
@@ -84,8 +134,8 @@ class TheReadmeShowsTheGif(unittest.TestCase):
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
line = f""
|
||||
self.assertIn(line, readme)
|
||||
self.assertLess(readme.index("## Quick install"), readme.index(line))
|
||||
self.assertLess(readme.index(line), readme.index("## Download BIOS packs"))
|
||||
self.assertLess(readme.index("## Install in one line"), readme.index(line))
|
||||
self.assertLess(readme.index(line), readme.index("## Or download a ZIP"))
|
||||
|
||||
def test_the_description_names_what_the_recording_measured(self):
|
||||
facts = _facts()
|
||||
@@ -112,7 +162,13 @@ class TheVideoLoadsOnlyOnScreen(unittest.TestCase):
|
||||
self.assertRegex(self.markup, rf"\n\t\t{attribute}\n")
|
||||
|
||||
def test_webm_comes_before_mp4(self):
|
||||
self.assertLess(self.markup.index("install.webm"), self.markup.index("install.mp4"))
|
||||
self.assertLess(self.markup.index("asset('webm')"), self.markup.index("asset('mp4')"))
|
||||
|
||||
def test_each_variant_has_its_files_and_its_own_ids(self):
|
||||
self.assertIn("const stem = variant === 'default' ? 'install' : `install-${variant}`;",
|
||||
self.source)
|
||||
self.assertIn("const textId = name ? `rb-demo-text-${name}` : 'rb-demo-text';",
|
||||
self.source)
|
||||
|
||||
def test_reduced_motion_keeps_the_poster_with_a_button(self):
|
||||
self.assertIn("matchMedia('(prefers-reduced-motion: reduce)')", self.source)
|
||||
@@ -121,44 +177,93 @@ class TheVideoLoadsOnlyOnScreen(unittest.TestCase):
|
||||
self.markup)
|
||||
|
||||
def test_screen_readers_get_the_description(self):
|
||||
self.assertIn('aria-describedby="rb-demo-text"', self.markup)
|
||||
self.assertIn('<figcaption id="rb-demo-text" class="sr-only">{description}</figcaption>',
|
||||
self.assertIn("aria-describedby={textId}", self.markup)
|
||||
self.assertIn('<figcaption id={textId} class="sr-only">{description}</figcaption>',
|
||||
self.markup)
|
||||
|
||||
def test_the_component_is_registered(self):
|
||||
self.assertEqual(sitestarlight.COMPONENTS["InstallDemo"], "components/InstallDemo.astro")
|
||||
|
||||
|
||||
def _tab_bodies(markdown: str) -> dict[str, str]:
|
||||
"""Each tab of the quick install box of Get your files, by label."""
|
||||
box = markdown[markdown.index("{ #quick-install }"):]
|
||||
box = box[:box.index("</Tabs>")]
|
||||
return dict(re.findall(r'<TabItem label="([^"]+)">(.*?)</TabItem>', box, re.S))
|
||||
|
||||
|
||||
class TheTwoPagesShowIt(unittest.TestCase):
|
||||
def test_home_and_get_your_files(self):
|
||||
def test_home_shows_the_terminal_recording(self):
|
||||
import generate_site # noqa: PLC0415
|
||||
|
||||
tag = generate_site.install_demo()[0]
|
||||
self.assertIn(f'description="{generate_readme.demo_description()}"', tag)
|
||||
source = Path(generate_site.__file__).read_text(encoding="utf-8")
|
||||
for function in ("def generate_home(", "def generate_which_pack("):
|
||||
body = source[source.index(function):]
|
||||
body = body[:body.index("\ndef ", 1)]
|
||||
with self.subTest(function=function):
|
||||
self.assertIn("*install_demo(),", body)
|
||||
body = source[source.index("def generate_home("):]
|
||||
body = body[:body.index("\ndef ", 1)]
|
||||
self.assertIn("*install_demo(),", body)
|
||||
|
||||
def test_the_site_serves_the_video_not_the_gif(self):
|
||||
def test_each_tab_of_get_your_files_shows_its_variant(self):
|
||||
import generate_site # noqa: PLC0415
|
||||
|
||||
self.assertEqual(generate_site.DEMO_ASSETS, ("install.webm", "install.mp4", "install.png"))
|
||||
tabs = _tab_bodies(generate_site.generate_which_pack())
|
||||
expected = {"Windows": None, "macOS": "default", "Linux": "default",
|
||||
"Steam Deck": "default", "Android (Termux)": "default",
|
||||
"On the device": "handheld"}
|
||||
self.assertEqual(set(tabs), set(expected))
|
||||
for label, variant in expected.items():
|
||||
demos = re.findall(r"<InstallDemo [^>]*/>", tabs[label])
|
||||
with self.subTest(tab=label):
|
||||
if variant is None:
|
||||
self.assertEqual(demos, [])
|
||||
continue
|
||||
self.assertEqual(len(demos), 1)
|
||||
self.assertIn(f'description="{_facts(variant)["alt"]}"', demos[0])
|
||||
self.assertIn(f'width="{_facts(variant)["width"]}"', demos[0])
|
||||
self.assertIn(f'variant="{variant}"', demos[0])
|
||||
# The demo below the box moved into its tabs: one per tab, no other.
|
||||
page = generate_site.generate_which_pack()
|
||||
self.assertEqual(page.count("<InstallDemo "), len(expected) - 1)
|
||||
|
||||
def test_the_site_serves_the_videos_not_the_gif(self):
|
||||
import generate_site # noqa: PLC0415
|
||||
|
||||
expected = tuple(name for variant in make_demo.VARIANTS.values()
|
||||
for name in variant.outputs if not name.endswith(".gif"))
|
||||
self.assertEqual(sorted(generate_site.DEMO_ASSETS), sorted(expected))
|
||||
|
||||
def test_the_built_pages_fetch_nothing_of_it(self):
|
||||
if not (DIST / "index.html").is_file():
|
||||
self.skipTest("no built site")
|
||||
for page in ("index.html", "which-pack/index.html"):
|
||||
html = (DIST / page).read_text(encoding="utf-8")
|
||||
figure = re.search(r'<figure class="rb-demo[^"]*".*?</figure>', html, re.S)
|
||||
figures = re.findall(r'<figure class="rb-demo[^"]*".*?</figure>', html, re.S)
|
||||
with self.subTest(page=page):
|
||||
self.assertIsNotNone(figure)
|
||||
self.assertIn('preload="none"', figure.group(0))
|
||||
self.assertNotRegex(figure.group(0), r"\s(src|poster)=")
|
||||
for name in ("install.webm", "install.mp4", "install.png"):
|
||||
self.assertTrue((DIST / "assets" / "demo" / name).is_file())
|
||||
self.assertTrue(figures)
|
||||
for figure in figures:
|
||||
self.assertIn('preload="none"', figure)
|
||||
self.assertNotRegex(figure, r"\s(src|poster)=")
|
||||
for name in generate_site_assets():
|
||||
self.assertTrue((DIST / "assets" / "demo" / name).is_file())
|
||||
|
||||
def test_the_built_tabs_hold_their_variant(self):
|
||||
page = DIST / "which-pack" / "index.html"
|
||||
if not page.is_file():
|
||||
self.skipTest("no built site")
|
||||
html = page.read_text(encoding="utf-8")
|
||||
panel = r'<div[^>]*role="tabpanel"'
|
||||
panels = re.findall(rf"{panel}[^>]*>(.*?)(?={panel}|</starlight-tabs>)", html, re.S)
|
||||
variants = [re.findall(r'data-variant="([a-z]+)"', panel) for panel in panels]
|
||||
# The quick install box: Windows, macOS, Linux, Steam Deck, Android, device.
|
||||
self.assertIn([[], ["default"], ["default"], ["default"], ["default"], ["handheld"]],
|
||||
[variants[i:i + 6] for i in range(len(variants) - 5)])
|
||||
self.assertIn("assets/demo/install-handheld.png", html)
|
||||
|
||||
|
||||
def generate_site_assets() -> tuple[str, ...]:
|
||||
import generate_site # noqa: PLC0415
|
||||
|
||||
return generate_site.DEMO_ASSETS
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -237,7 +237,7 @@ class FaqInstallsFromWhatYouHold(unittest.TestCase):
|
||||
word = rule.name.split()[0]
|
||||
with self.subTest(share=rule.name):
|
||||
self.assertIn(word, section)
|
||||
self.assertRegex(readme, rf"# SD card mounted on a PC: .*\b{word}\b")
|
||||
self.assertRegex(readme, rf"\b{word}\b[^.]*SD card plugged into the computer is found by itself")
|
||||
# The label the first screen gives a card found: "Onion SD card".
|
||||
self.assertEqual(install._card_word(("retroarch", Path("/x/BIOS"), "Onion")), "SD card")
|
||||
self.assertEqual(install._card_word(("batocera", Path("/x/bios"), "Batocera")),
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
"""The drawn steps of the install box (scripts/sitesteps.py).
|
||||
|
||||
Each drawing says in words what it shows, to a screen reader and to a
|
||||
reader whose images do not load: a title and a desc the SVG names. It tells
|
||||
the same steps as the text above it, the keys included, so the picture and
|
||||
the words never disagree. And it draws in the theme's colours.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tests # noqa: F401 offline, scratch under tmp/, the suite's own cache
|
||||
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(ROOT / "scripts"))
|
||||
|
||||
import sitesteps # noqa: E402
|
||||
from siteguides import TERMINALS # noqa: E402
|
||||
|
||||
SVG = "{http://www.w3.org/2000/svg}"
|
||||
DIST = ROOT / "website" / "dist"
|
||||
|
||||
|
||||
class EachDrawingNamesItsSteps(unittest.TestCase):
|
||||
def test_title_and_desc_are_what_aria_points_at(self):
|
||||
for tab in sitesteps.STEPS:
|
||||
for layout in ("wide", "narrow"):
|
||||
root = ET.fromstring(sitesteps._svg(tab, layout))
|
||||
with self.subTest(tab=tab, layout=layout):
|
||||
self.assertEqual(root.get("role"), "img")
|
||||
title, desc = root.find(f"{SVG}title"), root.find(f"{SVG}desc")
|
||||
self.assertIsNotNone(title)
|
||||
self.assertIsNotNone(desc)
|
||||
self.assertEqual(root.get("aria-labelledby").split(),
|
||||
[title.get("id"), desc.get("id")])
|
||||
self.assertEqual(desc.text, sitesteps.description(tab))
|
||||
|
||||
def test_every_caption_drawn_is_in_the_desc(self):
|
||||
for tab, (_title, steps) in sitesteps.STEPS.items():
|
||||
desc = sitesteps.description(tab)
|
||||
for step in steps:
|
||||
with self.subTest(tab=tab, step=step.caption):
|
||||
self.assertIn(step.caption, desc)
|
||||
|
||||
def test_the_drawing_and_the_text_name_the_same_keys(self):
|
||||
for tab, (_title, steps) in sitesteps.STEPS.items():
|
||||
text = TERMINALS[tab][1].replace("**", "")
|
||||
keys = {step.word for step in steps if step.icon == "keys"}
|
||||
with self.subTest(tab=tab):
|
||||
for word in keys:
|
||||
self.assertIn(word, text)
|
||||
drawn = set(re.findall(r"\b(?:Ctrl|Cmd|Shift|Alt)\+\w+(?:\+\w+)?", text))
|
||||
self.assertLessEqual(drawn, keys)
|
||||
self.assertIn("Click Copy", text)
|
||||
|
||||
def test_one_drawing_per_computer_tab_none_elsewhere(self):
|
||||
self.assertEqual(set(sitesteps.STEPS), {"windows", "macos", "linux", "steamdeck"})
|
||||
self.assertEqual(sitesteps.steps_figure("device"), [])
|
||||
|
||||
def test_colours_come_from_the_theme(self):
|
||||
for tab in sitesteps.STEPS:
|
||||
root = ET.fromstring(sitesteps._svg(tab, "wide"))
|
||||
for node in root.iter():
|
||||
tag = node.tag.removeprefix(SVG)
|
||||
if tag in ("rect", "path", "circle"):
|
||||
with self.subTest(tab=tab, node=ET.tostring(node)[:60]):
|
||||
self.assertTrue(node.get("class", "").startswith("rb-d-"))
|
||||
|
||||
def test_ids_are_unique_on_the_page(self):
|
||||
ids = re.findall(r'id="([^"]+)"', "".join(
|
||||
sitesteps._svg(tab, layout) for tab in sitesteps.STEPS for layout in ("wide", "narrow")))
|
||||
self.assertEqual(len(ids), len(set(ids)))
|
||||
|
||||
|
||||
class TheBuiltPageHoldsThem(unittest.TestCase):
|
||||
def test_under_each_tab_of_get_your_files(self):
|
||||
page = DIST / "which-pack" / "index.html"
|
||||
if not page.is_file():
|
||||
self.skipTest("no built site")
|
||||
html = page.read_text(encoding="utf-8")
|
||||
for tab in sitesteps.STEPS:
|
||||
with self.subTest(tab=tab):
|
||||
self.assertIn(f'aria-labelledby="rb-steps-{tab}-wide-t rb-steps-{tab}-wide-d"',
|
||||
html)
|
||||
self.assertIn(f'<desc id="rb-steps-{tab}-narrow-d">', html)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user