mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-27 22:27:21 -05:00
chore: merge the per-probe detection guard
This commit is contained in:
commit
ff7db8b5fd
7 files changed
+387
-83
No files matched your search
@@ -665,6 +665,84 @@ class AHomeThisUserCannotOpen(unittest.TestCase):
|
||||
self.assertIn(f"Could not look for setups: this user cannot open {home}",
|
||||
runs["detected"].stderr)
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or os.geteuid() == 0,
|
||||
"a folder without search permission is POSIX")
|
||||
def test_an_assumed_folder_is_not_called_detected(self):
|
||||
"""The refusal ended "than the one detected here" for the built-in
|
||||
default taken because RetroArch was not detected."""
|
||||
with FakeRepository() as repo:
|
||||
home = repo.root / "home"
|
||||
home.mkdir()
|
||||
env = {**repo.env(), "HOME": str(home), "RETROBIOS_OS": "linux"}
|
||||
os.chmod(home, 0o000)
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
[sys.executable, str(REPO_ROOT / "install.py"), "--check",
|
||||
"--no-input", "--platform", "retroarch"],
|
||||
env=env, capture_output=True, text=True, timeout=60,
|
||||
stdin=subprocess.DEVNULL)
|
||||
finally:
|
||||
os.chmod(home, 0o755)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr)
|
||||
said = " ".join(proc.stderr.split())
|
||||
self.assertNotIn("the one detected here", said)
|
||||
self.assertIn("than the one taken as RetroArch's default, RetroArch not being "
|
||||
"found here (name another with --dest).", said)
|
||||
|
||||
|
||||
class APartlyClosedHome(unittest.TestCase):
|
||||
"""~/.config/EmuDeck at 000 (a sudo run leaves it owned by root) made
|
||||
detection return nothing: the readable retroarch.cfg beside it was
|
||||
never read, and the run fell back to ~/.config/retroarch/system, a
|
||||
folder that RetroArch does not read."""
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or os.geteuid() == 0,
|
||||
"a folder without search permission is POSIX")
|
||||
def test_retroarch_is_found_past_the_closed_folder(self):
|
||||
with FakeRepository() as repo:
|
||||
home = repo.root / "home"
|
||||
closed = home / ".config" / "EmuDeck"
|
||||
closed.mkdir(parents=True)
|
||||
cfg = home / ".config" / "retroarch" / "retroarch.cfg"
|
||||
cfg.parent.mkdir()
|
||||
system = repo.root / "elsewhere" / "system"
|
||||
system.mkdir(parents=True)
|
||||
cfg.write_text(f'system_directory = "{system}"\n')
|
||||
env = {**repo.env(), "HOME": str(home), "RETROBIOS_OS": "linux"}
|
||||
runs = {}
|
||||
os.chmod(closed, 0o000)
|
||||
try:
|
||||
for name, extra in (("detected", []),
|
||||
("named", ["--platform", "retroarch"]),
|
||||
("events", ["--events"])):
|
||||
runs[name] = subprocess.run(
|
||||
[sys.executable, str(REPO_ROOT / "install.py"), "--check",
|
||||
"--no-input", *extra],
|
||||
env=env, capture_output=True, text=True, timeout=60,
|
||||
stdin=subprocess.DEVNULL)
|
||||
finally:
|
||||
os.chmod(closed, 0o755)
|
||||
refusal = (f"Could not look for setups: this user cannot open {closed} "
|
||||
"(Permission denied)")
|
||||
for name, proc in runs.items():
|
||||
with self.subTest(run=name):
|
||||
self.assertNotIn("Traceback", proc.stderr)
|
||||
self.assertEqual(" ".join(proc.stderr.split()).count(refusal), 1,
|
||||
proc.stderr)
|
||||
self.assertNotIn(str(home / ".config" / "retroarch" / "system"),
|
||||
proc.stdout + proc.stderr)
|
||||
self.assertIn(f"Found RetroArch at {system}", runs["detected"].stdout)
|
||||
self.assertIn("0/5 present", runs["named"].stdout)
|
||||
self.assertNotIn("not detected", runs["named"].stdout)
|
||||
events = [json.loads(line) for line in runs["events"].stdout.splitlines()]
|
||||
kinds = [event["event"] for event in events]
|
||||
self.assertLess(kinds.index("unsearched"), kinds.index("detect"))
|
||||
unsearched = events[kinds.index("unsearched")]
|
||||
self.assertEqual((unsearched["folder"], unsearched["reason"]),
|
||||
(str(closed), "Permission denied"))
|
||||
detect = events[kinds.index("detect")]
|
||||
self.assertEqual([entry["bios_dir"] for entry in detect["platforms"]], [str(system)])
|
||||
|
||||
|
||||
class OutputToAFileAsksNothing(unittest.TestCase):
|
||||
"""`install.py > log.txt` at a terminal: the menu went into the file
|
||||
|
||||
@@ -2967,6 +2967,112 @@ class AFolderThisUserCannotOpen(unittest.TestCase):
|
||||
def test_the_nearest_folder_stops_above_it(self):
|
||||
self.assertEqual(install._nearest_folder(self.dest / "deeper"), self.lock)
|
||||
|
||||
def test_a_closed_folder_under_home_hides_nothing_else(self):
|
||||
"""~/.config/EmuDeck at 000 made detection return nothing, and the
|
||||
folder screen offered ~/.config/retroarch/system, which this
|
||||
RetroArch does not read: its retroarch.cfg names another."""
|
||||
home = self.lock.parent / "home"
|
||||
closed = home / ".config" / "EmuDeck"
|
||||
closed.mkdir(parents=True)
|
||||
cfg = home / ".config" / "retroarch" / "retroarch.cfg"
|
||||
cfg.parent.mkdir()
|
||||
system = self.lock.parent / "elsewhere" / "system"
|
||||
system.mkdir(parents=True)
|
||||
cfg.write_text(f'system_directory = "{system}"\n')
|
||||
os.chmod(closed, 0o000)
|
||||
self.addCleanup(os.chmod, closed, 0o755)
|
||||
install._DETECTION_REFUSED.clear()
|
||||
self.addCleanup(install._DETECTION_REFUSED.clear)
|
||||
with mock.patch.dict(os.environ, {"HOME": str(home)}), \
|
||||
mock.patch.object(install, "_mounted_cards", return_value=[]), \
|
||||
mock.patch.object(install, "_RETROARCH_CONFIGS", {}):
|
||||
state, _effects = install.tui_start(_args(), "linux")
|
||||
self.assertEqual([setup[:2] for setup in state.setups], [("retroarch", system)])
|
||||
screen = " ".join(" ".join(install.tui_view(state, 80, 24)).split())
|
||||
self.assertEqual(screen.count("Could not look for setups: this user cannot open "
|
||||
"~/.config/EmuDeck (Permission denied)"), 1, screen)
|
||||
|
||||
def test_the_refusal_is_drawn_above_a_full_list(self):
|
||||
"""With a closed HOME the first screen is the 18 setups: the line,
|
||||
drawn under them, was dropped at 80x24 and at 40x15."""
|
||||
home = self.lock.parent / "home"
|
||||
home.mkdir()
|
||||
os.chmod(home, 0o000)
|
||||
self.addCleanup(os.chmod, home, 0o755)
|
||||
install._DETECTION_REFUSED.clear()
|
||||
self.addCleanup(install._DETECTION_REFUSED.clear)
|
||||
with mock.patch.dict(os.environ, {"HOME": str(home)}), \
|
||||
mock.patch.object(install, "_mounted_cards", return_value=[]):
|
||||
state, _effects = install.tui_start(_args(), "linux")
|
||||
self.assertEqual(state.screen, "platforms")
|
||||
for cols, rows in ((80, 24), (40, 15)):
|
||||
with self.subTest(size=f"{cols}x{rows}"):
|
||||
lines = install.tui_view(state, cols, rows)
|
||||
self.assertEqual(len(lines), rows)
|
||||
screen = " ".join(" ".join(lines).split())
|
||||
self.assertIn("Could not look for setups", screen)
|
||||
self.assertIn("name the BIOS folder with --dest.", screen)
|
||||
# The list keeps its focused row in view.
|
||||
self.assertIn("RetroArch", screen)
|
||||
|
||||
|
||||
class AGoesIntoASubfolder(unittest.TestCase):
|
||||
"""At HOME or a drive root A went into the first "dir" row: a mounted
|
||||
card or drive listed first (/mnt/d, the Windows D: drive, then took
|
||||
the BIOS files at its root) or .cache."""
|
||||
|
||||
def setUp(self):
|
||||
self.home = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
|
||||
self.addCleanup(shutil.rmtree, self.home, True)
|
||||
self.card = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
|
||||
self.addCleanup(shutil.rmtree, self.card, True)
|
||||
self.state = install.TuiState(os_type="linux", home=self.home)
|
||||
self.state.platform = "retroarch"
|
||||
self.state.stack = ["folder", "browse"]
|
||||
|
||||
def focused(self) -> install.TuiRow:
|
||||
return self.state.browse_rows[self.state.focus["browse"]]
|
||||
|
||||
def test_a_card_and_cache_are_passed_over(self):
|
||||
(self.home / ".cache").mkdir()
|
||||
(self.home / "Games").mkdir()
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[self.card]):
|
||||
install._browse_to(self.state, self.home)
|
||||
self.assertEqual(self.state.browse_rows[2].value, self.card)
|
||||
self.assertEqual(self.focused().label, "Games/")
|
||||
self.assertEqual(self.state.status, "")
|
||||
|
||||
def test_with_no_visible_subfolder_use_stays_and_says_where(self):
|
||||
(self.home / ".cache").mkdir()
|
||||
(self.home / ".config").mkdir()
|
||||
with mock.patch.object(install, "_mounted_cards", return_value=[self.card]):
|
||||
install._browse_to(self.state, self.home)
|
||||
self.assertEqual(self.focused().action, "use")
|
||||
self.assertIn("This is your home folder", self.state.status)
|
||||
screen = " ".join(" ".join(install.tui_view(self.state, 80, 24)).split())
|
||||
self.assertIn("This is your home folder: no setup reads its BIOS files here.",
|
||||
screen)
|
||||
|
||||
def test_on_windows_the_other_drives_are_passed_over(self):
|
||||
"""The card rows are drive roots there (E:\\): at D:\\ the first
|
||||
was E:\\, and at E:\\ it was D:\\."""
|
||||
(self.home / "Games").mkdir()
|
||||
drives = [Path("D:\\"), Path("E:\\")]
|
||||
windows = WindowsOs()
|
||||
windows.path = types.SimpleNamespace(
|
||||
**{name: getattr(os.path, name) for name in dir(os.path)
|
||||
if not name.startswith("_")})
|
||||
windows.path.exists = lambda path: str(path) in ("C:\\", "D:\\", "E:\\")
|
||||
with mock.patch.object(install, "os", windows), \
|
||||
mock.patch.object(install, "_mounted_cards", return_value=drives):
|
||||
install._browse_to(self.state, self.home)
|
||||
self.assertEqual(self.focused().label, "Games/")
|
||||
# The drives list keeps its first drive focused.
|
||||
install._browse_to(self.state, None)
|
||||
self.assertEqual([row.label for row in self.state.browse_rows],
|
||||
["C:\\", "D:\\", "E:\\"])
|
||||
self.assertEqual(self.state.focus["browse"], 0)
|
||||
|
||||
|
||||
# POSIX modules a Windows Python does not have: importing one raises there.
|
||||
POSIX_ONLY = ("termios", "tty", "pty", "fcntl", "select", "resource", "pwd", "grp")
|
||||
|
||||
Reference in new issue
Block a user