mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-01 07:33:45 -06:00
--offline given with the variable set is named as the option, and the runs the screen starts get it only when the user gave it. The first install page stays under its 400 words, the 3.8 runs skip only the pack test that needs generate_pack.
223 lines
10 KiB
Python
223 lines
10 KiB
Python
"""What the round 4 packages left between them once merged.
|
|
|
|
A data directory page printed its readers as a Python list, every board
|
|
page's breadcrumb read "Arcade / Arcade", the fba2012 section was headed
|
|
with its folder name, BizHawk's tile showed a GitHub avatar and MinUI's a
|
|
logo that is not its own, and the nodes the search gate starts wrote
|
|
Node's compile cache into /tmp.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import glob
|
|
import json
|
|
import re
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
import yaml
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
|
|
|
import check_freshness # noqa: E402
|
|
import generate_site as gs # noqa: E402
|
|
import sitediagrams # noqa: E402
|
|
import siterender # noqa: E402
|
|
|
|
DIST = REPO_ROOT / "website" / "dist"
|
|
|
|
|
|
def _profile(name: str) -> dict:
|
|
return yaml.safe_load((REPO_ROOT / "emulators" / f"{name}.yml").read_text(encoding="utf-8"))
|
|
|
|
|
|
class DataTreeReaders(unittest.TestCase):
|
|
def test_read_by_names_the_emulators(self):
|
|
ref = "y-sys"
|
|
gs._DATA_MEMBERS[ref] = {"a.bin": {"size": 1, "sha1": "0" * 40}}
|
|
gs._DATA_READERS[ref] = [("dolphin", "Dolphin"), ("ishiiruka", "Ishiiruka")]
|
|
try:
|
|
page = gs._data_tree_page(ref, {}, [("y-sys", ["a.bin"])], 0)
|
|
finally:
|
|
del gs._DATA_MEMBERS[ref], gs._DATA_READERS[ref]
|
|
self.assertIn("Read by [Dolphin](dolphin.md#data-directories) and "
|
|
"[Ishiiruka](ishiiruka.md#data-directories).", page)
|
|
self.assertNotIn("('dolphin'", page)
|
|
|
|
|
|
class EngineIntros(unittest.TestCase):
|
|
def test_every_intro_names_what_it_emulates(self):
|
|
for path in sorted(glob.glob(str(REPO_ROOT / "emulators" / "*.yml"))):
|
|
profile = yaml.safe_load(Path(path).read_text(encoding="utf-8"))
|
|
if not isinstance(profile, dict) or profile.get("type") in ("alias", "test"):
|
|
continue
|
|
name = Path(path).stem
|
|
with self.subTest(profile=name):
|
|
intro = gs._emulator_intro(str(profile.get("emulator") or name), profile)
|
|
self.assertNotRegex(intro, r"emulates\s*(?:\.|game\b|and\b|,)")
|
|
self.assertNotIn(" ", intro)
|
|
|
|
|
|
class SectionNames(unittest.TestCase):
|
|
def test_fba2012_is_headed_by_its_program(self):
|
|
self.assertEqual(gs._section_label("Arcade", "fba2012"), "FB Alpha 2012")
|
|
self.assertEqual(gs._section_label("Arcade", "Arcade"), gs.OTHER_ARCADE_LABEL)
|
|
self.assertEqual(gs._section_label("Sony", "PlayStation"), "PlayStation")
|
|
self.assertEqual(siterender.SECTION_LABELS[("Arcade", "fba2012")],
|
|
_profile("fbalpha2012")["emulator"])
|
|
|
|
|
|
class PlatformLogos(unittest.TestCase):
|
|
def setUp(self):
|
|
self.registry = yaml.safe_load(
|
|
(REPO_ROOT / "platforms" / "_registry.yml").read_text(encoding="utf-8"))["platforms"]
|
|
|
|
def test_bizhawk_shows_its_app_icon(self):
|
|
self.assertTrue(self.registry["bizhawk"]["logo"].endswith(
|
|
"/src/BizHawk.Client.EmuHawk/images/logo.ico"))
|
|
|
|
def test_minui_has_no_logo_and_no_stale_copy(self):
|
|
self.assertNotIn("logo", self.registry["minui"])
|
|
self.assertEqual(list((REPO_ROOT / "docs_assets" / "logos").glob("minui.*")), [])
|
|
|
|
def test_every_logo_copy_has_a_registry_logo(self):
|
|
sources = json.loads((REPO_ROOT / "docs_assets" / "logos" / "sources.json").read_text())
|
|
for entry in sources["images"]:
|
|
with self.subTest(platform=entry["platform"]):
|
|
self.assertEqual(self.registry[entry["platform"]].get("logo"), entry["source"])
|
|
|
|
|
|
class NodeCompileCache(unittest.TestCase):
|
|
def test_the_search_gate_starts_node_without_it(self):
|
|
source = (REPO_ROOT / "website" / "tools" / "search_gate.py").read_text(encoding="utf-8")
|
|
self.assertIn('NODE_ENV = {**os.environ, "NODE_DISABLE_COMPILE_CACHE": "1"}', source)
|
|
starts = [m.start() for m in re.finditer(r'subprocess\.(?:run|Popen)\(\s*\["node"', source)]
|
|
self.assertEqual(len(starts), 3)
|
|
for start in starts:
|
|
call = source[start:source.index("\n\n", start)]
|
|
self.assertIn("env=NODE_ENV", call)
|
|
|
|
def test_lighthouse_and_the_deploy(self):
|
|
self.assertIn('"NODE_DISABLE_COMPILE_CACHE": "1"',
|
|
(REPO_ROOT / "website" / "tools" / "lighthouse.py").read_text(encoding="utf-8"))
|
|
workflow = (REPO_ROOT / ".github" / "workflows" / "deploy-site.yml").read_text(encoding="utf-8")
|
|
build = workflow[workflow.index(" build:"):workflow.index(" steps:")]
|
|
self.assertIn('NODE_DISABLE_COMPILE_CACHE: "1"', build)
|
|
|
|
|
|
class SourcePathsFreshness(unittest.TestCase):
|
|
def test_the_committed_record_is_current(self):
|
|
from common import load_emulator_profiles # noqa: PLC0415
|
|
|
|
profiles = load_emulator_profiles(str(REPO_ROOT / "emulators"), skip_aliases=False)
|
|
finding = check_freshness.check_source_paths(profiles)
|
|
self.assertEqual(finding.status, check_freshness.OK, finding.detail)
|
|
|
|
def test_a_moved_pin_is_stale(self):
|
|
profile = _profile("geolith")
|
|
moved = dict(profile, source_commit="f" * 40, upstream_commit="e" * 40)
|
|
finding = check_freshness.check_source_paths({"geolith": moved})
|
|
self.assertEqual(finding.status, check_freshness.STALE)
|
|
self.assertIn("sitesources.py --fetch", finding.detail)
|
|
|
|
|
|
class OptionsGlanceFromTheParser(unittest.TestCase):
|
|
"""--declared-only and --offline reached install.py and its Options
|
|
table, and not the hand-written glance above it."""
|
|
|
|
def test_every_parser_option_has_a_group(self):
|
|
named = {flag for _label, flags in sitediagrams.GLANCE_GROUPS for flag in flags}
|
|
self.assertEqual(set(sitediagrams.installer_flags()) - named, set())
|
|
self.assertEqual(named - set(sitediagrams.installer_flags()), set())
|
|
|
|
def test_an_option_no_group_names_still_lands(self):
|
|
with mock.patch.object(sitediagrams, "installer_flags",
|
|
return_value=["--platform", "--brand-new"]):
|
|
lines = sitediagrams.options_glance()
|
|
self.assertEqual(lines, [
|
|
"- **Where and for what**: [`--platform`](#option-platform)",
|
|
"- **Other**: [`--brand-new`](#option-brand-new)",
|
|
])
|
|
|
|
def test_the_source_holds_no_list(self):
|
|
text = (REPO_ROOT / "wiki" / "installer.md").read_text(encoding="utf-8")
|
|
section = text[text.index(sitediagrams.GLANCE_HEADING):text.index("\n## One line")]
|
|
self.assertNotIn("\n- ", section)
|
|
with self.assertRaises(ValueError):
|
|
sitediagrams.expand_glance(f"# x\n\n{sitediagrams.GLANCE_HEADING}\n\n- a\n\n## y\n")
|
|
|
|
|
|
class FaqInstallsFromWhatYouHold(unittest.TestCase):
|
|
"""--from-pack reads the ZIP itself, and a wiped card had no answer."""
|
|
|
|
def setUp(self):
|
|
self.faq = (REPO_ROOT / "wiki" / "faq.md").read_text(encoding="utf-8")
|
|
|
|
def _section(self, heading: str) -> str:
|
|
return self.faq.split(f"## {heading}\n", 1)[1].split("\n## ", 1)[0]
|
|
|
|
def test_no_unzip_before_from_pack(self):
|
|
section = " ".join(self._section("No internet on the device?").split())
|
|
self.assertIn("point `--from-pack` at your ZIP:", section)
|
|
self.assertNotIn("unzip", section)
|
|
install = (REPO_ROOT / "install.py").read_text(encoding="utf-8")
|
|
self.assertIn("Install from a pack already downloaded: its ZIP, one of its parts",
|
|
(REPO_ROOT / "wiki" / "installer.md").read_text(encoding="utf-8"))
|
|
self.assertIn('"--from-pack"', install)
|
|
|
|
def test_the_cards_the_interface_finds(self):
|
|
"""Each system the SD card answer names is one install.py tells by
|
|
its card: a release file (_CARD_RULES) or a card rule."""
|
|
import install # noqa: PLC0415
|
|
|
|
section = " ".join(self._section("Fill an SD card from a computer?").split())
|
|
self.assertIn("The interface finds a muOS, Onion, spruceOS, MinUI, KNULLI or ROCKNIX "
|
|
"card by itself.", section)
|
|
known = {rule.name for rule in install._card_rules()}
|
|
known |= {install.display_name(name) for name, _marker, _prefix in install._CARD_RULES}
|
|
for name in ("muOS", "Onion", "spruceOS", "MinUI", "KNULLI", "ROCKNIX"):
|
|
with self.subTest(card=name):
|
|
self.assertIn(name, known)
|
|
# 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")),
|
|
"SHARE drive")
|
|
|
|
def test_a_wiped_card_links_the_copy(self):
|
|
section = self._section("Lost or wiped card?")
|
|
self.assertIn("`--from`", section)
|
|
self.assertIn("(installer.md#copy-from-an-old-card)", section)
|
|
installer = (REPO_ROOT / "wiki" / "installer.md").read_text(encoding="utf-8")
|
|
self.assertIn("## Copy from an old card { #copy-from-an-old-card }", installer)
|
|
self.assertIn('"--from"', (REPO_ROOT / "install.py").read_text(encoding="utf-8"))
|
|
|
|
|
|
@unittest.skipUnless((DIST / "systems" / "arcade-acclaim-zn-1" / "index.html").is_file(),
|
|
"site not built")
|
|
class BuiltCrumbs(unittest.TestCase):
|
|
def test_no_crumb_repeats_the_one_before(self):
|
|
repeated = []
|
|
for path in sorted(DIST.rglob("index.html")):
|
|
nav = re.search(r'<nav[^>]*rb-breadcrumbs[^>]*>(.*?)</nav>',
|
|
path.read_text(encoding="utf-8"), re.S)
|
|
if not nav:
|
|
continue
|
|
labels = [re.sub(r"<[^>]+>", "", item).strip()
|
|
for item in re.findall(r"<li[^>]*>(.*?)</li>", nav[1], re.S)]
|
|
if any(a == b for a, b in zip(labels, labels[1:])):
|
|
repeated.append(str(path.relative_to(DIST)))
|
|
self.assertEqual(repeated, [])
|
|
|
|
def test_a_board_page_ends_on_the_arcade_page(self):
|
|
text = (DIST / "systems" / "arcade-acclaim-zn-1" / "index.html").read_text(encoding="utf-8")
|
|
nav = re.search(r'<nav[^>]*rb-breadcrumbs[^>]*>(.*?)</nav>', text, re.S)[1]
|
|
self.assertIn('href="/retrobios/systems/arcade/"', nav)
|
|
self.assertNotIn('href="/retrobios/systems/#arcade"', nav)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|