mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-27 06:07:24 -05:00
chore: merge round 4 fixes (profiles)
This commit is contained in:
commit
43fe5a7b15
15 files changed
+354
-29
No files matched your search
@@ -153,5 +153,43 @@ class AnUnreadableSourceStopsTheRun(unittest.TestCase):
|
||||
self.assertIn("broken.yml", str(caught.exception))
|
||||
|
||||
|
||||
class DrasticNamesTheDSDumps(unittest.TestCase):
|
||||
"""DraStic opens nds_bios_arm9.bin, nds_bios_arm7.bin and nds_firmware.bin
|
||||
and checks their size only. Its profile listed nine other names none of
|
||||
its binaries contains, which were the only way the collection answered
|
||||
its own three names."""
|
||||
|
||||
def _aliases(self, files: dict) -> dict:
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
try:
|
||||
Path("emulators").mkdir()
|
||||
return generate_db._collect_all_aliases(files)
|
||||
finally:
|
||||
os.chdir(previous)
|
||||
|
||||
def test_the_collection_answers_drastic_names(self):
|
||||
files = {
|
||||
"a9": {"name": "NDS_Bios9.bin", "path": "bios/Nintendo/DS/NDS_Bios9.bin", "md5": "m9"},
|
||||
"a7": {"name": "NDS_Bios7.bin", "path": "bios/Nintendo/DS/NDS_Bios7.bin", "md5": "m7"},
|
||||
"fw": {"name": "NDS_Lite_Firmware.bin",
|
||||
"path": "bios/Nintendo/DS/NDS_Lite_Firmware.bin", "md5": "mf"},
|
||||
}
|
||||
aliases = self._aliases(files)
|
||||
named = {sha: {a["name"] for a in entries} for sha, entries in aliases.items()}
|
||||
self.assertIn("nds_bios_arm9.bin", named["a9"])
|
||||
self.assertIn("nds_bios_arm7.bin", named["a7"])
|
||||
self.assertIn("nds_firmware.bin", named["fw"])
|
||||
|
||||
def test_the_profile_carries_no_name_drastic_never_opens(self):
|
||||
import yaml
|
||||
|
||||
profile = yaml.safe_load((REPO_ROOT / "emulators" / "drastic.yml").read_text())
|
||||
self.assertEqual(
|
||||
[e["name"] for e in profile["files"] if e.get("aliases")], [],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -250,6 +250,50 @@ class LauncherLayerTest(unittest.TestCase):
|
||||
self.assertNotIn("core.bin", {u["name"] for u in self._report()})
|
||||
self.assertNotIn("core.bin", self._pack_names())
|
||||
|
||||
def test_the_default_name_a_launcher_replaces_is_not_packed(self) -> None:
|
||||
"""EmuDeck passes Complex_4627v1.03.bin to xemu, which then never
|
||||
opens Complex_4627.bin: the pack carried both, one read by nobody."""
|
||||
report = {u["path"]: u for u in self._report()}
|
||||
self.assertIn("sub/fix.bin", report)
|
||||
self.assertNotIn("core.bin", report)
|
||||
self.assertNotIn("core.bin", self._pack_names())
|
||||
|
||||
def test_a_link_of_a_named_file_is_a_place(self) -> None:
|
||||
"""ROCKNIX links /storage/roms/bios/nds_bios_arm9.bin into DraStic's
|
||||
system folder (start_drastic.sh:37-41): the file goes where the
|
||||
link reads it, not under the emulator's own folder."""
|
||||
self.config["launchers"][2].update(
|
||||
kind="links", names=["fix.bin"], search_dir="/storage/roms/bios",
|
||||
)
|
||||
places = [p for p in launcher_places(self.config) if p.kind == "links"]
|
||||
self.assertEqual([p.paths for p in places], [("fix.bin",)])
|
||||
self.assertTrue(places[0].stands_for_default)
|
||||
report = {u["path"]: u for u in self._report()}
|
||||
self.assertIn("fix.bin", report)
|
||||
self.assertNotIn("core.bin", report)
|
||||
|
||||
def test_a_link_of_a_directory_is_no_place(self) -> None:
|
||||
self.config["launchers"][2].update(
|
||||
kind="links", names=[], search_dir="/userdata/bios/sub",
|
||||
)
|
||||
self.assertFalse([p for p in launcher_places(self.config) if p.kind == "links"])
|
||||
|
||||
def test_the_platform_spelling_of_the_bios_folder_is_a_root(self) -> None:
|
||||
"""RetroPie names $biosdir, EmuDeck ${biosPath}, RetroDECK $bios_path:
|
||||
read as no folder at all, every place of those platforms was dropped."""
|
||||
for spelling in ("$biosdir", "${biosPath}", "$bios_path", "$HOME/RetroPie/bios"):
|
||||
self.config["launchers"][2]["search_dir"] = f"{spelling}/sub"
|
||||
with self.subTest(spelling=spelling):
|
||||
self.assertEqual(launcher_places(self.config)[2].paths, ("sub/sub/fix.bin",))
|
||||
|
||||
def test_every_extractor_spelling_of_the_bios_folder_is_known(self) -> None:
|
||||
import launchers
|
||||
from scraper import emudeck_launchers, retrodeck_launchers, retropie_launchers
|
||||
|
||||
for token in (emudeck_launchers.BIOS, retrodeck_launchers.BIOS,
|
||||
retropie_launchers.BIOSDIR):
|
||||
self.assertIn(token, launchers.BIOS_ROOT_TOKENS)
|
||||
|
||||
def test_no_place_is_filled_twice(self) -> None:
|
||||
added = [u["path"] for u in self._report() if u.get("launcher")]
|
||||
self.assertEqual(sorted(added), ["e.bin", "sub/fix.bin"])
|
||||
|
||||
@@ -269,6 +269,47 @@ class CommandLines(unittest.TestCase):
|
||||
rl.extract_launchers(files)
|
||||
|
||||
|
||||
DRASTIC = module("drastic", """
|
||||
function configure_drastic() {
|
||||
mkRomDir "nds"
|
||||
|
||||
addEmulator 1 "$md_id" "nds" "$md_inst/drastic.sh %ROM%"
|
||||
addSystem "nds"
|
||||
|
||||
[[ "$md_mode" == "remove" ]] && return
|
||||
|
||||
isPlatform "kms" && ! isPlatform "x11" && setBackend "$md_id" "x11"
|
||||
|
||||
cat > "$md_inst/drastic.sh" << _EOF_
|
||||
#!/bin/bash
|
||||
pushd "$md_conf_root/nds/drastic"
|
||||
$md_inst/drastic "\\$1"
|
||||
popd
|
||||
_EOF_
|
||||
chmod +x "$md_inst/drastic.sh"
|
||||
}
|
||||
""", 36)
|
||||
|
||||
|
||||
class WorkingDirectory(unittest.TestCase):
|
||||
def test_drastic_reads_below_the_folder_its_script_enters(self):
|
||||
found = records({f"{EMULATORS}/drastic.sh": DRASTIC}, "drastic")
|
||||
entered = [r for r in found if r["kind"] == "passes_path"]
|
||||
self.assertEqual(
|
||||
[(r["search_dir"], r["passes_to"], r["source_ref"]) for r in entered],
|
||||
[(
|
||||
"$md_conf_root/nds/drastic",
|
||||
"working directory of $md_inst/drastic.sh",
|
||||
f"{EMULATORS}/drastic.sh:48",
|
||||
)],
|
||||
)
|
||||
|
||||
def test_a_launch_script_that_no_longer_enters_a_folder_raises(self):
|
||||
files = {f"{EMULATORS}/drastic.sh": DRASTIC.replace('pushd "', 'echo "')}
|
||||
with self.assertRaises(rl.LauncherPatternMissing):
|
||||
rl.extract_launchers(files)
|
||||
|
||||
|
||||
class LaunchScripts(unittest.TestCase):
|
||||
def test_fs_uae_refuses_to_start_without_kick13(self):
|
||||
files = {f"{EMULATORS}/fs-uae.sh": FS_UAE, f"{EMULATORS}/fs-uae/fs-uae.sh": FS_UAE_LAUNCHER}
|
||||
|
||||
@@ -1347,5 +1347,37 @@ class ARefusedRegionalFileHoldsNoSlot(unittest.TestCase):
|
||||
self.assertIn("rg_jp.bin", report["pack_destinations"])
|
||||
|
||||
|
||||
class YmirLibretroRegions(unittest.TestCase):
|
||||
"""ymir's libretro port gives sega_101.bin the Japan region and
|
||||
mpr-17933.bin US_EU (apps/ymir-libretro/src/libretro.cpp:596-606) and
|
||||
loads the candidate a region asks for (627-648, 1290-1306). One entry for
|
||||
all three names put no region on any of them."""
|
||||
|
||||
def test_each_name_carries_the_region_the_port_gives_it(self):
|
||||
import yaml
|
||||
|
||||
profile = yaml.safe_load(
|
||||
(Path(__file__).resolve().parents[1] / "emulators" / "ymir.yml").read_text()
|
||||
)
|
||||
libretro = {
|
||||
entry["name"]: entry for entry in profile["files"]
|
||||
if entry.get("mode") == "libretro"
|
||||
and entry["name"] in ("sega_101.bin", "mpr-17933.bin", "saturn_bios.bin")
|
||||
}
|
||||
self.assertEqual(sorted(libretro), ["mpr-17933.bin", "saturn_bios.bin", "sega_101.bin"])
|
||||
self.assertEqual(libretro["sega_101.bin"]["region"], ["japan"])
|
||||
self.assertTrue(
|
||||
{"north-america", "europe"} <= set(libretro["mpr-17933.bin"]["region"])
|
||||
)
|
||||
self.assertNotIn("japan", libretro["mpr-17933.bin"]["region"])
|
||||
self.assertNotIn("region", libretro["saturn_bios.bin"])
|
||||
self.assertEqual(
|
||||
[libretro[n]["priority"] for n in ("sega_101.bin", "mpr-17933.bin", "saturn_bios.bin")],
|
||||
[1, 2, 3],
|
||||
)
|
||||
self.assertFalse(any(e.get("aliases") for e in profile["files"]
|
||||
if e["name"] == "sega_101.bin"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,49 @@
|
||||
"""Sega ROMs live under bios/Sega.
|
||||
|
||||
The SF-7000 disk unit ROM, which only the sega-sf7000 entries read, sat in
|
||||
bios/Microsoft/MSX because blueMSX keeps its machine folders together. The
|
||||
collection files a dump under the maker of the machine it belongs to, and
|
||||
the blueMSX layout is a destination the pack writes, not a storage rule.
|
||||
Reads the repository.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
|
||||
class SegaFilesStayUnderSega(unittest.TestCase):
|
||||
def test_no_sega_only_file_under_msx(self):
|
||||
folder = REPO_ROOT / "bios" / "Microsoft" / "MSX"
|
||||
if not folder.is_dir():
|
||||
self.skipTest("bios/Microsoft/MSX is absent")
|
||||
from common import load_emulator_profiles
|
||||
|
||||
systems: dict[str, set[str]] = {}
|
||||
for profile in load_emulator_profiles(str(REPO_ROOT / "emulators")).values():
|
||||
for entry in profile.get("files") or []:
|
||||
if not isinstance(entry, dict) or not entry.get("system"):
|
||||
continue
|
||||
for name in [entry.get("name", ""), *(entry.get("aliases") or [])]:
|
||||
key = Path(str(name)).name.lower()
|
||||
systems.setdefault(key, set()).add(str(entry["system"]))
|
||||
misfiled = sorted(
|
||||
str(path.relative_to(folder))
|
||||
for path in folder.rglob("*")
|
||||
if path.is_file()
|
||||
and systems.get(path.name.lower())
|
||||
and all(s.startswith("sega-") for s in systems[path.name.lower()])
|
||||
)
|
||||
self.assertEqual(misfiled, [])
|
||||
|
||||
def test_sf7000_rom_is_filed_under_sega(self):
|
||||
self.assertTrue((REPO_ROOT / "bios" / "Sega" / "SF-7000" / "sf7000.rom").is_file())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user