mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
refactor: hoist test imports, rank pairs at module level
This commit is contained in:
1 parent
a5f3a5db25
commit
226a5df74a
22 files changed
+78
-103
No files matched your search
@@ -318,9 +318,9 @@ def build_native_model(
|
||||
# 480-byte boot.bin is not RomM's 2 MB Dreamcast boot.bin.
|
||||
t_size = truth_entry.get("size")
|
||||
p_size = (candidate.platform or {}).get("size")
|
||||
if isinstance(t_size, int) and isinstance(p_size, int) and t_size != p_size:
|
||||
return False
|
||||
return True
|
||||
return not (
|
||||
isinstance(t_size, int) and isinstance(p_size, int) and t_size != p_size
|
||||
)
|
||||
|
||||
def by_hash(candidate: NativeFile) -> bool:
|
||||
if not t_hashes:
|
||||
|
||||
@@ -205,8 +205,11 @@ def verify_pack(
|
||||
# An archive the builder assembled (a MAME clone set): every
|
||||
# member must be a dump the collection holds, loose or inside a
|
||||
# romset.
|
||||
if status == "untracked" and name.endswith(".zip"):
|
||||
if _members_are_held(zf.read(name), by_md5, db):
|
||||
if (
|
||||
status == "untracked"
|
||||
and name.endswith(".zip")
|
||||
and _members_are_held(zf.read(name), by_md5, db)
|
||||
):
|
||||
status = "verified_members"
|
||||
file_name = os.path.basename(name)
|
||||
|
||||
|
||||
+24
-18
@@ -480,6 +480,26 @@ def _hash_set(entry: dict) -> set[str]:
|
||||
return values
|
||||
|
||||
|
||||
def _path_tail(value: object) -> str:
|
||||
return str(value or "").replace("\\", "/").casefold()
|
||||
|
||||
|
||||
def _pair_rank(truth_entry: dict, scraped_entry: dict) -> tuple[bool, bool, bool, bool]:
|
||||
"""How well a same-named truth entry describes a scraped one.
|
||||
|
||||
Exact path suffix, then same directory, then primary name over alias,
|
||||
then a shared hash.
|
||||
"""
|
||||
destination = _path_tail(scraped_entry.get("destination"))
|
||||
t_path = _path_tail(truth_entry.get("path"))
|
||||
return (
|
||||
bool(t_path) and destination.endswith(t_path),
|
||||
"/" in t_path and t_path.rsplit("/", 1)[0] == destination.rpartition("/")[0],
|
||||
truth_entry["name"].lower() == scraped_entry["name"].lower(),
|
||||
bool(_hash_set(scraped_entry) & _hash_set(truth_entry)),
|
||||
)
|
||||
|
||||
|
||||
def _diff_system(truth_sys: dict, scraped_sys: dict) -> dict:
|
||||
"""Compare files between truth and scraped for a single system.
|
||||
|
||||
@@ -502,9 +522,6 @@ def _diff_system(truth_sys: dict, scraped_sys: dict) -> dict:
|
||||
extra_phantom: list[dict] = []
|
||||
extra_unprofiled: list[dict] = []
|
||||
|
||||
def _tail(value: object) -> str:
|
||||
return str(value or "").replace("\\", "/").casefold()
|
||||
|
||||
matched: set[int] = set()
|
||||
unmatched_scraped: dict[int, dict] = {}
|
||||
for s_position, s_entry in enumerate(scraped_files):
|
||||
@@ -515,20 +532,9 @@ def _diff_system(truth_sys: dict, scraped_sys: dict) -> dict:
|
||||
if s_entry["name"].lower() not in truth_index:
|
||||
unmatched_scraped[s_position] = s_entry
|
||||
continue
|
||||
destination = _tail(s_entry.get("destination"))
|
||||
s_hashes = _hash_set(s_entry)
|
||||
|
||||
def rank(position: int) -> tuple[bool, bool, bool, bool]:
|
||||
t = truth_files[position]
|
||||
t_path = _tail(t.get("path"))
|
||||
return (
|
||||
bool(t_path) and destination.endswith(t_path),
|
||||
"/" in t_path and t_path.rsplit("/", 1)[0] == destination.rpartition("/")[0],
|
||||
t["name"].lower() == s_entry["name"].lower(),
|
||||
bool(s_hashes & _hash_set(t)),
|
||||
)
|
||||
|
||||
t_position = max(candidates, key=rank)
|
||||
# The first best candidate wins, as max() keeps the first maximum.
|
||||
ranked = [(_pair_rank(truth_files[p], s_entry), p) for p in candidates]
|
||||
t_position = max(ranked, key=lambda pair: pair[0])[1]
|
||||
matched.add(t_position)
|
||||
t_entry = truth_files[t_position]
|
||||
|
||||
@@ -594,7 +600,7 @@ def _diff_system(truth_sys: dict, scraped_sys: dict) -> dict:
|
||||
# file.
|
||||
seen_extra: set[tuple[str, str]] = set()
|
||||
for s_key, s_entry in unmatched_scraped.items():
|
||||
key = (s_entry["name"].lower(), _tail(s_entry.get("destination")))
|
||||
key = (s_entry["name"].lower(), _path_tail(s_entry.get("destination")))
|
||||
if s_key in rename_matched_scraped or key in seen_extra:
|
||||
continue
|
||||
seen_extra.add(key)
|
||||
|
||||
@@ -546,12 +546,9 @@ class PipelineRegressions(unittest.TestCase):
|
||||
|
||||
argv = ["pipeline.py", "--offline", "--skip-packs", "--skip-docs",
|
||||
"--with-export", "--target", "switch"]
|
||||
with (
|
||||
mock.patch.object(sys, "argv", argv),
|
||||
mock.patch.object(pipeline, "run", side_effect=fake_run),
|
||||
contextlib.redirect_stdout(io.StringIO()),
|
||||
):
|
||||
with contextlib.suppress(SystemExit):
|
||||
with mock.patch.object(sys, "argv", argv), mock.patch.object(
|
||||
pipeline, "run", side_effect=fake_run
|
||||
), contextlib.redirect_stdout(io.StringIO()), contextlib.suppress(SystemExit):
|
||||
pipeline.main()
|
||||
truth_runs = [c for c in commands if "scripts/generate_truth.py" in c]
|
||||
export = next(c for c in commands if "scripts/export_native.py" in c)
|
||||
|
||||
@@ -12,6 +12,7 @@ from __future__ import annotations
|
||||
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"))
|
||||
@@ -43,8 +44,6 @@ class Companions(unittest.TestCase):
|
||||
self.assertEqual([sha for sha, _ in found], ["a"])
|
||||
|
||||
def test_pcsx2_profiles_name_no_free_standing_companion(self):
|
||||
import yaml
|
||||
|
||||
for name in ("pcsx2", "pcsx2-legacy"):
|
||||
profile = yaml.safe_load((REPO_ROOT / "emulators" / f"{name}.yml").read_text())
|
||||
names = {str(f.get("name", "")).lower() for f in profile.get("files", [])}
|
||||
|
||||
@@ -15,12 +15,11 @@ import yaml
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from common import load_platform_config # noqa: E402
|
||||
|
||||
|
||||
class CaseInsensitiveWhereTheFilesystemIs(unittest.TestCase):
|
||||
def test_windows_and_macos_platforms_carry_the_flag(self):
|
||||
from common import load_platform_config
|
||||
|
||||
registry = yaml.safe_load((REPO_ROOT / "platforms" / "_registry.yml").read_text())
|
||||
for name, data in registry["platforms"].items():
|
||||
systems = {str(d.get("os")) for d in (data.get("install") or {}).get("detect", [])}
|
||||
|
||||
@@ -18,6 +18,7 @@ from unittest import mock
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
import generate_db # noqa: E402
|
||||
|
||||
|
||||
class _NoCoreInfo:
|
||||
@@ -27,8 +28,6 @@ class _NoCoreInfo:
|
||||
|
||||
class AliasesNeedAnUnambiguousName(unittest.TestCase):
|
||||
def _aliases(self, files: dict) -> dict:
|
||||
import generate_db
|
||||
|
||||
stub = types.ModuleType("scraper.coreinfo_scraper")
|
||||
stub.Scraper = _NoCoreInfo
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
@@ -71,8 +70,6 @@ class NoNetworkInTheBuild(unittest.TestCase):
|
||||
self.assertNotIn("urllib.request", source)
|
||||
|
||||
def test_hash_proven_entry_registers_its_own_name(self):
|
||||
import generate_db
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
@@ -91,8 +88,6 @@ class NoNetworkInTheBuild(unittest.TestCase):
|
||||
class AcceptedRevisionLists(unittest.TestCase):
|
||||
def test_a_list_of_sha1_names_every_held_revision(self):
|
||||
"""A profile accepting several revisions writes sha1 as a list."""
|
||||
import generate_db
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
@@ -114,8 +109,6 @@ class AcceptedRevisionLists(unittest.TestCase):
|
||||
class CrossNamingStaysInItsProfile(unittest.TestCase):
|
||||
def test_an_alias_naming_a_sibling_entry_is_not_indexed(self):
|
||||
"""dosbox-x aliases MT32_CONTROL.ROM and CM32L_CONTROL.ROM to each other."""
|
||||
import generate_db
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
|
||||
@@ -22,6 +22,8 @@ from exporter.baseline import NativeFile, NativeSystem, build_native_model # no
|
||||
from exporter.emudeck_exporter import Exporter as EmuDeck # noqa: E402
|
||||
from exporter.retrobat_exporter import Exporter as RetroBat # noqa: E402
|
||||
from exporter.retrodeck_exporter import Exporter as RetroDeck # noqa: E402
|
||||
from exporter.recalbox_exporter import Exporter as Recalbox # noqa: E402
|
||||
from exporter.retropie_exporter import Exporter as RetroPie # noqa: E402
|
||||
|
||||
A = "a" * 32
|
||||
B = "b" * 32
|
||||
@@ -171,16 +173,12 @@ class OneFileOneIdentity(unittest.TestCase):
|
||||
|
||||
class RecalboxKeepsItsOwnNotes(unittest.TestCase):
|
||||
def test_no_profile_prose_reaches_a_note(self):
|
||||
from exporter.recalbox_exporter import Exporter as Recalbox
|
||||
|
||||
fe = NativeFile("bios.bin", "bios.bin", "psx", platform={"md5": A},
|
||||
truth={"md5": A, "note": "Loaded at libretro.c:120"})
|
||||
self.assertNotIn("note=", Recalbox()._bios_element(fe, "psx"))
|
||||
|
||||
class RetroPieProposals(unittest.TestCase):
|
||||
def test_required_is_read_for_the_package_core(self):
|
||||
from exporter.retropie_exporter import Exporter as RetroPie
|
||||
|
||||
fe = NativeFile("scph5501.bin", "scph5501.bin", "psx",
|
||||
truth={"required": True, "_required_by": ["beetle_psx"],
|
||||
"_cores": ["beetle_psx", "pcsx_rearmed"]})
|
||||
@@ -188,8 +186,6 @@ class RetroPieProposals(unittest.TestCase):
|
||||
self.assertFalse(RetroPie._required_for(fe, "pcsx_rearmed"))
|
||||
|
||||
def test_a_list_of_alternatives_is_not_extended(self):
|
||||
from exporter.retropie_exporter import Exporter as RetroPie
|
||||
|
||||
alternatives = "Copy the required BIOS file a.rom or b.rom to $biosdir"
|
||||
enumeration = "Copy the required BIOS files a.rom and b.rom to $biosdir"
|
||||
self.assertIsNone(RetroPie._insertion_point(alternatives))
|
||||
|
||||
@@ -16,6 +16,8 @@ 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",
|
||||
@@ -29,9 +31,6 @@ ENTRY = {
|
||||
|
||||
class IdentityTravels(unittest.TestCase):
|
||||
def test_report_and_extra_keep_every_identity_field(self):
|
||||
from packextras import _collect_emulator_extras
|
||||
from verify import find_undeclared_files
|
||||
|
||||
profile = {
|
||||
"emulator": "NP2kai",
|
||||
"type": "libretro",
|
||||
|
||||
@@ -16,12 +16,11 @@ from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from generate_pack import verify_and_finalize_packs # noqa: E402
|
||||
|
||||
|
||||
class FinalizeByExactName(unittest.TestCase):
|
||||
def test_a_custom_pack_is_not_judged_as_the_platform_pack(self):
|
||||
from generate_pack import verify_and_finalize_packs
|
||||
|
||||
previous = os.getcwd()
|
||||
os.chdir(REPO_ROOT)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
|
||||
@@ -9,7 +9,6 @@ the pack and the manifest while verify, comparing md5, called it OK.
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
@@ -21,6 +20,9 @@ import yaml
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from common import load_platform_config # noqa: E402
|
||||
from generate_pack import generate_manifest, generate_pack # noqa: E402
|
||||
from verify import verify_platform # noqa: E402
|
||||
|
||||
|
||||
class FrontendDigestDecides(unittest.TestCase):
|
||||
@@ -61,10 +63,6 @@ class FrontendDigestDecides(unittest.TestCase):
|
||||
self.root = root
|
||||
|
||||
def test_pack_manifest_and_verify_agree(self):
|
||||
from common import load_platform_config
|
||||
from generate_pack import generate_manifest, generate_pack
|
||||
from verify import verify_platform
|
||||
|
||||
os.chdir(self.root)
|
||||
self.addCleanup(os.chdir, REPO_ROOT)
|
||||
zip_path = generate_pack(
|
||||
|
||||
@@ -12,6 +12,7 @@ import hashlib
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
@@ -24,6 +25,7 @@ sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
import common # noqa: E402
|
||||
import largefiles
|
||||
import check_release_assets # noqa: E402
|
||||
|
||||
PAYLOAD_A = b"A" * (256 * 1024)
|
||||
PAYLOAD_B = b"B" * (256 * 1024)
|
||||
@@ -366,7 +368,6 @@ class ReleaseAssetNames(unittest.TestCase):
|
||||
self.assertEqual(name, os.path.basename(registered_path))
|
||||
|
||||
def test_manifest_checker_and_fetcher_agree_on_a_path(self):
|
||||
import check_release_assets
|
||||
import generate_pack
|
||||
|
||||
expected = largefiles.asset_names(self.REGISTERED)
|
||||
@@ -488,8 +489,6 @@ class DownloadFailuresAndRevisions(unittest.TestCase):
|
||||
self.addCleanup(setattr, largefiles.urllib.request, "urlopen", self._urlopen)
|
||||
|
||||
def tearDown(self):
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(self.dir, ignore_errors=True)
|
||||
|
||||
def test_a_stalled_stream_leaves_no_scratch(self):
|
||||
@@ -534,8 +533,6 @@ class GameDataHasOneDefinition(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def test_the_release_section_follows_the_composition_tier(self):
|
||||
import check_release_assets
|
||||
|
||||
for path in (
|
||||
"bios/Id Software/Doom 3/demo/demo00.pk4",
|
||||
"bios/Valve/Half-Life/valve/pak0.pak",
|
||||
|
||||
@@ -45,6 +45,7 @@ class SuiteWithoutJsonschema(unittest.TestCase):
|
||||
[sys.executable, "-c", HIDE_AND_RUN, *names],
|
||||
cwd=REPO_ROOT,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
text=True,
|
||||
timeout=600,
|
||||
)
|
||||
|
||||
@@ -10,6 +10,8 @@ from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -18,12 +20,11 @@ from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from packverify import verify_pack # noqa: E402
|
||||
|
||||
|
||||
class MembersMustBeKnown(unittest.TestCase):
|
||||
def test_unknown_bytes_are_an_error_and_assembled_sets_pass(self):
|
||||
from packverify import verify_pack
|
||||
|
||||
known = b"known rom" * 10
|
||||
md5 = hashlib.md5(known).hexdigest()
|
||||
inner = io.BytesIO()
|
||||
@@ -46,9 +47,6 @@ class SchemaAcceptsEveryStatus(unittest.TestCase):
|
||||
"""verified_members reached every pack manifest and the schema refused it."""
|
||||
|
||||
def test_each_status_packverify_writes_is_in_the_schema(self):
|
||||
import json
|
||||
import re
|
||||
|
||||
source = (REPO_ROOT / "scripts" / "packverify.py").read_text(encoding="utf-8")
|
||||
written = set(re.findall(r'status = "([a-z_]+)"', source))
|
||||
schema = json.loads(
|
||||
|
||||
@@ -8,6 +8,7 @@ does not have, while the registry names the path.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
@@ -49,8 +50,6 @@ class GuidesPointAtTheReadPath(unittest.TestCase):
|
||||
class GuidesNameShippedInstallers(unittest.TestCase):
|
||||
def test_every_installer_named_exists(self):
|
||||
"""RetroBat's guide sent users to an install.bat no release carries."""
|
||||
import re
|
||||
|
||||
source = (REPO_ROOT / "scripts" / "packreadme.py").read_text(encoding="utf-8")
|
||||
for name in set(re.findall(r"install\.(?:bat|ps1|sh|py)", source)):
|
||||
with self.subTest(installer=name):
|
||||
|
||||
@@ -23,6 +23,7 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
import refresh_data_dirs as rdd # noqa: E402
|
||||
from generate_pack import _data_directory_members # noqa: E402
|
||||
|
||||
|
||||
def _zip_bytes(files: dict[str, bytes]) -> bytes:
|
||||
@@ -117,9 +118,8 @@ class RefreshConcurrency(unittest.TestCase):
|
||||
|
||||
class PackWalkHoldsTheCache(unittest.TestCase):
|
||||
def test_a_refresh_waits_for_the_walk(self):
|
||||
import fcntl
|
||||
import fcntl # noqa: PLC0415
|
||||
|
||||
from generate_pack import _data_directory_members
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
cache = Path(tmp) / "data" / "sdlpal"
|
||||
@@ -130,8 +130,10 @@ class PackWalkHoldsTheCache(unittest.TestCase):
|
||||
registry = {"sdlpal": {"local_cache": str(cache)}}
|
||||
walk = _data_directory_members(systems, registry, "p", "", False, set(), set(), set())
|
||||
next(walk)
|
||||
with open(cache.with_name(".sdlpal.lock"), "a") as handle:
|
||||
with self.assertRaises(BlockingIOError):
|
||||
with (
|
||||
open(cache.with_name(".sdlpal.lock"), "a") as handle,
|
||||
self.assertRaises(BlockingIOError),
|
||||
):
|
||||
fcntl.flock(handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
list(walk)
|
||||
with open(cache.with_name(".sdlpal.lock"), "a") as handle:
|
||||
|
||||
@@ -14,12 +14,11 @@ from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
from packextras import platform_region_groups # noqa: E402
|
||||
|
||||
|
||||
class RequiredOnlyBeforeRegion(unittest.TestCase):
|
||||
def test_optional_files_leave_the_groups(self):
|
||||
from packextras import platform_region_groups
|
||||
|
||||
systems = {"vic20": {"files": [
|
||||
{"name": "kernel-ntsc.bin", "destination": "Vic20/kernel-ntsc.bin", "required": True},
|
||||
{"name": "kernel-japanese.bin", "destination": "Vic20/kernel-japanese.bin",
|
||||
|
||||
@@ -24,7 +24,7 @@ class RequiredOnlyArchives(unittest.TestCase):
|
||||
result = subprocess.run(
|
||||
[sys.executable, "scripts/generate_pack.py", "--emulator", "geolith",
|
||||
"--required-only", "--offline", "--output-dir", tmp],
|
||||
capture_output=True, text=True, cwd=REPO_ROOT, timeout=600,
|
||||
capture_output=True, check=False, text=True, cwd=REPO_ROOT, timeout=600,
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||
pack = next(Path(tmp).glob("*.zip"))
|
||||
|
||||
+1
-2
@@ -12,6 +12,7 @@ from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
||||
|
||||
import slots # noqa: E402
|
||||
from slots import Claim, Conflict, arbitrate, format_decision # noqa: E402
|
||||
|
||||
|
||||
def _db(entries: dict[str, dict]) -> dict:
|
||||
@@ -559,8 +560,6 @@ class StrongestProfileClaimWins(unittest.TestCase):
|
||||
"""yaps2 pins GameIndex.yaml by sha1; armsx2 matched a path only."""
|
||||
|
||||
def test_hash_proof_beats_path_proof(self):
|
||||
from slots import Claim, Conflict, arbitrate, format_decision
|
||||
|
||||
def claim(emu, path, status):
|
||||
return Claim("profile", "pcsx2/resources/GameIndex.yaml", "GameIndex.yaml",
|
||||
emulator=emu, local_path=path, status=status)
|
||||
|
||||
@@ -8,6 +8,7 @@ packs built for it shrank without an error.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
import unittest
|
||||
import urllib.error
|
||||
@@ -35,9 +36,11 @@ class FailedRequestsStopTheScrape(unittest.TestCase):
|
||||
retropie_targets_scraper,
|
||||
retroarch_targets_scraper,
|
||||
):
|
||||
with self.subTest(scraper=module.__name__):
|
||||
with mock.patch.object(module.urllib.request, "urlopen", _refuse):
|
||||
with self.assertRaises(RuntimeError):
|
||||
with (
|
||||
self.subTest(scraper=module.__name__),
|
||||
mock.patch.object(module.urllib.request, "urlopen", _refuse),
|
||||
self.assertRaises(RuntimeError),
|
||||
):
|
||||
module.Scraper().fetch_targets()
|
||||
|
||||
def test_an_empty_listing_is_not_a_target(self):
|
||||
@@ -52,11 +55,11 @@ class FailedRequestsStopTheScrape(unittest.TestCase):
|
||||
return b"[]"
|
||||
|
||||
for module in (emudeck_targets_scraper, retropie_targets_scraper):
|
||||
with self.subTest(scraper=module.__name__):
|
||||
with mock.patch.object(
|
||||
module.urllib.request, "urlopen", lambda *a, **k: _Empty()
|
||||
with (
|
||||
self.subTest(scraper=module.__name__),
|
||||
mock.patch.object(module.urllib.request, "urlopen", lambda *_a, **_k: _Empty()),
|
||||
self.assertRaises(RuntimeError),
|
||||
):
|
||||
with self.assertRaises(RuntimeError):
|
||||
module.Scraper().fetch_targets()
|
||||
|
||||
|
||||
@@ -101,8 +104,6 @@ class RetroPieModuleFlags(unittest.TestCase):
|
||||
}
|
||||
|
||||
def fake_fetch(url, accept="text/plain"):
|
||||
import json
|
||||
|
||||
section = url.rstrip("/").rsplit("/", 1)[-1]
|
||||
if section in listings:
|
||||
return json.dumps(listings[section])
|
||||
|
||||
@@ -10,14 +10,16 @@ discrepancy that does not exist. Content decides, as everywhere else here.
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
from truth import _match_renames # noqa: E402
|
||||
from truth import _diff_system, _match_renames, _merge_file_into_system # noqa: E402
|
||||
|
||||
|
||||
def _entry(name: str, **hashes) -> dict:
|
||||
@@ -33,16 +35,13 @@ class ATargetedModelIsItsOwnArtifact(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def test_a_target_writes_beside_the_full_model(self):
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
repo = pathlib.Path(__file__).resolve().parent.parent
|
||||
with tempfile.TemporaryDirectory(dir=str(repo / "tmp")) as directory:
|
||||
for extra in ([], ["--target", "browser"]):
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "scripts/generate_truth.py", "--platform",
|
||||
"romm", *extra, "--output-dir", directory],
|
||||
capture_output=True, text=True, cwd=str(repo), timeout=400,
|
||||
capture_output=True, check=False, text=True, cwd=str(repo), timeout=400,
|
||||
)
|
||||
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
|
||||
produced = sorted(
|
||||
@@ -60,16 +59,13 @@ class ADiffThatComparedNothingFails(unittest.TestCase):
|
||||
"""diff_truth --all skipped every platform without a model and exited 0."""
|
||||
|
||||
def test_an_empty_truth_directory_is_an_error(self):
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
repo = pathlib.Path(__file__).resolve().parent.parent
|
||||
with tempfile.TemporaryDirectory(dir=str(repo / "tmp")) as directory:
|
||||
for selection in (["--all"], ["--platform", "retroarch"]):
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "scripts/diff_truth.py", *selection,
|
||||
"--truth-dir", directory, "--json"],
|
||||
capture_output=True, text=True, cwd=str(repo), timeout=120,
|
||||
capture_output=True, check=False, text=True, cwd=str(repo), timeout=120,
|
||||
)
|
||||
self.assertEqual(proc.returncode, 1, selection)
|
||||
self.assertIn("skip", proc.stderr)
|
||||
@@ -81,8 +77,6 @@ class OneNameSeveralFiles(unittest.TestCase):
|
||||
REGIONS = {"USA": "a" * 32, "EUR": "b" * 32, "JAP": "c" * 32}
|
||||
|
||||
def _system(self) -> dict:
|
||||
from truth import _merge_file_into_system
|
||||
|
||||
system: dict = {}
|
||||
for core in ("dolphin", "ishiiruka"):
|
||||
for region, md5 in self.REGIONS.items():
|
||||
@@ -105,8 +99,6 @@ class OneNameSeveralFiles(unittest.TestCase):
|
||||
self.assertEqual(entry["_cores"] - {"other"}, {"dolphin", "ishiiruka"})
|
||||
|
||||
def test_revisions_under_one_name_and_no_path_stay_one_file(self):
|
||||
from truth import _merge_file_into_system
|
||||
|
||||
system: dict = {}
|
||||
for md5 in ("a" * 32, "b" * 32):
|
||||
_merge_file_into_system(
|
||||
@@ -115,8 +107,6 @@ class OneNameSeveralFiles(unittest.TestCase):
|
||||
self.assertEqual(len(system["files"]), 1)
|
||||
|
||||
def test_the_diff_pairs_each_by_destination(self):
|
||||
from truth import _diff_system
|
||||
|
||||
scraped = {"files": [
|
||||
{"name": "IPL.bin", "destination": f"dolphin-emu/Sys/GC/{region}/IPL.bin",
|
||||
"md5": md5}
|
||||
|
||||
@@ -12,7 +12,7 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
def _run(*argv: str) -> subprocess.CompletedProcess:
|
||||
return subprocess.run(
|
||||
[sys.executable, *argv], capture_output=True, text=True, cwd=REPO_ROOT, timeout=300
|
||||
[sys.executable, *argv], capture_output=True, check=False, text=True, cwd=REPO_ROOT, timeout=300
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user