mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-16 16:33:27 -05:00
151 lines
6.8 KiB
Python
151 lines
6.8 KiB
Python
"""A core extra keeps every field that identifies its content.
|
|
|
|
Each hop kept its own subset: min_size and validation were lost, so
|
|
np2kai's bios.rom (98304 bytes minimum, size checked) resolved by name to an
|
|
IBM PCjr ROM and shipped in four packs, and dosbox's SC-55 ROMs to a
|
|
Galaksija ROM and a PS2 ROM2.BIN.
|
|
"""
|
|
|
|
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"))
|
|
|
|
from common import PROFILE_IDENTITY_FIELDS # noqa: E402
|
|
from packextras import _collect_emulator_extras # noqa: E402
|
|
from verify import find_undeclared_files # noqa: E402
|
|
|
|
ENTRY = {
|
|
"name": "bios.rom",
|
|
"path": "np2kai/bios.rom",
|
|
"min_size": 98304,
|
|
"validation": ["size"],
|
|
"aliases": ["BIOS.ROM"],
|
|
"crc32": "12345678",
|
|
}
|
|
|
|
|
|
class IdentityTravels(unittest.TestCase):
|
|
def test_report_and_extra_keep_every_identity_field(self):
|
|
profile = {
|
|
"emulator": "NP2kai",
|
|
"type": "libretro",
|
|
"systems": ["nec-pc-98"],
|
|
"files": [dict(ENTRY)],
|
|
}
|
|
config = {"cores": ["np2kai"], "systems": {}}
|
|
db = {
|
|
"files": {"s1": {"name": "bios.rom", "path": "bios/NEC/PC-98/bios.rom",
|
|
"size": 100000, "sha1": "s1", "md5": "m1", "crc32": "12345678"}},
|
|
"indexes": {"by_name": {"bios.rom": ["s1"]}, "by_md5": {"m1": "s1"},
|
|
"by_crc32": {"12345678": "s1"}},
|
|
}
|
|
report = find_undeclared_files(config, "emulators", db, emu_profiles={"np2kai": profile})
|
|
extras = _collect_emulator_extras(
|
|
config, "emulators", db, set(), "", {"np2kai": profile}, include_all=True
|
|
)
|
|
for label, item in (("report", report[0]), ("extra", extras[0])):
|
|
for field in ("min_size", "validation", "aliases", "crc32"):
|
|
with self.subTest(where=label, field=field):
|
|
self.assertEqual(item.get(field), ENTRY[field])
|
|
|
|
def test_every_hop_reads_the_shared_list(self):
|
|
for name in ("packextras.py", "verify.py"):
|
|
source = (REPO_ROOT / "scripts" / name).read_text(encoding="utf-8")
|
|
with self.subTest(module=name):
|
|
self.assertIn("PROFILE_IDENTITY_FIELDS", source)
|
|
self.assertNotIn('("sha1", "md5", "sha256", "crc32", "size"', source)
|
|
self.assertIn("validation", PROFILE_IDENTITY_FIELDS)
|
|
|
|
|
|
class UnsourceableIsNoCopy(unittest.TestCase):
|
|
"""The second pass copies a covered file to another core's path by name.
|
|
|
|
zc210 ships its own default.sf2; dosbox-staging reads a default.sf2 that
|
|
the operating system links to its SoundFont, which no collection holds.
|
|
The name was enough to give dosbox-staging a slot, recorded as missing
|
|
while zc210 was in the pack and absent once it was not, so a pack built
|
|
for a target disagreed with the installer narrowing the full list.
|
|
"""
|
|
|
|
def test_an_unsourceable_entry_gets_no_copy(self):
|
|
profiles = {
|
|
"zc210": {"emulator": "ZC", "type": "libretro", "systems": ["zc"],
|
|
"files": [{"name": "default.sf2", "path": "zc210/sf2/default.sf2"}]},
|
|
"dosbox-staging": {
|
|
"emulator": "DOSBox Staging", "type": "libretro", "systems": ["dos"],
|
|
"files": [{"name": "default.sf2", "path": "soundfonts/default.sf2",
|
|
"required": False, "unsourceable": "the system's own link"}],
|
|
},
|
|
}
|
|
config = {"cores": ["zc210", "dosbox-staging"], "systems": {}}
|
|
db = {
|
|
"files": {"s1": {"name": "default.sf2", "path": "bios/ZC/default.sf2",
|
|
"size": 10, "sha1": "s1", "md5": "m1", "crc32": "c1"}},
|
|
"indexes": {"by_name": {"default.sf2": ["s1"]}, "by_md5": {"m1": "s1"},
|
|
"by_crc32": {"c1": "s1"},
|
|
"by_path_suffix": {"zc210/sf2/default.sf2": ["s1"]}},
|
|
}
|
|
extras = _collect_emulator_extras(config, "emulators", db, set(), "", profiles)
|
|
self.assertEqual(
|
|
[(e["source_profile"], e["destination"]) for e in extras],
|
|
[("zc210", "zc210/sf2/default.sf2")],
|
|
)
|
|
|
|
|
|
class BareNameIsADestination(unittest.TestCase):
|
|
"""geargrafx reads syscard1.pce at the root of the system directory;
|
|
Recalbox declares it only under pcenginecd/. The declaration settles the
|
|
core's need on the promise that the builder copies the file to the
|
|
core's path, and the second pass skipped every entry with no path."""
|
|
|
|
def test_a_root_copy_of_a_file_declared_in_a_subdirectory(self):
|
|
profiles = {"geargrafx": {
|
|
"emulator": "Geargrafx", "type": "libretro", "systems": ["pce"],
|
|
"files": [{"name": "syscard1.pce"}],
|
|
}}
|
|
config = {"cores": ["geargrafx"], "systems": {"pcenginecd": {"files": [
|
|
{"name": "syscard1.pce", "destination": "pcenginecd/syscard1.pce"}]}}}
|
|
db = {
|
|
"files": {"s1": {"name": "syscard1.pce", "path": "bios/NEC/syscard1.pce",
|
|
"size": 10, "sha1": "s1", "md5": "m1", "crc32": "c1"}},
|
|
"indexes": {"by_name": {"syscard1.pce": ["s1"]}, "by_md5": {"m1": "s1"},
|
|
"by_crc32": {"c1": "s1"}, "by_path_suffix": {}},
|
|
}
|
|
extras = _collect_emulator_extras(
|
|
config, "emulators", db, {"pcenginecd/syscard1.pce"}, "", profiles
|
|
)
|
|
self.assertIn("syscard1.pce", [e["destination"] for e in extras])
|
|
|
|
|
|
class ArchiveMembersStayInside(unittest.TestCase):
|
|
"""fbneo reads msx.rom inside msx.zip. Once the second pass copied bare
|
|
names, it wrote that member loose at the root as soon as another core's
|
|
msx.rom covered the name, and 000-lo.lo landed beside neogeo.zip."""
|
|
|
|
def test_no_loose_copy_of_a_member(self):
|
|
profiles = {
|
|
"zesarux": {"emulator": "ZEsarUX", "type": "libretro", "systems": ["msx"],
|
|
"files": [{"name": "msx.rom"}]},
|
|
"fbneo": {"emulator": "FBNeo", "type": "libretro", "systems": ["msx"],
|
|
"files": [{"name": "msx.rom", "archive": "msx.zip"}]},
|
|
}
|
|
config = {"cores": ["zesarux", "fbneo"], "systems": {}}
|
|
db = {
|
|
"files": {"s1": {"name": "msx.rom", "path": "bios/MSX/msx.rom",
|
|
"size": 10, "sha1": "s1", "md5": "m1", "crc32": "c1"}},
|
|
"indexes": {"by_name": {"msx.rom": ["s1"]}, "by_md5": {"m1": "s1"},
|
|
"by_crc32": {"c1": "s1"}, "by_path_suffix": {}},
|
|
}
|
|
extras = _collect_emulator_extras(config, "emulators", db, set(), "", profiles)
|
|
loose = [e for e in extras if e["destination"] == "msx.rom"]
|
|
self.assertEqual([e["source_profile"] for e in loose], ["zesarux"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|