mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-24 12:49:03 -05:00
188 lines
8.3 KiB
Python
188 lines
8.3 KiB
Python
"""Emulator pages say what is needed first, in names (round 2, package 7).
|
|
|
|
DuckStation's page opened on "It reads 105 files, 3 of them required" and
|
|
read as "get all three", its three BIOS were cards 12 to 14 under one
|
|
heading, its header said "Official ports" and "duckstation, Duckstation",
|
|
and every system was an id ("sony-playstation").
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
|
|
|
import generate_site as gs # noqa: E402
|
|
import siterender # noqa: E402
|
|
|
|
EMPTY_DB = {"files": {}, "indexes": {"by_name": {}}}
|
|
|
|
|
|
def _profile(name: str) -> dict:
|
|
with open(REPO_ROOT / "emulators" / f"{name}.yml", encoding="utf-8") as handle:
|
|
return yaml.safe_load(handle)
|
|
|
|
|
|
def _page(name: str, profile: dict) -> str:
|
|
return gs.generate_emulator_page(name, profile, EMPTY_DB, None, set())
|
|
|
|
|
|
def _files(count: int, **fields: object) -> list[dict]:
|
|
return [{"name": f"f{i:03d}.bin", **fields} for i in range(count)]
|
|
|
|
|
|
class TheIntroSaysWhatIsNeeded(unittest.TestCase):
|
|
def test_one_bios_per_region(self):
|
|
profile = _profile("duckstation")
|
|
intro = gs._emulator_intro("DuckStation", profile)
|
|
self.assertIn(
|
|
"It picks the BIOS for your game's region: scph5500.bin (Japan), "
|
|
"scph5501.bin (North America and Latin America) or scph5502.bin "
|
|
"(Europe and Oceania).", intro)
|
|
others = len(profile["files"]) - 3
|
|
self.assertIn(f"The {others} other files are optional.", intro)
|
|
self.assertNotIn("3 of them required", intro)
|
|
self.assertIn("DuckStation emulates Sony PlayStation.", intro)
|
|
|
|
def test_required_files_without_regions_keep_the_count(self):
|
|
intro = gs._emulator_intro("X", {"files": [
|
|
{"name": "a.bin", "required": True}, {"name": "b.bin"}]})
|
|
self.assertIn("It reads 2 files, 1 of them required", intro)
|
|
|
|
def test_several_machines_say_who_needs_a_required_file(self):
|
|
intro = gs._emulator_intro("X", {
|
|
"systems": ["sony-playstation", "sega-saturn"],
|
|
"files": [{"name": "a.bin", "required": True}]})
|
|
self.assertIn("A required file is needed only by the machines that use it.", intro)
|
|
one = gs._emulator_intro("X", {
|
|
"systems": ["sony-playstation"], "files": [{"name": "a.bin", "required": True}]})
|
|
self.assertNotIn("machines that use it", one)
|
|
|
|
|
|
class TheHeaderReadsAsWords(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.page = _page("duckstation", _profile("duckstation"))
|
|
|
|
def test_singular_classification(self):
|
|
self.assertIn("| Classification | Official port |", self.page)
|
|
|
|
def test_cores_once_per_spelling(self):
|
|
# duckstation-sa is ROCKNIX's name for the standalone build.
|
|
self.assertIn("| Cores | duckstation, duckstation-sa |", self.page)
|
|
|
|
def test_systems_by_name(self):
|
|
row = next(line for line in self.page.splitlines() if line.startswith("| Systems |"))
|
|
self.assertIn("Sony PlayStation", row)
|
|
self.assertNotIn("[sony-playstation]", row)
|
|
|
|
def test_region_badge_is_labelled(self):
|
|
self.assertIn(">Region: Japan</span>", self.page)
|
|
self.assertNotIn('rb-badge-muted">japan</span>', self.page)
|
|
|
|
def test_profile_version_names_the_pinned_build(self):
|
|
# DuckStation numbers builds v0.1-<commits since tag 0.1>: the pin,
|
|
# 4122fed9, is 12,070 commits past it.
|
|
self.assertRegex(str(_profile("duckstation")["core_version"]), r"^v0\.1-\d+$")
|
|
|
|
def test_the_second_spelling_is_a_platform_name(self):
|
|
# The lookup is case-sensitive and EmuELEC launches "Duckstation":
|
|
# the page hides the duplicate, the profile keeps it.
|
|
with open(REPO_ROOT / "platforms" / "emuelec.yml", encoding="utf-8") as handle:
|
|
emuelec = yaml.safe_load(handle)
|
|
self.assertIn("Duckstation", emuelec["cores"])
|
|
self.assertIn("Duckstation", _profile("duckstation")["cores"])
|
|
|
|
|
|
class RequiredFilesComeFirst(unittest.TestCase):
|
|
def test_sections_in_need_order(self):
|
|
files = [
|
|
{"name": "data.pak", "category": "game_data", "required": True},
|
|
{"name": "opt.bin"},
|
|
{"name": "req.bin", "required": True, "region": ["japan"], "md5": "ab" * 16},
|
|
]
|
|
page = _page("x", {"type": "standalone", "files": files})
|
|
heads = [line for line in page.splitlines() if line.startswith("## ")]
|
|
self.assertEqual(heads[:4], ["## Files", "## Required", "## Optional", "## Game data"])
|
|
self.assertLess(page.index("## Required"), page.index("req.bin"))
|
|
self.assertLess(page.index("req.bin"), page.index("## Optional"))
|
|
self.assertLess(page.index("## Game data"), page.index("data.pak"))
|
|
|
|
def test_the_table_of_contents_turns_on(self):
|
|
page = _page("duckstation", _profile("duckstation"))
|
|
self.assertGreater(len(re.findall(r"^## ", page, re.M)), 2)
|
|
|
|
def test_a_summary_table_above_the_cards(self):
|
|
files = _files(gs.EMULATOR_SUMMARY_MIN - 1) + [
|
|
{"name": "req.bin", "required": True, "region": ["japan"], "md5": "ab" * 16}]
|
|
page = _page("x", {"type": "standalone", "files": files})
|
|
self.assertIn("| File | Region | Required | Hash |", page)
|
|
row = next(line for line in page.splitlines() if "req.bin" in line and "| yes |" in line)
|
|
self.assertIn("(#file-req-bin", row)
|
|
self.assertIn("| Japan |", row)
|
|
self.assertIn(f'MD5\u00a0<code title="{"ab" * 16}">{"ab" * 6}</code>', row)
|
|
# The required row is the first one.
|
|
table = page.index("| File | Region | Required | Hash |")
|
|
self.assertLess(page.index("req.bin", table), page.index("f000.bin", table))
|
|
|
|
def test_no_table_for_a_few_cards(self):
|
|
page = _page("x", {"type": "standalone", "files": _files(2)})
|
|
self.assertNotIn("| File | Region | Required | Hash |", page)
|
|
|
|
def test_a_split_page_puts_required_on_the_first_part(self):
|
|
count = gs.EMULATOR_CARDS_PER_PAGE * 2
|
|
files = _files(count) + [{"name": "last.bin", "required": True}]
|
|
parts = gs.emulator_parts("big", files)
|
|
self.assertIn(count, parts[0][1])
|
|
pages = gs.emulator_pages("big", {"emulator": "Big", "type": "standalone",
|
|
"files": files}, {"files": {}})
|
|
main = pages["big"]
|
|
self.assertLess(main.index("## Required"), main.index("## Optional"))
|
|
self.assertLess(main.index("last.bin"), main.index("f000.bin"))
|
|
self.assertIn("## Required", pages["big-files-1"])
|
|
|
|
|
|
class TheSummaryLineIsProse(unittest.TestCase):
|
|
def test_no_pipes_and_one_number_format(self):
|
|
files = _files(1563, category="bios_zip") + [
|
|
{"name": "a.pak", "category": "game_data"}, {"name": "b.pak", "category": "game_data"}]
|
|
for f in files[:164]:
|
|
f["required"] = True
|
|
text = "\n".join(gs._emulator_file_summary(files))
|
|
self.assertNotIn(" | ", text)
|
|
self.assertNotIn("1399", text)
|
|
self.assertIn("1,401 optional", text)
|
|
self.assertIn("By kind: 1,563 BIOS ZIPs and 2 game data.", text)
|
|
|
|
def test_category_badge_in_words(self):
|
|
badges = " ".join(gs._file_badges({"name": "a", "category": "game_data"}, True))
|
|
self.assertIn(">game data</span>", badges)
|
|
|
|
|
|
class TheIndexNamesEmulatorsAndSystems(unittest.TestCase):
|
|
def test_columns_and_counts(self):
|
|
saved = dict(siterender._system_page_map)
|
|
self.addCleanup(siterender.set_system_page_map, saved)
|
|
siterender.set_system_page_map({"sony-playstation": ("sony", "PlayStation")})
|
|
page = gs.generate_emulators_index({
|
|
"duckstation": {"emulator": "DuckStation", "core_classification": "official_port",
|
|
"systems": ["sony-playstation"], "files": _files(3)},
|
|
})
|
|
self.assertIn("| Emulator | Kind | Systems | Files |", page)
|
|
self.assertIn("\n## D\n", page)
|
|
self.assertNotIn("| Engine |", page)
|
|
self.assertNotIn(" -- ", page)
|
|
row = next(line for line in page.splitlines() if line.startswith("| [DuckStation]"))
|
|
self.assertIn(f"[{siterender.system_name('sony-playstation')}]", row)
|
|
self.assertIn("(../systems/sony.md#playstation)", row)
|
|
self.assertNotIn("sony-playstation |", row)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|