chore: merge round 5 package a29b43f1fc43aba6b

This commit is contained in:
Abdessamad Derraz committed 2026-10-24 01:27:26 +02:00
commit d47763fdc1
5 files changed
+423 -27

No files matched your search

+10
View File
@@ -10,6 +10,7 @@
# `{folders}` in it is the folder list of the page.
# `runs_on` names the hardware in the project's own words, cited beside it.
# `terminal` is how this system opens a terminal, from its own documentation.
# `card_run` names the computers that open the device's card, when not all do.
# `lead` comes before the folder table, `finish` closes the guide.
# `logo_owner` and `logo_licence` credit the logo the registry links: it is
# shown only to name the platform, with the licence of the repository the
@@ -214,7 +215,13 @@ handheld_guide:
folder_source: https://github.com/game-de-it/plumOS-XU20V32/blob/main/docs/developer/storage-and-updates.md
devices: [MagicX XU20 V32]
devices_source: https://github.com/game-de-it/plumOS-XU20V32
# RetroOZ publishes no build source. Its wiki keeps games under /roms and
# sends BIOS questions to the ArkOS wiki, whose folder is bios in roms. The
# 0.60 image sets system_directory "/roms/bios" (retroarch32/retroarch.cfg:3046).
# Written as the device path: no RetroOZ page names the card's parts.
- name: RetroOZ
folder: '`/roms/bios`, as the device names it'
folder_source: https://github.com/southoz/RetroOZ/wiki/Home/4ce4fafb78d647d422e9e468d5bd9cbc63dbe3ea
devices: [OGS, OGA, RGB10Max, RGB10Max2]
devices_source: https://github.com/southoz/RetroOZ/wiki
- name: UnofficialOS
@@ -618,6 +625,9 @@ guides:
# is the network folder above.
terminal: >-
Press **F4** in the game menu for a terminal. Paste the line. Press Enter.
# The BIOS folder is on the card's Linux partition (pack_manual below):
# from a computer, only Linux opens it.
card_run: [linux]
notes:
- >-
Install with `--platform retropie`, not RetroArch's files. The command does not run on
+162 -22
View File
@@ -547,7 +547,7 @@ def generate_home(
"",
*markup.steps([
"**Pick your device.** Its page shows your BIOS folder.",
"**Run one command**, or download a ZIP file.",
"**Run one command.** Some setups have a ZIP.",
"**Start a game.**",
]),
"## Pick your device",
@@ -720,6 +720,49 @@ def get_page_link(platform_name: str, prefix: str = "") -> str:
return f"{prefix}{release_record.GET_DIR}/{platform_name}.md"
def get_page_title(platform_name: str, display: str) -> str:
"""What a get/ page holds, by its name: the ZIP of a setup a release
publishes one for, the files of any other. "Download KNULLI" read as
the system's own download. A setup that is also an emulator (BizHawk)
names it last: "BizHawk BIOS files" is the title of its emulator page."""
kind = "BIOS pack" if has_release_pack(platform_name) else "BIOS files"
if (_REPO_ROOT / "emulators" / f"{platform_name}.yml").is_file():
return f"{kind} for {display}"
return f"{display} {kind}"
def _unzip_into(platform_name: str, display: str, extract_to: str | None, parts: int) -> list[str]:
"""Where the ZIP is unzipped, on the get/ page. A folder the registry
writes relative to the setup's own (`system/`, `bios/`) is named as the
setup's, with the way to find it."""
what = "them all" if parts > 1 else "it"
if not _setup_relative(extract_to):
return [f"- Unzip {what} into {_folder_words(display, extract_to)}.", ""]
lead = GUIDES[platform_name].lead if platform_name in GUIDES else ""
return [
f"- Unzip {what} into {_folder_words(display, extract_to)}. "
f"[Where is it?](../platforms/{platform_name}.md#where-the-files-go)",
"",
*([lead, ""] if lead else []),
]
def _setup_relative(extract_to: str | None) -> bool:
"""Whether the registry writes the folder relative to the setup's own
(`system/`, `Firmware/`), not as a path the device reads."""
return bool(extract_to) and not extract_to.startswith(("/", "~", "<"))
def _folder_words(display: str, extract_to: str | None) -> str:
"""The folder a pack or a copy goes into, in words: the device's path,
or a folder of the setup named as the setup's."""
if not extract_to:
return "your BIOS folder"
if _setup_relative(extract_to):
return f"{display}'s `{extract_to.rstrip('/')}` folder"
return f"`{extract_to}`"
def _pack_buttons(platform_name: str, label: str = "Pack", prefix: str = "../",
display: str | None = None) -> str:
"""The way to the platform's ZIP from its setup page: a button to its
@@ -757,7 +800,17 @@ def generate_get_page(platform_name: str) -> str:
record = release_record.load_advertised()
pack = release_record.pack_for(platform_name, record)
released = has_release_pack(platform_name)
lines = ["---", "search: exclude", "---", "", f"# Download {display}", ""]
title = get_page_title(platform_name, display)
if released and pack and pack.get("assets"):
description = (f"The BIOS pack for {display}: {_fmt_size(pack['download_size'])} to "
"download. The address stays the same and always gives the latest ZIP.")
else:
description = f"The BIOS files for {display}: one command installs and checks them."
lines = [
"---", "search: exclude", f"description: {json.dumps(description)}",
*_parent_front_matter((display, f"/platforms/{platform_name}/")), "---", "",
f"# {title}", "",
]
if released and pack and pack.get("assets"):
parts = len(pack["assets"])
release = release_line(platform_name, record)
@@ -772,9 +825,7 @@ def generate_get_page(platform_name: str) -> str:
f"{_fmt_size(pack['extracted_size'])} once unzipped.",
*(["- You need both parts." if parts == 2 else f"- You need all {parts} parts."]
if parts > 1 else []),
f"- Unzip {'them all' if parts > 1 else 'it'} into "
+ (f"`{extract_to}`." if extract_to else "your BIOS folder."),
"",
*_unzip_into(platform_name, display, extract_to, parts),
*(line for text in release for line in (text, "")),
version_line(platform_name, record, named=len(release) > 1),
"",
@@ -784,7 +835,7 @@ def generate_get_page(platform_name: str) -> str:
f"No {display} ZIP yet. The next release has one. "
"The command installs every file and checks it.",
"",
*install_commands(f"--platform {platform_name}"),
*_setup_routes(platform_name, display),
]
elif released:
lines += [
@@ -797,7 +848,7 @@ def generate_get_page(platform_name: str) -> str:
lines += [
no_zip_line(display),
"",
*install_commands(f"--platform {platform_name}"),
*_setup_routes(platform_name, display),
f"[Why no ZIP?](../{NO_ZIP_FAQ})",
"",
]
@@ -809,6 +860,29 @@ def generate_get_page(platform_name: str) -> str:
return "\n".join(lines)
def generate_get_index() -> str:
"""get/: the permanent page of every setup, grouped as the home tiles
are. A link trimmed to /get/ answered 404."""
registry = load_platform_registry("platforms")
lines = [
"---", "search: exclude",
'description: "The BIOS files of every setup, one page each. Each address stays the same."',
"---", "",
"# BIOS files by setup", "",
"One page per setup. Its address stays the same, so it is the one to share.", "",
]
for group, (label, _description) in DEVICE_GROUPS.items():
names = [name for name, entry in registry.items() if entry.get("device_group") == group]
if not names:
continue
lines += [f"## {label}", ""]
for name in names:
display = load_platform_config(name, "platforms").get("platform", name)
lines.append(f"- [{get_page_title(name, display)}]({name}.md)")
lines.append("")
return "\n".join(lines)
# The home tile counts the whole collection. Labelled "Files" above a table
# of pack buttons, it read as what one pack contains.
COLLECTION_FILES_LABEL = "Files collected"
@@ -3633,6 +3707,12 @@ MISSING_IN_PLACE = "Reported missing anyway? `--check` names a wrong file."
# page shows in full, so the setup page links it.
SAFE_LINK = "[Is it safe?](../index.md#is-it-safe)"
# The pass line of "How to check". `--check` prints "All files up to date."
# only when no file is missing or wrong (install.py, the args.check branch
# after check_local). "0 wrong hash" alone is also what an empty folder
# prints: 0/14508 present (0 verified, 0 wrong hash).
CHECK_PASS_LINE = "All good when it says `All files up to date.`"
# Under "From your computer": a device with no network installs from the ZIP
# (`--from-pack`). The id is the one wiki/installer.md gives its section.
OFFLINE_LINE = ("No internet on the device? "
@@ -3658,6 +3738,71 @@ def _offline_line(name: str) -> list[str]:
return [OFFLINE_LINE, ""] if pack and pack.get("assets") else []
# The route of a setup with no ZIP when the device has no network: the
# command writes to any folder named after --dest (wiki/installer.md), so a
# computer fills the device's card. The FAQ answers it with an example.
CARD_ROUTE_FAQ = "wiki/faq.md#fill-an-sd-card-from-a-computer"
def _card_route(name: str, display: str, guide: Guide) -> list[str]:
"""The route with no network on the device, for a setup whose ZIP no
release publishes: the command run on a computer, into the card. A
setup with a ZIP has the offline line, a card setup's command already
runs on the computer. The folder named after --dest is the one the
command fills on the device (the registry's extract_to): AmberELEC's is
`/storage/roms/`, which holds `bios/` and `neogeo/`. How a computer
sees it is the reader's to name: no guide cites it."""
if guide.on_card or _offline_line(name):
return []
extract_to = (load_platform_registry("platforms").get(name) or {}).get("extract_to")
leaf = (extract_to or "bios").rstrip("/").rsplit("/", 1)[-1].lstrip("~") or "bios"
tabs = guide.card_run or ("windows", "macos", "linux")
args = {key: f"--platform {name} --dest "
+ (f"E:\\path\\to\\{leaf}" if key == "windows" else f"/path/to/{leaf}")
for key in tabs}
if guide.run != ("device",):
lead = ("No network here? Run the command on a computer that has one, with a USB "
f"drive's folder after `--dest`. Then copy it into {_folder_words(display, extract_to)}.")
return [lead, "", *terminal_tabs(tabs, args, steps=False)]
lead = ("No network? Put the device's card in your computer. After `--dest`, "
f"name the folder the device calls `{extract_to}`.")
return [lead, "", *terminal_tabs(tabs, args, steps=False),
f"[More on SD cards](../{CARD_ROUTE_FAQ})", ""]
def _get_page_line(name: str, display: str) -> list[str]:
"""The setup's get/ page, under the command of a setup with no ZIP: the
address a guide writer keeps. A setup with a ZIP links it by its button."""
if has_release_pack(name):
return []
return [f"Link to share: [{get_page_title(name, display)}](../{get_page_link(name)})", ""]
def _setup_routes(name: str, display: str, page_link: bool = False) -> list[str]:
"""The ways to run the command for a setup no ZIP serves first, written
once for its setup page and its get/ page: the network folder from a
computer, the card from a computer when the device has no network, and
the device's own terminal. *page_link* adds the get/ page, on the setup
page only."""
guide = GUIDES[name]
share = _network_share(name, guide)
card = _card_route(name, display, guide)
shared = _get_page_line(name, display) if page_link else []
if share or (card and guide.run == ("device",)):
computer = ["## From your computer { #from-your-computer }", ""]
if share:
computer += [
"Needs the device on your network. Run the command on the computer.",
"",
*terminal_tabs(("windows",), {"windows": f"--platform {name} --dest {share}"}),
SAFE_LINK,
"",
]
return [*computer, *card,
*_guide_install(name, guide, "## On the device { #install }"), *shared]
return [*_guide_install(name, guide, "## Install"), *shared, *card]
# Shown in the "On the device" tab of a guide that has no `terminal:` of its own.
DEVICE_TERMINAL_FALLBACK = "Or fill the folder from your computer, with the ZIP."
@@ -3868,7 +4013,6 @@ def _platform_guide(name: str, display: str, cov: dict, registry: dict, no_list:
])
if guide.on_card:
lines += ["<!-- image: minui-card -->", ""]
share = _network_share(name, guide)
if _computer_first(name, guide):
lines += [
*_guide_download(name, display, guide, extract_to,
@@ -3876,21 +4020,9 @@ def _platform_guide(name: str, display: str, cov: dict, registry: dict, no_list:
*_offline_line(name),
*_guide_install(name, guide, "## On the device { #install }"),
]
elif share:
lines += [
"## From your computer { #from-your-computer }",
"",
"Needs the device on your network. Run the command on the computer.",
"",
*terminal_tabs(("windows",), {"windows": f"--platform {name} --dest {share}"}),
SAFE_LINK,
"",
*_guide_install(name, guide, "## On the device { #install }"),
*_guide_download(name, display, guide, extract_to, "## Download"),
]
else:
lines += [
*_guide_install(name, guide, "## Install"),
*_setup_routes(name, display, page_link=True),
*_guide_download(name, display, guide, extract_to, "## Download"),
*_offline_line(name),
]
@@ -3901,7 +4033,7 @@ def _platform_guide(name: str, display: str, cov: dict, registry: dict, no_list:
"Add `--check` to the command. It changes nothing.",
"",
*terminal_tabs(guide.run, check_args, steps=False),
"All good when you see `0 wrong hash`.",
CHECK_PASS_LINE,
"",
_check_sentence(display, cov["mode"], cov["config"], no_list),
"",
@@ -9728,6 +9860,9 @@ IOS_SOURCES = {
"provenance": "https://wiki.provenance-emu.com/using-provenance/importing-roms",
}
IOS_DEVICES = ("iPhone", "iPad", "iOS", "Delta", "Provenance")
# The same names as which-pack's search terms, the section's meta field
# alone leaving "ios" unanswered.
IOS_TERMS = tuple(name.lower() for name in IOS_DEVICES)
def ios_section() -> list[str]:
@@ -9764,6 +9899,10 @@ def generate_which_pack() -> str:
display = {key: load_platform_config(key, "platforms").get("platform", key) for key in registry}
all_tabs = ("windows", "macos", "linux", "steamdeck", "android")
lines = [
"---",
f"terms: {', '.join(IOS_TERMS)}",
"---",
"",
"# Get your files",
"",
"Pick your setup. Its page gives the folder and the command.",
@@ -10450,6 +10589,7 @@ def _generate(args: argparse.Namespace) -> None:
get_dir.mkdir(parents=True, exist_ok=True)
for name in platform_names:
write_if_changed(str(get_dir / f"{name}.md"), generate_get_page(name))
write_if_changed(str(get_dir / "index.md"), generate_get_index())
print("Generating contributing page...")
write_if_changed(str(docs / "contributing.md"), generate_contributing())
+10 -4
View File
@@ -41,7 +41,9 @@ class Guide:
README inside the pack. `logo_owner` and `logo_licence` credit the
logo the registry links. `runs_on` names the hardware, in the project's
own words, for its tile and its row. `terminal` replaces the shared
"On the device" text with how this system opens a terminal. `lead` comes
"On the device" text with how this system opens a terminal. `card_run`
names the computers that can open the BIOS folder on the device's card,
when not every one can. `lead` comes
before the folder table, `finish` closes the guide. `{folders}` in
`pack_manual` is the folder list of the page, so the README and the page
cannot name two folders for one device.
@@ -66,6 +68,7 @@ class Guide:
terminal: str = ""
lead: str = ""
finish: str = ""
card_run: tuple[str, ...] = ()
@dataclass(frozen=True)
@@ -180,10 +183,13 @@ def _guide(name: str, data: object, extract_to: str, terminals: dict) -> Guide:
if missing:
raise GuideError(f"{where}: missing {', '.join(missing)}")
run = _texts(data["run"], f"{where}.run")
unknown_tabs = [key for key in run if key not in terminals]
if unknown_tabs:
raise GuideError(f"{where}.run: no terminal named {', '.join(unknown_tabs)}")
card_run = _texts(data["card_run"], f"{where}.card_run") if "card_run" in data else ()
for key, tabs in (("run", run), ("card_run", card_run)):
unknown_tabs = [tab for tab in tabs if tab not in terminals]
if unknown_tabs:
raise GuideError(f"{where}.{key}: no terminal named {', '.join(unknown_tabs)}")
values: dict = {
"card_run": card_run,
"summary": _text(data["summary"], f"{where}.summary"),
"folders": _folder_rows(data["folders"], extract_to, f"{where}.folders"),
"run": run,
+1 -1
View File
@@ -314,7 +314,7 @@ class EveryPlatformHasAPermanentPage(unittest.TestCase):
page = generate_site.generate_get_page(name)
pack = release_record.pack_for(name, record)
with self.subTest(platform=name):
self.assertIn("# Download ", page)
self.assertRegex(page, r"\n# (.+ )?BIOS (pack|files)( for .+)?\n")
if name in RELEASED and pack:
for asset in pack["assets"]:
self.assertIn(
+240
View File
@@ -0,0 +1,240 @@
"""Entry pages, get/ and guides (round 5, package 4).
The get/ page of a setup with no ZIP printed one command for three
systems, with no --dest, so it failed on the computer most readers open
it on. "All good when you see 0 wrong hash" was also what an empty folder
prints. Setups with no ZIP lost every route that works without a network.
The get/ pages were titled "Download KNULLI", /get/ answered 404, and two
Linux handheld rows sent the reader to a menu.
"""
from __future__ import annotations
import re
import sys
import unittest
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))
sys.path.insert(0, str(REPO_ROOT))
import generate_site # noqa: E402
import release_record # noqa: E402
import siteguides # noqa: E402
from common import load_platform_config, load_platform_registry # noqa: E402
from tests import sitepages # noqa: E402
REGISTRY = load_platform_registry(str(REPO_ROOT / "platforms"))
SETUPS = [name for name in siteguides.GUIDES if name in REGISTRY]
COMMAND = re.compile(r"^(?:curl -fsSL |&\(\[scriptblock\]|irm ).*$", re.M)
OFFLINE_ANCHOR = "#without-a-network-offline-install"
CARD_FAQ = "/retrobios/wiki/faq/#fill-an-sd-card-from-a-computer"
def _page(name: str) -> str:
sitepages.require()
return re.sub(r"</?abbr[^>]*>", "", sitepages.page(name).read_text(encoding="utf-8"))
def _guide_part(text: str) -> str:
match = re.search(r"^## Reference\b", text, re.M)
return text[: match.start()] if match else text
def _with_zip(name: str) -> bool:
pack = release_record.pack_for(name, release_record.load_advertised())
return bool(pack and pack.get("assets"))
def _display(name: str) -> str:
return load_platform_config(name, str(REPO_ROOT / "platforms")).get("platform", name)
def _tab_labels(text: str) -> set[str]:
return set(re.findall(r'<TabItem label="([^"]+)"', text))
class GetPagesGiveTheSetupsOwnRoutes(unittest.TestCase):
def test_every_command_on_a_get_page_is_on_its_setup_page(self):
for name in SETUPS:
get = set(COMMAND.findall(_page(f"get/{name}.md")))
setup = set(COMMAND.findall(_page(f"platforms/{name}.md")))
with self.subTest(setup=name):
self.assertTrue(get <= setup, sorted(get - setup))
if not _with_zip(name):
self.assertTrue(get, "a setup with no ZIP gets its command")
def test_a_card_setup_names_the_card(self):
for name in SETUPS:
if not siteguides.GUIDES[name].on_card:
continue
with self.subTest(setup=name):
for command in COMMAND.findall(_page(f"get/{name}.md")):
self.assertIn("--dest ", command)
def test_no_tab_for_a_system_the_setup_does_not_run_from(self):
labels = {key: entry[0] for key, entry in siteguides.TERMINALS.items()}
for name in SETUPS:
if _with_zip(name):
continue
guide = siteguides.GUIDES[name]
allowed = {labels[key] for key in guide.run}
allowed |= {labels[key] for key in guide.card_run or ("windows", "macos", "linux")}
if generate_site._network_share(name, guide):
allowed.add(labels["windows"])
with self.subTest(setup=name):
self.assertLessEqual(_tab_labels(_page(f"get/{name}.md")), allowed)
self.assertNotIn("Android (Termux", _page(f"get/{name}.md"))
def test_retrodeck_runs_from_linux_and_the_deck(self):
text = _page("get/retrodeck.md")
install = text.split("## Install", 1)[1].split("No network", 1)[0]
self.assertEqual(_tab_labels(install), {"Steam Deck", "Linux"})
def test_one_helper_writes_both_pages(self):
source = Path(generate_site.__file__).read_text(encoding="utf-8")
get_page = source.split("def generate_get_page", 1)[1].split("\ndef ", 1)[0]
guide = source.split("def _platform_guide", 1)[1].split("\ndef ", 1)[0]
self.assertNotIn("install_commands(", get_page)
self.assertIn("_setup_routes(", get_page)
self.assertIn("_setup_routes(", guide)
class CheckNeedsTheFiles(unittest.TestCase):
def test_the_pass_line_is_what_the_installer_prints_only_when_complete(self):
installer = (REPO_ROOT / "install.py").read_text(encoding="utf-8")
printed = re.search(r"`([^`]+)`", generate_site.CHECK_PASS_LINE)[1]
self.assertIn(f'print("\\n {printed}")', installer)
self.assertNotIn("wrong hash", generate_site.CHECK_PASS_LINE)
def test_no_setup_page_passes_an_empty_folder(self):
for name in SETUPS:
text = _page(f"platforms/{name}.md")
with self.subTest(setup=name):
self.assertNotIn("All good when you see `0 wrong hash`", text)
self.assertIn(generate_site.CHECK_PASS_LINE, text)
class ARouteWithoutANetwork(unittest.TestCase):
def test_every_setup_page_has_the_offline_line_or_the_card_route(self):
for name in SETUPS:
guide = siteguides.GUIDES[name]
text = _guide_part(_page(f"platforms/{name}.md"))
with self.subTest(setup=name):
if _with_zip(name):
self.assertIn(OFFLINE_ANCHOR, text)
elif guide.on_card:
self.assertIn("Put the SD card in a computer.", text)
else:
self.assertIn("No network", text)
self.assertNotIn(OFFLINE_ANCHOR, text)
def test_every_device_setup_with_no_zip_links_the_card_answer(self):
for name in SETUPS:
guide = siteguides.GUIDES[name]
if _with_zip(name) or guide.run != ("device",):
continue
extract_to = REGISTRY[name]["extract_to"]
for page in (f"platforms/{name}.md", f"get/{name}.md"):
text = _page(page)
with self.subTest(page=page):
self.assertIn("## From your computer { #from-your-computer }", text)
self.assertIn(CARD_FAQ, text)
self.assertIn(f"the folder the device calls `{extract_to}`", text)
self.assertIn(f"--platform {name} --dest /path/to/", text)
def test_rocknix_has_a_computer_route(self):
text = _guide_part(_page("platforms/rocknix.md"))
self.assertLess(text.index("## From your computer"), text.index("## On the device"))
def test_retropie_card_is_read_from_linux_only(self):
self.assertEqual(siteguides.GUIDES["retropie"].card_run, ("linux",))
text = _page("platforms/retropie.md")
card = text.split("No network?", 1)[1].split("## On the device", 1)[0]
self.assertEqual(_tab_labels(card), {"Linux"})
def test_no_zip_is_promised_for_an_unmarked_setup(self):
for name in SETUPS:
if REGISTRY[name].get("release_pack") is True:
continue
with self.subTest(setup=name):
for page in (f"platforms/{name}.md", f"get/{name}.md"):
text = _guide_part(_page(page))
self.assertNotIn("/releases/download/", text)
self.assertNotIn(OFFLINE_ANCHOR, text)
class GetPagesSayWhatTheyHold(unittest.TestCase):
def test_title_description_and_parent(self):
for name in SETUPS:
display = _display(name)
text = sitepages.page(f"get/{name}.md").read_text(encoding="utf-8")
kind = "pack" if REGISTRY[name].get("release_pack") is True else "files"
title = (f"BIOS {kind} for {display}"
if (REPO_ROOT / "emulators" / f"{name}.yml").is_file()
else f"{display} BIOS {kind}")
with self.subTest(setup=name):
self.assertEqual(generate_site.get_page_title(name, display), title)
self.assertIn(f"title: {title}\n", text)
self.assertNotIn("Download ", text.split("\n---\n", 1)[0].split("title:", 1)[1]
.split("\n", 1)[0])
self.assertIn(f"link: /platforms/{name}/", text)
if kind == "files":
self.assertIn(f"The BIOS files for {display}: one command installs and "
"checks them.", text)
def test_a_setup_with_no_zip_links_its_get_page(self):
for name in SETUPS:
if REGISTRY[name].get("release_pack") is True:
continue
with self.subTest(setup=name):
title = generate_site.get_page_title(name, _display(name))
self.assertIn(f"Link to share: [{title}](/retrobios/get/{name}/)",
_page(f"platforms/{name}.md"))
def test_a_relative_folder_is_named_as_the_setups(self):
text = _page("get/retroarch.md")
self.assertIn("Unzip them all into RetroArch's `system` folder. "
"[Where is it?](/retrobios/platforms/retroarch/#where-the-files-go)", text)
self.assertIn("In RetroArch, open **Settings > Directory > System/BIOS**", text)
self.assertIn("into RetroBat's `bios` folder", _page("get/retrobat.md"))
self.assertNotIn("into `system/`", text)
class HandheldRowsSayWhere(unittest.TestCase):
def test_retrooz_names_its_folder_with_a_pinned_source(self):
system = next(s for s in siteguides.HANDHELD_GUIDE.systems if s.name == "RetroOZ")
self.assertIn("`/roms/bios`", system.folder)
self.assertRegex(system.folder_source, r"/wiki/Home/[0-9a-f]{40}$")
row = next(line for line in _page("platforms/linux-handhelds.md").splitlines()
if line.startswith("| RetroOZ |"))
self.assertNotIn(generate_site.RETROARCH_FOLDER_SETTING, row)
class GetIndex(unittest.TestCase):
def test_every_setup_is_linked_under_its_group(self):
text = _page("get/index.md")
for name in SETUPS:
with self.subTest(setup=name):
self.assertIn(f"(/retrobios/get/{name}/)", text)
for label, _description in siteguides.DEVICE_GROUPS.values():
self.assertIn(f"## {label}", text)
class HomeAndWhichPack(unittest.TestCase):
def test_the_home_step_does_not_promise_a_zip(self):
text = _page("index.md")
self.assertIn("**Run one command.** Some setups have a ZIP.", text)
self.assertNotIn("or download a ZIP file", text)
def test_which_pack_answers_ios(self):
text = _page("which-pack.md")
meta = re.search(r'data-pagefind-meta="terms:([^"]+)"', text)
self.assertIsNotNone(meta)
for word in ("ios", "iphone", "ipad", "delta", "provenance"):
self.assertIn(word, meta[1].split())
if __name__ == "__main__":
unittest.main()