diff --git a/install.ps1 b/install.ps1 index d31fa3a10..1403f0b94 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "6e625f7a8c9c3ba095c8240dc3e8482dddd514e438302a576a2f80807e79a547" + $defaultInstallSha256 = "137a32f9e9c89dca56e62171c690955692b79ef8636bc8492cd4b68d707c32e2" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 0bd9c4d18..3ff9dc274 100644 --- a/install.py +++ b/install.py @@ -495,7 +495,7 @@ def terminal_size() -> tuple[int, int]: every layout of it makes. Python 3.8 gives a pty of no size as 0 and 0, where 3.11 falls back to 80 and 24: a list laid out in 0 columns never ended, the plan printed an empty heading, and the progress line lost - every figure but its percentage (code_audit_23 P3-5).""" + every figure but its percentage.""" size = shutil.get_terminal_size((80, 24)) return max(size.columns or 80, LINE_MIN_COLS), size.lines or 24 @@ -1187,7 +1187,7 @@ def shown_path(path: Path | str) -> str: text = f"{match.group(1).upper()}:\\" + (match.group(2) or "").replace("/", "\\") # A folder's name comes from whoever named it: a card's label, a # retroarch.cfg, a pack. Printed raw, a control character in it is a - # terminal command (code_audit_18 P2-1). + # terminal command. return screen_text(text) @@ -2734,7 +2734,7 @@ def detect_platforms(os_type: str) -> list[tuple[str, Path]]: if _CONTROLS.search(str(path)): # A config naming a folder with a control character: printed, # the name is a terminal command, and the folder one nobody can - # type (code_audit_18 P2-1). Its default is then no answer: the + # type. Its default is then no answer: the # setup reads the folder named. if name not in _UNNAMEABLE: _UNNAMEABLE.append(name) @@ -3120,7 +3120,7 @@ def _safe_relative_path(value: object, field: str) -> PurePosixPath: ): # A control character is refused with NUL: a pack's member named # x]0;PWN.bin set the window title in the progress line, - # and the file was written under that name (code_audit_18 P2-1). + # and the file was written under that name. raise ValueError(f"unsafe {field}: {value!r}") path = PurePosixPath(value) if path.is_absolute() or any(part in ("", ".", "..") for part in path.parts): @@ -4401,8 +4401,7 @@ def recorded_axes(files: list[dict], omitted: list[dict] = ()) -> frozenset: """What a file list lets --system, --core and --region narrow by: its systems, its cores, its regions. A list from an older release records none. The MinUI family's records cores and regions and no system: all - three were refused on it, by a remedy that fetched the same list - (tui_audit_11 P2-1).""" + three were refused on it, by a remedy that fetched the same list.""" entries = [*files, *omitted] systems = any("systems" in entry for entry in entries) if not systems and not any("regions" in entry for entry in entries): @@ -4801,7 +4800,7 @@ def say_saves(plat: str, files: list[dict], omitted: list[dict], bios_path: Path # The digests the line menu's head read of the files in place, by path and # by what stat says of the file, kept for the check that follows Enter: the -# head named a wrong copy of the right size in place (code_audit_23 P3-2), +# head named a wrong copy of the right size in place, # and a card read twice is read at the speed of its reader. Emptied once # that check has read them (head_reads_done). _HEAD_READS: dict[tuple, dict[str, str]] = {} @@ -5348,7 +5347,7 @@ def _download_one( except ValueError: return str(f.get("dest", "?")), False, "unsafe destination" # Nothing to write, no folder made: a pack lacking the list's files - # left 405 empty folders in the BIOS folder (tui_audit_13 P3-8). + # left 405 empty folders in the BIOS folder. if copy is None and LOCAL.pack is not None and LOCAL.pack.find(f) is None: return f["dest"], False, NOT_IN_PACK if copy is None and LOCAL.pack is None and offline_requested(): @@ -5805,7 +5804,7 @@ _CHOICE_OPTIONS = ("--system", "--core", "--region", "--for-games", "--required- # The order every command given back writes its options in: the list, what # narrows it, where files are copied from, then how the run goes. The screen # wrote --manifest before --from and line mode after it, for one choice -# (tui_audit_16 P3-14). An option not named here comes after them. +# An option not named here comes after them. _COMMAND_ORDER = ( "--manifest", "--from-pack", "--system", "--core", "--emulator", "--region", "--for-games", "--required-only", "--target", "--no-game-data", "--installed-cores", "--cores-dir", "--every-board", @@ -5968,7 +5967,7 @@ def write_remedy(path: Path, plat: str, hint: Invocation, commands: bool = True) return [read_only_words(path)] if hint.os_type == "android": # Termux has no sudo: its shared storage is reached once Android - # gives it the storage permission (tui_audit_17 P2-2). + # gives it the storage permission. return [TERMUX_STORAGE_WORDS] if not commands: return [] @@ -6040,8 +6039,7 @@ def _plural(count: int, word: str) -> str: def agree(count: int, one: str, many: str) -> str: """The verb a count takes: "1 needs", "2 need". Each count said with a - verb reads it here: "1 need the internet" stood on the plan - (code_audit_23 P3-4).""" + verb reads it here: "1 need the internet" stood on the plan.""" return f"{count} {one if count == 1 else many}" @@ -6128,7 +6126,7 @@ def _report_outcome( """ say = _status_print(term) # The command making the same choice ends every result the screen ends - # with it: "Finished with files missing" gave none (tui_audit_15 P3-8). + # with it: "Finished with files missing" gave none. same_lines = ([f"Same choice without questions: {screen_text(same_choice)}"] if same_choice else []) # A file --offline left out is not a failure, whether the run asked or @@ -6146,7 +6144,7 @@ def _report_outcome( f"{format_duration(seconds)} ({format_size(int(transferred / seconds))}/s).") reasons = {reason for _dest, reason in failures or []} # A failure the progress already named on its FAILED line is not named - # again: line mode listed each one twice (tui_audit_17 P3-7). + # again: line mode listed each one twice. unsaid = [failure for failure in failures or [] if failure[0] not in SAID_FAILED] if failures and len(failures) > 1 and len(reasons) == 1 and reasons != {""}: # One cause, said once: a read-only folder listed ten of its files @@ -6230,8 +6228,8 @@ def _report_outcome( failed = f", {errors} failed" if errors else "" if downloaded and sources: # One count, the remedy under it, as the screen's result: the - # count came twice, "installed" then "copied" (tui_audit_15 - # P3-8). The failed files are in it. + # count came twice, "installed" then "copied". The failed files are + # in it. say(f"\nFinished with files missing. {sources}") sources = "" elif downloaded: @@ -6249,7 +6247,7 @@ def _report_outcome( if missing is not None and missing.bios and missing.games: # The kinds still missing, as the screen's result says them, # before the remedy: "They are not in OLD" followed the files - # installed (tui_audit_16 P3-3). + # installed. say(f" Still missing: {installed_words(missing.bios, missing.games)}.") # Under the files it is about: after the save-directory line, "They" # read as that one file. @@ -6282,7 +6280,7 @@ def _report_outcome( if errors: # One count: "42 files installed, 2 files failed." over "38 files # copied from E:\, 4 downloaded, 2 still missing." said it twice, - # the failed files as missing ones (tui_audit_16 P3-11). + # the failed files as missing ones. say(f"\nFinished with errors. {sources}" if sources else f"\nFinished with errors. {_plural(downloaded, 'file')} installed, " f"{_plural(errors, 'file')} failed.") @@ -6302,13 +6300,12 @@ def _report_outcome( # No zero count, the screen's words: "Done. 0 files installed, 22 # files already up to date" beside its "Everything is in place" - # (code_audit_22 P3-4). in_place = f" {_plural(up_to_date, 'file')} already in place." if up_to_date else "" if not downloaded: say(f"\nDone. {EVERYTHING_IN_PLACE}") elif sources and "," not in sources and not KEPT.summary(): # Every file from one place: "22 files installed." over "22 files - # copied from packx." said one count twice (tui_audit_15 P3-8). + # copied from packx." said one count twice. say(f"\nDone. {sources}{in_place}") sources = "" else: @@ -6330,7 +6327,7 @@ def _report_outcome( say(line) if same_choice: # After the questions, as the screen's result ends: "the same - # command" was one that asked them (tui_audit_11 P3-21). + # command" was one that asked them. for line in same_lines: say(line) say("To check this later, run that command with --check.") @@ -6363,7 +6360,7 @@ SAID_FAILED: set[str] = set() def _retry_words(failures: list | None) -> str: """What to do when every failure is a file the pack does not hold: a second run fails them the same way, and "run it again to retry only - those" sent people round (code_audit_21 P3-3). "" otherwise.""" + those" sent people round. "" otherwise.""" lacking = [dest for dest, reason in failures or [] if str(reason) == NOT_IN_PACK] if not lacking or len(lacking) != len([ dest for dest, reason in failures or [] if not str(reason).startswith(NOT_KEPT)]): @@ -6424,8 +6421,7 @@ def game_data_missing(names: str, count: int, folders: list[Path]) -> str: where = (f" into {', '.join(places[:3])}" + (f" and {len(places) - 3} more folders" if len(places) > 3 else "")) if places else "" # The names first, the kind after them in a word: the definition was - # spliced into this sentence, and said again on its own line - # (tui_audit_13 P3-5). + # spliced into this sentence, and said again on its own line. return (f"Not available here: {names}, game data " f"{'its game reads' if one else 'their games read'}. Copy " f"{'it' if one else 'them'} from your own copy of the game{where}.") @@ -6433,7 +6429,7 @@ def game_data_missing(names: str, count: int, folders: list[Path]) -> str: def not_installable_words(count: int, required: int, reasons: dict[str, int]) -> str: """The line under the index count for the files the list leaves out: - "(1 required, not found: 37)" read as a sum (tui_audit_16 P3-6).""" + "(1 required, not found: 37)" read as a sum.""" need = ("" if not required else ", required" if count == 1 else f", {required} of them required") if set(reasons) == {"not_found"}: @@ -6573,7 +6569,7 @@ def _print_plan( trees = [(entry, needed) for entry, needed in trees if needed] tree_counts = tally(meta for _entry, needed in trees for meta in needed.values()) tree_files = tree_counts.files - # One count for the plan, the screen's (code_audit_21 P3-8): "8252 + # One count for the plan, the screen's: "8252 # files, and 2636 data files" read as two kinds of one thing. The kinds # follow, adding up to it. total = counts.files + tree_files @@ -6675,7 +6671,7 @@ def _check_free_space(bios_path: Path, needed: int, plat: str = "", code: int = file=sys.stderr) if card: # Its system reads this card alone: another drive, with RetroArch's - # list, was offered for an Onion card (code_audit_18 P3-2). + # list, was offered for an Onion card. print(f" Free up {format_size(needed - free)} on the card, then run it again: " "its system reads its BIOS files there only.", file=sys.stderr) sys.exit(code) @@ -6871,7 +6867,7 @@ def install_data_directory(entry: dict, bios_path: Path, state: tuple[Path, dict[str, dict], int] | None = None) -> dict: """Rebuild one data tree from its source archive, file by file verified. state is the tree's data_directory_state when the run already read it: - each read hashes every file in place (code_audit_22 P3-3). + each read hashes every file in place. Returns counts: present, installed, changed (the source no longer holds the recorded bytes), absent (not in the archive), error, the reason @@ -7346,7 +7342,7 @@ def _choose_platform(title: str, default: str = "", setups: list | None = None, print(f"\n{title}") # Wrapped at the width between words, its devices under its name: left # to the terminal, "Miyoo Flip" was folded inside "Miy" and "oo" below - # 40 columns (tui_audit_16 P3-15). + # 40 columns. cols = terminal_size()[0] - 1 width = len(str(len(choices))) for i, (_name, label) in enumerate(choices, 1): @@ -7466,9 +7462,9 @@ def drive_targets(plat: str) -> list[tuple[str, Path]]: card of a system that reads plat's list by its own BIOS folder, a drive nothing names by its bios folder. A drive's root is no answer: no setup reads its BIOS files there, and RetroArch's list landed beside the roms/ - and system/ of a Batocera SHARE drive (code_audit_18 P2-2, tui_audit_11 - P1-2). Another system's card or drive, and one two systems fit, are - reached through their own setup (drives_left_out).""" + and system/ of a Batocera SHARE drive. Another system's card or drive, and + one two systems fit, are reached through their own setup + (drives_left_out).""" targets = [] for mount in _mounted_cards(): found = card_system(mount) @@ -7481,7 +7477,7 @@ def drive_targets(plat: str) -> list[tuple[str, Path]]: else: # A drive its files show to be no card is called a drive, under # the note that says so: "card or drive" sat under "nothing on - # it shows a handheld's card" (tui_audit_16 P3-9). + # it shows a handheld's card". targets.append((f"{_drive_folder(mount, 'bios')} (drive)", mount / "bios")) return targets @@ -7490,13 +7486,13 @@ def folder_drives(os_type: str, plat: str, side: bool = True) -> list[tuple[str, """The folders the folder question numbers for a setup that runs from no card, in the one order both modes give them: the other side's usual folder (side, under WSL), then the drives. Line mode and the screen - gave them in two orders (code_audit_23 P3-6).""" + gave them in two orders.""" return [*(other_side(os_type, plat) if side else []), *drive_targets(plat)] # What a handheld system writes on the games part a computer mounts, beside # its bios folder: a drive holding these is that card, and a data drive or -# a stick with an emulation library holds none of them (code_audit_22 P2-1). +# a stick with an emulation library holds none of them. # Each rule's values must all be there, with bios/, on a drive the system # does not call fixed (games_part). One system may have several rules: any # one of them is its proof. @@ -7511,7 +7507,7 @@ _GAMES_PART_RULES = ( # (game_systems.txt:23,54, finishing_touches.sh:288-290,420-430). # themes/ is no proof: the 12262020 update left it on the system part of # a card with under 1 GB free (Update-RGB10.sh:59-69), and 2020's trees - # hold none (code_audit_23 P3-1). + # hold none. # Its list is RetroArch's, written in the bios folder of that part. _OsRule("retroarch", "ArkOS", "games_part", ("bgmusic",), "bios"), _OsRule("retroarch", "ArkOS", "games_part", ("launchimages",), "bios"), @@ -7596,7 +7592,7 @@ def games_part(root: Path) -> _OsRule | None: system's own card everywhere (card_system, the first screen, the card routes, line mode). ArkOS's was a card "of a system that reads RetroArch's list", named nowhere and called a card RetroBIOS cannot - tell on the ArkOS route (tui_audit_17 P2-3).""" + tell on the ArkOS route.""" return next((rule for rule in _GAMES_PART_RULES if _games_part_matches(rule, root)), None) @@ -7615,7 +7611,7 @@ def _names_and(names: list[str]) -> str: def unproven_words() -> str: """The plain note on those drives, "" for none: what was looked for on - them, and what the reader does (tui_audit_16 P3-9).""" + them, and what the reader does.""" drives = unproven_drives() if not drives: return "" @@ -7627,17 +7623,16 @@ def unproven_words() -> str: def _said_with(label: str, words: str) -> str: """label with words in its parenthesis, or in one of their own: two side - by side read as a slip (tui_audit_16 P3-9).""" + by side read as a slip.""" return f"{label[:-1]}, {words})" if label.endswith(")") else f"{label} ({words})" def numbered_folder(label: str, folder: Path) -> str: """A folder numbered at the folder question: its row's label, then the folder and whether it exists in one parenthesis. "DATA: bios (card or - drive) (/media/me/DATA/bios)" put two side by side (tui_audit_16 - P3-9). A label that spells its folder (the Windows side's) is not - followed by it again. Said of a folder that is missing, as the screen - says it (code_audit_21 P3-7).""" + drive) (/media/me/DATA/bios)" put two side by side. A label that spells its + folder (the Windows side's) is not followed by it again. Said of a folder + that is missing, as the screen says it.""" shown = shown_path(folder) said = [] if shown in label else [shown] said += [] if _is_dir(folder) else ["does not exist yet"] @@ -7647,8 +7642,7 @@ def numbered_folder(label: str, folder: Path) -> str: def _drive_folder(mount: Path, below: str) -> str: """A folder on a mounted drive as a row names it: D:\\bios where the drive is a letter (Windows, and WSL's /mnt/d), USBSTICK: bios where it - is a label. "D:: bios" and "D:\\: bios" doubled the colon - (code_audit_20 P3-3).""" + is a label. "D:: bios" and "D:\\: bios" doubled the colon.""" name = _mount_name(mount) if name.endswith((":", ":\\")): return shown_path(mount / below) if below else shown_path(mount) @@ -7823,7 +7817,7 @@ def other_side(os_type: str, plat: str) -> list[tuple[str, Path]]: """(label, folder) of the Windows side's usual folder under WSL, where the one offered first is this Linux's: a Windows RetroArch outside the folders detection knows never reads ~/.config/retroarch/system, and no - row reached C:\\ (tui_audit_12 P3-11).""" + row reached C:\\.""" if os_type != "wsl": return [] windows = _os_default_dests("windows").get(plat) @@ -7835,7 +7829,7 @@ def other_side(os_type: str, plat: str) -> list[tuple[str, Path]]: def side_name(os_type: str, plat: str) -> str: """The setup named by its side where the folder question offers both (other_side): Linux RetroArch beside Windows RetroArch under WSL. The - Windows one alone was named so (code_audit_20 P3-3).""" + Windows one alone was named so.""" name = display_name(plat) return f"Linux {name}" if other_side(os_type, plat) else name @@ -7904,7 +7898,7 @@ def _prompt_platform_choice( if other is not None: print(" o) another setup or folder") print(" q) quit") - # "a number from 1 to 1" for a single row (code_audit_18 P3-5). + # "a number from 1 to 1" for a single row. usage = (" Type 1" if len(platforms) == 1 else f" Type a number from 1 to {len(platforms)}") + ( ", o for another setup or folder" if other is not None else "") + ", or q to quit." @@ -7929,7 +7923,7 @@ def fold_line(text: str, hang: str = " ") -> str: the first indented by hang under its own lead, a word wider than a line cut after a slash: left to the terminal, below 40 columns "Found Onion at /media/moi/ONION/BIOS" broke inside "(RetroArch files)" and a folder - inside its name (tui_audit_17 P3-8).""" + inside its name.""" width = terminal_size()[0] cols = max(width - 1, 8) if cell_width(text) <= cols or width >= TUI_MIN_COLS or not _is_terminal(sys.stdout): @@ -8019,8 +8013,7 @@ def _size_lines(size: str, room: int, words: int = 0) -> list[str]: its shared part apart. words shortens the shared part: 0 says "and 1689 files, 334.2 MB shared with other systems", 1 "... shared", 2 "+1689 files, 334.2 MB shared". 26 of 66 sizes were folded by an - 80-column terminal, and a row that fitted on one line took two - (code_audit_22 P3-6).""" + 80-column terminal, and a row that fitted on one line took two.""" if words: size = size.replace(_SHARED_LONG, _SHARED_SHORT) if words > 1: @@ -8037,7 +8030,7 @@ def _size_lines(size: str, room: int, words: int = 0) -> list[str]: def _no_widow(lines: list[str], room: int) -> list[str]: """Wrapped lines whose last one is not a word alone: "shared" stood on a - line of its own under its size at 40 columns (tui_audit_16 P3-5). The + line of its own under its size at 40 columns. The word before it goes down with it where both fit.""" if len(lines) < 2 or len(_glued_words(lines[-1])) > 1: return lines @@ -8067,8 +8060,7 @@ def _pick( shown = {name: screen_text((labels or {}).get(name, name)) for name, _files in rows} sizes = {name: sizer(files) for name, files in rows} # One cell short of the terminal: a line as wide as it was folded by - # some terminals, the next row then starting on its last cell - # (tui_audit_16 P3-5). + # some terminals, the next row then starting on its last cell. cols = terminal_size()[0] - 1 # The fewest lines, the whole words where they cost no line: one # wording for the whole list, the id dropped where it takes a tenth @@ -8109,8 +8101,8 @@ def _pick_lines(rows: list[tuple[str, list[dict]]], shown: dict, sizes: dict, """The numbered rows of a line question, cols wide at most. The sizes stand in one column placed for the labels, where every size of one part fits beside the longest label that leaves it room: the column was - placed for the longest size, and every row but five took two lines - (code_audit_22 P3-6, tui_audit_15 P3-14). A row keeps one line where + placed for the longest size, and every row but five took two lines. + A row keeps one line where its label and its size fit, a longer size goes on under its column, and a label too long for the column takes its own line.""" width = len(str(len(rows))) @@ -8132,7 +8124,7 @@ def _pick_lines(rows: list[tuple[str, list[dict]]], shown: dict, sizes: dict, continue # The size beside the label only where all of it fits there: its # first part alone left "21 files, 1.4 MB," with its shared files - # unsaid (tui_audit_16 P3-5). + # unsaid. fitted = _size_lines(size, cols, words) whole = fitted[0] if len(fitted) == 1 else size if cell_width(f"{number}{label} {whole}") <= cols: @@ -8189,7 +8181,7 @@ def game_data_only(named: list[str], files: list[dict]) -> list[str]: def game_data_only_words(titles: list[str]) -> str: """Said on the plan and in line mode's head of those systems, before the question: "For 1 of 8 systems (--system)" stood for two systems named - and said nothing of the other (tui_audit_16 P3-7). "" for none.""" + and said nothing of the other. "" for none.""" if not titles: return "" verb = "holds" if len(titles) == 1 else "hold" @@ -8270,7 +8262,7 @@ def cannot_write_words(bios_path: Path, plat: str, hint: Invocation, commands: b """What the plan says of a folder this user cannot write, one remedy for a card: unlock it, never another folder its system does not read. Line mode has no folder row: "choose another one" there offered no way - to (code_audit_18 P3-3), so it names --dest, the screen its row.""" + to, so it names --dest, the screen its row.""" said = write_remedy(bios_path, plat, hint, commands) if remedy else [] if card and _on_read_only_mount(bios_path): return said @@ -8395,7 +8387,7 @@ def _prompt_custom_selection( if kept and all_in_place(kept, kept_trees, bios_path): # Read before the menu, as the screen reads before it asks: a # rerun was offered an install that installs nothing, then told - # so twice (tui_audit_16 P3-4). The check after it reads none + # so twice. The check after it reads none # of it again (_HEAD_READS). print(f"\n{name or display_name(plat)}: " f"{_plural(len(kept) + sum(len(t.get('files') or {}) for t in kept_trees), 'file')}" @@ -8414,8 +8406,7 @@ def _prompt_custom_selection( if cut is not None else []) kept = menu_choice(files, omitted, installed, current, cutting)[0] # A choice that keeps no file says so in the headline, as the screen - # does, and offers no Enter and no command: both installed nothing - # (code_audit_21 P3-6). + # does, and offers no Enter and no command: both installed nothing. emptied = (emptied_words([system_title(name_, manifest) for name_ in current[0]], cutting) if isinstance(current, tuple) and not kept else "") @@ -8462,7 +8453,7 @@ def _prompt_custom_selection( if installed is not None and current != INSTALLED_ONLY: print(f" i) only what the installed cores read: {_sized(installed[0])}") # What c asks, named: "systems, cores and regions" was offered with - # a pack that records systems only (tui_audit_11 P3-10). + # a pack that records systems only. axes = narrowing_words(files, omitted) if choosable else "" choosable = bool(axes) if choosable: @@ -8537,7 +8528,7 @@ def _print_menu_head( total = len(listed) # The systems chosen that still hold a file: Sega Dreamcast holding # only game data, g left the line at "2 of 8" where the screen, - # which drops it, said "1 of 8" (tui_audit_13 P3-11). + # which drops it, said "1 of 8". held = len(set(systems) & set(listed)) named = ", " + ", ".join(filter(None, [ f"for {held} of {total} systems" + (" (--system)" if flag else "") @@ -8545,7 +8536,7 @@ def _print_menu_head( # Out of the cores the systems chosen offered, as Cores counts # them: "1 core chosen" read as one of one. A flag typed is # named after the words, never alone: "--region." stood as a - # sentence of its own (tui_audit_17 P3-4). + # sentence of its own. core_count_words(cores, choosable_cores(files, omitted, systems)) + (" (--core)" if flag else "") if cores else "", "regions ranked" + (" (--region)" if flag else "") if regions else ""])) @@ -8560,9 +8551,9 @@ def _print_menu_head( print(f" BIOS folder: {shown_path(shown_bios_folder(bios_path, files))}") return # One total, data files in it, the kinds on the line under it adding up - # to it, as the screen's headline (code_audit_21 P3-8). With --from, + # to it, as the screen's headline. With --from, # what the folders hold first, as the screen's plan says it: nothing - # said how many were found before Enter (tui_audit_15 P3-8). + # said how many were found before Enter. found = (found_head(shown, kept_trees, bios_path) if LOCAL.folders and bios_path is not None else "") print(f"\n{name or display_name(plat)}: " + (found or ( @@ -8591,7 +8582,7 @@ def _print_menu_head( for line in save_lines(shown, kept_omitted, bios_path, display_name(plat, manifest)): print(f" {line}") # The required files the collection cannot supply, named as the screen's - # plan names them (tui_audit_16 P3-6). + # plan names them. for line in unavailable_lines([entry for entry in kept_omitted if entry.get("required")], manifest, bios_path, (manifest or {}).get("files") or shown): print(f" {line}") @@ -8603,9 +8594,9 @@ def found_head(files: list[dict], trees: list[dict], bios_path: Path) -> str: internet". "" when they hold none of them. A file of the wrong size is not in place. One of the right size is read, as check_local reads it: judged by its size, a wrong copy of the right size was in place, and - "nothing to download" stood over a run that left it (code_audit_23 - P3-2). What is read here is kept for the check after Enter - (_HEAD_READS): a card read twice is read at the speed of its reader.""" + "nothing to download" stood over a run that left it. What is read here is + kept for the check after Enter (_HEAD_READS): a card read twice is read at + the speed of its reader.""" def held(path: Path, size: object) -> bool: try: @@ -8625,7 +8616,7 @@ def found_head(files: list[dict], trees: list[dict], bios_path: Path) -> str: needed.append(entry) # Only a copy of the right size is read, on the check's workers and # with its count: one at a time and silent, 400 files of a card read - # as a hung run before the menu (code_audit_24 P3-4). + # as a hung run before the menu. needed += [entry for (entry, _path), verdict in zip(sized, read_in_place(sized)) if verdict != "up_to_date"] copies = plan_local_copies(needed, bios_path, None, LOCAL.folders) @@ -8726,7 +8717,7 @@ def menu_choice( def narrowing_words(files: list[dict], omitted: list[dict]) -> str: """What c chooses among for these files, in words, "" for nothing: a - question with one answer is not asked (tui_audit_11 P3-10).""" + question with one answer is not asked.""" axes = recorded_axes(files, omitted) choices = available_choices(files, omitted) named = [word for word, axis, enough in ( @@ -8746,9 +8737,9 @@ def _choose_narrowing(files: list[dict], omitted: list[dict], manifest: dict | N systems_listed = (systems_in_order(listed, files, manifest, bios_path) if len(listed) > 1 else []) # Said under the list it explains, before the question: above - # "Systems:" it read as a heading (tui_audit_13 P3-13). + # "Systems:" it read as a heading. # One sentence wrapped at the width: its line break, placed for a - # shorter title, left "platform" alone on a line (tui_audit_16 P3-5). + # shorter title, left "platform" alone on a line. note = (f"'{OTHER_TITLE}' holds what cores load for systems this platform " "does not list, such as game engines and extra computers." if OTHER_SYSTEMS in systems_listed else "") @@ -10998,8 +10989,7 @@ def pack_holds_trees(data_dirs: list[dict]) -> bool: a member below the tree's folder was the test, and blueMSX's tree, whose folder is the BIOS folder itself, held every BIOS file of any pack. One holding none of the files offered and focused Install, and - its result counted 8252 failed beside 10888 missing (tui_audit_15 - P3-7).""" + its result counted 8252 failed beside 10888 missing.""" if LOCAL.pack is None: return False names = LOCAL.pack.members @@ -11030,7 +11020,7 @@ class _Offline(OSError): OFFLINE_VARIABLE = "RETROBIOS_INSTALL_OFFLINE" OFFLINE_WORDS = "this run makes no network request" # The value --offline gives the variable: the words then name the option, -# and the variable itself where it was set (tui_audit_11 P3-12). +# and the variable itself where it was set. OFFLINE_FLAG_VALUE = "--offline" @@ -11763,7 +11753,7 @@ def readers(entry: dict, manifest: dict) -> list[str]: def opened_line(entry: dict, manifest: dict, bios_path: Path) -> str: """Where the emulators read an entry, and which ones: "read by mgba at ...", "expected at ..." where the list names none. "opened at" under - "missing:" read as a file that was opened (tui_audit_16 P3-12).""" + "missing:" read as a file that was opened.""" try: where = _entry_path(bios_path, entry) except ValueError: @@ -12261,7 +12251,7 @@ def sources_line( in the wrong place of the BIOS folder is "copied", as the plan says: "fixed" read as a wrong copy, of files that were missing. wrong counts the wrong copies left in place, apart from missing: "1 still missing" - was said of a file --check counts as a wrong copy (code_audit_23 P3-3). + was said of a file --check counts as a wrong copy. failed counts the files a run tried and could not write or fetch.""" parts = [(count, f"copied from {screen_text(shown_path(label))}") for label, count in folders] parts.append((fixed, "copied from the wrong place in the BIOS folder")) @@ -13138,8 +13128,8 @@ def main() -> None: sys.exit(run_tui(args)) if not (plain_requested(args) or args.declared_only): # The questions came line by line with no word of why: the page - # says a smaller window says so (tui_audit_11 P3-4), and a TERM - # unset or dumb said nothing (tui_audit_12 P3-14). + # says a smaller window says so, and a TERM + # unset or dumb said nothing. said = line_mode_reason(blocker) if said: print(fold_line(said)) @@ -13328,7 +13318,7 @@ def _ask_from_folder(files: list[dict] | None = None, bios_path: Path | None = N label = str(drives[int(raw) - 1]) elif raw.isdigit() and drives and not _is_dir(_typed_folder(raw)): # A number out of range, said as one: "2" was read as the folder - # ./2 (tui_audit_11 P3-10). + # ./2. count = "1" if len(drives) == 1 else f"a number from 1 to {len(drives)}" print(f" Type {count}, a folder, or Enter.") continue @@ -13515,7 +13505,7 @@ def _card_rules() -> list[_OsRule]: bios=rule.bios[len(mount):], configs=())) # The games part of a handheld system: the files it writes there name # the card as surely as Onion's .tmp_update (games_part), ArkOS's as - # AmberELEC's (tui_audit_17 P2-3). + # AmberELEC's. rules += list(_GAMES_PART_RULES) return rules @@ -13772,7 +13762,7 @@ def card_setups() -> list[CardSetup]: if below: own = tuple(rule for rule in rules if rule.name in (name, _built_on(name))) # Told by the games part alone, as AmberELEC's: a card that holds - # none of it yet is taken as named, said so (tui_audit_17 P2-3). + # none of it yet is taken as named, said so. setups.append(CardSetup(name, "retroarch", below, own, bool(own) and all(rule.method == "games_part" for rule in own))) @@ -13790,7 +13780,7 @@ def card_where(name: str, below: str) -> str: return f"on its SD card, in its {below} folder" if name in _GAMES_PART_CARDS: # Its card shows two drives on a computer: "the root of its SD - # card" named neither (tui_audit_8 P3-13). + # card" named neither. return "on the games part of its SD card" return "at the root of its SD card" @@ -13873,7 +13863,7 @@ def _not_the_card(setup: CardSetup, folder: Path, card: Path, other: str) -> Car if games: # The file the rule reads, never its first folder: AmberELEC's card # holds a bezels folder too, and EmuELEC's refusal named it as the - # mark of an EmuELEC card (code_audit_24 P3-7). + # mark of an EmuELEC card. held = " or ".join(dict.fromkeys(_names_and(list(rule.values)) for rule in games)) where = ("on the games part of its card" if setup.name in _GAMES_PART_CARDS else "on its card") @@ -14497,7 +14487,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: _line_setups(setups, mounted, os_type)) > 1: # A list or a pack that card setups read too: they are offered, # RetroArch first, as the screen offers them. Its folder question - # alone left ArkOS, muOS and JELOS out of reach (tui_audit_11 P1-2). + # alone left ArkOS, muOS and JELOS out of reach. print(f" {display_name(args.platform)} was not found here.") platforms = _prompt_manual_platform( os_type, not (args.check or args.dry_run or args.yes), True, @@ -14515,8 +14505,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # Without questions nothing found here stops, as without a list, # where --yes filled this computer's default folder. # Said as the stop without a list is said, and of the pack where - # a pack was named: "the file list" was one the user never gave - # (code_audit_20 P3-6, tui_audit_13 P3-13). + # a pack was named: "the file list" was one the user never gave. source = ("the pack" if LOCAL.pack is not None and LOCAL.manifest is None else "the file list") message = (f"No supported platform detected: {display_name(args.platform)} was " @@ -14528,7 +14517,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: hint.os_type, hint.options = os_type, _INVOCATION.options example = _default_dest(os_type, args.platform) # The run's own way of answering, kept: a script copying the - # example stopped at a question (tui_audit_14 P3-12). + # example stopped at a question. answered = "".join(f" {flag}" for flag, on in ( ("--yes", args.yes), ("--no-input", args.no_input)) if on) print(" Name its folder with --dest, for example:\n " @@ -14628,7 +14617,6 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # A folder typed, or a card's root, is checked there. # Said once, by the detection line above: "Nothing was found # here." came twice, and after "A card is in the reader" - # (tui_audit_16 P3-2). platforms = _prompt_manual_platform( os_type, not (args.check or args.dry_run or args.yes), check_typed=True, title="Which setup?") @@ -14686,7 +14674,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # Files --offline left out at a terminal: missing, never "as answered". total_offline = 0 # Of those, the wrong copies left in place: the result names them apart - # from the files still missing, as --check does (code_audit_23 P3-3). + # from the files still missing, as --check does. total_wrong_left = 0 # The BIOS list's files it left out, wrong copies aside: the result # counts them by kind. @@ -14922,7 +14910,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # --no-game-data leaves the game data out once the list is narrowed # to the choice: taken out first, its line named the 5099 game data # files of every system under a run for the PlayStation alone - # (tui_audit_13 P2-3). What is chosen among is the list without it. + # What is chosen among is the list without it. bare, bare_omitted = (leave_out_game_data(files, omitted_files)[:2] if args.no_game_data else (files, omitted_files)) @@ -15050,7 +15038,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: run_counts = tally(files) # Whether the list was narrowed: the data trees kept are then those # of the files kept. Computed once, for the head and the run, which - # must count the same trees (code_audit_21 P3-10). + # must count the same trees. narrowed = bool( target or args.system or args.core or args.region or args.installed_cores or args.declared_only or len(files) + game_data_cut + len(unplaced) @@ -15061,14 +15049,14 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # The kinds as the plan and the menu head say them (parts_words), # the data files of the folders kept among them: this head said # BIOS files and game data beside a plan of three kinds, neither - # defined (code_audit_20 P3-5). One total above them, the data files - # in it (code_audit_21 P3-8). + # defined. One total above them, the data files + # in it. head_data = sum(len(entry.get("files") or {}) for entry in data_dirs) head_bytes = sum(meta.get("size", 0) for entry in data_dirs for meta in (entry.get("files") or {}).values()) if not menu: # An answered menu said these lines right above: the run head - # repeated them under it (tui_audit_15 P3-9). + # repeated them under it. print(f" {_plural(run_counts.files + head_data, 'file')} " f"({format_size(run_counts.size + head_bytes)})") categorized_list = bool(manifest.get("categorized")) @@ -15082,7 +15070,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: if defined: print(f" {defined}") # A choice that keeps no file says so where "All files up to date" - # was said of it (tui_audit_13 P3-11). + # was said of it. empty_choice = "" if run_counts.files or not (selection or game_data_cut) else ( emptied_words([system_title(name, manifest) for name in (selection[0] if selection else [])], bool(game_data_cut))) @@ -15127,13 +15115,11 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: ) present = len(up_to_date) + len(mismatched) # The screen's words: "0/22 present (0 verified, 0 wrong hash)" - # beside its "0 in place, 22 missing, 0 wrong copies" (tui_audit_14 - # P3-10). The data files the head counts are among them, as the - # screen counts them (tui_audit_14 P3-7). + # beside its "0 in place, 22 missing, 0 wrong copies". The data files + # the head counts are among them, as the screen counts them. wrong = len(mismatched) # Each data tree read and hashed once in the run: the count here, - # the check, the events, the plan and the install read this - # (code_audit_22 P3-3). + # the check, the events, the plan and the install read this. data_states = [(entry, data_directory_state(entry, bios_path)) for entry in data_dirs] head_reads_done() trees_missing = sum(len(state[1]) for _entry, state in data_states) @@ -15198,7 +15184,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: print(line) offline = _offline_only() # What the pack lacks is said before the count, as the - # screen says it (code_audit_21 P3-3). + # screen says it. lacking = pack_lacks([f for f in to_download if id(f) not in copies]) if lacking: print(f"\n {pack_lacks_words(len(lacking), len(to_download) - len(copies))}") @@ -15242,7 +15228,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: planned = [f for f in to_download if id(f) not in copies] # Said before the plan promises a count and a size, as an # install says it: the dry run promised 23 files where the pack - # held 20 (code_audit_21 P3-3). + # held 20. lacking = {id(f) for f in pack_lacks(planned)} if lacking: print(f"\n {pack_lacks_words(len(lacking), len(planned))}") @@ -15274,7 +15260,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: fetched = [] # What the pack does not hold is said before a size is promised: # a pack older than the list gave "Copy 6.6 GB" and 8358 files - # failed (tui_audit_13 P3-8). They are still tried, and fail as + # failed. They are still tried, and fail as # not in the pack, the size and the question leaving them out. lacking = {id(f) for f in pack_lacks(fetched)} if lacking: @@ -15344,7 +15330,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: f"{origin}{rest}{where}{sized if rest else ''}...") elif LOCAL.pack is not None: # The files the pack holds: "Copying 23 files (85.0 KB)" sat - # beside the size of 20 (code_audit_21 P3-3). + # beside the size of 20. print(f"\nCopying {_plural(len(to_download) - len(lacking), 'file')} " f"({format_size(dl_size)}) from {LOCAL.pack.name}...") else: @@ -15411,7 +15397,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: break elif len(platforms) > 1: # One setup's run ends on "Done. Everything is in place.": said - # here too, it came twice (tui_audit_16 P3-4). + # here too, it came twice. print(f"\n {EVERYTHING_IN_PLACE}") total_up_to_date += len(up_to_date) @@ -15899,7 +15885,7 @@ def _split_word(word: str, room: int) -> list[str]: head = fit(word, max(room, 1)) # After the last separator that fits, a Windows one too: cut where # a third of the room was left, a folder broke inside its name - # ("tui_au" / "dit13", tui_audit_13 P3-3). + # ("Game Bo" / "y Advance"). cut = max(head.rfind("/"), head.rfind("\\")) + 1 if cut <= 1: cut = len(head) @@ -15936,7 +15922,7 @@ def _path_tail(text: str, width: int) -> str: """A path cut to its last folders that fit after ".../", as a person reads it on a narrow screen (".../retroarch/system"). Its last name is kept whole however long: cut in its middle, RetroArch_BIOS_Pack.zip - read "Pack.zip" (tui_audit_15 P3-2).""" + read "Pack.zip".""" if cell_width(text) <= width: return text separator = "\\" if "\\" in text and "/" not in text else "/" @@ -15952,8 +15938,7 @@ def _path_tail(text: str, width: int) -> str: def _command_groups(text: str) -> list[str]: """A command's shell words as they stay together on a line: a long - option with its value. "--platform" ended a line, its value on the next - (tui_audit_14 P3-8).""" + option with its value. "--platform" ended a line, its value on the next.""" groups: list[str] = [] for word in _SHELL_WORD.findall(text): last = groups[-1] if groups else "" @@ -15969,7 +15954,7 @@ def _continuation(powershell: bool | None = None) -> str: """The character that ends a line of a command the shell reads on: a backtick in PowerShell, a backslash in sh. Asked as the command's words ask it: with RETROBIOS_OS=windows elsewhere one command had - PowerShell's quotes and sh's line ends (code_audit_22 P3-5).""" + PowerShell's quotes and sh's line ends.""" return "`" if (_INVOCATION.powershell() if powershell is None else powershell) else "\\" @@ -15980,7 +15965,7 @@ def _command_wrap(text: str, width: int, indent: str = " ", copy of the lines runs as the command does. A line one group wide that fits only without the indent loses it. A path still wider keeps its last folders (_path_tail), said by TUI_SHORTENED: folded by the - terminal, it read as broken inside a word (tui_audit_14 P3-8). A web + terminal, it read as broken inside a word. A web address is never cut.""" lead = text[:len(text) - len(text.lstrip(" "))] tail = " " + _continuation(powershell) @@ -16054,15 +16039,15 @@ def _wrap(text: str, width: int, indent: str = " ", whole: str = "", if len(words) == 1 and _is_path_word(text.strip()): # A folder on a line of its own goes on at its own indent: the # rest of a save folder sat two cells under its start, the BIOS - # folder's at its label's (tui_audit_15 P3-12). + # folder's at its label's. indent = "" def close(done: str) -> str: # A line one word wide that fits without the indent loses it: one # cell too wide, a folder was folded by the terminal inside a word - # ("syste" / "m", tui_audit_12 P3-7). The line's own lead too: a + # ("syste" / "m"). The line's own lead too: a # pack path of 75 cells was folded at 80 columns under an indent - # of 6 (tui_audit_13 P3-3). + # of 6. prefix = lead + indent if lines else lead if cell_width(prefix + done) > width >= cell_width(lead + done): prefix = lead @@ -16077,8 +16062,7 @@ def _wrap(text: str, width: int, indent: str = " ", whole: str = "", room = width - len(lead + indent) # A word that fits on a line of its own stays whole there (close). # A path only where it fits at the indent its line has: dropped to - # fit, a folder stood at one indent and its neighbour at another - # (tui_audit_15 P3-12). + # fit, a folder stood at one indent and its neighbour at another. alone = lead + indent if (lines or line) and _is_path_word(word) else lead pieces = ([word] if whole == "command" or (whole and not _is_path_word(word)) or cell_width(alone + word) <= width else _split_word(word, room)) @@ -16096,8 +16080,7 @@ def _wrap(text: str, width: int, indent: str = " ", whole: str = "", # a path was drawn "retroarch/ system", and copied wrong. longer = f"{line}{'' if index else ' '}{piece}" if line else piece # A path's pieces keep the indent, which they are cut to fit: - # joined past it, the last piece of a folder lost its indent - # (tui_audit_14 P3-9). + # joined past it, the last piece of a folder lost its indent. if not line or cell_width(prefix + longer) <= width or ( lines and " " not in longer and cell_width(lead + longer) <= width and not _is_path_word(word)): @@ -16156,13 +16139,13 @@ def _bar_keys() -> set[str]: def _bar_spans(text: str, first: str) -> list[tuple[int, int, str]]: """The bar's key names faint, the first in first, its actions plain: drawn faint, Back and Quit were the hardest words to find on a - handheld, B being its way back (tui_audit_12 P3-3).""" + handheld, B being its way back.""" spans = [] for number, entry in enumerate(re.finditer(r"\S+(?: \S+)*", text)): key = entry.group().split(" ", 1)[0] if entry.group().endswith(TUI_ARMED_SHORT): # Armed by a first tap: the whole entry stands out, a plain - # ": tap again" looked like no change at all (tui_audit_14 P3-2). + # ": tap again" looked like no change at all. spans.append((entry.start(), entry.end(), first)) elif key in _bar_keys() and " " in entry.group(): spans.append((entry.start(), entry.start() + len(key), @@ -16185,7 +16168,7 @@ def tui_paint(text: str, style: str, colour: bool) -> str: base = _COLOUR_BASES.get(style, "") if style == "folder": # The rest of a BIOS folder wrapped onto its own line, as bold as - # its start (tui_audit_12 P3-7). + # its start. start = len(text) - len(text.lstrip(" ")) return painted(text, [(start, len(text.rstrip(" ")), "strong")], base) if style not in ("", "head", "title", "hint", "refusal"): @@ -16299,7 +16282,7 @@ class TuiState: self.pressed: tuple | None = None # The row a tap last focused, with its screen and depth: a second # tap on it opens it. A screen just opened has none, so the row it - # opens on is never chosen by one tap (tui_audit_12 P1-1). + # opens on is never chosen by one tap. self.tapped: tuple | None = None # Whether the terminal reports clicks here (tui_mouse_blocker): the # help and the bar say how to tap only then. @@ -16340,14 +16323,14 @@ class TuiState: self.emptied: list[str] = [] # Systems ticked that the last check did not list, game data left # out: still the choice, ticked again by the check that lists them - # (tui_audit_14 P2-2), as line mode's g keeps its choice. + #, as line mode's g keeps its choice. self.hidden_ticks: set[str] = set() # Choose systems asked on a plan --system narrowed: the systems are # opened once the check of every system is in. self.widen: bool = False # The plan row a recount started from, focused again once it is in: # the plan came back on Install, and a second Enter to undo the - # Game data change opened Confirm (tui_audit_15 P3-4). + # Game data change opened Confirm. self.refocus: str = "" # The --system plan Choose systems widened, by _CHECK_FIELDS. self.widened_from: dict | None = None @@ -16895,7 +16878,7 @@ def tui_wants_mouse(state: TuiState, lines: list[str]) -> bool: if state.screen in ("command", "path"): return False # Read from the frame's model: a command wrapped over lines was missed - # by a match on the drawn text, its URL cut in two (code_audit_19 P3-5). + # by a match on the drawn text, its URL cut in two. return not any(getattr(line, "command", False) for line in lines) @@ -17076,7 +17059,7 @@ def _filter_row(state: TuiState) -> TuiRow: "evmapy": "with a keyboard", "miyoo": "with a keyboard"}.get(state.pad, "/ to type") if state.screen == "platforms": # A device name finds its setups: said where it is typed. Plain, as - # the first screen sends a beginner there (tui_audit_12 P3-3). + # the first screen sends a beginner there. return TuiRow("filter", "Filter: setup or device (/)" if how == "/ to type" else f"Filter ({how})") return TuiRow("filter", f"Filter ({how})") @@ -17144,7 +17127,7 @@ def _core_base(state: TuiState) -> list[str]: def tui_cores_ticked(state: TuiState) -> int: """The cores of the systems chosen that are ticked: a core of another - system ticked counted toward "all cores" (code_audit_24 P3-2).""" + system ticked counted toward "all cores".""" base = _core_base(state) if not state.cores: return 0 if state.no_cores else len(base) @@ -17202,7 +17185,7 @@ def cores_words(chosen: int, total: int) -> str: def core_count_words(cores: list[str], base: list[str]) -> str: """cores_words for the cores named out of those the systems chosen offer: a core of another system counted toward "all cores", the run - keeping none of the system's own (code_audit_24 P3-2).""" + keeping none of the system's own.""" return cores_words(len(set(cores) & set(base)), len(base)) @@ -17235,7 +17218,7 @@ def tui_rows(state: TuiState) -> list[TuiRow]: rows = [TuiRow("setup", label, value=index) for index, (_plat, _path, label) in enumerate(state.setups)] # A drive two systems fit, under each: "Nothing was found here" - # beside a KNULLI card in the reader (tui_audit_12 P2-5). + # beside a KNULLI card in the reader. rows += [TuiRow("doubt", f"{_mount_name(mount)}: if it is {_doubt_kinds((plat,))}", value=(plat, mount)) for plat, mount in state.doubts] return rows + [TuiRow("another", "Another setup or folder")] @@ -17254,10 +17237,9 @@ def tui_rows(state: TuiState) -> list[TuiRow]: # question, each by the BIOS folder its system reads, after the # Windows side's usual folder under WSL. # The Windows side's folder said missing where it is: taken, the - # plan said RetroArch reads a folder no RetroArch had (tui_audit_13 - # P3-9). + # plan said RetroArch reads a folder no RetroArch had. # Every row whose folder is missing says so, in both modes: the - # Windows row alone did (code_audit_21 P3-7). + # Windows row alone did. drives = [] if state.folder_kind == "share" else [ TuiRow("drive", label if _is_dir(folder) else _said_with(label, "does not exist yet"), @@ -17310,7 +17292,7 @@ def tui_rows(state: TuiState) -> list[TuiRow]: key=region_title) # The order drawn when the screen opened, ranked regions first: a # tick moved its row to the top, and the next tap on the same spot - # ticked the region that slid under the finger (tui_audit_13 P2-2). + # ticked the region that slid under the finger. # The rank says the order, and the screen opens on it next time. order = list(state.region_order or [*state.regions, *( name for name in known if name not in state.regions)]) @@ -17322,13 +17304,12 @@ def tui_rows(state: TuiState) -> list[TuiRow]: needle = state.filters.get(screen, "") # The cores the run accepts (choosable_cores): the whole list's # 189 held 8 that read only the save directory the run set aside, - # and an untick sent them to a run that refused them (tui_audit_17 - # P1-1). + # and an untick sent them to a run that refused them. every = tui_choices(state)["cores"] theirs = _chosen_cores(state) # The cores of the systems chosen first, the others behind a row: # with --system sony-playstation the list opened on a5200 and - # amiberry, 189 cores long (tui_audit_13 P3-12). A core the command + # amiberry, 189 cores long. A core the command # line named stays in view. shown = every if theirs is None or state.cores_all else [ name for name in every if name in theirs or name in state.cli_cores] @@ -17336,7 +17317,7 @@ def tui_rows(state: TuiState) -> list[TuiRow]: # Every core ticked when no core narrows the run, as Choose systems # ticks every system: all boxes empty read as nothing chosen, and # the owner ticked each one by hand. Each with what it adds, as - # line mode sizes it (tui_audit_17 P3-2). + # line mode sizes it. rows = [_filter_row(state)] + [ TuiRow("core", f"[{'x' if core_ticked(state, name) else ' '}] {name}", _core_right(sizes.get(name)), name, "" if sizes.get(name) else "dim", @@ -17351,7 +17332,7 @@ def tui_rows(state: TuiState) -> list[TuiRow]: return [] if not _needed(state.dry) and not state.dry.get("data_missing"): # Counted again, every file is in place: Install wrote nothing - # and said Done (code_audit_21 P3-4). + # and said Done. return [TuiRow("close", "Close"), TuiRow("back", "Back")] if _offline_only() and not _dry_copies(state): # The plan's rule: Install would only fail every file. @@ -17371,7 +17352,7 @@ def tui_rows(state: TuiState) -> list[TuiRow]: if screen == "result" and _app_offer(state): # Exit first: the app is put only when it is chosen. Its short # form where the whole one does not fit: cut inside "from" at 40 - # columns (tui_audit_15 P3-3). + # columns. width = min(state.cols or TUI_MAX_WIDTH, TUI_MAX_WIDTH) - 2 offer = APP_OFFER if cell_width(f"> {APP_OFFER}") <= width else APP_OFFER_SHORT return [TuiRow("exit", "Exit"), TuiRow("addapp", offer)] @@ -17387,7 +17368,7 @@ def _emptied_words(state: TuiState) -> str: def _choice_in_place(state: TuiState) -> str: """The plan's headline when every file of the systems ticked is in place, while the check counted the whole list: "NEC PC Engine is in - place", Install offered nothing (code_audit_21 P3-4). "" otherwise.""" + place", Install offered nothing. "" otherwise.""" if not state.systems or not state.ticked or not _tui_estimating(state): return "" chosen = [row for row in state.systems if row["system"] in state.ticked] @@ -17414,7 +17395,7 @@ def _plan_rows(state: TuiState) -> list[TuiRow]: if not (_needed(check) if check else 0) and not check.get("data_missing"): return [TuiRow("close", "Close"), *_games_rows(state), TuiRow("options", "Options")] # The size the pack can give: "Install 6.6 GB" from a pack holding - # none of the files (tui_audit_13 P3-8). + # none of the files. lacking = set(_tui_pack_lacks(state, [event["dest"] for event in state.files])) size = check.get("bytes_needed", 0) - sum(event["size"] for event in state.files if event["dest"] in lacking) @@ -17430,13 +17411,13 @@ def _plan_rows(state: TuiState) -> list[TuiRow]: and len(_tui_pack_lacks(state, sorted(files))) == len(files) and not (check.get("data_missing") and _tui_pack_trees(state))): # The pack holds none of them, nor the data files: Install would - # fail every one (tui_audit_14 P3-1). + # fail every one. rows = [] if _on_its_card(state) and (state.facts.get("writable") is False or _short_of_space(state, check)): # Its system reads this card alone: room is made on it, or it is # unlocked, then counted again, first in focus. Install anyway on - # a mount nobody can write would only fail (tui_audit_11 P3-1). + # a mount nobody can write would only fail. locked = state.facts.get("writable") is False rows = [TuiRow("recheck", "Check again"), TuiRow("folder", "Choose another folder"), *([TuiRow("install", "Install anyway")] if rows and not locked else [])] @@ -17451,7 +17432,7 @@ def _plan_rows(state: TuiState) -> list[TuiRow]: if not rows: # Nothing can be installed: the remedy the plan names comes first, # in focus. Choose systems was, whose systems need the internet - # too (tui_audit_11 P3-8). + # too. rows.append(copy) # Right under Install: the choice the plan opened on, the whole list one # press away. @@ -17597,7 +17578,7 @@ def _choice_entries(state: TuiState, hidden: bool = False) -> list[dict]: # and the installed cores included, and only the systems ticked are # left to apply: its files and the game data it left out are that # list. Narrowed by the axes alone, the row offered the 8 game data - # files of every system under a plan for one (code_audit_20 P2-1). + # files of every system under a plan for one. reached = _checked_scope(state) return [entry for entry in kept if entry.get("dest") in reached] if reached else kept @@ -17624,7 +17605,7 @@ def _game_data_row(state: TuiState) -> TuiRow | None: if not games.games: return None # The state first, its count after and never cut inside a word: at 40 - # columns "kept, leave out" lost its state (tui_audit_12 P2-2). + # columns "kept, leave out" lost its state. sized = f"{_plural(games.games, 'file')}, {format_size(games.game_size)}" return TuiRow("gamedata", f"Game data: {'left out' if state.no_game_data else 'kept'}", sized, narrow=(f"{games.games}, {format_size(games.game_size)}",), @@ -17694,9 +17675,9 @@ def _system_rows(state: TuiState) -> list[TuiRow]: # The rows a list of ticks ends on, the same on Choose systems, Cores and # Preferred regions: below the items, so the focus a list opens on is its # first item and A there ticks it. All and None sat above the items, and A -# on the None the systems opened on unticked every system (tui_audit_17 -# P3-1). Preferred regions has no All: every region ranked in the order -# drawn is no choice anyone made, and none ticked keeps every region. +# on the None the systems opened on unticked every system. Preferred regions +# has no All: every region ranked in the order drawn is no choice anyone made, +# and none ticked keeps every region. _CHECKLIST_END = [TuiRow("all", "All"), TuiRow("none", "None"), TuiRow("done", "Done")] _REGIONS_END = [TuiRow("none", "None"), TuiRow("done", "Done")] @@ -17751,8 +17732,7 @@ def _option_rows(state: TuiState) -> list[TuiRow]: "--installed-cores")) if len(choices["cores"]) > 1: # The plan's words, the noun left to the row's own label. A list - # with one core asks nothing, as line mode does not (tui_audit_17 - # P3-3). + # with one core asks nothing, as line mode does not. rows.append(TuiRow("cores", "Cores: " + cores_words( tui_cores_ticked(state), len(_core_base(state))).replace(" cores", ""), "--core")) copied = ", ".join(str(folder) for folder in state.from_folders) or "none" @@ -17761,12 +17741,12 @@ def _option_rows(state: TuiState) -> list[TuiRow]: rows.append(TuiRow("savedir", f"Save folder: {_save_folder_words(state)}", "--save-dir", style="path")) if not LOCAL.offline: - # From a pack, or offline, nothing is downloaded (tui_audit_11 P3-16). + # From a pack, or offline, nothing is downloaded. rows.append(TuiRow("jobs", f"Parallel downloads: {state.jobs}", "--jobs")) rows += [ # The plan's folder: AmberELEC's read the games part here and its - # bios folder on the plan, two values under one name (tui_audit_17 - # P3-6). --dest stays the games part, as the command line takes it. + # bios folder on the plan, two values under one name. --dest stays the + # games part, as the command line takes it. TuiRow("folder", "BIOS folder: " + _short_path(_plan_folder(state, state.dest), state.home), "--dest", style="path"), @@ -17801,7 +17781,7 @@ def _save_folder_words(state: TuiState) -> str: def _focus_plan(state: TuiState, action: str) -> None: """The plan's focus on the row doing action. A plan that keeps no file, a choice emptied or already in place, opens on Choose systems: the - focus kept its index, and Enter opened Options (tui_audit_15 P3-5).""" + focus kept its index, and Enter opened Options.""" actions = [row.action for row in tui_rows(state)] keeps_none = _choice_in_place(state) or (state.emptied and state.systems and not state.ticked) @@ -17836,7 +17816,7 @@ def _back(state: TuiState) -> list[tuple]: if refused: # Done and B leave a list of ticks alike, never with nothing # ticked: said on every length of list, in the line the rows - # leave (tui_audit_17 P2-4). + # leave. state.status = refused return effects chose = state.screen == "systems" and state.ticked != (state.ticked_before or set()) @@ -17894,7 +17874,7 @@ def tui_quit(state: TuiState, code: int | None = None, asked: bool = True) -> li """Leave now: with the install's own code once it ran, else QUIT_CODE for a quit the user chose (q, Quit) and 130 for Ctrl-C. asked is a quit the user chose, said as one: it read "stopped", the word of an - interrupted run (tui_audit_11 P3-19).""" + interrupted run.""" state.quit_asked = asked if code is None: code = QUIT_CODE if asked else 130 @@ -18065,7 +18045,7 @@ def _card_status(state: TuiState, choice: CardChoice, given: bool = False) -> No if given: # --dest is fixed for this run: only another system's card gets # "choose another setup". A folder inside a card, or one that is no - # card, is named again in the command (code_audit_15 P3-3). + # card, is named again in the command. then = (f"Run it again with --dest {shown_path(choice.root)}." if choice.root else "--dest names it: choose another setup." if choice.other else "Run it again with the card's top folder.") @@ -18542,7 +18522,7 @@ def _activate(state: TuiState, row: TuiRow) -> list[tuple]: return _start_check(state) if len(state.stack) == 1: # The folder came from --dest: nothing is under this screen, and - # Back asked Quit? with Quit in focus (code_audit_20 P2-3). The + # Back asked Quit? with Quit in focus. The # folder screen takes its place, as the plan's row opens it. state.stack.pop() return _open_folder_screen(state, state.dest, "chosen", rebind=True) @@ -18585,7 +18565,7 @@ def _activate(state: TuiState, row: TuiRow) -> list[tuple]: if action == "gamedata": # One press, then counted again, as Back from Options counts, # the systems ticked kept: the check set them back to every - # system, and the install wrote all eight (tui_audit_13 P1-1). + # system, and the install wrote all eight. state.no_game_data = not state.no_game_data effects = _start_check(state) state.refocus = "gamedata" @@ -18601,7 +18581,7 @@ def _activate(state: TuiState, row: TuiRow) -> list[tuple]: if action == "systems": state.ticked_before = set(state.ticked) # On the first system, A ticking it: Choose systems opened on None, - # and A there unticked every system (tui_audit_17 P3-1). + # and A there unticked every system. _push(state, action) state.focus[action] = _first_item(state) return [] @@ -19067,7 +19047,7 @@ def _computer_named(plat: str, needle: str) -> list[str]: """The computer systems the filter names that run plat.""" key = _device_key(needle) # Two letters are a word on their way: "wi" said "No setup matches" - # between "w" and "win" (tui_audit_11 P3-17). "pc" is one of the words. + # between "w" and "win". "pc" is one of the words. if len(key) < 2: return [] return [name for name, (words, plats) in _COMPUTER_SYSTEMS.items() @@ -19089,7 +19069,7 @@ TUI_DEVICE_ROOM = 12 def _aligned_devices(rows: list[TuiRow], width: int) -> list[TuiRow]: """The setup list's devices starting at one column, two cells after the longest setup name, where that leaves them room: at 80 columns they - began anywhere from column 20 to 70 (tui_audit_12 P3-1).""" + began anywhere from column 20 to 70.""" named = [row for row in rows if row.action in ("platform", "cardsystem")] if not named: return rows @@ -19255,8 +19235,7 @@ def _tick(state: TuiState, row: TuiRow, on: bool | None) -> None: elif not state.cores and not state.no_cores: # Every core was ticked, those of the other systems too: one # untick keeps every other one ticked. Kept to the systems chosen, - # it cleared the other systems' cores drawn ticked (code_audit_24 - # P3-1). + # it cleared the other systems' cores drawn ticked. state.cores = [name for name in tui_choices(state)["cores"] if name != value] state.no_cores = not state.cores elif value in state.cores: @@ -19448,7 +19427,7 @@ def tui_update(state: TuiState, key: TuiKey) -> list[tuple]: last = len(rows) - 1 page = _page_step(state) if key.name in ("pgup", "pgdn") else 1 # A list of ticks wraps at any length: None and Done, at its end, are - # a few presses up from its first item on a pad (tui_audit_17 P3-1). + # a few presses up from its first item on a pad. wrap = len(rows) < 10 or screen in (*_CHECKLISTS, "regions") name = key.name if name == "up" or char == "k": @@ -19562,7 +19541,7 @@ def tui_mouse(state: TuiState, event: TuiMouse) -> list[tuple]: # A tap is a press and a release on one target of one frame: a release # on a frame drawn after its press is dropped, and so is a press within # TUI_TAP_SETTLE of a new screen, so the second tap of a double tap that - # changed the screen does nothing on the new one (tui_audit_14 P2-1). + # changed the screen does nothing on the new one. seen_on = (hits.frame, state.screen, len(state.stack), state.help, target) if not event.release: settled = state.now - hits.shown >= TUI_TAP_SETTLE @@ -19666,8 +19645,8 @@ def _armed(state: TuiState) -> TuiKey | None: """The key a first tap armed on this screen, a second tap pressing it: a bar entry that writes files, or the row in focus a tap chose. A tap on the focused Install row was counted and drawn nowhere - (tui_audit_15 P3-1), and one on any other focused row too: the row a - beginner taps first gave no sign the tap was seen (tui_audit_16 P3-8). +, and one on any other focused row too: the row a + beginner taps first gave no sign the tap was seen. A tick is no choice: a tap ticks it at once.""" tapped = state.tapped if state.help or not tapped: @@ -19685,7 +19664,7 @@ def _armed_hint(state: TuiState, parts: tuple, width: int) -> tuple: """The bar with the entry a first tap armed saying that a second one presses it, in the longest words the bar keeps whole: at 40 columns "click or tap again" was cut inside its last word, and the bar's B - went with it (tui_audit_15 P3-3).""" + went with it.""" key = _armed(state) if key is None: return parts @@ -19699,8 +19678,7 @@ def _armed_hint(state: TuiState, parts: tuple, width: int) -> tuple: forms = (f"{part}: {said}", f"{part.split(' ', 1)[0]} {' '.join(verb.split()[:3])}: {said}") # Every entry kept first, then every one but the help, then the armed - # one whole: on a phone at 40 columns Esc Quit went first - # (tui_audit_17 P3-11). + # one whole: on a phone at 40 columns Esc Quit went first. for keep in (len(parts), len([p for p in parts if not p.startswith("? ")]), 1): for form in forms: armed = (*parts[:at], form, *parts[at + 1:]) @@ -19830,7 +19808,7 @@ def _take_event(state: TuiState, event: dict) -> None: return if kind == "error" and state.run == "install" and event.get("stage") == "dest": # The BIOS folder could not be created: every file fails for that - # one reason, said as it happened (tui_audit_17 P2-1). + # one reason, said as it happened. state.dest_error = event return if kind == "checking" and state.run in ("check", "install"): @@ -19955,7 +19933,7 @@ def tui_receive(state: TuiState, message: tuple) -> list[tuple]: state.hidden_ticks = state.keep_ticked - listed if state.keep_ticked and not state.ticked: # Every system chosen holds nothing under these options: - # said, never taken as every system (tui_audit_13 P1-1). + # said, never taken as every system. state.emptied = sorted(state.ticked_names.get(name, name) for name in state.keep_ticked) state.keep_ticked = None @@ -20010,7 +19988,7 @@ def _route_hint(state: TuiState, parts: tuple, width: int | None = None) -> tupl """The bar's entries named as the run's input names them. On Android with no pad route named (Termux on a phone), a bar too narrow for both names keeps the key's: it said "A Continue" where a phone has an Enter - key and no A button, and the a key does nothing (tui_audit_16 P3-13). + key and no A button, and the a key does nothing. The help still names both.""" pad = ("keys" if state.pad == "both" and state.os_type == "android" and width is not None and width < TUI_LONG_BAR_WIDTH else state.pad) @@ -20057,7 +20035,7 @@ def _hint(width: int, *parts: str) -> str: entries from the right.""" full = " ".join(parts) # One rule for every screen of a width: at 40 columns the plan read - # "A Install" and the next screen "A/Enter Install" (tui_audit_11 P3-5). + # "A Install" and the next screen "A/Enter Install". if cell_width(full) <= width and width >= TUI_LONG_BAR_WIDTH: return full short = [] @@ -20099,7 +20077,7 @@ _ROW_VERBS = { # The widest a row's two columns spread: at 120 columns a system's size sat -# 85 columns from its name (tui_audit_11 P3-20). +# 85 columns from its name. TUI_ROW_SPREAD = 78 @@ -20167,7 +20145,7 @@ def _text_lines(items: list, width: int, whole: bool = False) -> list[TuiLine]: lines.append(_styled(middle(str(item), width))) continue # A command is wrapped between its shell words on every screen: the - # plan's root command was cut inside its URL (code_audit_19 P3-5). + # plan's root command was cut inside its URL. command = style == "command" or getattr(item, "command", False) kind = "command" if command else "text" if whole else "" folder = str(item).lstrip(" ").startswith(_FOLDER_LABEL) @@ -20273,7 +20251,7 @@ def _compose( if str(item).rstrip().endswith(":") and index + 1 < len(before): # A line that leads into the next one gives way with it, the # rest of a wrapped folder included: the save line ended on - # "under:" at 60x20, its folder cut (tui_audit_13 P3-7). + # "under:" at 60x20, its folder cut. led = [before[index + 1]] for more in before[index + 2:]: if not str(more).startswith(" "): @@ -20290,7 +20268,7 @@ def _compose( gap = [_styled("")] if top and row_lines and budget > 0 else [] budget -= len(gap) # Whole items only: cut to the room left, a note ended in the - # middle of its sentence at 40x12 (tui_audit_14 P3-5). + # middle of its sentence at 40x12. tail: list[TuiLine] = [] for item in after: lines = _text_lines([item], width) @@ -20402,14 +20380,14 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: # the size to download leave it out, from the check's own events. On # Confirm the dry run's files are matched the same way: it called the # files a --from folder holds downloads, and sent an offline user for - # a pack (code_audit_20 P2-2). + # a pack. dry = check is state.dry and check is not state.check sizes = {event["dest"]: event["size"] for event in (state.dry_files if dry else state.files)} copied = _plan_copies(state, check) if dry or check is state.check else [] # The files the pack does not hold are said before a size is promised, # and left out of it: the plan offered "Install 6.6 GB" from a pack that - # held none of them (tui_audit_13 P3-8). + # held none of them. lacking = _tui_pack_lacks(state, [dest_ for dest_ in sizes if dest_ not in copied]) fetch = max(0, need - len(copied) - len(lacking)) fetch_bytes = max(0, check["bytes_needed"] - sum(sizes[dest_] for dest_ in copied) @@ -20419,13 +20397,12 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: offline = _offline_only() # The data files are files to fetch like the others: one count and one # size, the kinds apart on the line under the folder. "8358 files and - # 2636 data files" read as two kinds of one thing (tui_audit_13 P3-6). + # 2636 data files" read as two kinds of one thing. data_bytes = check.get("data_bytes", 0) if data else 0 if elsewhere: # The folder by its last name: the whole path pushed the BIOS # folder off a 40x15 screen. The Options row spells it out. The - # data files are among those to fetch: one count (code_audit_21 - # P3-8). + # data files are among those to fetch: one count. where = ", ".join(f"{len(events)} found in {_last_name(folder)}" for folder, events in elsewhere.items()) rest = fetch + data @@ -20471,7 +20448,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: wrong = check["wrong_hash"] # Where some were found, the plan names the rest by kind ("Not in old: # 10 BIOS files and 6 game data files.", _view_plan), and the remedy - # follows it: "They" sat under a split of all 22 (tui_audit_14 P3-7). + # follows it: "They" sat under a split of all 22. offline_lines = ([_offline_remedy([_last_name(str(folder)) for folder in state.from_folders], named=bool(elsewhere) and not dry)] @@ -20485,7 +20462,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: found_in = _retroarch_config_at(dest) if dest is not None else None if found_in: # Right under the folder it names: after the save lines it read as - # naming them (tui_audit_11 P3-6). + # naming them. lines.append(_styled(f"Named by {_short_path(Path(found_in[0]), state.home)}", "path")) if state.facts.get("writable") is False: # The remedy itself comes below, after the counts. @@ -20496,8 +20473,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: # plan named ~ alone. lines += filter(None, [_no_setup_reads(state, dest)]) # The data files missing among the missing: the headline counts them, - # and "10888 need the internet" sat over "8252 missing" (tui_audit_14 - # P3-7). + # and "10888 need the internet" sat over "8252 missing". counts = (f"{check['present']} in place, {check['missing'] + data} missing, " f"{_plural(wrong, 'wrong copy')}") # A first install's missing files are its normal state, not a warning. @@ -20527,7 +20503,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: # The wrong copies something replaces: offline, those a folder copied # from holds, else those the network or the pack brings too. "The 1 # wrong copy is replaced" stood over a copy no folder held, which the - # result then said was left (code_audit_24 P3-5). + # result then said was left. wrong_dests = [event["dest"] for event in (state.dry_files if dry else state.files) if event.get("state") == "wrong_hash"] backup = (sum(1 for dest_ in wrong_dests if dest_ in copied) if offline @@ -20567,7 +20543,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: if Path(folder).absolute() not in held] if empty and not need: # Every file is in place: "packx holds none of these files" read - # as an empty card, where it holds all 22 (tui_audit_13 P3-4). + # as an empty card, where it holds all 22. offline_lines = [f"Nothing to copy from {', '.join(empty)}: every file is in " "place."] elif empty and offline_lines and len(empty) == len(state.from_folders): @@ -20584,7 +20560,7 @@ def _plan_lines(check: dict, dest: Path | None, state: TuiState) -> list: # On Confirm the remedy comes right after the headline: at 40x12 it was # what got cut, Back left alone below it. On the plan it comes after the # folder and what named it: between them, Named by sat lines under its - # folder (tui_audit_12 P3-15). + # folder. at = 1 if check is state.dry else 3 if found_in else 2 return lines[:at] + offline_lines + lines[at:] @@ -20665,7 +20641,7 @@ def _saves_lines(state: TuiState, saves: dict | None, whole: bool = False) -> li # The folder alone is cut in the middle: cut with the sentence, it # lost "directory goes to" even at 80 columns. # The folder on its own line at the BIOS folder's indent: at the - # label's, the two folders of a plan sat at two (tui_audit_14 P3-9). + # label's, the two folders of a plan sat at two. return [f"{_plural(count, 'file')} read from {name}'s save directory " f"{'goes' if count == 1 else 'go'} to{' ' + words if words else ''}:", " " + (shown_path(folder) if whole else _short_path(Path(folder), state.home))] @@ -20685,8 +20661,7 @@ def _unplaced_lines(summary: dict | None, state: TuiState, # Said when ES-DE is found, and in fewer words where the long form would -# give way: at 40x12 it ended in the middle of its sentence (tui_audit_14 -# P3-5). +# give way: at 40x12 it ended in the middle of its sentence. TUI_ESDE_NOTE = "ES-DE found: its BIOS files go to each emulator, not to ES-DE itself." TUI_ESDE_SHORT = "ES-DE: files go to each emulator." @@ -20802,7 +20777,7 @@ def _fitted_compose(state: TuiState, width: int, height: int, first: list, core: notes go first, the last one first, then the lines before the core, then a folder that does not fit its lines is drawn on one, cut in its middle. At 40x12 a note took the room and the folder Use this folder - takes went with it (tui_audit_16 P3-1).""" + takes went with it.""" def shown(body: list, before: list) -> bool: top = _text_lines(list(pinned), width) wanted = len(_text_lines(before, width)) + (len(top) + 1 if top else 0) @@ -20835,8 +20810,7 @@ def _status_after(state: TuiState) -> list[str]: def _view_browse(state: TuiState, width: int, height: int) -> tuple: - # Under WSL a drive is E:\ on every screen: the title said /mnt/e - # (tui_audit_11 P3-13). + # Under WSL a drive is E:\ on every screen: the title said /mnt/e. where = "Drives" if state.browse_dir is None else middle(shown_path(state.browse_dir), width) hint: list = [] if state.browse_for == "from": @@ -20912,7 +20886,7 @@ def _view_checking(state: TuiState, width: int, height: int) -> tuple: # plan then gives (8179 after "File list: 8169 files"). lines += ["File list received.", _reading_line(state, elapsed)] # Back first: a double tap on the Continue before it pressed the Quit - # drawn in the same cell (tui_audit_13 P2-1). + # drawn in the same cell. return ("Checking", _compose(state, width, height, lines, []), ("B/Esc Back", "Ctrl-C Quit")) @@ -20955,21 +20929,21 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: # total of all of them. Their data files too, as line mode's head. chosen = _ticked_files(state) # One total, the data files in it, the kinds under the folder - # adding up to it (code_audit_21 P3-8). + # adding up to it. lines[0] = _styled(f"About {_plural(len(chosen) + data, 'file')}, " f"{format_size(sum(e['size'] for e in chosen) + (data_size or 0))}" f", for {len(state.ticked)} of {len(state.systems)} systems", "title") if _offline_only(): # Offline, what the folders copied from hold of the systems # ticked: the plan counted the whole list beside "For your 1 of - # 11 systems" (code_audit_21 P3-5). + # 11 systems". took = {event["dest"] for events in _tui_found_elsewhere(state).values() for event in events} held = [event for event in chosen if event["dest"] in took] rest = len(chosen) - len(held) + data # Nothing at hand: the head the whole list's plan says, for the # systems ticked. "About 0 files, 0 B" stood over 20 files the - # internet would bring (tui_audit_17 P3-5). + # internet would bring. lines[0] = _styled( f"{agree(rest, 'file needs', 'files need')} the internet, which " f"{offline_named()} does not use, for {len(state.ticked)} of " @@ -21006,8 +20980,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: if state.cli_systems and state.systems else []), # Named as line mode names it, out of how many, the flag after # the words where the command line gave it: "--core" said - # nothing of the count, and "--region." stood alone - # (tui_audit_17 P3-4). + # nothing of the count, and "--region." stood alone. *([core_count_words(state.cores, _core_base(state)) + (" (--core)" if state.cores == state.cli_cores else "")] if tui_core_flags(state) else []), @@ -21017,7 +20990,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: if said and not said.startswith("for "): said = f"for your choice: {said}" # A system --system named that --no-game-data left empty, in line mode's - # words (tui_audit_16 P3-7). + # words. listed = {row["system"] for row in state.systems} emptied_named = game_data_only_words([ system_title(system, state.manifest) for system in game_data_only( @@ -21025,18 +20998,16 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: (state.manifest or {}).get("files") or [])]) if state.no_game_data else "" # Named on the command line: said in line mode's words, and widened by # Choose systems. --core and --region were said in line mode alone - # (tui_audit_11 P3-11). # Of the files the headline counts, by kind: those ticked when it # estimates them, those to install otherwise. Under the folder, never - # above it: inserted second, it pushed the folder off a 40x12 plan - # (tui_audit_12 P3-10). + # above it: inserted second, it pushed the folder off a 40x12 plan. kinds_of = (_ticked_files(state) if estimating else [event for event in state.files if event["state"] != "present"]) found = (_tui_found_elsewhere(state) if not estimating and _offline_only() and state.check is check else {}) if found: # Some were found in a folder: the kinds split those the headline - # says need the internet, named as such (tui_audit_14 P3-7). + # says need the internet, named as such. took = {event["dest"] for events in found.values() for event in events} rest = [event for event in kinds_of if event["dest"] not in took] if rest or data: @@ -21044,7 +21015,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: else: # Every file found: the kinds are those of the files copied, # and game data is defined as the pack's plan defines it. The - # --from plan said neither (tui_audit_15 P3-11). + # --from plan said neither. found = {} parts, defined = _kinds_lines(state, kinds_of, data, data_size, whole=bool(found)) if _choice_in_place(state) or (state.emptied and state.systems and not state.ticked): @@ -21061,7 +21032,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: *([parts] if parts else []), *games_plan_words(state)] if state.version: # Before the free space, which gives way first: appended last, the - # note was cut from the 40x12 plan with no sign (tui_audit_13 P3-1). + # note was cut from the 40x12 plan with no sign. free = next((index for index, line in enumerate(lines) if str(line).startswith("Free space:")), len(lines)) lines.insert(free, state.version) @@ -21070,7 +21041,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: if defined: # Once, after the counts and before the save line: last, it was # the first line to give way at 80 columns, where the counts named - # data files nothing defined (tui_audit_13 P3-6). The help says it + # data files nothing defined. The help says it # where the screen has no room. saves = next((index for index, line in enumerate(lines) if "'s save directory" in str(line)), len(lines)) @@ -21078,7 +21049,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: # A folder that does not fit is wrapped, as the first screen wraps it: # cut in its middle, the plan hid the part being checked before Install. # At 40 columns too, broken after a separator: cut there, it was spelled - # one way on the plan and another on the result (tui_audit_13 P3-3). + # one way on the plan and another on the result. lines = [piece for line in lines for piece in ( [_styled(part, "folder" if index and str(line).startswith(_FOLDER_LABEL) else "") for index, part in enumerate(_wrap( @@ -21097,7 +21068,7 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: "replaced.") if str(line).startswith(long_form) else line for line in lines] # Above the count it explains, which gives way first: the folder - # spelled whole takes two lines at 40 columns (tui_audit_13 P3-3). + # spelled whole takes two lines at 40 columns. counted = f"{check.get('present', 0)} in place, " at = next((index for index, line in enumerate(lines) if str(line).startswith(counted)), None) @@ -21116,9 +21087,9 @@ def _plan_body(state: TuiState, width: int, height: int, lines: list, """The plan's text and rows. Where both do not fit, the headline, the whole BIOS folder and the version note stay and the rows scroll under them: at 40x12 the plan named ~/.var/app/ as the folder, and dropped the - note that the list is for another version (tui_audit_14 P3-6). With + note that the list is for another version. With no room for its sentences the note is said in one line (short): at - 40x12 the RetroBat note was still dropped (tui_audit_15 P3-13).""" + 40x12 the RetroBat note was still dropped.""" body = _compose(state, width, height, lines, rows) at = next((index for index, line in enumerate(lines) if str(line).startswith(_FOLDER_LABEL.rstrip())), None) @@ -21133,7 +21104,7 @@ def _plan_body(state: TuiState, width: int, height: int, lines: list, and str(line) in (state.version, state.version_short)] # Why the folder rows are offered, before Install anyway: at 40x12 the # plan offered Choose another folder and Install anyway and no word of - # why (tui_audit_17 P2-2). + # why. kept += [line for line in lines if str(line).startswith(CANNOT_WRITE)] top = _text_lines(kept, width) drawn = [str(line).strip() for line in body] @@ -21182,7 +21153,7 @@ def _kinds_lines(state: TuiState, events: list[dict], data: int, if whole and not parts and counts.files: parts = f"{_plural(counts.files, 'file')} ({format_size(counts.size)})" # Game data named as missing is defined too, on its own line: the - # definition was spliced into that sentence (tui_audit_13 P3-5). + # definition was spliced into that sentence. missing = any(entry.get("category") == GAME_DATA for entry in _unavailable(state)[0]) defined = kinds_definition(categorized and bool(counts.games or left or missing), bool(data)) @@ -21262,7 +21233,7 @@ def _view_systems(state: TuiState, width: int, height: int) -> tuple: if needle and not any(row.action == "system" for row in rows): footer.insert(0, f"No system matches '{needle}'.") # In the lines the rows leave on every length of list: below the rows - # it was dropped once they filled the screen (tui_audit_17 P2-4). + # it was dropped once they filled the screen. if state.status: footer.insert(0, _styled(str(state.status), "refusal")) return ("Choose systems", @@ -21308,7 +21279,7 @@ def _view_regions(state: TuiState, width: int, height: int) -> tuple: (*_CHECKLIST_BAR[:2], "Left/Right Order", "? Help")) -# The bar of the three lists of ticks, one wording (tui_audit_17 P3-1). +# The bar of the three lists of ticks, one wording. _CHECKLIST_BAR = ("A/Enter Tick", "B/Esc Done", "? Help") @@ -21318,7 +21289,7 @@ def _status_footer(state: TuiState) -> list: def _view_cores(state: TuiState, width: int, height: int) -> tuple: # Kept above a list that scrolls: dropped once the rows filled the - # screen, 189 cores never said what unticking does (tui_audit_17 P2-4). + # screen, 189 cores never said what unticking does. pinned = ["Untick the cores you do not use: the platform's own files are always kept, " "and a core with no extra file reads only those."] return ("Cores", _compose(state, width, height, [], tui_rows(state), (), @@ -21549,8 +21520,7 @@ def unavailable_lines(needed: list[dict], manifest: dict | None, dest: Path | No files: list[dict]) -> list[str]: """The screen's plan and line mode's head say these sentences of the required files the collection cannot supply: line mode counted "1 - required, not found: 37" and never named the file or its folder - (tui_audit_16 P3-6).""" + required, not found: 37" and never named the file or its folder.""" if not needed: return [] @@ -21641,8 +21611,7 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: # The plan said the wrong copies are replaced: the result counts them. replaced = sum(kept.get("files", 0) for kept in summary.get("kept") or []) # One kind is named in the count, not on a line of its own: "78 - # files installed" above "Installed: 78 BIOS files" (tui_audit_13 - # P3-14). + # files installed" above "Installed: 78 BIOS files". word = "BIOS file" if _one_kind(state, installed) else "file" head = (f"{_plural(installed, word)} installed{source}" + (f", {replaced} of them replaced" if replaced else "") + ".") @@ -21657,26 +21626,25 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: or [event["dest"] for event in state.files if event["dest"] not in ok_dests][:left]) if left else [] # A wrong copy left in place is no missing file: --check counts it apart, - # and the result said "1 still missing" of it (code_audit_23 P3-3). + # and the result said "1 still missing" of it. wrong_dests = {event["dest"] for event in state.files if event.get("state") == "wrong_hash"} wrong_left = sum(1 for dest in missing if dest in wrong_dests) sources = _tui_sources(state, installed, left - wrong_left, wrong_left, len(failed)) if (left or failed) and installed and sources: # One count, then the remedy, as line mode says it: the count came - # twice, the remedy between them (tui_audit_11 P3-18). + # twice, the remedy between them. lines[0] = sources sources = "" elif title == "Done" and sources and "," not in sources and not summary.get("kept"): # Every file from one place: "22 files installed." over "22 files - # copied from packx." said one count twice (tui_audit_14 P3-10). + # copied from packx." said one count twice. lines[0] = sources + head[head.index(".") + 1:] sources = "" if sources: lines.append(sources) if left: # What is still missing by kind, as the copies are counted: 6 of the - # 16 were game data, and the old card's result said 16 files - # (tui_audit_13 P3-14). + # 16 were game data, and the old card's result said 16 files. apart = _tui_tally(state, [{"dest": dest, "size": 0} for dest in missing if dest not in wrong_dests]) if _tui_categories(state) and apart.bios and apart.games: @@ -21700,7 +21668,7 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: lines.append(f"BIOS folder: {shown_path(_plan_folder(state, state.dest))}") if installed + up_to_date: # Spelled as the BIOS folder above it is, whole: "~/" beside a full - # path was two spellings on one screen (tui_audit_12 P3-7). + # path was two spellings on one screen. lines += _saves_lines(state, state.done_saves, whole=True) if state.version: # Said again with the result, as line mode ends: the system's own @@ -21735,7 +21703,7 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: lines.append(f" ... and {shown - 20} more") if title == "Finished with errors": # What a rerun does, as line mode and the first install page say - # it: the screen never did (tui_audit_17 P3-7). + # it: the screen never did. pairs = [(failure["dest"], failure["reason"]) for failure in failed] retry = _retry_words(pairs) if retry: @@ -21747,7 +21715,7 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: landed = max(0, installed - sum(1 for _dest, good, _why in state.finished if good)) if expected > landed and not left and title != "Stopped" and summary: # The data files the plan counted, never named on a result that - # counted the BIOS files alone (tui_audit_14 P3-1). + # counted the BIOS files alone. lines.append(f"{_plural(expected - landed, 'data file')} not installed" + (f": not in {LOCAL.pack.name}." if LOCAL.pack is not None else ".")) if state.dest is not None and any(failure["reason"] == NOT_WRITABLE @@ -21784,7 +21752,7 @@ def tui_outcome(state: TuiState) -> tuple[str, list[str]]: lines.append(f"Details: {state.log}") if state.mouse and typed: # A drag over the command selected nothing: the terminal sends the - # press as a report. Said where it is read (tui_audit_13 P3-10). + # press as a report. Said where it is read. lines.append(_styled(TUI_RESULT_AGAIN if state.os_type == "android" else TUI_RESULT_COPY, "dim")) return title, lines @@ -21794,7 +21762,7 @@ def _dest_error_outcome(state: TuiState, installed: int) -> tuple[str, list[str] """The result of a run whose BIOS folder could not be created: that reason for every file, and its remedy. It said "22 files not fetched (RETROBIOS_INSTALL_OFFLINE=1)" and sent the user for a pack holding all - 22 (tui_audit_17 P2-1).""" + 22.""" message = str((state.dest_error or {}).get("message", "")) folder = shown_path(_plan_folder(state, state.dest)) _where, _sep, why = message.rpartition(": ") @@ -21816,8 +21784,7 @@ def _dest_error_outcome(state: TuiState, installed: int) -> tuple[str, list[str] # How to copy from the result, under its command while the mouse is on. -# Termux has no Shift key under a finger: there the second sentence alone -# (tui_audit_14 P3-3). +# Termux has no Shift key under a finger: there the second sentence alone. TUI_RESULT_AGAIN = "All of this is shown again in the terminal after Exit." TUI_RESULT_COPY = f"Shift and a drag select text. {TUI_RESULT_AGAIN}" @@ -21865,7 +21832,7 @@ def _view_result(state: TuiState, width: int, height: int) -> tuple: if rows: focused = rows[max(0, min(state.focus.get(state.screen, 0), len(rows) - 1))] # Exit in focus: A says it, and B saying it again named one action - # twice (tui_audit_15 P3-3). + # twice. return (title, _compose(state, width, height, lines, rows), ("A/Enter Choose",) if focused.action == "exit" else ("A/Enter Choose", "B/Esc Exit")) @@ -21878,7 +21845,7 @@ def _view_result(state: TuiState, width: int, height: int) -> tuple: def _view_error(state: TuiState, width: int, height: int) -> tuple: """The message and its rows. A message longer than the room the rows leave scrolls, with a line saying which lines are in view: at 40x12 the - offline screen dropped its remedy without a word (tui_audit_11 P3-2).""" + offline screen dropped its remedy without a word.""" rows = tui_rows(state) text = _text_lines(list(state.error), width) room = height - len(rows) - (1 if rows else 0) @@ -21899,7 +21866,7 @@ def _view_quit(state: TuiState, width: int, height: int) -> tuple: rows = tui_rows(state) focus = max(0, min(state.focus.get("quit", 0), len(rows) - 1)) # On Stay, A says Stay: a second "B/Esc Stay" beside it named one choice - # twice (tui_audit_14 P3-11). + # twice. hint = (("A/Enter Choose",) if rows[focus].action == "stay" else ("A/Enter Choose", "B/Esc Stay")) return ("Quit?", @@ -21940,7 +21907,7 @@ def _help_lines(state: TuiState) -> list[tuple[str, str]]: *_route_extras(state), *_help_key(state)] if state.editing: # Typing a filter: Space, a, n and q type there, and the help listed - # them as ticks, all, none and quit (tui_audit_11 P3-9). + # them as ticks, all, none and quit. return [("Enter", "Done"), ("Esc", "Clear the filter"), ("Backspace", "Delete a character"), ("Ctrl-U", "Clear"), ("Ctrl-C", "Quit"), *_route_extras(state)] @@ -21961,7 +21928,7 @@ def _help_lines(state: TuiState) -> list[tuple[str, str]]: if screen in _CHECKLISTS: keys.append((names["tick"], "Tick, untick")) # How a tap acts, before what the list says elsewhere: last, it was the - # line a 40x12 help cut (code_audit_20 P3-1). + # line a 40x12 help cut. keys += _tap_help(state) if screen in _CHECKLISTS: keys.append(("a, n", "All, none")) @@ -22051,7 +22018,7 @@ def _view_help(state: TuiState, width: int, height: int) -> tuple: more = ["", state.status_more] if state.status_more else [] # What the plan's kinds are: at 40 columns the plan has no room for the # sentence, and the game data row was a choice nothing explained - # (tui_audit_13 P3-2). Said before the keys a list also says elsewhere. + # Said before the keys a list also says elsewhere. words = _screen_definition(state) defined = ["", *textwrap.wrap(words, width)] if words else [] # Cut from its end at 40x12, the help lost Quit and This help with no @@ -22066,7 +22033,7 @@ def _view_help(state: TuiState, width: int, height: int) -> tuple: elif spare == "gap": # The blank line before the definitions, before a definition # is shortened: the Tap line that says Install takes a second - # tap is kept at every size (tui_audit_14 P3-4). + # tap is kept at every size. defined = defined[1:] if defined[:1] == [""] else defined elif spare == "definitions": # The short form at 40x12, whole: the long one was cut in the @@ -22114,7 +22081,7 @@ def tui_view(state: TuiState, cols: int, rows: int) -> list[str]: if (tapped != routed and "? Help" in _hint(width, *routed) and "? Help" not in _hint(width, *tapped)): # At 40 columns "/tap" pushed "? Help" off the bar: the help, which - # says how a tap acts, keeps its entry (code_audit_20 P3-1). + # says how a tap acts, keeps its entry. tapped = routed hint = _armed_hint(state, tapped, width) lines = [_styled(fit(f" RetroBIOS: {title}", cols), "head"), _styled("")] @@ -22311,7 +22278,7 @@ def found_setups(os_type: str) -> tuple[list[tuple[str, Path, str]], set]: if systems.count(card[2]) > 1} # Two cards of one system read alike: each says what its BIOS folder # holds, and the one with fewer files, the card being set up rather - # than the old one, comes first (tui_audit_11 P3-15). + # than the old one, comes first. taken.sort(key=lambda item: (systems.index(item[0][2]), counts.get(item[1], -1))) for card, mount in taken: kind = _card_word(card) @@ -22408,8 +22375,8 @@ def tui_start( if (getattr(args, "platform_from_list", False) and not bound and len(setup_list( state.setups, state.mounted_setups, "", os_type, LOCAL.serves())) > 1): # A list or a pack card setups read too: the setup list, filtered - # to them and RetroArch first, as line mode asks (tui_audit_11 - # P1-2). The folder question alone left them out of reach. + # to them and RetroArch first, as line mode asks. The folder + # question alone left them out of reach. state.stack = ["platforms"] state.focus["platforms"] = _platform_focus(state, plat) return state, [] @@ -22591,8 +22558,7 @@ def _tui_fetch(plat: str, inbox: queue.Queue, log: io.StringIO) -> None: if code == "network": lines = [f"The list of BIOS files could not be downloaded: {words}.", "Check the Wi-Fi or the cable, then choose Try again.", - # A handheld with no Wi-Fi has the pack as its way - # (tui_audit_11 P3-3). + # A handheld with no Wi-Fi has the pack as its way. "Or copy a pack to the card and run the installer with --from-pack " "PACK: no network is needed then."] proxy = next((name for name in ("HTTPS_PROXY", "https_proxy", "ALL_PROXY", @@ -22859,7 +22825,7 @@ def _farewell_lines(state: TuiState) -> list[str]: lines = _said_lines(state) # The version note in every farewell of a run that read it: with # everything in place it was the one thing left to say, and the - # farewell said only that (tui_audit_13 P3-1). + # farewell said only that. if state.version and state.screen != "crashed" and state.version not in lines: lines.append(state.version) return lines @@ -22900,7 +22866,7 @@ TUI_QUIT_WORDS = "RetroBIOS: quit. Nothing was installed." # The result's remedy for the save files left out, as the terminal says it # once the screen is gone: Options are not there to choose from -# (code_audit_20 P3-4). Line mode's words. +# Line mode's words. TUI_SAVE_REMEDY = "Choose it in Options, Save folder (--save-dir), next time." LINE_SAVE_REMEDY = "Name it with --save-dir next time." @@ -22925,8 +22891,8 @@ def tui_ctrl_z(state: TuiState) -> bool: with job control can resume it, the installer's process group being one of its jobs, not its session's own. Started from a terminal app's -e, a desktop entry or a launcher's sh -c, nothing ever sent SIGCONT, and - the screen and its launcher stayed stopped for good (code_audit_18 - P3-1). Otherwise the key is ignored and the bar says why.""" + the screen and its launcher stayed stopped for good. Otherwise the key is + ignored and the bar says why.""" if (hasattr(signal, "SIGSTOP") and hasattr(os, "getsid") and os.getpgrp() != os.getsid(0)): return True @@ -23115,7 +23081,7 @@ def run_tui(args: argparse.Namespace) -> int: # A new screen's settle runs from when it is on the screen, # after its layout and its write: the second click of a # double click waited out a slow layout in the input and - # acted on the screen it had never seen (code_audit_22 P3-1). + # acted on the screen it had never seen. state.hits = state.hits._replace(shown=time.monotonic()) for key in terminal.keys(TUI_FRAME): if key.name == "ctrl-z": diff --git a/install.sh b/install.sh index d98b63192..d1bc42370 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="6e625f7a8c9c3ba095c8240dc3e8482dddd514e438302a576a2f80807e79a547" +DEFAULT_INSTALL_SHA256="137a32f9e9c89dca56e62171c690955692b79ef8636bc8492cd4b68d707c32e2" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index bbf635adc..5bdf77d3d 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1079846, - "sha256": "6e625f7a8c9c3ba095c8240dc3e8482dddd514e438302a576a2f80807e79a547", + "size": 1075087, + "sha256": "137a32f9e9c89dca56e62171c690955692b79ef8636bc8492cd4b68d707c32e2", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1133023, - "sha256": "ff64d48ae2d5bd2dcf341917c55da88f8ca7174a2ccbc4e7786b69444da11ff8" + "size": 1128264, + "sha256": "948ea83c0b7edceac9550b5ed737189084b9bbed1f2e2579ebe5616956703fb6" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1079846, - "sha256": "6e625f7a8c9c3ba095c8240dc3e8482dddd514e438302a576a2f80807e79a547", + "size": 1075087, + "sha256": "137a32f9e9c89dca56e62171c690955692b79ef8636bc8492cd4b68d707c32e2", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1079846, - "sha256": "6e625f7a8c9c3ba095c8240dc3e8482dddd514e438302a576a2f80807e79a547", + "size": 1075087, + "sha256": "137a32f9e9c89dca56e62171c690955692b79ef8636bc8492cd4b68d707c32e2", "executable": false }, { diff --git a/scripts/generate_installer_doc.py b/scripts/generate_installer_doc.py index e3f799958..5775298e3 100644 --- a/scripts/generate_installer_doc.py +++ b/scripts/generate_installer_doc.py @@ -223,8 +223,7 @@ def line_menu() -> str: """The line menu of a RetroArch run, g then Enter pressed, as install.py prints it for the RetroArch list (install/retroarch.json): the very function line mode runs, its questions answered here. The page carried - a copy typed by hand, whose keys and counts drifted from the installer - (code_audit_22, owner's note on which-pack).""" + a copy typed by hand, whose keys and counts drifted from the installer.""" import io # noqa: PLC0415 from unittest import mock # noqa: PLC0415 @@ -290,7 +289,7 @@ class _ListHandler(http.server.SimpleHTTPRequestHandler): class _LoopbackServer(http.server.ThreadingHTTPServer): """The list server, named by its number: HTTPServer.server_bind looks 127.0.0.1 up with socket.getfqdn, a DNS query wherever /etc/hosts does - not name it (code_audit_24 P3-12).""" + not name it.""" def server_bind(self) -> None: socketserver.TCPServer.server_bind(self) diff --git a/scripts/generate_site.py b/scripts/generate_site.py index 2a763163b..ac9c8b872 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -3943,9 +3943,9 @@ def first_screen_words() -> list[str]: installer = _installer() # The screen it opens first: the setup found, or the list when none # is. Install comes on the next one, Choose systems beside it and named - # above on the page (tui_audit_16 P3-10). + # above on the page. # Nothing found, the folder comes before Install: which-pack left it - # out (tui_audit_17 P3-9). + # out. return [f"It asks **{installer.TUI_FOUND_TITLE}** (or **{installer.TUI_CHOOSE_TITLE}** " f"and **{installer.TUI_FOLDER_TITLE}**), then offers **{installer.TUI_INSTALL_ROW}**."] @@ -3954,7 +3954,7 @@ def check_pass_line() -> str: """The pass line of "How to check": the words `--check` prints only when no file is missing or wrong (install.py EVERYTHING_IN_PLACE), read from the installer. Typed here, it kept "All files up to date." after the - installer said "Everything is in place." (tui_audit_15 P3-10).""" + installer said "Everything is in place.".""" return f"All good when it says `{_installer().EVERYTHING_IN_PLACE}`" # Under "From your computer": a device with no network installs from the ZIP @@ -9970,7 +9970,7 @@ def _emulator_part_page( for n, (stem, _e) in enumerate(parts, 1)], number - 1), f"# {emu_name} files, part {number} of {len(parts)}", "", - # The crumbs end on the emulator, read from parent: (round 5, 7.5). + # The crumbs end on the emulator, read from parent:. f"This part holds {_count(len(files), 'entry', 'entries')}, " f"{_code(first)} to {_code(last)}. The other parts: {others}.", "", diff --git a/scripts/sitebootstrap.py b/scripts/sitebootstrap.py index 6856d86f1..5efca67d9 100644 --- a/scripts/sitebootstrap.py +++ b/scripts/sitebootstrap.py @@ -45,7 +45,7 @@ PIN: dict[str, re.Pattern[str]] = { # What the served copy says of a refused installer. It names a commit's # install.py, which never changes, and both downloaders fail on a short # transfer before the hash is read: neither a cut download nor caches of -# two ages explain a mismatch there (code_audit_21 P3-1). +# two ages explain a mismatch there. SERVED_ADVICE = ("The file was changed on its way here, most often by a proxy or an " "antivirus that rewrites downloads. Run the command again from another " "network, or with that web protection paused.") @@ -73,7 +73,7 @@ def served_text(name: str, root: Path, commit: str) -> str: advice fitted to that. A pin that is not the SHA-256 of root's install.py stops the build: published, that copy refused every install until the next good deploy, where a failed build keeps the last good - pair served (code_audit_21 P3-2).""" + pair served.""" source, line = SOURCES[name] text = (root / source).read_text(encoding="utf-8") pinned = PIN[name].findall(text) diff --git a/tests/netguard/sitecustomize.py b/tests/netguard/sitecustomize.py index d7ab23fb8..bb3965e6b 100644 --- a/tests/netguard/sitecustomize.py +++ b/tests/netguard/sitecustomize.py @@ -8,7 +8,7 @@ that is down) and written to RETROBIOS_TEST_NETLOG, and the cards and drives mounted under /media, /run/media, /mnt and /Volumes, which read as folders no drive is mounted on. A test module passed on a machine with no network and no card, and failed with an AmberELEC card in the reader, while 261 -connections to GitHub left the module in a run (code_audit_24 P3-13). +connections to GitHub left the module in a run. """ from __future__ import annotations diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 4f18a8ca8..93eef3cb2 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -4427,7 +4427,7 @@ class EmulatorPagesStateTheirDataForMachines(unittest.TestCase): {"name": "free.bin"}], }) self.assertEqual(data["about"]["codeRepository"], "https://github.com/stenzek/duckstation") - # The release the profile describes, never the pin (round 5, 3.5). + # The release the profile describes, never the pin. self.assertEqual(data["about"]["version"], "v0.1-12070") self.assertNotIn("description", data["about"]) self.assertEqual(data["dateModified"], "2026-03-23") diff --git a/tests/test_doc_pages.py b/tests/test_doc_pages.py index 1a36ca46b..106c62e78 100644 --- a/tests/test_doc_pages.py +++ b/tests/test_doc_pages.py @@ -159,12 +159,12 @@ class InstallerOutputExample(unittest.TestCase): """The run counted 8069 files where its menu counted 3259 BIOS files and 5089 game data files: the parts add up to the total they divide, the sizes within the rounding of their three figures.""" - # Data files are a third kind, counted beside the two (tui_audit_12 P2-3). + # Data files are a third kind, counted beside the two. split = re.search(r"(\d+) BIOS files \(([\d.]+) ([KMG]B)\)(?:,| and) (\d+) game data " r"files \(([\d.]+) ([KMG]B)\)", text) self.assertIsNotNone(split, "a categorized list says its BIOS files and game data") bios, bios_size, bios_unit, games, game_size, game_unit = split.groups() - # The data files in the one total, the third kind (code_audit_21 P3-8). + # The data files in the one total, the third kind. data = re.search(r"and (\d+) data files \(([\d.]+) ([KMG]B)\)", text) data_count, data_size, data_unit = data.groups() if data else ("0", "0", "KB") self.assertEqual(int(bios) + int(games) + int(data_count), int(count)) @@ -176,7 +176,7 @@ class InstallerOutputExample(unittest.TestCase): class InstallerSamplesSayWhatTheCodePrints(unittest.TestCase): - """code_audit_24 P3-8 to P3-12: samples typed by hand outside the + """Samples typed by hand outside the generated blocks, a sentence on a log read as the terminal's, pages that described the generator as tables alone, and a sandbox that asked DNS.""" diff --git a/tests/test_handheld_launchers.py b/tests/test_handheld_launchers.py index 835376c61..0f69a24cc 100644 --- a/tests/test_handheld_launchers.py +++ b/tests/test_handheld_launchers.py @@ -965,7 +965,7 @@ class ThePortMasterPort(unittest.TestCase): self.assertIn("log.txt", device.screen) def test_a_quit_chosen_shows_no_message(self): - """code_audit_19 P3-1: a quit chosen exits 2, below 128, and the + """A quit chosen exits 2, below 128, and the first line of tui.err went into a message box waiting for A.""" device = self.device() proc = device.run(["bash", self.script], FAKE_QUIT="1", FAKE_CODE="2", diff --git a/tests/test_install.py b/tests/test_install.py index f6d72e39a..ef218e4df 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -35,8 +35,8 @@ _spec.loader.exec_module(install) sys.path.insert(0, str(REPO_ROOT / "tests")) from netguard import module_guard # noqa: E402 -# No connection off the loopback and no card of the host reaches a test -# (code_audit_24 P3-13): the module fails at its end otherwise. +# No connection off the loopback and no card of the host reaches a test: +# the module fails at its end otherwise. setUpModule, tearDownModule = module_guard("test_install") @@ -1807,7 +1807,7 @@ class TestDetectedPlatformPrompt(unittest.TestCase): self.assertIn("Type a number from 1 to 2, or q to quit.", out) def test_enter_takes_the_first_and_there_is_no_all(self): - """tui_audit_9 P3-11: the screen focuses the first and has no All.""" + """The screen focuses the first and has no All.""" result, out = self._answer("") self.assertEqual(result, [self.PLATFORMS[0]]) self.assertNotIn("All", out) @@ -1817,8 +1817,7 @@ class TestManualPlatformPrompt(unittest.TestCase): """With nothing detected, an interactive run asks instead of exiting. Every test runs on no drive and a home of its own: two read the host's - drives and home, and failed with a card in the reader (code_audit_23 - P3-7).""" + drives and home, and failed with a card in the reader.""" def setUp(self): home = Path(_tempdir(self)) @@ -1869,7 +1868,7 @@ class TestManualPlatformPrompt(unittest.TestCase): self.assertEqual(chosen, [("lakka", install.DEFAULT_DESTS["lakka"])]) def test_batocera_on_a_computer_gets_no_default(self): - """tui_audit_8 P2-4: /userdata/bios, a folder only the Batocera + """/userdata/bios, a folder only the Batocera machine has, was offered on a computer, and Enter took it.""" answers = iter(["batocera", "", "~/share/bios"]) out = io.StringIO() @@ -4204,7 +4203,7 @@ class AQuestionLeftWithCtrlDOrCtrlCIsAStop(unittest.TestCase): [sys.executable, "install.py", "--plain"], cwd=REPO_ROOT, stdin=slave, stdout=slave, stderr=slave, # No request leaves the machine: the standalone emulators' lists - # come from the network (code_audit_24 P3-13). + # come from the network. env={**os.environ, "HOME": str(home), "RETROBIOS_OS": "linux", "RETROBIOS_INSTALL_OFFLINE": "1"}, ) @@ -4272,8 +4271,7 @@ class RunsAgainstTheRealLists(unittest.TestCase, _LoopbackRun): lines = [line for line in proc.stdout.splitlines() if line.strip()] self.assertIn("Nothing was written", lines[-1]) at = next(index for index, line in enumerate(lines) if line.startswith("Would download")) - # One total on the header, the data files among the kinds under it - # (code_audit_21 P3-8). + # One total on the header, the data files among the kinds under it. self.assertNotIn("data files", lines[at]) self.assertIn("data files", lines[at + 1]) @@ -4321,7 +4319,7 @@ class DestAloneFollowsWhatIsFoundHere(unittest.TestCase): return exc, out.getvalue() def test_a_card_system_chosen_checks_the_folder(self): - """code_audit_13 P2-3: the menu offered no card system, and one + """The menu offered no card system, and one chosen now reads --dest as --platform does.""" root = Path(_tempdir(self)) answers = iter(["Onion", "retroarch"]) @@ -5245,7 +5243,7 @@ class EventsDescribeTheRun(unittest.TestCase, _SyntheticTree): # The systems Choose systems lists, before the files are read. {"event": "choices", "platform": "retroarch", "systems": ["sys-a", "sys-b", "other"]}, - # Nothing set aside before the choice (code_audit_24 P3-3). + # Nothing set aside before the choice. {"event": "set_aside", "platform": "retroarch", "dests": []}, # a.bin and b.bin are in place: the first read and the last. {"event": "checking", "files_done": 1, "files_total": 2}, diff --git a/tests/test_install_cores.py b/tests/test_install_cores.py index beb738b11..8bc3507ff 100644 --- a/tests/test_install_cores.py +++ b/tests/test_install_cores.py @@ -371,7 +371,7 @@ class RefusedBeforeAnyInstall(unittest.TestCase): (tmp / "cores").mkdir() (tmp / "cores" / "mgba_libretro.so").write_bytes(b"") # Two setups found stop a run without questions before either is - # read (code_audit_18 P2-3): the refusal is checked with Batocera + # read: the refusal is checked with Batocera # named, and with both found nothing is fetched either. for argv, said in ( (["--platform", "batocera", "--dest", str(tmp / "bios")], diff --git a/tests/test_install_experience.py b/tests/test_install_experience.py index 4a7306aa0..20aa43215 100644 --- a/tests/test_install_experience.py +++ b/tests/test_install_experience.py @@ -1210,7 +1210,7 @@ class ADetectedClosedFolderSaysWhereItCameFrom(unittest.TestCase): self.assertIn(f"than the one {self.cfg} names (name another with --dest)", said) def test_two_setups_stop_before_either_folder_is_read(self): - """code_audit_18 P2-3: a run without questions installs for one + """A run without questions installs for one setup, so two found stop on what to name before either folder is read, the closed one included.""" proc = self.run_detected(True) diff --git a/tests/test_install_offline.py b/tests/test_install_offline.py index deaf72b81..a4498a0fd 100644 --- a/tests/test_install_offline.py +++ b/tests/test_install_offline.py @@ -237,7 +237,7 @@ class CheckNamesWhyAFileIsRefused(Scratch): self.assertIn(f"read by beetle_psx, pcsx_rearmed at {here / 'scph5501.bin'}", out) self.assertIn(f"read by beetle_psx, pcsx_rearmed at {here / 'pcsx' / 'extra.bin'}", out) - # Never "opened" of a file that is not there (tui_audit_16 P3-12). + # Never "opened" of a file that is not there. self.assertNotIn("opened at", out) def test_a_complete_folder_says_nothing_more(self): @@ -476,7 +476,7 @@ class FromPackInstallsOffline(Scratch): self.assertEqual((self.dest / "dolphin-emu" / rel).read_bytes(), data) def test_the_data_trees_say_what_they_weigh(self): - """tui_audit_4 P3-10.8: the plan read "and 2636 data files" with no + """The plan read "and 2636 data files" with no size. The data event carries the bytes check's data_missing counts.""" tree = {"Sys/GC/font.bin": b"font bytes", "Sys/Wii/setting.txt": b"setting"} listed = manifest() @@ -664,7 +664,7 @@ class OfflineMakesNoRequest(Scratch): self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr) self.assertEqual((self.dest / "scph5501.bin").read_bytes(), US) self.assertFalse((self.dest / "gba_bios.bin").exists()) - # Missing, never failed (code_audit_15 P3-1): no FAILED line per file. + # Missing, never failed: no FAILED line per file. self.assertIn("3 still missing", proc.stdout + proc.stderr) self.assertNotIn("FAILED", proc.stdout + proc.stderr) self.assertIn("without --offline", proc.stdout + proc.stderr) @@ -785,7 +785,7 @@ class ADryRunOpensOnItsTotals(Scratch): class OfflineLeavesFilesMissing(Scratch): - """code_audit_13 P1-1, P3-7, P3-8: the files --offline leaves out at a + """The files --offline leaves out at a terminal were counted with a "no" to the size question. Once one file came from this machine, 14,696 missing ended on Done and exit 0.""" @@ -803,8 +803,7 @@ class OfflineLeavesFilesMissing(Scratch): sources="4 files copied from old, 14696 still missing.") self.assertEqual(code, 1) self.assertNotIn("Done", text) - # One count, the sources line as the head, as the screen's result - # (tui_audit_15 P3-8). + # One count, the sources line as the head, as the screen's result. self.assertIn("Finished with files missing. 4 files copied from old, 14696 still " "missing.", text) self.assertEqual(text.count("14696"), 1) @@ -854,7 +853,7 @@ class OfflineLeavesFilesMissing(Scratch): class OneOfflineVocabulary(Scratch): - """code_audit_14 P3-1 to P3-4, tui_audit_7 P3-4: --offline said one + """--offline said one thing at a terminal and another without questions, on the screen and under --check.""" @@ -865,7 +864,7 @@ class OneOfflineVocabulary(Scratch): return old def test_a_run_without_questions_says_missing_not_failed(self): - """P3-2: "Finished with errors ... 3 files failed" and "Run the + """"Finished with errors ... 3 files failed" and "Run the same command again to retry only those".""" proc = self.run_installer("--offline", "--manifest", str(self.list), "--from", str(self.old()), "--no-input") @@ -879,7 +878,7 @@ class OneOfflineVocabulary(Scratch): self.assertNotIn(said, out) def test_nothing_installed_is_said_so(self): - """P3-3: "Finished with files missing. 0 files installed".""" + """"Finished with files missing. 0 files installed".""" failures = [("a.bin", install.NOT_WRITABLE), ("b.bin", install.NOT_WRITABLE)] with contextlib.redirect_stdout(io.StringIO()) as out, \ self.assertRaises(SystemExit) as stop: @@ -891,7 +890,7 @@ class OneOfflineVocabulary(Scratch): self.assertNotIn("0 files installed", out.getvalue()) def test_the_command_suggested_keeps_the_offline_setting(self): - """P3-3: sudo does not pass RETROBIOS_INSTALL_OFFLINE on.""" + """Sudo does not pass RETROBIOS_INSTALL_OFFLINE on.""" import test_install_tui as tui args = tui._args(platform="retroarch", declared_only=False, offline=False) @@ -901,7 +900,7 @@ class OneOfflineVocabulary(Scratch): self.assertIn("--offline", hint.command("retroarch", self.dest, elevated=True)) def test_check_offline_says_what_cannot_come(self): - """P3-4: "Run the same command without --check to fetch them".""" + """"Run the same command without --check to fetch them".""" proc = self.run_installer("--check", "--offline", "--manifest", str(self.list)) out = proc.stdout + proc.stderr self.assertEqual(proc.returncode, 1, out) @@ -910,7 +909,7 @@ class OneOfflineVocabulary(Scratch): self.assertIn("Copy them from your old card or a folder (--from)", out) def test_the_screen_says_missing_not_failed(self): - """P3-2 on the full screen: "Finished with errors, 20 failed".""" + """On the full screen: "Finished with errors, 20 failed".""" import test_install_tui as tui reason = f"not fetched: {install.OFFLINE_WORDS}" @@ -928,7 +927,7 @@ class OneOfflineVocabulary(Scratch): self.assertEqual(install.tui_outcome(state)[0], "Nothing installed") def test_the_line_menu_copies_from_a_folder(self): - """tui_audit_7 P3-4: no way to a folder, and an install of nothing + """No way to a folder, and an install of nothing offered.""" old = self.old() install.LOCAL.reset() @@ -947,7 +946,7 @@ class OneOfflineVocabulary(Scratch): class AuditFifteenOffline(Scratch): - """code_audit_15 P3-1, P3-5 and tui_audit_8 P3-11: what --offline and a + """What --offline and a pack leave out, and what a folder copied from holds, said as such.""" def test_yes_offline_counts_the_rest_missing_never_failed(self): diff --git a/tests/test_install_selection.py b/tests/test_install_selection.py index f1129e35e..c24ffe144 100644 --- a/tests/test_install_selection.py +++ b/tests/test_install_selection.py @@ -390,7 +390,7 @@ class DecliningTheSizePointsAtTheChoice(unittest.TestCase): self.assertNotIn("see --help", out) def test_options_given_keep_the_option_advice(self): - # The menu is shown with --system too (tui_audit_9 P3-8): Enter keeps it. + # The menu is shown with --system too: Enter keeps it. out = self._run(["", "n"], "--system", "sony-playstation") self.assertIn("--system, --core and --region install less", out) @@ -677,7 +677,7 @@ class TheOneLinerNarrows(unittest.TestCase): @unittest.skipUnless(shutil.which("script"), "script(1) provides the terminal") def test_the_custom_mode_at_a_terminal(self): """Typed answers: customise, PlayStation only, US first. Its one - core is not asked about (tui_audit_11 P3-10).""" + core is not asked about.""" with FakeRepository() as repo: command = " ".join(shlex.quote(part) for part in repo.command()) proc = subprocess.run( @@ -724,7 +724,7 @@ class TheOneLinerNarrows(unittest.TestCase): def test_q_at_every_menu_stops_on_the_quit_code(self): """`install.sh && retroarch` started RetroArch after a q, which left with 0. A quit chosen ends on 2, nothing installed, where Ctrl+C and - Ctrl+D leave with 130 (code_audit_19 P3-1).""" + Ctrl+D leave with 130.""" files = [{"dest": "a.bin", "size": 1, "systems": ["nintendo-gba"]}] menus = ( lambda: install._choose_platform("Platform:"), @@ -1632,7 +1632,7 @@ class SomethingElseAtADestination(unittest.TestCase): proc = repo.run("--yes") self.assertEqual(proc.returncode, 1, proc.stderr) self.assertNotIn("Traceback", proc.stderr) - # Each failure named once, on its FAILED line (tui_audit_17 P3-7). + # Each failure named once, on its FAILED line. self.assertIn("FAILED scph5500.bin (a folder sits where this file goes", proc.stdout) self.assertIn("FAILED scph5501.bin (file in place could not be kept aside", diff --git a/tests/test_install_tui.py b/tests/test_install_tui.py index 03bc22ffd..ed017799a 100644 --- a/tests/test_install_tui.py +++ b/tests/test_install_tui.py @@ -48,7 +48,7 @@ from test_install_selection import FakeRepository, _QuietHandler # noqa: E402 from netguard import module_guard # noqa: E402 # No connection off the loopback and no card of the host reaches a test, in -# this process or one it starts (code_audit_24 P3-13): 261 connections to +# this process or one it starts: 261 connections to # GitHub left this module in a run, and two tests failed with an AmberELEC # card in the reader. The module fails at its end when one is tried. setUpModule, tearDownModule = module_guard("test_install_tui") @@ -503,7 +503,7 @@ class Flow(unittest.TestCase): if row.value == "nintendo-gba") state.focus["systems"] = focus # A ticks the system in focus, B goes back to the plan, and Install - # there counts the choice first (tui_audit_17 P3-1). + # there counts the choice first. self.assertEqual(press(state, "enter", "esc"), []) self.assertEqual(state.ticked, {"nintendo-gba"}) self.assertEqual(state.screen, "plan") @@ -659,7 +659,7 @@ class Flow(unittest.TestCase): self.assertEqual(install.tui_rows(state)[state.focus["platforms"]].value, "retroarch") press(state, "/", "b", "a", "t", "o") self.assertEqual([row.value for row in install.tui_rows(state)][1:], ["batocera"]) - # tui_audit_7 P3-9.2: the one match is chosen with the first Enter. + # the one match is chosen with the first Enter. press(state, "enter") self.assertEqual(state.screen, "folder") self.assertEqual(state.platform, "batocera") @@ -858,7 +858,7 @@ class Widgets(unittest.TestCase): press(state, "up") self.assertEqual(state.focus["platforms"], 0) # A list of ticks wraps at any length: None and Done, at its end, - # are a few presses up from its first item (tui_audit_17 P3-1). + # are a few presses up from its first item. state = self.systems_state(20) state.focus["systems"] = 0 press(state, "up") @@ -1136,8 +1136,8 @@ class Views(unittest.TestCase): state.cols, state.rows = cols, rows lines = install.tui_view(state, cols, rows) for line in lines: - # The bar's key names faint, its actions not - # (tui_audit_12 P3-3): the rest as before. + # The bar's key names faint, its actions not: + # the rest as before. self.assertEqual(install.tui_paint(str(line), line.style, False), install.painted(line, install._bar_spans( line, "strong")) if line.style == "hint" @@ -1178,7 +1178,7 @@ class Views(unittest.TestCase): for text in (" Writing to the card...", " Any key closes this help"): self.assertEqual(install.tui_paint(text, "hint", True), text) painted = install.tui_paint(" A/Enter Exit B/Esc Back", "hint", True) - # The actions plain, the other keys faint (tui_audit_12 P3-3). + # The actions plain, the other keys faint. self.assertEqual(painted, " " + install._sgr("accent") + "A/Enter\x1b[0m Exit " + install._sgr("muted") + "B/Esc\x1b[0m Back") @@ -1485,7 +1485,7 @@ class ControlCharacters(unittest.TestCase): class SmallFixes(unittest.TestCase): def test_a_system_name_is_said_once_with_a_pack(self): - """tui_audit_5 P3-8.1: "Onion gets the RetroArch file list" was + """"Onion gets the RetroArch file list" was printed by the pack check, then again where the platform is read.""" pack = mock.Mock(files=[Path("RetroArch_BIOS_Pack.zip")]) pack.name = "RetroArch_BIOS_Pack.zip" @@ -1708,7 +1708,7 @@ class CleanupSurvivesABrokenTerminal(unittest.TestCase): class AuditRoundTwo(unittest.TestCase): - """tui_audit_1.md, each finding held where it was found.""" + """Ticks, the key bar, the network clock and typed paths.""" def systems(self) -> install.TuiState: state = checked_state() @@ -1720,7 +1720,7 @@ class AuditRoundTwo(unittest.TestCase): rows = install.tui_rows(state) return rows[state.focus[state.screen]] - def test_p1_3_the_filter_never_changes_the_ticks(self): + def test_the_filter_never_changes_the_ticks(self): state = self.systems() press(state, "n") state.focus["systems"] = next(i for i, row in enumerate(install.tui_rows(state)) @@ -1747,7 +1747,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(state.editing, "") self.assertEqual(state.ticked, {"nintendo-gba"}) - def test_p2_2_the_bar_names_what_a_does_on_the_focused_row(self): + def test_the_bar_names_what_a_does_on_the_focused_row(self): state = checked_state() self.assertTrue(install.tui_view(state, 80, 24)[-1].strip().startswith("A/Enter Install")) press(state, "down") @@ -1757,7 +1757,7 @@ class AuditRoundTwo(unittest.TestCase): if row.action == "all") self.assertIn("A/Enter Tick all", install.tui_view(state, 80, 24)[-1]) - def test_p2_2_b_esc_and_q_stop_an_install(self): + def test_esc_and_q_stop_an_install(self): for key in ("esc", "backspace", "q"): with self.subTest(key=key): state = checked_state() @@ -1766,7 +1766,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertTrue(state.stopping) self.assertEqual(press(state, key), [("kill",)]) - def test_p2_3_options_read_the_plan_again(self): + def test_options_read_the_plan_again(self): state = self.systems() press(state, "n") state.focus["systems"] = 1 @@ -1789,11 +1789,11 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(state.ticked, ticked) for cols, rows in ((80, 24), (40, 15)): text = "\n".join(install.tui_view(state, cols, rows)) - # tui_audit_6 P3-4: the headline counts the ticked systems. + # the headline counts the ticked systems. self.assertIn("About 1 file, 16.0 KB, for 1 of 3 systems", " ".join(text.split())) self.assertNotIn("3 files to download", text) - def test_p2_4_no_network_is_said_at_once(self): + def test_no_network_is_said_at_once(self): import socket with socket.socket() as probe: @@ -1809,7 +1809,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual((kind, title, code), ("manifest_failed", "No connection", 1)) self.assertIn("could not be downloaded: the server refused the connection", lines[0]) # The pack is the one option named: the way of a handheld with no - # Wi-Fi (tui_audit_11 P3-3). + # Wi-Fi. self.assertIn("Or copy a pack to the card and run the installer with --from-pack", " ".join(lines)) self.assertNotIn("--", " ".join(lines).replace("--from-pack", "")) @@ -1820,7 +1820,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual([row.action for row in install.tui_rows(state)], ["retry", "elsewhere", "quit"]) - def test_p2_4_the_clock_says_so(self): + def test_the_clock_says_so(self): import ssl inbox = __import__("queue").Queue() @@ -1833,7 +1833,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(title, "The clock is wrong") self.assertIn("The clock reads 1980-01-01", lines[0]) - def test_p2_5_one_line_per_cause(self): + def test_one_line_per_cause(self): state = checked_state() state.stack.append("result") state.code = 2 @@ -1844,7 +1844,7 @@ class AuditRoundTwo(unittest.TestCase): ["Nothing was installed: 50 files failed.", " 50 files failed, all for one reason: folder not writable."]) - def test_p2_6_a_folder_inside_a_card_offers_its_root(self): + def test_folder_inside_a_card_offers_its_root(self): card = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) self.addCleanup(shutil.rmtree, card, True) (card / ".system").mkdir() @@ -1859,7 +1859,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(press(state, "enter"), [("fetch", "minui")]) self.assertEqual(state.dest, card) - def test_p2_6_the_banner_is_not_an_error_line(self): + def test_the_banner_is_not_an_error_line(self): state = fresh_state() state.platform, state.dest = "retroarch", SYSTEM_DIR state.manifest, state.manifest_for = MANIFEST, "retroarch" @@ -1869,7 +1869,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(state.error, ["Error: refused."]) self.assertNotIn("retry", [row.action for row in install.tui_rows(state)]) - def test_p2_7_a_typed_path_replaces_the_one_offered(self): + def test_typed_path_replaces_the_one_offered(self): state = fresh_state() state.platform, state.stack = "retroarch", ["folder"] state.folder_default = SYSTEM_DIR @@ -1883,7 +1883,7 @@ class AuditRoundTwo(unittest.TestCase): install.tui_update(state, Key("paste", '/media/x"')) self.assertEqual(install.typed_path(state.path_text), Path("/media/x")) - def test_p2_7_a_path_from_the_root_is_not_created_on_a(self): + def test_path_from_the_root_is_not_created_on_a(self): state = fresh_state() state.stack = ["folder"] install._choose(state, "retroarch", Path("/no/such/deep/folder")) @@ -1896,7 +1896,7 @@ class AuditRoundTwo(unittest.TestCase): install._choose(state, "retroarch", near / "bios") self.assertEqual(self.focused(state).action, "create") - def test_p2_9_two_setups_of_one_name(self): + def test_two_setups_of_one_name(self): flatpak = HOME / ".var/app/org.libretro.RetroArch/config/retroarch/system" setups = install.tell_apart([("retroarch", flatpak, "RetroArch"), ("retroarch", SYSTEM_DIR, "RetroArch"), @@ -1919,7 +1919,7 @@ class AuditRoundTwo(unittest.TestCase): ("retroarch", SYSTEM_DIR, "RetroArch")]) self.assertEqual(setups[0][2], "RetroArch (Flatpak)") - def test_p2_10_the_check_counts_while_it_reads(self): + def test_the_check_counts_while_it_reads(self): state = fresh_state() state.platform, state.dest = "retroarch", SYSTEM_DIR state.manifest, state.manifest_for = MANIFEST, "retroarch" @@ -1929,19 +1929,19 @@ class AuditRoundTwo(unittest.TestCase): self.assertIn("Reading the files already in the folder: 120 of 400", "\n".join(install.tui_view(state, 80, 24))) - def test_p2_11_a_narrow_bar_keeps_the_keys_to_finish(self): + def test_narrow_bar_keeps_the_keys_to_finish(self): state = self.systems() self.assertEqual(install.tui_view(state, 40, 15)[-1].strip(), "A Tick B Done ? Help") - def test_p2_12_a_device_name_finds_its_setup(self): + def test_device_name_finds_its_setup(self): state = fresh_state() state.stack = ["platforms"] press(state, "/", "m", "u", "o", "s") self.assertEqual([row.value for row in install.tui_rows(state)][1:], [("retroarch", "muOS")]) - def test_p2_13_a_long_preview_wraps_only_what_is_in_view(self): + def test_long_preview_wraps_only_what_is_in_view(self): state = checked_state() state.stack += ["options", "preview"] state.dry = dict(CHECK) @@ -1960,7 +1960,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertLess(sum(calls), 40) self.assertIn("file07999.bin", "\n".join(lines)) - def test_p2_1_titles_and_regions(self): + def test_titles_and_regions(self): state = checked_state() state.manifest = {**MANIFEST, "system_titles": {"nintendo-gba": "Game Boy Advance"}} state.stack.append("systems") @@ -1969,7 +1969,7 @@ class AuditRoundTwo(unittest.TestCase): self.assertEqual(install.region_title("asia-ntsc"), "Asia (NTSC)") self.assertEqual(install.region_title("north-america"), "North America") - def test_p3_jobs_stop_at_the_ends_and_q_keeps_the_error_code(self): + def test_jobs_stop_at_the_ends_and_q_keeps_the_error_code(self): state = checked_state() state.jobs = 1 install._option(state, "jobs", -1) @@ -1982,10 +1982,10 @@ class AuditRoundTwo(unittest.TestCase): press(state, "q") self.assertEqual(state.exit_code, 2) - def test_p3_ascii_keeps_the_columns(self): + def test_ascii_keeps_the_columns(self): self.assertEqual(install.ascii_text("Édition ファミ"), "Edition ??????") - def test_p3_a_refused_tui_says_why_without_the_usage(self): + def test_refused_tui_says_why_without_the_usage(self): proc = install_run("--tui") self.assertEqual(proc.returncode, 2) self.assertEqual(proc.stderr.strip().splitlines(), @@ -2219,7 +2219,7 @@ class CopyFromAnOldCard(unittest.TestCase): self.recheck(state, [found("scph5500.bin", str(SYSTEM_DIR), "nested folder: bios/scph5500.bin")]) text = " ".join(line.strip() for line in install.tui_view(state, 120, 40)) - # tui_audit_4 P3-10.13: a fix copies, and the screen says the user's + # a fix copies, and the screen says the user's # copy stays. self.assertIn("1 file is in the wrong place, it will be copied where the emulators " "read it, your copy left as it is.", text) @@ -2274,7 +2274,7 @@ class CopyFromAnOldCard(unittest.TestCase): class AuditRoundThree(unittest.TestCase): - """tui_audit_2.md: its P1 and P2 findings, each held by a test.""" + """Each card by its own files, Space on install, and a short card.""" CARDS = { "muOS": ({"MUOS/": ""}, "retroarch", "MUOS/bios"), @@ -2298,22 +2298,22 @@ class AuditRoundThree(unittest.TestCase): path.write_text(text, encoding="utf-8") return root - # P1-1: a handheld's card mounted on a computer. + # a handheld's card mounted on a computer. - def test_p1_1_each_card_by_its_own_files(self): + def test_each_card_by_its_own_files(self): for name, (files, plat, folder) in self.CARDS.items(): with self.subTest(card=name): root = self.card(files) self.assertEqual(install.card_system(root), (plat, root / folder, name)) - def test_p1_1_a_card_nothing_names_is_left_alone(self): + def test_card_nothing_names_is_left_alone(self): self.assertIsNone(install.card_system(self.card({"roms/": "", "BIOS/": ""}))) - # code_audit_17 P2-3: Batocera's own share is its SHARE drive, read + # Batocera's own share is its SHARE drive, read # by a batocera.conf that names no KNULLI. share = self.card({"system/batocera.conf": "system.hostname=BATOCERA\n"}) self.assertEqual(install.card_system(share), ("batocera", share / "bios", "Batocera")) - def test_p1_1_the_card_rules_are_the_device_rules(self): + def test_the_card_rules_are_the_device_rules(self): # The folder and the marker come from the rule the device reads, so # they are never written twice. rules = {rule.name: rule for rule in install._card_rules()} @@ -2329,7 +2329,7 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(install.DEFAULT_DESTS["knulli"], Path("/userdata") / "bios") self.assertEqual(install.DEFAULT_DESTS["rocknix"], Path("/storage") / "roms/bios") - def test_p1_1_the_first_screen_offers_the_card_folder(self): + def test_the_first_screen_offers_the_card_folder(self): root = self.card(self.CARDS["muOS"][0]) with mock.patch.object(install, "_mounted_cards", return_value=[root]), \ mock.patch.object(install, "detect_platforms", return_value=[]), \ @@ -2344,16 +2344,16 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(press(state, "enter"), [("fetch", "retroarch")]) self.assertEqual(state.dest, root / "MUOS" / "bios") - def test_p1_1_a_drive_letter_names_the_card(self): + def test_drive_letter_names_the_card(self): self.assertEqual(install._mount_name(PureWindowsPath("E:\\")), "E:\\") self.assertEqual(install._mount_name(Path("/media/me/MUOS")), "MUOS") - # tui_audit_5 P3-2: under WSL the card screen listed "d (card or drive)". + # under WSL the card screen listed "d (card or drive)". with mock.patch.dict(install._WSL, {"active": True}): self.assertEqual(install._mount_name(Path("/mnt/d")), "D:") self.assertEqual(install._mount_name(Path("/mnt/wslg")), "wslg") self.assertEqual(install._mount_name(Path("/mnt/d")), "d") - def test_p1_1_on_the_device_its_card_is_not_offered_twice(self): + def test_on_the_device_its_card_is_not_offered_twice(self): root = self.card(self.CARDS["muOS"][0]) bound = Path("/run/muos/storage/bios") with mock.patch.object(install, "_mounted_cards", return_value=[root]), \ @@ -2364,7 +2364,7 @@ class AuditRoundThree(unittest.TestCase): state, _effects = install.tui_start(_args(), "linux") self.assertEqual([setup[1] for setup in state.setups], [bound]) - def test_p1_1_browsing_to_the_card_root_uses_its_folder(self): + def test_browsing_to_the_card_root_uses_its_folder(self): root = self.card(self.CARDS["KNULLI"][0]) with mock.patch.object(install, "_mounted_cards", return_value=[root]): rows, _error = install._browse_rows(REPO_ROOT / "tests") @@ -2376,7 +2376,7 @@ class AuditRoundThree(unittest.TestCase): install._choose(state, "batocera", root) self.assertEqual(state.dest, root) - def test_p1_1_the_command_line_writes_where_muos_reads(self): + def test_the_command_line_writes_where_muos_reads(self): root = self.card(self.CARDS["muOS"][0]) with FakeRepository() as repo: proc = install_run("--platform", "muos", "--dest", str(root), "--yes", @@ -2386,14 +2386,14 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(sorted(path.name for path in root.iterdir()), ["MUOS"]) self.assertTrue((root / "MUOS" / "bios" / "scph5501.bin").is_file()) - def test_p1_1_a_folder_that_is_no_muos_card_is_refused(self): + def test_folder_that_is_no_muos_card_is_refused(self): root = self.card({"roms/": ""}) proc = install_run("--platform", "muos", "--dest", str(root), "--yes") self.assertEqual(proc.returncode, 1) self.assertIn(f"{root} is not a muOS SD card: no muOS files on it. muOS keeps " "MUOS at the root of its card.", proc.stderr) # muOS always names its card: /MUOS/bios would be refused the - # same (code_audit_15 P3-4), the card's top folder is the remedy. + # same, the card's top folder is the remedy. self.assertIn("Name the top folder of the muOS card with --dest", proc.stderr) self.assertNotIn("/", proc.stderr) self.assertEqual(list(root.iterdir()), [root / "roms"]) @@ -2411,7 +2411,7 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(install.card_dest("retroarch", "retroarch", root), ("retroarch", root)) - def test_p1_1_the_folder_named_is_compared_by_folders(self): + def test_the_folder_named_is_compared_by_folders(self): """NOTMUOS/bios ended with MUOS/bios as text and was taken for a muOS card's folder.""" root = self.card({"roms/": ""}) @@ -2424,7 +2424,7 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(install.card_dest("muos", "retroarch", card / "muos" / "BIOS"), ("retroarch", card / "muos" / "BIOS")) - def test_p1_1_a_card_two_systems_claim_says_so(self): + def test_card_two_systems_claim_says_so(self): root = self.card({"MUOS/": "", "spruce/": ""}) self.assertIsNone(install.card_system(root)) with contextlib.redirect_stdout(io.StringIO()) as out: @@ -2439,9 +2439,9 @@ class AuditRoundThree(unittest.TestCase): ("retroarch", root / "MUOS/bios")) self.assertIn("muOS card", out.getvalue()) - # P1-2: Space is X on PortMaster and Y on muxterm. + # Space is X on PortMaster and Y on muxterm. - def test_p1_2_space_on_install_opens_the_confirm_screen(self): + def test_space_on_install_opens_the_confirm_screen(self): state = checked_state() self.assertEqual(install.tui_rows(state)[0].action, "install") self.assertEqual(press(state, " "), [("run", "confirm")]) @@ -2455,7 +2455,7 @@ class AuditRoundThree(unittest.TestCase): self.assertEqual(state.screen, "confirm") self.assertEqual(press(state, "enter"), [("run", "install")]) - def test_p1_2_space_never_closes_or_quits(self): + def test_space_never_closes_or_quits(self): for action in ("quit", "close"): with self.subTest(row=action): state = checked_state() @@ -2471,12 +2471,12 @@ class AuditRoundThree(unittest.TestCase): press(state, " ") self.assertEqual(state.screen, "options") - def test_p1_2_enter_still_installs_in_three_presses(self): + def test_enter_still_installs_in_three_presses(self): state = checked_state() self.assertEqual(press(state, "enter"), [("run", "install")]) self.assertEqual(state.screen, "installing") - # P2-1: a card too small for the download. + # a card too small for the download. def test_a_stop_asked_for_says_only_the_outcome(self): """Start+Select (SIGTERM) or SIGHUP stops the child before it writes @@ -2505,7 +2505,7 @@ class AuditRoundThree(unittest.TestCase): self.assertNotIn("to download", plan) self.assertEqual(lines[0], "3 files installed from the pack.") - def test_p2_1_another_folder_comes_first_when_space_is_short(self): + def test_another_folder_comes_first_when_space_is_short(self): state = checked_state({"free": 1024, "writable": True, "cores": []}) self.assertEqual([row.label for row in install.tui_rows(state)[:2]], ["Choose another folder", "Install anyway"]) @@ -2533,7 +2533,7 @@ class AuditRoundThree(unittest.TestCase): " python3 install.py --platform retroarch --dest ''", ] - def test_p2_1_a_full_card_is_said_in_words(self): + def test_full_card_is_said_in_words(self): root = self.card(self.CARDS["muOS"][0]) state = checked_state() state.dest, state.log = root / "MUOS" / "bios", "/tmp/retrobios-tui-x/install.log" @@ -2549,7 +2549,7 @@ class AuditRoundThree(unittest.TestCase): self.assertNotIn(raw, text) self.assertFalse(install.tui_keeps_log(state)) - def test_p2_1_advice_never_names_the_interface_list(self): + def test_advice_never_names_the_interface_list(self): if hasattr(os, "geteuid") and os.geteuid() == 0: self.skipTest("root writes to a read-only folder") folder = self.card({}) @@ -2563,9 +2563,9 @@ class AuditRoundThree(unittest.TestCase): self.assertIn("sudo", proc.stdout + proc.stderr) self.assertNotIn("--manifest", proc.stdout + proc.stderr) - # P2-2: the BIOS folder line on a handheld screen. + # the BIOS folder line on a handheld screen. - def test_p2_2_the_plan_keeps_the_folder_at_handheld_sizes(self): + def test_the_plan_keeps_the_folder_at_handheld_sizes(self): zipped = "/home/me/a/long/path/to/the/Downloads/PSX BIOS.zip" for cols, rows in ((40, 12), (40, 15)): with self.subTest(size=f"{cols}x{rows}"): @@ -2578,15 +2578,15 @@ class AuditRoundThree(unittest.TestCase): if line.startswith("BIOS folder: ")) # Whole, broken after a separator: cut in its middle at 40 # columns, it was spelled one way on the plan and another on - # the result (tui_audit_13 P3-3). + # the result. self.assertEqual(lines[at] + lines[at + 1], "BIOS folder: /home/someone/with/" "a/long/path/.config/retroarch/system") self.assertIn("1 found in PSX BIOS.zip,", " ".join(lines)) self.assertNotIn("/home/me/a/long", " ".join(lines)) - # P2-3: where the files came from. + # where the files came from. - def test_p2_3_the_result_says_what_came_from_the_card(self): + def test_the_result_says_what_came_from_the_card(self): state = checked_state() state.stack.append("result") state.code, state.download = 0, {"files": 5, "bytes": 10} @@ -2599,18 +2599,18 @@ class AuditRoundThree(unittest.TestCase): state.summary = {"installed": 4, "up_to_date": 0, "failed": [ {"dest": "fc/disksys.rom", "reason": "HTTP 404"}]} _title, lines = install.tui_outcome(state) - # One count, the failed file said as failed (tui_audit_16 P3-11). + # One count, the failed file said as failed. self.assertEqual(lines[0], "2 files copied from OLD, 1 copied from the wrong place " "in the BIOS folder, 1 downloaded, 1 failed.") # The line mode's own sentence, from the same counts. self.assertEqual(lines[0], install.sources_line([("OLD", 2)], 1, 1, 0, failed=1)) - def test_p2_3_a_run_that_copied_nothing_adds_no_line(self): + def test_run_that_copied_nothing_adds_no_line(self): state = install.TuiState() state.summary, state.finished = {"installed": 2, "failed": []}, [("a", True, "")] self.assertEqual(install._tui_sources(state, 2, 0), "") - # P2-4 and P2-5: the systems list. + # the systems list. def systems_state(self) -> install.TuiState: state = checked_state() @@ -2630,7 +2630,7 @@ class AuditRoundThree(unittest.TestCase): state.stack.append("systems") return state - def test_p2_4_the_other_row_is_named_and_explained(self): + def test_the_other_row_is_named_and_explained(self): state = self.systems_state() rows = install.tui_rows(state) other = next(i for i, row in enumerate(rows) if row.value == "other") @@ -2640,7 +2640,7 @@ class AuditRoundThree(unittest.TestCase): self.assertIn("Other systems and game engines: what cores load for systems this " "setup does not list", text) - def test_p2_5_shared_files_are_counted_apart(self): + def test_shared_files_are_counted_apart(self): state = self.systems_state() rows = install.tui_rows(state) three = next(i for i, row in enumerate(rows) if row.value == "3do") @@ -2656,7 +2656,7 @@ class AuditRoundThree(unittest.TestCase): narrow = install.tui_view(state, 40, 15) self.assertTrue(any("100 B + 2 shared" in line for line in narrow), narrow) - # P2-6: a file that cannot be supplied, by name, where it matters. + # a file that cannot be supplied, by name, where it matters. def unavailable_state(self) -> install.TuiState: state = checked_state() @@ -2671,14 +2671,14 @@ class AuditRoundThree(unittest.TestCase): state.summary = {"installed": 1, "up_to_date": 0, "failed": []} return state - def test_p2_6_the_missing_file_is_named_with_its_system(self): + def test_the_missing_file_is_named_with_its_system(self): state = self.unavailable_state() _title, lines = install.tui_outcome(state) self.assertIn("Not available here, and needed to start its emulator: gba_extra.bin " "(Game Boy Advance). Your own copy goes in the BIOS folder.", lines) self.assertNotIn("collection", " ".join(lines)) - def test_p2_6_it_is_left_out_when_it_does_not_concern_the_run(self): + def test_it_is_left_out_when_it_does_not_concern_the_run(self): state = self.unavailable_state() state.ticked = {"sony-playstation"} self.assertEqual(install._unavailable_lines(state), []) @@ -2686,7 +2686,7 @@ class AuditRoundThree(unittest.TestCase): state.summary = {"installed": 1, "failed": [], "interrupted": True} self.assertFalse(any("Not available" in line for line in install.tui_outcome(state)[1])) - # P3: small fixes the audit listed. + # small fixes the audit listed. def fetch_failure(self, error: BaseException, env: dict | None = None) -> tuple: inbox = __import__("queue").Queue() @@ -2699,7 +2699,7 @@ class AuditRoundThree(unittest.TestCase): _kind, _plat, title, lines, _code = inbox.get_nowait() return title, lines - def test_p3_the_clock_names_the_row_to_choose(self): + def test_the_clock_names_the_row_to_choose(self): import ssl error = urllib_error(ssl.SSLCertVerificationError("certificate is not yet valid")) @@ -2708,7 +2708,7 @@ class AuditRoundThree(unittest.TestCase): _title, lines = self.fetch_failure(error) self.assertTrue(lines[0].endswith("then choose Try again."), lines[0]) - def test_p3_a_proxy_in_the_way_is_named_not_shown(self): + def test_proxy_in_the_way_is_named_not_shown(self): error = urllib_error(ConnectionRefusedError(111, "Connection refused")) _title, lines = self.fetch_failure( error, {"HTTPS_PROXY": "http://me:secret@10.0.0.1:3128"}) @@ -2718,7 +2718,7 @@ class AuditRoundThree(unittest.TestCase): _title, lines = self.fetch_failure(error) self.assertFalse(any("PROXY" in line for line in lines)) - def test_p3_a_list_that_is_no_json_is_said_in_words(self): + def test_list_that_is_no_json_is_said_in_words(self): try: install.json.loads("") except install.json.JSONDecodeError as cause: @@ -2729,7 +2729,7 @@ class AuditRoundThree(unittest.TestCase): self.assertNotIn("Expecting value", " ".join(lines)) self.assertIn("a Wi-Fi sign-in page or a cut download looks like this.", lines[0]) - def test_p3_the_preview_counts_its_files_only(self): + def test_the_preview_counts_its_files_only(self): state = checked_state() state.stack += ["options", "preview"] state.dry = dict(CHECK) @@ -2738,7 +2738,7 @@ class AuditRoundThree(unittest.TestCase): lines = [line.strip() for line in install.tui_view(state, 80, 24)] self.assertIn("1-18 of 40", lines) - def test_p3_game_data_reads_without_a_double_negative(self): + def test_game_data_reads_without_a_double_negative(self): state = checked_state() label = next(row.label for row in install._option_rows(state) if row.action == "game_data") @@ -2748,7 +2748,7 @@ class AuditRoundThree(unittest.TestCase): if row.action == "game_data") self.assertEqual(label, "Game data: left out") - def test_p3_the_plan_says_which_config_named_the_folder(self): + def test_the_plan_says_which_config_named_the_folder(self): config = HOME / ".config/retroarch/retroarch.cfg" with mock.patch.dict(install._RETROARCH_CONFIGS, {SYSTEM_DIR: (config, config.parent)}): text = "\n".join(install.tui_view(checked_state(), 80, 24)) @@ -2958,12 +2958,12 @@ class AReadErrorIsNotAClosedWindow(unittest.TestCase): class AuditRoundFour(unittest.TestCase): - """tui_audit_3.md, each finding held where it was found.""" + """Files left out of the save directory are said.""" UNPLACED = {"reason": "no_save_directory", "label": "no save directory", "files": 2, "required": 0} - def test_p1_1_files_left_out_of_the_save_directory_are_said(self): + def test_files_left_out_of_the_save_directory_are_said(self): state = fresh_state() state.stack = ["setup"] with mock.patch.object(install.Path, "exists", return_value=True): @@ -3004,7 +3004,7 @@ class TheSaveFolderHasARow(unittest.TestCase): state = self.state() rows = install._option_rows(state) [row] = [row for row in rows if row.action == "savedir"] - # Named as line mode names it, from the same rules (tui_audit_12 P3-15). + # Named as line mode names it, from the same rules. place = install.save_directory_for(state.dest, state.manifest, None) self.assertEqual((row.label, row.right), (f"Save folder: {install._short_path(place.directory, HOME)}", @@ -3102,7 +3102,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): return mock.patch.object(install, "_ask", side_effect=answer), asked def test_a_typed_root_that_does_not_exist_is_asked_again(self): - """code_audit_12 P2-3: a typo four folders deep was created and + """A typo four folders deep was created and filled, and a menu answer (8) became the card.""" onion = self.card(self.ONION) typo = REPO_ROOT / "tmp" / "no-such" / "media" / "NEXT" @@ -3120,7 +3120,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertFalse((REPO_ROOT / "tmp" / "no-such").exists()) def test_a_typed_root_that_is_no_card_of_that_system_is_asked_again(self): - """code_audit_12 P3-4: a folder that was no Onion card ended the run.""" + """A folder that was no Onion card ended the run.""" blank, onion = self.card({"roms/a": ""}), self.card(self.ONION) patcher, asked = self.ask(str(blank), str(onion)) with mock.patch.object(install, "_mounted_cards", return_value=[]), patcher, \ @@ -3143,8 +3143,8 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): ".system/version.txt at the root of its card.", out.getvalue()) def test_the_mounted_drives_are_listed_and_taken_by_number(self): - """tui_audit_5 P3-8.4: the screen lists the mounted cards, the - prompt did not. tui_audit_6 P3-8, code_audit_13 P3-6: it listed + """The screen lists the mounted cards, the + prompt did not: it listed every drive, a muOS card beside Onion's question, and the muOS card taken by number made the run a muOS install.""" muos, blank = self.card({"MUOS/bios/x": ""}), self.card({"roms/a": ""}) @@ -3159,14 +3159,14 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertIn(f"1) {first.name} (KNULLI card, {first})", out.getvalue()) self.assertIn(f"2) {second.name} (KNULLI card, {second})", out.getvalue()) self.assertNotIn(str(muos), out.getvalue()) - # tui_audit_10 P3-8: KNULLI fills its card when it first starts, and + # KNULLI fills its card when it first starts, and # a blank drive is listed after its own cards, as on the screen. self.assertIn(f"3) {blank.name} (card or drive, {blank})", out.getvalue()) self.assertIn("Type a number from 1 to 3, a folder, Enter to look again, or q to " "quit.", out.getvalue()) def test_creating_several_folders_on_the_card_is_asked(self): - """tui_audit_6 P3-8: N to the question ended the whole run where it + """N to the question ended the whole run where it meant "not that card".""" root = self.card({"roms/a.txt": ""}) rocknix = root / "R" @@ -3184,7 +3184,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertFalse((rocknix / "roms").exists()) def test_the_menu_asks_a_card_system_for_its_card(self): - """code_audit_12 P3-3: ROCKNIX picked from the menu on a PC was + """ROCKNIX picked from the menu on a PC was offered /storage/roms/bios.""" card = self.card({"roms/a": ""}) make_card(card, "ROCKNIX") @@ -3197,7 +3197,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertEqual(asked, ["Card root, Enter to look again, q to quit: "]) def test_a_card_of_another_system_is_not_offered(self): - """tui_audit_5 P1-1: A on the first mount wrote Onion's BIOS/ on a + """A on the first mount wrote Onion's BIOS/ on a muOS card, which reads MUOS/bios.""" muos, blank = self.card({"MUOS/bios/x": ""}), self.card({"roms/a": ""}) found = [("retroarch", SYSTEM_DIR)] @@ -3229,7 +3229,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): [("card", first), ("card", second)]) self.assertNotIn("rescan", [row.action for row in rows]) self.assertEqual(state.dest, first / "BIOS") - # Titled as the card found by itself (tui_audit_5 P3-7). + # Titled as the card found by itself. self.assertEqual(install.detected_os("retroarch", first / "BIOS"), "Onion") def test_look_again_finds_the_card_inserted(self): @@ -3262,11 +3262,11 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertIn("Not an Onion SD card: no Onion files on it.", state.status) self.assertIn(f"{blank} is not an Onion SD card", state.status_more) self.assertIsNone(state.dest) - # tui_audit_6 P3-8: a muOS card made the run a muOS install + # a muOS card made the run a muOS install # without a word. install._browse_to(state, muos) press(state, "enter") - # tui_audit_7 P3-1: it is a card's top folder, of another card. + # it is a card's top folder, of another card. self.assertEqual(state.status, "That is a muOS card. Insert the Onion card, or " "go back and choose muOS.") self.assertIsNone(state.dest) @@ -3295,7 +3295,7 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): self.assertIn("Not an Onion SD card", state.status) def test_change_folder_names_the_folder_it_reuses(self): - """code_audit_12 P3-1: Use this folder on the card screen named + """Use this folder on the card screen named nothing.""" onion = self.card(self.ONION) state = checked_state() @@ -3337,12 +3337,12 @@ class ACardSystemNamedOnAComputer(unittest.TestCase): class TheSetupFilterKnowsDevices(unittest.TestCase): - """tui_audit_4 P3-10.5: the filter found nothing for steam deck, r36s, + """The filter found nothing for steam deck, r36s, trimui or retroid, and miyoo found RetroArch with muOS, JELOS... beside it.""" TYPED = { "steam deck": {"retroarch", "batocera", "emudeck", "retrodeck"}, - # MinUI and MyMinUI list their devices (code_audit_15 P2-1), and on + # MinUI and MyMinUI list their devices, and on # a computer an Android device is no RetroArch of this machine's. "r36s": {"retroarch", "rocknix", "myminui"}, "rg35xx": {"retroarch", "rocknix", "knulli", "minui", "myminui"}, @@ -3372,7 +3372,7 @@ class TheSetupFilterKnowsDevices(unittest.TestCase): def test_the_right_column_names_what_matched(self): rows = self.rows("miyoo") - # tui_audit_6 P1-1, code_audit_13 P2-3: MiyooCFW stayed on the + # MiyooCFW stayed on the # RetroArch row, which opened this computer's folder. self.assertNotIn("retroarch", [row.value for row in rows if row.action == "platform"]) self.assertEqual([row.label for row in rows if row.action == "cardsystem"], @@ -3404,7 +3404,7 @@ class TheSetupFilterKnowsDevices(unittest.TestCase): class ACardSetupIsOneDesign(unittest.TestCase): - """code_audit_12 P2-1 to P3-2, tui_audit_5 P1-2: a setup that runs from + """A setup that runs from its SD card, chosen on a computer, always asks for that card.""" def platforms(self, needle: str = "") -> install.TuiState: @@ -3475,7 +3475,7 @@ class ACardSetupIsOneDesign(unittest.TestCase): class OneSystemInFewPresses(unittest.TestCase): - """tui_audit_4 P3-10.11: one system with a controller took 15 presses on + """One system with a controller took 15 presses on the fixture list, about 60 on muxterm, which has no page key.""" # The buttons each route sends, as the keys the interface reads. @@ -3513,7 +3513,7 @@ class OneSystemInFewPresses(unittest.TestCase): if target in (row.value, row.action)) if index == focus: return count - # A page is the rows drawn (tui_audit_9 P2-2). + # A page is the rows drawn. page = install._page_step(state) if index > focus: button = "R1" if paging and index - focus >= page else "down" @@ -3531,7 +3531,7 @@ class OneSystemInFewPresses(unittest.TestCase): self.press_button(state, pad, button) count += 1 self.assertEqual(state.screen, "systems") - # On its first system (tui_audit_17 P3-1), None at the list's end. + # On its first system, None at the list's end. self.assertEqual(install.tui_rows(state)[state.focus["systems"]].action, "system") paging = pad != "muxterm" or fast # Up from the first item wraps to the list's end: Done, then None. @@ -3555,9 +3555,9 @@ class OneSystemInFewPresses(unittest.TestCase): # The audit's path, A Down A Up Up A R1 x5 X Start A A. Before the # fast path it took 17 presses here, 57 on muxterm (None kept the # focus, and muxterm had no page key). - # A page is the rows drawn since tui_audit_9 P2-2, ten here where it + # A page is the rows drawn, ten here where it # was nine: sys-45 is four pages and five Downs away, not five pages. - # None now at the list's end (tui_audit_17 P3-1), three presses up + # None now at the list's end, three presses up # from the first system: the list wraps. fast pages down to sys-45. self.assertEqual(self.presses("gptokeyb", fast=True), 21) self.assertEqual(self.presses("muxterm", fast=False), 57) @@ -3578,8 +3578,8 @@ class OneSystemInFewPresses(unittest.TestCase): state = self.long_list("keys") state.stack.append("systems") state.focus["systems"] = 5 - # tui_audit_6 P2-1: nothing runs from the list. A unticks the system - # in focus (tui_audit_17 P3-1), B goes back to the plan. + # nothing runs from the list. A unticks the system + # in focus, B goes back to the plan. self.assertEqual(press(state, "enter"), []) self.assertEqual((state.screen, len(state.ticked)), ("systems", 65)) press(state, "esc") @@ -3608,7 +3608,7 @@ class OneSystemInFewPresses(unittest.TestCase): class DataFilesHaveASize(unittest.TestCase): - """tui_audit_4 P3-10.8: "8179 files to download, 6.6 GB, and 2636 data + """"8179 files to download, 6.6 GB, and 2636 data files", the data files with no size.""" def test_the_plan_gives_the_data_files_size(self): @@ -3630,7 +3630,7 @@ class DataFilesHaveASize(unittest.TestCase): class ThePagerCountsLines(unittest.TestCase): - """tui_audit_4 P3-9.4: at 40x12 the result read "1-2 of 5" over eight + """At 40x12 the result read "1-2 of 5" over eight lines, counting paragraphs, and its last paragraph was cut.""" def result_state(self, cols: int, rows: int) -> install.TuiState: @@ -3680,7 +3680,7 @@ class OfflineInTheInterface(unittest.TestCase): self.addCleanup(patcher.stop) def test_the_variable_is_named_when_it_made_the_run_offline(self): - """tui_audit_11 P3-12: "(--offline)" and "without --offline" with + """"(--offline)" and "without --offline" with RETROBIOS_INSTALL_OFFLINE=1 and no --offline: nothing to remove.""" with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}): inbox = queue.Queue() @@ -3731,7 +3731,7 @@ class OfflineInTheInterface(unittest.TestCase): class AuditFive(unittest.TestCase): - """tui_audit_5 P2-1, P2-2 and its P3 points.""" + """Going back keeps the ticks, and the save folder is said once.""" def long_list(self) -> install.TuiState: state = OneSystemInFewPresses().long_list("keys") @@ -3742,7 +3742,7 @@ class AuditFive(unittest.TestCase): state = self.long_list() everything = set(state.ticked) press(state, "down", "enter") - # The list opens on its first system, None at its end (tui_audit_17 P3-1). + # The list opens on its first system, None at its end. self.assertEqual(install.tui_rows(state)[state.focus["systems"]].action, "system") press(state, "n") self.assertEqual(state.ticked, set()) @@ -3791,7 +3791,7 @@ class AuditFive(unittest.TestCase): "reason": "misplaced"}] with mock.patch.object(install.LOCAL, "pack", mock.Mock()): text = " ".join(" ".join(install.tui_view(state, 120, 40)).split()) - # tui_audit_6 P3-3: one count, "4 files to install" above "3 from + # one count, "4 files to install" above "3 from # the pack", where "3 to install from the pack" sat over "4". self.assertIn("4 files to install, 1.0 MB", text) self.assertIn("3 from the pack, 1 copied from this machine", text) @@ -3813,7 +3813,7 @@ class AuditFive(unittest.TestCase): saves = {"files": 1, "folder": str(HOME / ".config" / "retroarch" / "saves" / "")} lines = install._saves_lines(state, saves) # In words: "saves/" read as a folder named . - # The folder at the BIOS folder's indent (tui_audit_14 P3-9). + # The folder at the BIOS folder's indent. self.assertEqual(lines, ["1 file read from RetroArch's save directory goes to a " "folder per core under:", " ~/.config/retroarch/saves"]) @@ -3845,9 +3845,9 @@ class AuditFive(unittest.TestCase): state.ticked = set() state.focus["systems"] = install._first_item(state) bar = install.tui_view(state, 40, 15)[-1] - # A is Space on a Miyoo, and ticks as Start does (tui_audit_17 P3-1). + # A is Space on a Miyoo, and ticks as Start does. self.assertTrue(bar.strip().startswith("A Tick")) - # tui_audit_6 P3-9.1: the way out was the entry given up at 40 columns. + # the way out was the entry given up at 40 columns. self.assertIn("R2 Done", bar) def test_muxterm_help_names_no_home_key(self): @@ -3861,7 +3861,7 @@ class AuditFive(unittest.TestCase): class LineModeOffline(unittest.TestCase): - """tui_audit_5 P2-3 and P3-8.4: the line mode under --offline asked to + """The line mode under --offline asked to download, and said nothing of the data files.""" @unittest.skipUnless(pyte and pty and hasattr(pty, "fork"), @@ -3878,13 +3878,13 @@ class LineModeOffline(unittest.TestCase): out = install.unpainted(term.raw.decode("utf-8", "replace")) self.assertIn("--offline: only the files found on this machine are installed, and no " "--from names a folder to copy them from.", out) - # tui_audit_7 P3-4: nothing to copy from, nothing to install. + # nothing to copy from, nothing to install. self.assertIn("Enter) check the BIOS folder, nothing can be downloaded", out) self.assertIn("f) copy from a folder or an old card", out) self.assertIn("5 files need the internet, which --offline does not use.", out) self.assertNotIn("Downloading", out) self.assertNotIn("failed", out.lower()) - # tui_audit_6 P2-3, code_audit_13 P1-1: nothing installed ended on + # nothing installed ended on # exit 0, where the screen's run gives 2. self.assertIn("Nothing installed: 5 files need the internet, which --offline does " "not use.", out.replace("\r\n", " ").replace("\n", " ")) @@ -3897,7 +3897,7 @@ class LineModeOffline(unittest.TestCase): with mock.patch.object(install, "_ask", return_value=""), \ contextlib.redirect_stdout(io.StringIO()) as out: install._prompt_custom_selection("retroarch", files, [], data_trees=trees) - # One total, the kinds under it adding up to it (code_audit_21 P3-8). + # One total, the kinds under it adding up to it. self.assertIn("RetroArch: 3 files, 5.0 KB.\n 1 BIOS file (1.0 KB) and 2 data files " "(4.0 KB).", out.getvalue()) @@ -3934,7 +3934,7 @@ class NarrowSystemNames(unittest.TestCase): for cols, rows in ((40, 15), (40, 12), (52, 15)): with self.subTest(size=f"{cols}x{rows}"): text = "\n".join(install.tui_view(state, cols, rows)) - # tui_audit_10 P3-14: the size stays as the total counts it, + # the size stays as the total counts it, # 30.0 MB, and a name too long beside it is cut where the # three still read apart. lines = [line for line in text.splitlines() if "[x]" in line] @@ -4039,7 +4039,7 @@ class TheSaveFolderLineFollowsTheChoice(unittest.TestCase): "folder": "/home/user/MySaves/"} LINE = ("1 file read from RetroArch's save directory goes to a folder per core under: " "~/MySaves") - # The result spells every folder in full (tui_audit_12 P3-7). + # The result spells every folder in full. RESULT = ("1 file read from RetroArch's save directory goes to a folder per core under: " "/home/user/MySaves") @@ -4225,7 +4225,7 @@ class AGoesIntoASubfolder(unittest.TestCase): self.assertEqual(self.state.status, "") def test_with_no_visible_subfolder_a_folder_below_takes_the_focus(self): - """tui_audit_10 P2-5: the focus stayed on Use this folder under the + """The focus stayed on Use this folder under the sentence that warns against it, and A, A, A installed BizHawk into the home folder.""" (self.home / ".cache").mkdir() @@ -4871,7 +4871,7 @@ class EndToEnd(unittest.TestCase): term.send(DOWN, "\r") term.wait("Choose systems") # D-pad and A only: the list opens on its first system, A unticks - # it, B goes back to the plan (tui_audit_17 P3-1). + # it, B goes back to the plan. term.send("\r") screen = term.wait("1 of 2 systems") self.assertIn("> [ ] nintendo-gba", screen) @@ -5180,8 +5180,7 @@ class EndToEnd(unittest.TestCase): term.wait("Enter for RetroArch") term.send("\r") if value is None: - # In place since the first run: no menu, nothing asked - # (tui_audit_16 P3-4). + # In place since the first run: no menu, nothing asked. term.wait("every one in place: nothing to install") else: term.wait("Enter) install everything") @@ -5545,7 +5544,7 @@ class TheTerminalComesBack(unittest.TestCase): self.assertGivenBack(term) def test_ctrl_z_with_no_shell_to_resume_it_is_ignored(self): - """code_audit_18 P3-1: started straight on a terminal (a terminal + """Started straight on a terminal (a terminal app's -e, a desktop entry) or under a launcher's sh -c, nothing ever resumed the screen a Ctrl-Z stopped. It now goes on, and says why.""" self.repo() @@ -5599,14 +5598,14 @@ class TheTerminalComesBack(unittest.TestCase): @unittest.skipUnless(Path("/proc/self/stat").exists(), "reads process states in /proc") def test_ctrl_z_through_install_sh_stops_the_wrapper_and_the_install(self): - """code_audit_17 P2-1: Ctrl-Z stopped the installer alone. install.sh, + """Ctrl-Z stopped the installer alone. install.sh, which runs it as a child, kept waiting, the shell never got its prompt back, and the install run behind the screen kept writing.""" repo = self.repo(GameDataRepository, slow=True) env = {**self.env, "PS1": "PROMPT$ ", "PATH": f"{Path(sys.executable).parent}{os.pathsep}{self.env['PATH']}"} # Typed at an interactive bash, as a person runs it: install.sh is a - # job of a shell that can resume it (code_audit_18 P3-1). + # job of a shell that can resume it. term = Pty(["--norc", "--noprofile", "-i"], env, program=["/bin/bash"]) self.addCleanup(lambda: term.status is None and os.killpg(term.pid, 9)) term.wait("PROMPT$") @@ -5720,8 +5719,7 @@ class ThePlanNumbersAddUp(unittest.TestCase): state.found = [found("scph5500.bin", str(SYSTEM_DIR), "one folder too deep")] screen = " ".join(" ".join(install.tui_view(state, 120, 40)).split()) self.assertIn("3 files to download", screen) - # The backup line under the count it explains, then the split - # (tui_audit_8 P3-5). + # The backup line under the count it explains, then the split. self.assertIn("1 in place, 3 missing, 1 wrong copy The 1 wrong copy is replaced, the " "old one kept in a backup folder. 4 to install: 1 copied from this " "machine, 3 downloaded", screen) @@ -5745,7 +5743,7 @@ class GameDataIsNoFirmwareAlarm(unittest.TestCase): # The folder it goes in, and what game data is (the Android run of # 2026-10-27 said neither). # The names first, the kind in a word, the definition on its own - # line of the plan (tui_audit_13 P3-5). + # line of the plan. self.assertIn("Not available here: jazz2/Source/Anims.j2a (Jazz Jackrabbit 2), game " "data its game reads. Copy it", lines[1]) self.assertNotIn("files a game or a game engine reads", lines[1]) @@ -5894,7 +5892,7 @@ def _setup_folder(setup: install.CardSetup, card: Path) -> Path: class EveryCardSetupGoesToItsCard(unittest.TestCase): - """code_audit_13 P2-3, tui_audit_6 P1-1: the card setups were fixed one + """The card setups were fixed one by one, and UnofficialOS, ArchR, ArkOS, MiyooCFW and the Anbernic firmware stayed on the RetroArch row, which listed them and opened this computer's folder. Each system that runs from its SD card, from every @@ -6015,7 +6013,7 @@ class EveryCardSetupGoesToItsCard(unittest.TestCase): for index, setup in enumerate(self.setups): with self.subTest(system=setup.name): card = _card_from_rules(self.root / f"card{index}", setup) - # code_audit_14 P2-1: a card no file names gets its folder + # a card no file names gets its folder # below the root with --dest too, as typed. want = _setup_folder(setup, card) with contextlib.redirect_stdout(io.StringIO()): @@ -6028,7 +6026,7 @@ class EveryCardSetupGoesToItsCard(unittest.TestCase): _args(platform=setup.name, dest=str(card)), "linux") self.assertEqual(state.dest, want) # --dest alone, then the setup's row: the folder of the - # same --dest (code_audit_13 P2-2). + # same --dest. state, _effects = install.tui_start(_args(dest=str(card)), "linux") if state.screen == "platforms": rows = install.tui_rows(state) @@ -6043,7 +6041,7 @@ class EveryCardSetupGoesToItsCard(unittest.TestCase): ("", _setup_folder(setup, card))) def test_another_systems_card_is_refused_for_each(self): - """code_audit_13 P2-1, tui_audit_6 P2-5: KNULLI and ROCKNIX took a + """KNULLI and ROCKNIX took a muOS or an Onion card, and wrote their layout into it.""" cards = {} for name in ("muOS", "Onion", "MinUI"): @@ -6080,7 +6078,7 @@ class EveryCardSetupGoesToItsCard(unittest.TestCase): class AuditSix(unittest.TestCase): - """tui_audit_6 and code_audit_13: what remains of each finding.""" + """Confirm before an install, refusals said in full, and card rows.""" def setUp(self): self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) @@ -6092,13 +6090,13 @@ class AuditSix(unittest.TestCase): return card def test_continue_never_installs_without_confirm(self): - """P2-1: A on a system, the ticks unchanged, installed at once, + """A on a system, the ticks unchanged, installed at once, offline too where the plan had no Install.""" state = checked_state() press(state, "down", "enter") self.assertEqual(state.screen, "systems") # A ticks there, and Done goes back to the plan: nothing runs from - # the list (tui_audit_17 P3-1). + # the list. self.assertEqual(install._primary(state), "A/Enter Tick") self.assertEqual(press(state, "enter"), []) self.assertEqual(state.screen, "systems") @@ -6112,7 +6110,7 @@ class AuditSix(unittest.TestCase): state.focus["plan"] = [row.action for row in install.tui_rows(state)].index( "systems") press(state, "enter") - # A ticks: the list runs nothing (tui_audit_17 P3-1). The way to + # A ticks: the list runs nothing. The way to # Confirm is Space on the plan's Install. self.assertEqual(press(state, "enter", "esc"), []) state.focus["plan"] = 0 @@ -6127,7 +6125,7 @@ class AuditSix(unittest.TestCase): view = install.tui_view(state, 40, 12) text = " ".join(" ".join(view).split()) self.assertEqual(state.screen, "confirm") - # code_audit_13 P3-3: Back alone, no word of an Install. + # Back alone, no word of an Install. self.assertNotIn("before Install", text) self.assertNotIn("backup folder", text) self.assertIn("Copy them from your old card", text) @@ -6135,7 +6133,7 @@ class AuditSix(unittest.TestCase): self.assertEqual(view[-1].strip(), "A Back ? Help") def test_a_refusal_shows_at_40x12_on_type_a_path(self): - """P2-2: Enter seemed to do nothing, the refusal drawn below the + """Enter seemed to do nothing, the refusal drawn below the last line.""" blank = self.root / "USBSTICK" blank.mkdir() @@ -6148,10 +6146,10 @@ class AuditSix(unittest.TestCase): text = " ".join(" ".join(install.tui_view(state, 40, 12)).split()) self.assertIn("Not an Onion SD card: no Onion files on it.", text) self.assertNotIn("Ctrl-U clears", text) - # P3-1: no hidden folder named in the short form, the detail after. + # no hidden folder named in the short form, the detail after. self.assertNotIn(".tmp_update", state.status) self.assertIn(".tmp_update", state.status_more) - # code_audit_13 P3-5: the prompt asks for the card. + # the prompt asks for the card. self.assertIn("The top folder of the Onion SD card:", text) def test_the_help_says_the_refusal_in_full(self): @@ -6168,7 +6166,7 @@ class AuditSix(unittest.TestCase): ".tmp_update at the root of its card.", text) def test_wsl_drive_letters_are_taken_as_typed(self): - """P2-4: the screen says D:, and D: typed was refused.""" + """The screen says D:, and D: typed was refused.""" with mock.patch.dict(install._WSL, {"active": True}): for typed in ("D:", "D:\\", "d:\\", "\"D:\\\""): with self.subTest(typed=typed): @@ -6184,7 +6182,7 @@ class AuditSix(unittest.TestCase): self.assertEqual(install._typed_folder("D:"), Path("D:")) def test_a_dest_refused_on_the_setup_list_names_dest(self): - """code_audit_13 P3-2: "Choose the root of the Onion card", where + """"Choose the root of the Onion card", where --dest fixes the folder, and the refused system stayed chosen.""" blank = self.root / "USBSTICK" blank.mkdir() @@ -6198,13 +6196,13 @@ class AuditSix(unittest.TestCase): self.assertEqual(press(state, "enter"), []) self.assertEqual(state.screen, "platforms") # --dest is fixed: a stick that is no card is named again in the - # command, another setup would not help (code_audit_15 P3-3). + # command, another setup would not help. self.assertIn("Run it again with the card's top folder.", state.status) self.assertNotIn("choose another setup", state.status) self.assertEqual((state.platform, state.card_bound), ("", None)) def test_on_the_device_a_folder_typed_is_taken_as_typed(self): - """code_audit_13 P3-1: a KNULLI got bios added to what was typed.""" + """A KNULLI got bios added to what was typed.""" share = self.root / "userdata" / "share" share.mkdir(parents=True) state = fresh_state() @@ -6220,7 +6218,7 @@ class AuditSix(unittest.TestCase): self.assertEqual(state.dest, share) def test_a_card_in_a_reader_asks_for_its_card_once(self): - """code_audit_13 P3-9, tui_audit_6 P3-7: "Which folder? Onion reads + """"Which folder? Onion reads its BIOS files from" on a computer, the same card listed twice.""" first, second = self.onion("D"), self.onion("E") with mock.patch.object(install, "_mounted_cards", return_value=[first, second]), \ @@ -6249,7 +6247,7 @@ class AuditSix(unittest.TestCase): self.assertEqual(state.folder_default, SYSTEM_DIR) def test_browsing_for_a_card_starts_on_the_drives(self): - """tui_audit_6 P3-2: the browser opened on the home folder, Use this + """The browser opened on the home folder, Use this folder focused, saying to go back, the cards listed under it.""" card = self.onion() state = fresh_state() @@ -6266,7 +6264,7 @@ class AuditSix(unittest.TestCase): self.assertEqual(state.status, "Choose the Onion card below.") def test_a_number_outside_the_list_is_said(self): - """tui_audit_6 P3-1: 9 was read as a folder.""" + """9 was read as a folder.""" card, other = self.onion(), self.onion("SECOND") answers = iter(["9", "0", "2"]) with mock.patch.object(install, "_mounted_cards", return_value=[card, other]), \ @@ -6283,7 +6281,7 @@ class AuditSix(unittest.TestCase): ["an Onion", "an Allium", "an ArkOS", "a muOS", "a KNULLI"]) def test_every_card_row_reads_the_same(self): - """tui_audit_6 P3-6: KNULLI, ROCKNIX and the MinUI family asked for + """KNULLI, ROCKNIX and the MinUI family asked for their card without saying so.""" state = fresh_state() state.stack = ["setup", "platforms"] @@ -6301,8 +6299,8 @@ class AuditSix(unittest.TestCase): self.assertEqual(labels["knulli"], "KNULLI") def test_offline_plan_counts_agree(self): - """code_audit_13 P3-4: "3 downloaded" under "3 need the internet"; - tui_audit_6 P3-9.2: the data files read as if on hand.""" + """"3 downloaded" under "3 need the internet"; + the data files read as if on hand.""" state = checked_state() state.found = [{"event": "found", "platform": "retroarch", "dest": FILES[0]["dest"], "folder": "/media/old", "path": "/media/old/x", "member": "", @@ -6313,13 +6311,13 @@ class AuditSix(unittest.TestCase): state.found = [] state.check = dict(state.check, data_missing=2636, data_bytes=40 * 1024 * 1024) text = " ".join(" ".join(install.tui_view(state, 120, 40)).split()) - # One count of files, the kinds apart under the folder (tui_audit_13 - # P3-6): "4 files and 2636 data files" read as two kinds of one. + # One count of files, the kinds apart under the folder: "4 files and + # 2636 data files" read as two kinds of one. self.assertIn("2640 files need the internet, which --offline does not use", text) self.assertIn("2636 data files (40.0 MB).", text) def test_the_error_row_and_the_bar_agree(self): - """tui_audit_6 P3-9.3: "Choose another setup or folder" over + """"Choose another setup or folder" over "A/Enter Back".""" state = checked_state() state.run = "check" @@ -6331,8 +6329,8 @@ class AuditSix(unittest.TestCase): self.assertNotEqual(state.screen, "error") def test_a_long_name_keeps_a_size_at_40_columns(self): - """tui_audit_6 P3-5: Nintendo Game Boy Advance lost its size. - tui_audit_10 P3-14: and kept it rounded, 3 KB beside a total of + """Nintendo Game Boy Advance lost its size. + It also kept it rounded, 3 KB beside a total of 2.7 KB. The size stays whole, the name is cut.""" row = install.TuiRow("system", "[x] Nintendo Game Boy Advance", "1 file, 16.0 KB", "nintendo-gba", narrow=("16.0 KB",), keep_right=True) @@ -6341,7 +6339,7 @@ class AuditSix(unittest.TestCase): self.assertRegex(line, r"Nintendo Game Boy A?d?\.\.\.") def test_the_shared_note_keeps_its_line(self): - """tui_audit_6 P3-5: the page held 4, 3 and 5 systems as the note + """The page held 4, 3 and 5 systems as the note came and went, and "+19" read as 19 more.""" state = OneSystemInFewPresses().long_list("keys") state.files = [{"event": "file", "dest": "mame.zip", "size": 10, @@ -6360,7 +6358,7 @@ class AuditSix(unittest.TestCase): class AuditSevenOneCardReading(unittest.TestCase): - """code_audit_14 P2-1 to P3-12 and tui_audit_7 P2-5, P3-1: one reading + """One reading of a card's root, said the same on the screen and in line mode.""" def setUp(self): @@ -6383,7 +6381,7 @@ class AuditSevenOneCardReading(unittest.TestCase): return state def test_a_blank_card_gets_one_folder_and_one_note_everywhere(self): - """code_audit_14 P2-1, tui_audit_7 P2-5: --dest kept the stick's + """--dest kept the stick's root, typed it got bios below it, and the screen said nothing.""" stick = self.blank() for named, plat, below in (("knulli", "knulli", "bios"), @@ -6399,7 +6397,7 @@ class AuditSevenOneCardReading(unittest.TestCase): state = self.start(platform=named, dest=str(stick)) self.assertEqual(state.dest, stick / below) self.assertEqual(state.card_note, note) - # tui_audit_10 P3-8: one rule with line mode, whose question + # one rule with line mode, whose question # creates one missing level and says it. Two are asked, and # the note is kept on Create the folder? and on the plan. one = (stick / below).parent.is_dir() @@ -6411,7 +6409,7 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertEqual(state.card_note, note) def test_the_minui_family_refuses_a_blank_dest(self): - """code_audit_14 P2-2: taken with --dest, refused typed.""" + """Taken with --dest, refused typed.""" stick = self.blank() for plat in ("minui", "nextui", "myminui"): with self.subTest(platform=plat): @@ -6422,7 +6420,7 @@ class AuditSevenOneCardReading(unittest.TestCase): install.card_dest(plat, plat, stick) def test_a_card_mounted_as_its_bios_folder_is_the_card(self): - """code_audit_14 P3-7: an Onion card mounted as BIOS was refused, + """An Onion card mounted as BIOS was refused, ROCKNIX's roms/bios was taken for KNULLI, a muOS card's folder too.""" onion = self.root / "BIOS" @@ -6459,7 +6457,7 @@ class AuditSevenOneCardReading(unittest.TestCase): install.card_setup("knulli", "knulli"), bios), (bios, False)) def test_a_refused_dest_says_why_in_the_events(self): - """code_audit_14 P3-8: code 1 and no reason in the stream.""" + """Code 1 and no reason in the stream.""" stick = self.blank() proc = install_run("--events", "--platform", "onion", "--dest", str(stick), "--manifest", str(REPO_ROOT / "install" / "retroarch.json"), @@ -6474,13 +6472,13 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertIn("not the card of the system named", table) def test_a_card_no_file_names_is_titled_by_its_system(self): - """code_audit_14 P3-9: an ArkOS card chosen read as RetroArch.""" + """An ArkOS card chosen read as RetroArch.""" stick = self.blank() state = self.start(platform="ArkOS", dest=str(stick)) self.assertEqual(install.detected_os("retroarch", state.dest), "ArkOS") def test_a_list_named_for_another_systems_card_says_so(self): - """code_audit_14 P3-10: --platform batocera on an Onion card.""" + """--platform batocera on an Onion card.""" onion = self.root / "ONION" make_card(onion, "Onion") choice = install.card_choice("batocera", "batocera", onion) @@ -6491,7 +6489,7 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertEqual(state.card_note, choice.note) def test_amberelec_and_emuelec_are_asked_for_their_card(self): - """code_audit_14 P3-11: "Use this folder" on /storage/roms of a PC.""" + """"Use this folder" on /storage/roms of a PC.""" for plat, name in (("amberelec", "AmberELEC"), ("emuelec", "EmuELEC")): with self.subTest(system=name): setup = install.card_setup(plat, plat) @@ -6506,12 +6504,12 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertEqual(choice.folder, stick) # Its card is told by what it writes at every boot: a stick # holding none of it is one not started yet, never "cannot - # tell" (tui_audit_16 P2-1). + # tell". self.assertIn(f"says it is {install._a(name)} card yet", choice.note) self.assertNotIn("cannot tell", choice.note) def test_install_py_has_two_blank_lines_around_each_definition(self): - """code_audit_14 P3-12: E305 after _card_mount, and the same slip + """E305 after _card_mount, and the same slip before _Interrupted, TuiRow and _setup_label (pycodestyle E302, E303, E305 at top level).""" import ast @@ -6545,7 +6543,7 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertEqual(count, 2) def test_a_refusal_is_said_once_and_another_card_names_its_remedy(self): - """tui_audit_7 P3-1: said twice, and "Choose the card's top folder" + """Said twice, and "Choose the card's top folder" for the top folder of another card.""" stick = self.blank() state = self.start(platform="onion") @@ -6572,7 +6570,7 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertIn("Insert the Onion card, or choose muOS for that one.", out.getvalue()) def test_line_mode_names_the_card_picked_and_its_folder(self): - """tui_audit_7 P2-3, P3-5: no echo of the card picked, "Mount the + """No echo of the card picked, "Mount the card" under two mounted, /mnt/d where the list says D:.""" cards = [self.root / "ONION", self.root / "ONION2"] for card in cards: @@ -6601,7 +6599,6 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertNotIn("gets the RetroArch file list", proc.stdout) def test_wsl_names_the_folder_by_its_drive_letter(self): - """tui_audit_7 P3-6, code_audit_14 P3-5.""" with mock.patch.dict(install._WSL, {"active": True, "root": "/mnt"}): self.assertEqual(install._short_path(Path("/mnt/d/BIOS"), HOME), "D:\\BIOS") self.assertEqual(install.shown_path(Path("/mnt/d")), "D:\\") @@ -6616,7 +6613,6 @@ class AuditSevenOneCardReading(unittest.TestCase): self.assertEqual(install._short_path(Path("/mnt/d/BIOS"), HOME), "/mnt/d/BIOS") def test_a_multi_word_system_example_can_be_pasted(self): - """code_audit_14 P3-6.""" with mock.patch.object(install, "_mounted_cards", return_value=[]), \ contextlib.redirect_stderr(io.StringIO()) as err, \ self.assertRaises(SystemExit): @@ -6625,7 +6621,7 @@ class AuditSevenOneCardReading(unittest.TestCase): class AuditSevenScreens(unittest.TestCase): - """tui_audit_7 P2-1 to P3-9: what each screen offers and says.""" + """What each screen offers and says.""" def setUp(self): self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) @@ -6639,7 +6635,7 @@ class AuditSevenScreens(unittest.TestCase): return state def test_a_handheld_is_found_by_its_device_in_few_presses(self): - """P2-1: Onion was row 30 of 34, its row said "RetroArch files".""" + """Onion was row 30 of 34, its row said "RetroArch files".""" state = self.setups("gptokeyb") rows = install.tui_rows(state) labels = [row.label for row in rows] @@ -6666,7 +6662,7 @@ class AuditSevenScreens(unittest.TestCase): self.assertEqual([row.label for row in install.tui_rows(found)][2], "Batocera") def test_line_mode_takes_a_device_name(self): - """P2-1: "miyoo" refused at the line menu.""" + """"miyoo" refused at the line menu.""" with mock.patch.object(install, "_ask", side_effect=["bittboy"]), \ contextlib.redirect_stdout(io.StringIO()) as out: self.assertEqual(install._choose_platform("Which?"), "MiyooCFW") @@ -6680,7 +6676,6 @@ class AuditSevenScreens(unittest.TestCase): self.assertIn(f"{onion}) Onion, SD card (Miyoo Mini, Miyoo Mini Plus)", out.getvalue()) def test_one_spelling_per_device_and_one_press_for_one_match(self): - """P3-9.2, P3-9.3, P3-9.4.""" for name, devices in install._SETUP_DEVICES.items(): with self.subTest(system=name): self.assertFalse(any("+" in device for device in devices)) @@ -6700,7 +6695,7 @@ class AuditSevenScreens(unittest.TestCase): self.assertNotIn("PAN4ELEC", rows["amberelec"].right) def test_help_rows_keep_their_column_at_40(self): - """P3-9.1: "/ Filter (Esc clears)" ran back to the left edge.""" + """"/ Filter (Esc clears)" ran back to the left edge.""" for pad in ("gptokeyb", "gptokeyb_muxterm", "miyoo", "evmapy"): with self.subTest(pad=pad): state = self.setups(pad) @@ -6714,7 +6709,7 @@ class AuditSevenScreens(unittest.TestCase): == " ", line) def test_copy_from_a_folder_with_none_says_so(self): - """P2-2: the plan came back the same.""" + """The plan came back the same.""" state = checked_state() old = self.root / "old" old.mkdir() @@ -6734,21 +6729,19 @@ class AuditSevenScreens(unittest.TestCase): self.assertEqual(rows[state.focus["browse"]].value, stick) def test_offline_plan_names_the_folder_already_copied_from(self): - """code_audit_14 P3-1.""" state = checked_state() state.from_folders = [self.root / "from1"] state.found = [found("gba_bios.bin", str(self.root / "from1"))] with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}): text = " ".join(" ".join(install.tui_view(state, 100, 40)).split()) - # The rest named by kind as not in it, the remedy after - # (tui_audit_14 P3-7). + # The rest named by kind as not in it, the remedy after. self.assertIn("Not in from1: ", text) self.assertIn("Run the installer again with a pack (--from-pack)", text) self.assertNotIn("They are not in", text) self.assertNotIn("Copy them from your old card", text) def test_the_card_browser_focuses_the_card_asked_for(self): - """P3-2: the muOS card, listed first, was focused for Onion.""" + """The muOS card, listed first, was focused for Onion.""" muos, onion, second = self.root / "A_MUOS", self.root / "B_ONION", self.root / "C" make_card(muos, "muOS") make_card(onion, "Onion") @@ -6769,7 +6762,6 @@ class AuditSevenScreens(unittest.TestCase): self.assertNotIn("Go back", line) def test_confirm_offers_no_install_while_it_counts(self): - """P3-3.""" state = checked_state() state.stack.append("confirm") state.running, state.dry = True, None @@ -6778,7 +6770,6 @@ class AuditSevenScreens(unittest.TestCase): self.assertNotIn("Install", [what for _key, what in install._help_lines(state)]) def test_back_after_choosing_systems_lands_on_install(self): - """P3-8.""" state = checked_state() state.focus["plan"] = [row.action for row in install.tui_rows(state)].index("systems") press(state, "enter") @@ -6792,7 +6783,7 @@ class AuditSevenScreens(unittest.TestCase): self.assertEqual(rows[state.focus["plan"]].action, "install") def test_a_lone_card_opens_the_first_screen_with_a_list(self): - """P3-7: with --manifest, the card's folder was the first screen.""" + """With --manifest, the card's folder was the first screen.""" onion = self.root / "ONIONB" make_card(onion, "Onion") shutil.rmtree(onion / "BIOS") @@ -6807,7 +6798,7 @@ class AuditSevenScreens(unittest.TestCase): self.assertEqual((state.screen, effects), ("setup", [])) def test_a_file_left_for_its_save_directory_is_said_so(self): - """P2-4: the menu counted 23, 22 were checked, and the end blamed + """The menu counted 23, 22 were checked, and the end blamed the collection for the file whose save directory is unknown.""" menus = [] @@ -6819,8 +6810,7 @@ class AuditSevenScreens(unittest.TestCase): argv = ["install.py", "--platform", "retroarch", "--dest", str(repo.dest), "--manifest", str(repo.root / "install" / "retroarch.json")] # The files come from the repository on the loopback: the module - # read its base before the environment named it (code_audit_24 - # P3-13). + # read its base before the environment named it. served = repo.env()["RETROBIOS_BASE_URL"] + "/{path}" with mock.patch.dict(os.environ, repo.env()), \ mock.patch.object(install, "RAW_FILE_URL", served), \ @@ -6847,7 +6837,6 @@ class AuditSevenScreens(unittest.TestCase): self.assertNotIn("the collection does not hold", text) def test_plural_game_data_and_the_backup_line_at_40x12(self): - """P3-9.5, P3-9.6.""" state = checked_state() games = [{"dest": f"g{index}.dat", "system": "", "category": install.GAME_DATA} for index in range(2)] @@ -6977,8 +6966,8 @@ def screen_plan(args: argparse.Namespace, manifest: dict, events: list[dict], class _CardFixtures: - """Drives, lists and packs of code_audit_18 and tui_audit_11, for the - classes that test them on the screen and in line mode.""" + """Drives, lists and packs for the classes that test them on the screen and + in line mode.""" ABOUT = "system/configs/emulationstation/about.info" @@ -6991,7 +6980,7 @@ class _CardFixtures: return root def renamed(self) -> dict: - """The drives code_audit_18 P1-1 names: KNULLI and Batocera each + """Renamed drives: KNULLI and Batocera each renamed in its own menu, with and without the file KNULLI alone writes, and Recalbox's share.""" conf = "system/batocera.conf" @@ -7076,14 +7065,14 @@ class _CardFixtures: class _LineModeFindings(_CardFixtures): - """The line-mode findings of code_audit_18 and tui_audit_11, run by + """The line-mode cases of the card fixtures, run by LineModeAndScreenDecideAlike.""" def test_a_drive_two_systems_fit_is_taken_as_named_and_said(self): - """code_audit_18 P1-1: --platform knulli is never refused on a + """--platform knulli is never refused on a drive whose only evidence is a batocera.conf, --platform batocera takes its bios folder, and the doubt is said. Recalbox refuses it - with words for a SHARE drive (P3-4).""" + with words for a SHARE drive.""" drives = self.renamed() for name in ("renamed, no about.info", "Batocera as shipped"): drive = drives[name] @@ -7107,7 +7096,7 @@ class _LineModeFindings(_CardFixtures): "--platform batocera", words) def test_the_first_screen_and_line_mode_say_the_doubt(self): - """code_audit_18 P1-1: the screen's first row was "Batocera SHARE + """The screen's first row was "Batocera SHARE drive (KNULLI2)". A renamed card with about.info is KNULLI's, one without is listed by neither and said.""" drives = self.renamed() @@ -7132,7 +7121,7 @@ class _LineModeFindings(_CardFixtures): self.assertEqual([setup[0] for setup in state.setups], ["knulli"]) def test_a_list_without_systems_narrows_by_what_it_records(self): - """tui_audit_11 P2-1: install/minui.json records cores and regions, + """Install/minui.json records cores and regions, no system, and all three options were refused with a remedy that fetched the same list.""" listing, _pack, _listed = self.minui() @@ -7156,7 +7145,7 @@ class _LineModeFindings(_CardFixtures): @unittest.skipIf(sys.version_info < (3, 9), "generate_pack.py's context managers need Python 3.9") def test_a_pack_names_its_list_only_when_that_list_records_it(self): - """tui_audit_11 P2-1: a MinUI pack sent --core to install/minui.json, + """A MinUI pack sent --core to install/minui.json, refused the same way, and a MiSTer pack to install/misterfpga.json, which records no core. The pack now records what its list narrows by, and each remedy changes the outcome.""" @@ -7183,7 +7172,7 @@ class _LineModeFindings(_CardFixtures): self.assertTrue(mister_list.exists()) def test_line_mode_offers_what_can_be_chosen(self): - """tui_audit_11 P3-10: "c) choose systems, cores and regions" with a + """"c) choose systems, cores and regions" with a pack that records systems only, and "Cores: 1) azahar" asked with one answer.""" mister, _pack, _listed = self.minui("misterfpga", systems=True, cores=False, @@ -7201,7 +7190,7 @@ class _LineModeFindings(_CardFixtures): self.assertNotIn("Cores:", out.getvalue()) self.assertEqual(asked.call_count, 0) - # code_audit_18 P3-2, P3-3, tui_audit_11 P3-1: the remedies of a card. + # the remedies of a card. def test_a_full_card_is_freed_never_left_for_another_drive(self): with mock.patch.object(install.shutil, "disk_usage", @@ -7230,7 +7219,7 @@ class _LineModeFindings(_CardFixtures): class _OutsideTextFindings: - """code_audit_18 P2-1: a pack's member path, a --manifest dest, the + """A pack's member path, a --manifest dest, the names a list records, a card's label and a retroarch.cfg folder reached line mode, the events and the disk with their control characters. Each source is fed escape sequences, and none comes out raw.""" @@ -7345,7 +7334,7 @@ class _OutsideTextFindings: class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, unittest.TestCase): - """tui_audit_8 P1-1, P2-1 and code_audit_15 P2-2: line mode looked at + """Line mode looked at this machine alone, took this computer's default folder with a card in the reader or nothing found, and the screen put RetroArch under A for a KNULLI card named with --dest. The same inputs now give the same @@ -7404,18 +7393,18 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, blank = self.root / "blank" blank.mkdir() scenarios = { - # code_audit_16 P1-1, P2-2, tui_audit_9 P1-1: the drive's root in + # the drive's root in # line mode, another system's card first on the screen. "a Batocera list, its SHARE drive": ( [share], [], {"manifest": batocera}, ("batocera", share / "bios")), "a Batocera list, a muOS card and its SHARE drive": ( [muos, share], [], {"manifest": batocera}, ("batocera", share / "bios")), - # tui_audit_9 P2-3, P3-11: the setups found asked as the screen + # the setups found asked as the screen # asks, Enter on the first. "nothing named, RetroArch here": ([], pc, {}, ("retroarch", self.here)), "a list, RetroArch here and an Onion card": ( [onion], pc, {"manifest": self.list}, ("retroarch", self.here)), - # code_audit_16 P3-1: --dest with a setup found. + # --dest with a setup found. "--dest a blank folder, RetroArch here": ( [onion], pc, {"dest": blank}, ("retroarch", blank)), "a list, an Onion card in the reader": ( @@ -7470,7 +7459,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, raise AssertionError(out.getvalue()) def test_a_run_without_questions_sees_the_cards_the_screen_sees(self): - """tui_audit_11 P1-1: --yes and --no-input looked at this machine + """--yes and --no-input looked at this machine alone, beside the Onion card the screen and line mode open on: the files went to the home folder, or the run said nothing is here.""" onion = self.card("ONION", "Onion") @@ -7494,7 +7483,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(chosen, [screen]) def test_a_run_without_questions_stops_on_two_setups(self): - """code_audit_18 P2-3, tui_audit_11 P1-1: --yes beside two setups + """--yes beside two setups installed for both, where its help says it stops on what to name. It now stops with an error event naming each and its --dest.""" onion, muos = self.card("ONION", "Onion"), self.card("MUOS", "muOS") @@ -7523,7 +7512,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, return share def test_a_drive_is_offered_by_the_folder_its_system_reads(self): - """code_audit_18 P2-2, tui_audit_11 P1-2: RetroArch's folder question + """RetroArch's folder question numbered a Batocera SHARE drive and a KNULLI card, and one press put RetroArch's list at their root, beside roms/ and system/. A drive nothing names went to its root too. Now another system's drive is @@ -7540,7 +7529,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertRaises(SystemExit): install.ask_platform_folder("linux", "retroarch") text = out.getvalue() - # One parenthesis a row (tui_audit_16 P3-9). + # One parenthesis a row. self.assertIn(f"1) EASYROMS: bios (drive, {stick / 'bios'})", text) self.assertIn(f"2) ONION: BIOS (Onion SD card, {onion / 'BIOS'})", text) self.assertNotIn("3)", text) @@ -7563,7 +7552,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(state.dest, stick / "bios") def test_a_list_card_setups_read_offers_them_first(self): - """tui_audit_11 P1-2: with a RetroArch pack or list and nothing found, + """With a RetroArch pack or list and nothing found, the first screen was RetroArch's folder question: ArkOS, muOS and JELOS, which read the same list, were out of reach. Both modes now open on the setups that read it, RetroArch first.""" @@ -7669,8 +7658,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, contextlib.redirect_stdout(io.StringIO()), \ contextlib.redirect_stderr(io.StringIO()): install._install(args, real) - # Every file from one folder: one count, as the screen's result - # (tui_audit_15 P3-8). + # Every file from one folder: one count, as the screen's result. self.assertIn(f"Done. 2 files copied from {backup}.", real.getvalue()) self.assertIn("Installed: 1 BIOS file and 1 game data file.", real.getvalue()) @@ -7699,8 +7687,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn("RetroArch: 4 files, 123 B.\n 1 BIOS file (3 B) and 3 game data files " "(120 B).", text) self.assertIn("g) Game data: kept (3 files, 120 B): leave it out", text) - # Said once, by the menu: the run head repeated it right under it - # (tui_audit_15 P3-9). + # Said once, by the menu: the run head repeated it right under it. after = text[text.index("q) quit"):text.index("Checking existing files")] self.assertNotIn("4 files (123 B)", after) self.assertIn("0 in place, 4 missing, 0 wrong copies", text) @@ -7718,7 +7705,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, after = text[text.index("Counted again"):] self.assertIn("g) Game data: kept (3 files, 120 B): leave it out", after) # doom holds only game data: Enter is refused, as the screen offers - # no Install for it (tui_audit_13 P3-11), and g puts it back. + # no Install for it, and g puts it back. self.assertIn("g) Game data: left out (3 files, 120 B): keep it", after) self.assertIn("doom holds only game data: nothing is left to install.", after) self.assertNotIn("All files up to date", text) @@ -7775,7 +7762,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, row = next(row for row in install.tui_rows(state) if row.action == "gamedata") self.assertEqual((row.label, row.right), ("Game data: kept", "2 files, 8 B")) - # code_audit_18 P3-5, tui_audit_11 P3-10 and P3-21: line mode wording. + # line mode wording. def test_one_row_says_type_1(self): with mock.patch.object(install, "_ask", side_effect=["2", "q"]), \ @@ -7865,7 +7852,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("No supported platform detected", text) def test_a_pack_gets_the_menu_and_its_folder_named(self): - """P1-1: no menu and no folder before the copy, the pack's list + """No menu and no folder before the copy, the pack's list recording no system.""" from test_install_offline import _pack, PAYLOAD @@ -7905,7 +7892,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("c) choose systems", text) self.assertNotIn("Copying", text) - # code_audit_17 and tui_audit_10: every line-mode finding, each answered + # every line-mode finding, each answered # by line mode and the screen from one decision. def line_run(self, args: argparse.Namespace, answers: list, mounts: list = (), @@ -7955,7 +7942,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, "systems": systems, **extra} def test_o_then_the_setup_found_offers_the_folder_it_reads(self): - """code_audit_17 P2-2, tui_audit_10 P1-1: o then RetroArch offered + """O then RetroArch offered its built-in folder, and Enter filled it, where the screen keeps the folder retroarch.cfg names.""" pc = [("retroarch", self.here)] @@ -7976,7 +7963,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual((state.platform, state.dest), ("retroarch", self.here)) def test_a_share_drive_typed_is_read_as_its_bios_folder(self): - """code_audit_17 P2-3, tui_audit_10 P3-11: the SHARE drive's root, + """The SHARE drive's root, typed for Batocera or Recalbox, was the BIOS folder, beside roms/ and system/. Another system's drive is refused, in both modes.""" shares = {} @@ -8012,7 +7999,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(refused.screen, "path") def test_the_setups_found_are_labelled_alike(self): - """code_audit_17 P3-1, tui_audit_10 P3-3, P3-13: "Onion SD card + """"Onion SD card (ONION) (/media/me/ONION/BIOS)", two pairs of brackets, and a MinUI card named by its root where its BIOS folder is Bios.""" onion, minui = self.card("ONION", "Onion"), self.card("MINUI", "MinUI") @@ -8037,7 +8024,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn(f"BIOSfolder:{folder}", screen.replace(" ", "")) def test_both_count_the_systems_out_of_the_same_list(self): - """code_audit_17 P3-2: the plan said 1 of 12 systems where Choose + """The plan said 1 of 12 systems where Choose systems and line mode listed 11, a system whose only file is read from an unknown save directory counted.""" payload = b"gba" @@ -8063,7 +8050,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(len(install.tui_systems(state)), 2) def test_after_o_the_list_offers_the_setups_its_file_list_serves(self): - """code_audit_17 P3-3: Batocera was offered for a RetroArch list, + """Batocera was offered for a RetroArch list, and refused once its folder had been asked.""" install.LOCAL.reset() self.addCleanup(install.LOCAL.reset) @@ -8080,7 +8067,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("knulli", line) def test_a_choice_of_systems_is_confirmed_before_anything_is_written(self): - """tui_audit_10 P2-1, code_audit_17 P2-4: c installed as soon as the + """C installed as soon as the last list was answered, and its command left out --dest and --manifest. The menu comes back counted, as the screen's Confirm.""" files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"]), @@ -8114,7 +8101,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, "files": {f"f{n}.dat": {"sha1": "a" * 40, "size": 10} for n in range(count)}} def test_both_count_the_data_files_of_the_systems_kept(self): - """tui_audit_10 P2-2: line mode counted 2636 data files of other + """Line mode counted 2636 data files of other systems for every --system tried, where the screen counts none.""" files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"]), self.entry("scph5501.bin", b"psx", ["sony-playstation"])] @@ -8135,7 +8122,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, @unittest.skipUnless(hasattr(os, "statvfs"), "statvfs reads mount flags") def test_a_read_only_card_gets_one_remedy_and_no_sudo(self): - """tui_audit_10 P2-3: the plan offered sudo for a read-only mount, + """The plan offered sudo for a read-only mount, with a command that dropped --from-pack and --manifest, and the result offered nothing. One advice, line mode before its menu, the plan and the result.""" @@ -8158,7 +8145,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("sudo", said) def test_the_sudo_command_keeps_every_option_of_the_run(self): - """tui_audit_10 P2-3: the plan's sudo line dropped --from-pack and + """The plan's sudo line dropped --from-pack and --manifest, and with --offline stopped at the file list.""" state = checked_state({"free": 10 ** 9, "writable": False, "cores": []}) state.manifest_path, state.manifest_given = Path("/l/retroarch.json"), True @@ -8172,7 +8159,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn(option, line) def test_the_save_files_are_counted_after_the_choice(self): - """tui_audit_10 P3-2: --system sony-playstation said 106 files went + """--system sony-playstation said 106 files went to the save directory, none of them PlayStation's.""" here = self.root / "pc" / "system" files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"]), @@ -8194,7 +8181,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(saves, []) def test_a_list_that_leaves_out_save_files_says_so_before_the_menu(self): - """tui_audit_10 P3-4: ROCKNIX's 44 files left out were said after + """ROCKNIX's 44 files left out were said after the install only, as the frontend's, where the plan says them.""" omitted = [{"dest": f"saves/{n}.key", "name": f"{n}.key", "system": "", "systems": [], "required": False, "reason": "no_save_directory", @@ -8218,7 +8205,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn(said, out.getvalue()) def test_the_drives_mounted_here_are_offered_in_both(self): - """tui_audit_10 P3-6: the copy question listed no drive and took q + """The copy question listed no drive and took q as a folder, and the screen's Which folder? listed none where line mode numbered them.""" stick, onion = self.root / "media" / "USBSTICK", self.card("ONION", "Onion") @@ -8242,7 +8229,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, mock.patch.object(install, "_ask", side_effect=["1"]), \ mock.patch.object(install, "_missing_dest", return_value=True): folder = install.ask_platform_folder("linux", "retroarch") - # tui_audit_11 P1-2: a drive is offered by its bios folder, never its + # a drive is offered by its bios folder, never its # root, which no setup reads. self.assertEqual(folder, stick / "bios") state = install.TuiState(os_type="linux", home=HOME) @@ -8254,7 +8241,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, [stick / "bios"]) def test_the_systems_are_listed_by_title_in_the_screen_order(self): - """tui_audit_10 P3-7: line mode listed ids, nintendo-3ds before + """Line mode listed ids, nintendo-3ds before nintendo-ds, where the screen lists titles.""" titles = {"nintendo-ds": "Nintendo DS", "nintendo-gba": "Nintendo Game Boy Advance"} files = [self.entry("ds.bin", b"ds", ["nintendo-ds"]), @@ -8278,7 +8265,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(order, ["nintendo-ds", "nintendo-gba", "nintendo-3ds"]) def test_the_card_question_looks_again_and_lists_blank_drives(self): - """tui_audit_10 P3-8: Enter at Card root never looked again, a + """Enter at Card root never looked again, a blank stick was listed for KNULLI on the screen alone, and the two modes differed on creating its bios.""" onion = self.card("ONION", "Onion") @@ -8321,7 +8308,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual((state.dest, state.screen), (stick / "bios", "checking")) def test_a_full_or_read_only_folder_is_said_before_enter(self): - """tui_audit_10 P3-9, P3-19: line mode showed Enter) install + """Line mode showed Enter) install everything over a full card and refused after it. On a card setup both say to free space on the card.""" onion = self.card("ONION", "Onion") @@ -8343,7 +8330,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn("Free some space on the card first.", plan) def test_a_device_typed_is_named_first(self): - """tui_audit_10 P3-12: "miyoo mini" listed MinUI with RG28XX, RG34XX + """"miyoo mini" listed MinUI with RG28XX, RG34XX and RG34XX SP, where the screen's row names the Miyoo Mini.""" install.LOCAL.reset() choices = install._line_setups([], set(), "linux") @@ -8359,15 +8346,15 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertTrue(label.split("(", 1)[1].startswith(first), (label, first)) def test_line_mode_says_setup_where_the_screen_does(self): - """tui_audit_10 P3-13: "Detecting platform..." and "No supported + """"Detecting platform..." and "No supported platform found here", where the screen says setup and "Nothing was found here.\"""" # The standalone emulators' lists come from the network: none here - # (code_audit_24 P3-13), and none found. + #, and none found. with mock.patch.object(install, "_install_standalone_folders", return_value=False): text, _asked = self.line_run(_args(declared_only=False), []) self.assertIn("Looking for setups here...", text) - # Said once, the question alone after it (tui_audit_16 P3-2). + # Said once, the question alone after it. self.assertEqual(text.count("Nothing was found here."), 1) self.assertIn("\nWhich setup?\n", text) self.assertNotIn("Detecting platform", text) @@ -8377,7 +8364,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn("Nothing was found here.", " ".join(install.tui_view(state, 80, 24))) def test_yes_at_a_terminal_asks_nothing(self): - """tui_audit_10 P3-20: --yes waited at Install for: and at the menu.""" + """--yes waited at Install for: and at the menu.""" seen = [] with mock.patch.object(sys, "argv", ["install.py", "--yes", "--plain"]), \ mock.patch.object(install, "_run", side_effect=seen.append): @@ -8392,7 +8379,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, _text, asked = self.line_run(seen[0], [], found=pc) self.assertEqual(asked, []) - # code_audit_19 and tui_audit_12: line mode, and the screen beside it. + # line mode, and the screen beside it. def copy_folder(self) -> tuple[Path, Path]: listing, _files = self.game_list() @@ -8403,7 +8390,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, return listing, old def test_the_copy_line_says_copying_once(self): - """code_audit_19 P3-4, tui_audit_12 P3-13: "Copying 22 files copied + """"Copying 22 files copied from ...", its size read as the folder's.""" listing, old = self.copy_folder() args = _args(manifest=listing, dest=self.here, declared_only=False, no_input=True, @@ -8414,7 +8401,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("files copied from", text[text.index("\nCopying "):]) def test_narrowed_is_said_only_when_the_list_shrank(self): - """tui_audit_12 P3-13: Enter for every system said "Narrowed 4 to 4".""" + """Enter for every system said "Narrowed 4 to 4".""" args = dict(manifest=self.counted_list(), dest=self.here, declared_only=False, dry_run=True) text, _asked = self.line_run(_args(**args), ["c", "", ""]) @@ -8429,7 +8416,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertRegex(text, r"Narrowed 4 to \d files") def test_the_dry_run_names_systems_by_their_titles(self): - """tui_audit_12 P3-13: --dry-run listed microsoft-msx where the list + """--dry-run listed microsoft-msx where the list and the screen say Microsoft MSX.""" files = [self.entry("msx/msx.rom", b"msx", ["microsoft-msx"]), self.entry("gba_bios.bin", b"gba", ["nintendo-gba"])] @@ -8448,7 +8435,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, "Microsoft MSX") def test_the_largest_systems_tail_counts_groups(self): - """code_audit_19 P3-3: "... and 78 more systems" under a plan of 65.""" + """"... and 78 more systems" under a plan of 65.""" files = [{"dest": f"{n}.bin", "size": n + 1, "systems": [f"s{n}"]} for n in range(12)] files.append({"dest": "shared.bin", "size": 1, "systems": ["s0", "s1"]}) out = io.StringIO() @@ -8464,7 +8451,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn(" ... and 2 more groups (--check --verbose lists them all)", lines) def test_a_command_given_back_keeps_offline_in_both_modes(self): - """code_audit_19 P2-2, tui_audit_12 P3-13: with the variable alone, + """With the variable alone, line mode's Same choice ended with --offline and the screen's not.""" args = dict(manifest=self.counted_list(), dest=self.here, declared_only=False, dry_run=True) @@ -8476,7 +8463,6 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertIn(" --offline", install.tui_command(state)) def test_q_quits_on_the_quit_code_in_both_modes(self): - """code_audit_19 P3-1.""" args = dict(manifest=self.counted_list(), dest=self.here, declared_only=False) install.LOCAL.reset() with mock.patch.object(install, "_ask", return_value="q"), \ @@ -8491,7 +8477,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, del args def test_a_card_in_the_reader_is_offered_not_asked_for(self): - """code_audit_19 P3-7: line mode numbered the card and said to mount + """Line mode numbered the card and said to mount it, the screen said none was mounted.""" card = self.root / "media" / "KNULLI2" (card / "system").mkdir(parents=True) @@ -8518,7 +8504,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertNotIn("is mounted", text) def test_a_list_and_nothing_found_stops_a_run_without_questions(self): - """tui_audit_12 P3-12: --yes with a list filled this computer's + """--yes with a list filled this computer's default folder, where the page says a run that needs an answer stops.""" for flag in ({"yes": True}, {}): with self.subTest(flag=flag): @@ -8532,7 +8518,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(chosen, [("retroarch", install._default_dest("linux", "retroarch"))]) def test_a_terminal_the_screen_cannot_use_is_named(self): - """tui_audit_12 P3-14: TERM unset or dumb gave line questions without + """TERM unset or dumb gave line questions without a word, where a small window said why.""" reason = install.line_mode_reason self.assertEqual(reason("TERM is dumb or not set", {}), @@ -8549,7 +8535,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertEqual(reason("the input is not a terminal", {}), "") def test_game_data_has_one_wording_and_one_decision(self): - """tui_audit_12 P3-4, P3-5: five wordings, "No game data" read as a + """Five wordings, "No game data" read as a list holding none, and --no-game-data given offered it back on the screen alone.""" listing, _files = self.game_list() @@ -8569,7 +8555,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, self.assertFalse(any(row.action == "gamedata" for row in install.tui_rows(state))) def test_three_kinds_are_named_in_both_modes(self): - """tui_audit_12 P2-3: "data files" beside game data files, never + """"data files" beside game data files, never said what they were.""" listing, _files = self.game_list() manifest = json.loads(listing.read_text(encoding="utf-8")) @@ -8586,7 +8572,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, out.getvalue()) def test_the_wsl_folder_question_offers_both_sides(self): - """tui_audit_12 P3-11, line mode's half.""" + """Line mode's half.""" with mock.patch.object(install, "_mounted_cards", return_value=[]), \ mock.patch.object(install, "_ask", side_effect=["q"]), \ contextlib.redirect_stdout(io.StringIO()) as out, \ @@ -8598,7 +8584,7 @@ class LineModeAndScreenDecideAlike(_LineModeFindings, _OutsideTextFindings, class AuditSeventeenAndTen(unittest.TestCase): - """code_audit_17 and tui_audit_10: what the screen, the packs, the + """What the screen, the packs, the wording and the docs answer, line mode's parity being in LineModeAndScreenDecideAlike.""" @@ -8611,7 +8597,7 @@ class AuditSeventeenAndTen(unittest.TestCase): @unittest.skipUnless(pyte and pty and hasattr(pty, "fork") and shutil.which("script"), "the line mode run needs a pty") def test_the_printed_command_makes_the_same_choice(self): - """code_audit_17 P2-4, tui_audit_10 P2-1: "Same choice without + """"Same choice without questions" left out the folder chosen at a question and the file list, and installed elsewhere or was refused. Run as printed, it finds every file of the choice in place and nothing else.""" @@ -8628,7 +8614,7 @@ class AuditSeventeenAndTen(unittest.TestCase): proc = subprocess.run( ["script", "-qec", command, "/dev/null"], # Enter on RetroArch, first of the setups that read its list - # (tui_audit_11 P1-2), then its folder. + #, then its folder. input=f"\n{repo.dest}\nc\n2\n2\n\n", env=env, capture_output=True, text=True, timeout=120, check=False) self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) @@ -8648,7 +8634,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(sorted(event["dest"] for event in files), installed) self.assertTrue(all(event["state"] == "present" for event in files)) - # tui_audit_10 P2-4: a pack's own list records its systems. + # a pack's own list records its systems. @unittest.skipIf(sys.version_info < (3, 9), "generate_pack.py's context managers need Python 3.9") @@ -8719,7 +8705,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertNotIn("older release", err.getvalue()) def test_a_pack_cannot_write_escapes_through_its_system_names(self): - """Security review of tui_audit_10 P2-4: the titles and ids a pack + """The titles and ids a pack records reached print() raw in the systems list.""" from test_install_offline import GBA, US # noqa: PLC0415 @@ -8757,7 +8743,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertNotIn("\x1b", out.getvalue()) def test_the_home_folder_is_said_on_the_plan(self): - """tui_audit_10 P2-5: the plan named ~ and said nothing more.""" + """The plan named ~ and said nothing more.""" state = checked_state() state.dest = state.home lines = " ".join(str(line) for line in install._plan_lines(state.check, state.dest, @@ -8765,7 +8751,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertIn("No setup reads BIOS files in your home folder.", lines) def test_systems_seen_and_left_unchanged_keep_the_exact_plan(self): - """tui_audit_10 P3-1: opening Choose systems on a --system plan and + """Opening Choose systems on a --system plan and going back turned the exact plan into an estimate.""" state = checked_state() state.cli_systems = ["nintendo-gba"] @@ -8803,7 +8789,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertNotIn(f"{CHECK['present']} in place,", text) def test_the_copy_browser_leaves_the_card_being_installed_to(self): - """tui_audit_10 P3-5: the card installed to was focused and taken, + """The card installed to was focused and taken, and WSL rows read /mnt/d where every other screen writes D:.""" dest_card, old = self.root / "d", self.root / "e" make_card(dest_card, "Onion") @@ -8816,8 +8802,7 @@ class AuditSeventeenAndTen(unittest.TestCase): install._open_from_browser(state) rows = install.tui_rows(state) self.assertEqual(rows[state.focus["browse"]].value, old) - # Not offered at all, as line mode's Copy from leaves it out - # (tui_audit_12 P3-16). + # Not offered at all, as line mode's Copy from leaves it out. self.assertNotIn("D: (Onion card)", [row.label for row in rows]) self.assertIn("E: (card or drive)", [row.label for row in rows]) # Reached through its folders all the same, it is refused. @@ -8829,7 +8814,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(state.from_folders, []) def test_typing_a_filter_names_the_keys_that_end_it(self): - """tui_audit_10 P3-10: while typing, the bar named Tick and Help, + """While typing, the bar named Tick and Help, the focus stayed on None, F1 ended the typing, and a filter that matched nothing said nothing.""" state = checked_state() @@ -8849,7 +8834,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual((state.help, state.editing), (False, "systems")) def test_a_computer_finds_its_own_setups(self): - """tui_audit_10 P3-11: windows and mac matched nothing, RetroBat + """Windows and mac matched nothing, RetroBat came 27th on Windows, and a Batocera SHARE drive was not found.""" names = {install._row_name(row) for row in install.setup_list([], set(), "windows", "windows")} @@ -8871,7 +8856,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(mounted, {("batocera", share / "bios")}) def test_a_pack_preview_installs_from_the_pack(self): - """tui_audit_10 P3-15: "23 files to download" on a --from-pack run.""" + """"23 files to download" on a --from-pack run.""" state = checked_state() state.stack.append("preview") state.dry = dict(CHECK) @@ -8879,7 +8864,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertIn("to install from the pack", install._pager_items(state)[0]) def test_scroll_is_named_only_where_the_text_scrolls(self): - """tui_audit_10 P3-16: "Up/Down Scroll" over nine lines that fit.""" + """"Up/Down Scroll" over nine lines that fit.""" state = checked_state() state.stack = ["result"] state.summary = {"installed": 1, "up_to_date": 0, "pending": 0, "failed": [], @@ -8890,7 +8875,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertIn("Scroll", install.tui_view(state, 80, 12)[-1]) def test_gptokeyb_names_select_then_start(self): - """tui_audit_10 P3-17: "Start+Select" on the bars, "Select, then + """"Start+Select" on the bars, "Select, then Start" in the help and the docs.""" state = checked_state() state.pad = "gptokeyb" @@ -8899,7 +8884,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(install.TUI_ROUTES["gptokeyb"].stop[1], "B or Select+Start") def test_nothing_to_confirm_is_titled_so(self): - """tui_audit_10 P3-18: Confirm over nothing to confirm, offline.""" + """Confirm over nothing to confirm, offline.""" state = checked_state() state.stack.append("confirm") state.dry = dict(CHECK) @@ -8907,7 +8892,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertIn("Nothing to install", install.tui_view(state, 80, 24)[0]) def test_another_folder_for_a_card_setup_asks_for_its_card(self): - """tui_audit_10 P3-19: a full Onion card offered another folder for + """A full Onion card offered another folder for RetroArch, and the result said to choose another folder.""" onion = self.root / "ONION" make_card(onion, "Onion") @@ -8929,7 +8914,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertIn("Free some space on the card, then run again.", lines) def test_the_dest_example_is_this_systems(self): - """code_audit_17 P3-4: /media/$USER/SHARE/bios on macOS and Windows.""" + """/media/$USER/SHARE/bios on macOS and Windows.""" self.assertEqual(install.drive_example("darwin", "SHARE", "bios"), "/Volumes/SHARE/bios") self.assertEqual(install.drive_example("wsl", "SHARE", "bios"), "/mnt/e/bios") self.assertEqual(install.drive_example("windows", "SHARE", "bios", "batocera"), @@ -8938,7 +8923,7 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(install.drive_example("linux", ""), "/media/$USER/") def test_the_copy_browser_opens_on_a_path_without_dot_dot(self): - """code_audit_17 P3-5: --from t/../packx opened the browser on t/..""" + """--from t/../packx opened the browser on t/..""" packx = self.root / "packx" packx.mkdir() state, _effects = install.tui_start( @@ -8946,7 +8931,6 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertEqual(state.from_folders, [packx]) def test_no_clause_semicolon_in_what_the_installer_prints(self): - """code_audit_17 P3-6.""" self.assertNotIn("; ", " ".join(install.build_parser().format_help().split())) source = Path(install.__file__).read_text(encoding="utf-8") for said in ("to fetch them; a file", "every board; --target", "with the system; ", @@ -8955,7 +8939,6 @@ class AuditSeventeenAndTen(unittest.TestCase): self.assertNotIn(said, source) def test_the_docs_say_what_the_installer_does(self): - """code_audit_17 P3-7.""" page = (REPO_ROOT / "wiki" / "installer.md").read_text(encoding="utf-8") menu = page[re.search(r"RetroArch: \d+ files, [\d.]+ [KMG]B[.,]", page).start():] menu = menu[:menu.index("```")] @@ -8974,7 +8957,7 @@ class AuditSeventeenAndTen(unittest.TestCase): class OneDeviceRegistry(unittest.TestCase): - """code_audit_15 P2-1, tui_audit_8 P3-2, P3-3, P3-4: one device spelled + """One device spelled several ways found one system, one press took it, MinUI listed brands.""" def found(self, typed: str, os_type: str = "linux") -> set: @@ -9047,13 +9030,14 @@ class OneDeviceRegistry(unittest.TestCase): line = str(install._row_line(rows[label], False, 38)) self.assertIn(label, line) self.assertTrue(line.rstrip() != (" " + label).rstrip(), line) - # tui_audit_9 P3-3: its one device, cut, where "1 device" named none. + # its one device, cut, where "1 device" named none. self.assertTrue(str(install._row_line(rows["CrossMix-OS, SD card"], False, 38)) .rstrip().endswith("TrimUI Smar...")) class AuditFifteenAndEightScreens(unittest.TestCase): - """The P3 points of code_audit_15 and tui_audit_8 the screens show.""" + """Card folders, refusals and bars at 40 columns, as the screens show + them.""" def setUp(self): self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) @@ -9069,7 +9053,7 @@ class AuditFifteenAndEightScreens(unittest.TestCase): return install.tui_start(_args(**given), "linux") def test_a_card_found_by_its_files_gets_its_folder_without_a_question(self): - """tui_audit_8 P3-12: Create the folder? for the Onion card's own + """Create the folder? for the Onion card's own BIOS, which line mode created.""" onion = self.root / "ONIONB" make_card(onion, "Onion") @@ -9080,7 +9064,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn("BIOS is created on ONIONB", state.card_note) def test_a_refused_dest_says_the_remedy_that_works(self): - """code_audit_15 P3-3, P3-4.""" rocknix = self.root / "ROCKNIX" make_card(rocknix, "ROCKNIX") stick = self.root / "STICK" @@ -9104,7 +9087,7 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn(f"Run it again with --dest {minui}.", state.status) def test_wsl_names_drives_in_line_mode_messages(self): - """code_audit_15 P3-7: /mnt/f in a refusal where D:\\ was typed.""" + """/mnt/f in a refusal where D:\\ was typed.""" mnt = self.root / "mnt" make_card(mnt / "f", "muOS") (mnt / "g" / "photos").mkdir(parents=True) @@ -9121,7 +9104,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertEqual(install._last_name(str(mnt / "g" / "old")), "old") def test_choose_the_card_below_only_when_one_is_mounted(self): - """tui_audit_8 P3-6.""" muos = self.root / "MUOS" make_card(muos, "muOS") stick = self.root / "USBSTICK" @@ -9138,7 +9120,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertEqual(focused.value, stick) def test_type_a_path_says_f1_and_f1_says_more(self): - """tui_audit_8 P2-2.""" muos = self.root / "MUOS" make_card(muos, "muOS") with mock.patch.object(install, "_mounted_cards", return_value=[]): @@ -9156,7 +9137,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn("Onion keeps .tmp_update at the root of its card", help_text) def test_batocera_on_a_computer_offers_its_share(self): - """tui_audit_8 P2-4.""" stick = self.root / "SHARE" stick.mkdir() state, _effects = self.start([stick]) @@ -9173,7 +9153,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertEqual(rows[0].value, stick / "bios") def test_the_first_screen_bar_says_quit(self): - """tui_audit_8 P3-10.""" state, _effects = self.start() self.assertEqual(state.stack, ["platforms"]) self.assertIn("B/Esc Quit", install._TUI_VIEWS["platforms"](state, 80, 24)[2]) @@ -9181,7 +9160,7 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn("B/Esc Back", install._TUI_VIEWS["platforms"](state, 80, 24)[2]) def test_a_pad_result_prints_no_command(self): - """tui_audit_8 P3-9: a shell command on a controller-only screen.""" + """A shell command on a controller-only screen.""" state = _installed_state(self.root / "bios") state.summary["kept"] = [{"folder": str(self.root / "kept"), "files": 1}] state.pad = "muxterm" @@ -9193,7 +9172,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn("Same choice without questions:", install.tui_outcome(state)[1]) def test_the_checking_screen_is_titled_as_the_plan(self): - """code_audit_15 P3-9.1.""" state = install.TuiState() state.platform, state.dest = "retroarch", self.root / "bios" install._DETECTED_OS[("retroarch", state.dest)] = "ArkOS" @@ -9202,7 +9180,7 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertIn("ArkOS (RetroArch files):", text) def test_the_backup_line_survives_forty_columns(self): - """tui_audit_8 P3-5: under the pack and copy split it was cut.""" + """Under the pack and copy split it was cut.""" state = checked_state() state.found = [found("gba_bios.bin", "/media/old")] lines = [str(line) for line in install._plan_lines(state.check, state.dest, state)] @@ -9211,7 +9189,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.assertTrue(lines[counts + 1].startswith("The 1 wrong copy is replaced"), lines) def test_an_empty_folder_is_said_once(self): - """tui_audit_8 P3-7.""" old = self.root / "USBSTICK" old.mkdir() state = checked_state() @@ -9224,7 +9201,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): "with a pack (--from-pack) or without --offline."]) def test_amberelec_keeps_its_files_on_the_games_part(self): - """tui_audit_8 P3-13.""" self.assertEqual(install.card_where("AmberELEC", ""), "on the games part of its SD card") files = [{"dest": "bios/a.bin"}, {"dest": "bios/Machines/b.xml"}] @@ -9233,7 +9209,6 @@ class AuditFifteenAndEightScreens(unittest.TestCase): self.root) def test_a_save_directory_left_out_has_one_wording(self): - """code_audit_15 P3-9.3, tui_audit_8 P3-8.""" files = [{"dest": "keys.txt", "root": "save", "sha1": "0" * 40, "size": 1}] with contextlib.redirect_stdout(io.StringIO()) as out: install.place_save_entries(files, self.root / "BIOS", @@ -9246,7 +9221,7 @@ class AuditFifteenAndEightScreens(unittest.TestCase): class CardBoundaries(unittest.TestCase): - """code_audit_15 P3-2, P3-9.5: three folders at most, a bind mount not + """Three folders at most, a bind mount not seen, a folder named MUOS taken for a card, ismount unprobed.""" def setUp(self): @@ -9299,7 +9274,7 @@ def _screen_text(state: install.TuiState, cols: int = 80, rows: int = 24) -> str class AuditSixteenAndNineLineMode(unittest.TestCase): - """code_audit_16 and tui_audit_9: line mode read other decisions than the + """Line mode read other decisions than the screen (a drive's root for Batocera, no other setup once one was found, no Enter default, a folder question with no way out).""" @@ -9329,7 +9304,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): return drive def test_a_numbered_share_drive_is_its_bios_folder(self): - """code_audit_16 P1-1, tui_audit_9 P1-1: 2) SHARE gave the drive's + """2) SHARE gave the drive's root, the screen its bios folder.""" muos = self.root / "media" / "MUOS" make_card(muos, "muOS") @@ -9345,7 +9320,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertNotIn("MUOS", text) def test_the_folder_question_quits_on_q_and_says_what_to_type(self): - """code_audit_16 P2-3: q became the folder ./q, filled, and Enter + """Q became the folder ./q, filled, and Enter with no default repeated the prompt with no word.""" patcher, asked = self.ask("", "q") with mock.patch.object(install, "_mounted_cards", return_value=[]), patcher, \ @@ -9358,7 +9333,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertFalse((Path.cwd() / "q").exists()) def test_a_relative_folder_is_named_in_full(self): - """code_audit_16 P2-3: BIOS folder: q, Created q, Location: q.""" + """BIOS folder: q, Created q, Location: q.""" here = self.root / "work" here.mkdir() patcher, _asked = self.ask("./q") @@ -9381,7 +9356,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertEqual(asked, ["Card root, Enter to look again, q to quit: "]) def test_install_for_takes_enter_and_offers_another_setup(self): - """tui_audit_9 P2-3, P3-11: no Enter default, an All the screen does + """No Enter default, an All the screen does not have, and no other setup once one was found.""" here = self.root / "system" found = [("retroarch", here)] @@ -9399,7 +9374,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertEqual(install._prompt_platform_choice(found, other=lambda: other), other) def test_the_setups_for_a_dest_come_in_the_screens_order(self): - """code_audit_16 P3-1: with RetroArch found, --plain --dest put Onion + """With RetroArch found, --plain --dest put Onion at 19, the screen at 29.""" dest = self.root / "blank" dest.mkdir() @@ -9431,7 +9406,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertEqual(install._row_name(rows[state.focus["platforms"]]), listed["default"]) def test_system_named_on_the_command_line_keeps_the_menu(self): - """tui_audit_9 P3-8: --system skipped the menu and its folder line.""" + """--system skipped the menu and its folder line.""" files = [{"dest": "a.bin", "size": 1, "systems": ["nintendo-gba"], "cores": None}, {"dest": "b.bin", "size": 1, "systems": ["sega-saturn"], "cores": None}] given = (["nintendo-gba"], [], []) @@ -9450,7 +9425,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertNotIn("} -> {len(files)}", source) def test_android_typed_names_retroarch(self): - """tui_audit_9 P3-5: android matched nothing, and nothing more.""" + """Android matched nothing, and nothing more.""" patcher, _asked = self.ask("android", "q") with patcher, mock.patch.object(install, "detect_os", return_value="linux"), \ contextlib.redirect_stdout(io.StringIO()) as out, \ @@ -9459,7 +9434,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): self.assertIn("On Android, choose RetroArch", out.getvalue()) def test_batocera_named_on_a_computer_without_questions_is_refused(self): - """code_audit_16 P3-3: /userdata/bios taken, Cannot create, end 2 + """/userdata/bios taken, Cannot create, end 2 with no error event.""" listing = self.root / "batocera.json" listing.write_text(json.dumps({"manifest_version": 2, "platform": "batocera", @@ -9481,7 +9456,7 @@ class AuditSixteenAndNineLineMode(unittest.TestCase): class AuditSixteenAndNineScreens(unittest.TestCase): - """The screen points of code_audit_16 and tui_audit_9.""" + """Rows, filters and help as the screens draw them.""" def setUp(self): self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) @@ -9498,7 +9473,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): return install.tui_start(_args(**given), "linux") def test_a_folder_holding_a_mounted_muos_card_is_no_muos_card(self): - """code_audit_16 P2-2: /media/me held the MUOS mount point and read as + """/media/me held the MUOS mount point and read as a muOS card, and _own_card_root walked above the mount.""" parent = self.root / "media" muos = parent / "MUOS" @@ -9512,7 +9487,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertEqual(install._own_card_root(muos / "MUOS" / "bios"), muos) def test_batocera_share_rows_leave_out_another_systems_card(self): - """code_audit_16 P2-2: the muOS card was the first share row.""" + """The muOS card was the first share row.""" muos = self.root / "MUOS" make_card(muos, "muOS") share = self.root / "SHARE" @@ -9525,7 +9500,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertNotIn(("share", "MUOS: bios"), rows) def test_a_proposed_folder_is_created_without_the_guard(self): - """tui_audit_9 P2-1: Use this folder, then Create the folder? focused + """Use this folder, then Create the folder? focused on Choose another folder, and Enter, Enter looped.""" state = install.TuiState(os_type="linux", home=self.root) usual = self.root / ".config" / "retroarch" / "system" @@ -9543,7 +9518,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertEqual(install.tui_rows(state)[state.focus["create"]].action, "other") def test_a_page_moves_by_the_rows_drawn(self): - """tui_audit_9 P2-2: at 40x12 PgDn moved six rows over four drawn, + """At 40x12 PgDn moved six rows over four drawn, and muOS and ROCKNIX were never shown.""" for cols, rows in ((40, 12), (40, 15), (80, 24)): with self.subTest(size=f"{cols}x{rows}"): @@ -9561,7 +9536,6 @@ class AuditSixteenAndNineScreens(unittest.TestCase): name) def test_the_first_screen_says_quit_and_a_filter_says_clear(self): - """tui_audit_9 P3-1, P3-2.""" state, _effects = self.start(platform="onion") self.assertEqual(state.stack, ["folder"]) bar = install.tui_view(state, 80, 24)[-1] @@ -9574,7 +9548,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("Esc Clear", install.tui_view(state, 80, 24)[-1]) def test_rows_at_40_columns_name_a_device(self): - """tui_audit_9 P3-3: "1 device" for CrossMix-OS.""" + """"1 device" for CrossMix-OS.""" state, _effects = self.start() text = _screen_text(state, 40, 60) self.assertNotIn("1 device", text) @@ -9582,7 +9556,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("TrimUI", crossmix) def test_a_model_finds_the_systems_that_list_its_family(self): - """code_audit_16 P2-1, tui_audit_9 P3-4: RG353V missed ROCKNIX, RG351P + """RG353V missed ROCKNIX, RG351P missed AmberELEC and ROCKNIX.""" for system, devices in install._SETUP_DEVICES.items(): for device in devices: @@ -9593,7 +9567,6 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn(system, names) def test_the_filter_reads_system_names_as_line_mode_does(self): - """code_audit_16 P3-2.""" for typed, system in (("spruce os", "spruceOS"), ("unofficial os", "UnofficialOS"), ("cross mix", "CrossMix-OS")): with self.subTest(typed=typed): @@ -9606,7 +9579,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("On Android, choose RetroArch", " ".join(_screen_text(state).split())) def test_a_wrapped_path_has_no_space_inserted(self): - """tui_audit_9 P3-6: retroarch/ system.""" + """Retroarch/ system.""" path = "/home/moi/retroarch_system/tmp/tui_audit9/sb/nd/home/.config/retroarch/system" for width in range(30, 100): lines = install._wrap(f"{path} does not exist.", width) @@ -9617,7 +9590,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertTrue(all("/ " not in line for line in lines), lines) def test_f1_names_what_the_card_lacks(self): - """tui_audit_9 P3-7: F1 said the refusal again.""" + """F1 said the refusal again.""" muos = self.root / "MUOS" make_card(muos, "muOS") setup = install.card_setup("Onion", "retroarch") @@ -9625,7 +9598,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn(".tmp_update", choice.detail) def test_help_at_40x12_keeps_quit_and_this_help(self): - """tui_audit_9 P3-15, and Space for ticking on a keyboard.""" + """And Space for ticking on a keyboard.""" state = checked_state() press(state, "down", "down", "down", "down", "enter") state.stack.append("systems") @@ -9636,7 +9609,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("X, Space, Right/Left", " ".join(text.split())) def test_the_copy_hint_fits_at_40_columns(self): - """tui_audit_9 P3-16: cut after "copied,". On the CI runner /home + """Cut after "copied,". On the CI runner /home held three folders, and the list cut the hint: it is kept whole, the list scrolling, from a folder of this test's own.""" home = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) @@ -9654,7 +9627,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("> Use this folder", text) def test_the_miyoo_bar_says_what_a_does(self): - """tui_audit_9 P3-17: A Tick on All and None, where A unticks.""" + """A Tick on All and None, where A unticks.""" state = checked_state() state.pad = "miyoo" state.stack.append("systems") @@ -9666,7 +9639,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertIn("A Tick", install.tui_view(state, 40, 12)[-1]) def test_system_given_is_said_and_widened(self): - """tui_audit_9 P3-8: one system named, no word on the plan and no + """One system named, no word on the plan and no way to widen it.""" state = checked_state() state.cli_systems = ["gba"] @@ -9680,7 +9653,7 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertTrue(state.widen) def test_a_local_copy_draws_no_speed(self): - """tui_audit_9 P3-9: 0 B/s 0:00 left.""" + """0 B/s 0:00 left.""" out = io.StringIO() term = install.Terminal(out) term.live = True @@ -9691,7 +9664,6 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertNotIn("left", out.getvalue()) def test_the_offline_remedy_follows_the_files_it_is_about(self): - """tui_audit_9 P3-10.""" unplaced = [{"reason": "no_save_directory", "frontend": "RetroArch"}] with mock.patch.object(install, "_offline_only", return_value=True), \ contextlib.redirect_stdout(io.StringIO()) as out, \ @@ -9708,13 +9680,12 @@ class AuditSixteenAndNineScreens(unittest.TestCase): self.assertLess(remedy, save) def test_first_install_says_where_to_type(self): - """code_audit_16 P3-4, tui_audit_9 P3-19.""" page = (REPO_ROOT / "wiki" / "first-install.md").read_text(encoding="utf-8") self.assertNotIn("There, type its name", page) self.assertIn("Press / and type the device", page) def test_a_folder_that_cannot_be_created_ends_on_an_error_and_a_summary(self): - """code_audit_16 P3-3: Cannot create, then end 2 and nothing else.""" + """Cannot create, then end 2 and nothing else.""" import subprocess # noqa: PLC0415 from test_install_offline import PAYLOAD, _offline_env, _pack @@ -9766,7 +9737,7 @@ class EdgesTheMutantsFound(unittest.TestCase): return root / "card" def test_a_card_is_looked_for_up_to_its_mount_point_and_no_further(self): - """code_audit_15 P3-2 reads every folder up to the mount point: + """Every folder up to the mount point is read: three at most took MUOS/a/b/c/d for a KNULLI card.""" card = self.card("KNULLI") setup = install.card_setup("KNULLI", "knulli") @@ -9803,7 +9774,7 @@ class EdgesTheMutantsFound(unittest.TestCase): class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): - """code_audit_18 and tui_audit_11: what the cards, the screens and the + """What the cards, the screens and the docs answer, line mode's parity being in LineModeAndScreenDecideAlike.""" def setUp(self): @@ -9818,7 +9789,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.addCleanup(patcher.stop) def test_a_renamed_card_is_named_by_the_file_no_menu_writes(self): - """code_audit_18 P1-1: a KNULLI card whose hostname was changed in + """A KNULLI card whose hostname was changed in its menu was a Batocera SHARE drive, Enter filled it with Batocera's list and --platform knulli was refused.""" drives = self.renamed() @@ -9844,7 +9815,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): ("batocera", "recalbox")) def test_a_share_drive_is_never_called_a_card(self): - """code_audit_18 P3-4, tui_audit_11 P3-14: "is a Batocera card" + """"is a Batocera card" and "is a Recalbox card" for their SHARE drives.""" drives = self.renamed() for name in ("Batocera as shipped", "Recalbox"): @@ -9854,7 +9825,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertNotIn(" card, which reads", choice.note) def test_two_cards_of_one_system_say_what_they_hold(self): - """tui_audit_11 P3-15: an old Onion card with 6 BIOS files and a new + """An old Onion card with 6 BIOS files and a new empty one looked the same, and Enter took the first by name.""" old = self.root / "media" / "OLDONION" make_card(old, "Onion") @@ -9871,7 +9842,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): ["Onion SD card (ONION, no BIOS folder)", "Onion SD card (OLDONION, 6 BIOS files)"]) - # tui_audit_11 P2-1: a list or a pack that records some axes only. + # a list or a pack that records some axes only. def test_a_card_plan_offers_one_remedy_first(self): for facts, locked in (({"free": 50 * 1024 ** 3, "writable": False, "cores": []}, True), @@ -9889,7 +9860,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertEqual(effects, [("run", "check")]) def test_options_offer_no_downloads_when_nothing_is_downloaded(self): - """P3-16: Parallel downloads offered for an install from a pack.""" + """Parallel downloads offered for an install from a pack.""" state = checked_state() state.stack.append("options") with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: ""}): @@ -9898,17 +9869,17 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertNotIn("jobs", [row.action for row in install.tui_rows(state)]) def test_nothing_installable_focuses_the_copy(self): - """tui_audit_11 P3-8: offline with nothing to copy, the plan focused + """Offline with nothing to copy, the plan focused Choose systems, whose systems need the internet too.""" with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}): state = checked_state() rows = install.tui_rows(state) self.assertEqual(rows[state.focus.get("plan", 0)].action, "fromcard") - # tui_audit_11 P3-2 to P3-20: the screens' polish. + # the screens' polish. def test_a_long_message_scrolls_with_its_position(self): - """P3-2: at 40x12 the offline screen dropped its remedy unsaid.""" + """At 40x12 the offline screen dropped its remedy unsaid.""" state = fresh_state() state.stack = ["error"] state.error_title = install.TUI_OFFLINE_TITLE @@ -9926,7 +9897,6 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertIn("--offline.", end) def test_a_small_window_says_why_the_questions_come_line_by_line(self): - """P3-4.""" with mock.patch.object(install, "tui_blocker", return_value="the terminal is 39x12, smaller than 40x12"), \ mock.patch.object(install, "_run", side_effect=SystemExit(0)), \ @@ -9940,7 +9910,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): "screen).", out.getvalue()) def test_one_bar_rule_per_width(self): - """P3-5: at 40 columns the plan read "A Install", Confirm "A/Enter".""" + """At 40 columns the plan read "A Install", Confirm "A/Enter".""" states = golden_states() for name in ("preview", "confirm", "result", "quit"): with self.subTest(screen=name): @@ -9949,7 +9919,6 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertNotIn("B/Esc", bar) def test_the_folder_its_config_named_is_said_under_it(self): - """P3-6, P3-7.""" state = checked_state() long_dest = Path("/home/user/" + "a-long-folder-name/" * 5 + "system") state.dest = long_dest @@ -9963,7 +9932,6 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertLessEqual(tail - at, 3) def test_the_help_while_typing_lists_what_does_not_type(self): - """P3-9.""" state = checked_state() state.stack.append("systems") state.editing = "systems" @@ -9974,16 +9942,14 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertNotIn("Tick, untick", help_text) def test_the_plan_names_core_and_region_as_line_mode(self): - """P3-11.""" state = checked_state() state.cli_systems, state.cores, state.regions = ["sony-playstation"], ["x"], ["us"] state.cli_cores, state.cli_regions = ["x"], ["us"] text = " ".join(" ".join(install.tui_view(state, 120, 40)).split()) - # The flag after the words, never alone (tui_audit_17 P3-4). + # The flag after the words, never alone. self.assertIn("(--system), 0 of 1 cores (--core), regions ranked (--region).", text) def test_pc_and_short_prefixes_find_the_computer_setups(self): - """P3-17.""" for typed in ("pc", "wi", "win"): with self.subTest(typed=typed): found = {row.value for row in install.setup_list([], set(), typed, "linux") @@ -9991,7 +9957,6 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertIn("retrobat", found) def test_a_partial_result_counts_once_then_says_the_remedy(self): - """P3-18.""" state = _installed_state(Path("/x/system")) state.summary.update(installed=6, pending=16, failed=[]) state.from_folders = [Path("/media/me/OLD")] @@ -10003,7 +9968,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertIn("They are not in", lines[1]) def test_q_is_said_as_a_quit(self): - """P3-19: q reported "stopped", the word of an interrupted run.""" + """Q reported "stopped", the word of an interrupted run.""" state = checked_state() press(state, "q") self.assertEqual(state.exit_code, install.QUIT_CODE) @@ -10015,13 +9980,11 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): ["RetroBIOS: stopped. Nothing was installed."]) def test_wide_rows_keep_the_size_near_the_name(self): - """P3-20.""" row = install.TuiRow("system", "[x] 3DO 3do", "2 files, 4.9 KB") line = str(install._row_line(row, False, 118)) self.assertLessEqual(len(line.rstrip()), install.TUI_ROW_SPREAD) def test_the_wsl_browser_titles_a_drive_by_its_letter(self): - """P3-13.""" state = fresh_state() state.stack = ["browse"] state.browse_dir = Path("/mnt/e") @@ -10033,7 +9996,7 @@ class AuditEighteenAndEleven(_CardFixtures, unittest.TestCase): self.assertNotIn("/mnt/e", title) def test_the_card_marker_table_is_written_from_the_rules(self): - """code_audit_18 P3-6, tui_audit_11 P2-2: the table left out the + """The table left out the SHARE drives. It is generated: every card rule and SHARE drive file is a row, about.info among them.""" sys.path.insert(0, str(REPO_ROOT / "scripts")) @@ -10108,13 +10071,13 @@ class TheAndroidResultReadsWhole(unittest.TestCase): words = [word for line in lines for word in line.split()] self.assertIn("--restore", words) # The command keeps it whole where its line holds it, cut to - # its last folders and said so where not (tui_audit_14 P3-8). + # its last folders and said so where not. if cols >= 60: self.assertIn(full, words) else: self.assertIn(install.TUI_SHORTENED, lines) - # Prose breaks it after a separator only, never inside a name - # (tui_audit_13 P3-3): glued again, it is whole. + # Prose breaks it after a separator only, never inside a name: + # glued again, it is whole. self.assertIn(full, re.sub(r"/ ", "/", " ".join(lines))) self.assertFalse(any(line.endswith(("retrobios-ba", "20261027-")) for line in lines), lines) @@ -10149,7 +10112,7 @@ class TheAndroidResultReadsWhole(unittest.TestCase): said = " ".join(lines) self.assertIn(f"into {bios / 'jazz2' / 'Source'}{os.sep}", said) # Defined on its own line, never spliced into the sentence naming - # the file (tui_audit_13 P3-5). + # the file. self.assertIn("files a game or a game engine reads", said) self.assertEqual([line for line in lines if "game engine reads" in line], [" Game data: files a game or a game engine reads, of no use to " @@ -10718,7 +10681,7 @@ def _game_state() -> install.TuiState: class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): - """code_audit_19 and tui_audit_12: what the screens answer, line mode's + """What the screens answer, line mode's parity being in LineModeAndScreenDecideAlike.""" def setUp(self): @@ -10750,7 +10713,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): and (value is None or mark[2][1] == value)) def test_a_tap_on_a_system_ticks_it_and_never_continues(self): - """tui_audit_12 P1-1: two taps on a system opened Confirm, and the + """Two taps on a system opened Confirm, and the next tap installed every file, the system meant to be left out with them.""" for cols, rows in ((40, 12), (80, 24)): @@ -10822,7 +10785,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertNotIn("Tap", " ".join(install.tui_view(plain, 80, 24))) def test_the_result_is_left_by_a_tap(self): - """tui_audit_12 P3-9: the result gave the mouse back, and on Termux + """The result gave the mouse back, and on Termux leaving it took the keyboard. A tap on its Exit closes it, and its commands are printed again in the terminal.""" state = _installed_state(SYSTEM_DIR) @@ -10838,7 +10801,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Root cause 2: one narrowed list drives every count. def test_the_game_data_row_and_the_save_line_follow_the_choice(self): - """tui_audit_12 P2-1: with only the GBA ticked, the plan said 1 game + """With only the GBA ticked, the plan said 1 game data file and a save file of the PlayStation.""" state = _game_state() text = " ".join(" ".join(install.tui_view(state, 120, 40)).split()) @@ -10861,7 +10824,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertNotIn("No game data", text) def test_the_game_data_row_keeps_its_state_at_40_columns(self): - """tui_audit_12 P2-2: "kept," then "left o" at 40x12.""" + """"kept," then "left o" at 40x12.""" state = _game_state() state.manifest["files"] += [ {"dest": f"game/{index}.dat", "size": 50 * 1024 ** 2, "category": "game_data", @@ -10875,7 +10838,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertRegex(line, rf"^ Game data: {word} +51(, | files, )2\.4 GB$") def test_data_files_are_named_apart(self): - """tui_audit_12 P2-3: data files beside BIOS files and game data, the + """Data files beside BIOS files and game data, the parts adding up to the count above, each kind said once.""" state = _game_state() state.check = {**state.check, "data_missing": 7, "data_bytes": 2048} @@ -10887,7 +10850,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): "folder of its own, such as Dolphin's Sys and PPSSPP's assets.", text) def test_confirm_counts_the_kinds_apart(self): - """tui_audit_12, extra criteria: the plan split BIOS files and game + """Extra criteria: the plan split BIOS files and game data, Confirm did not.""" state = _game_state() state.stack.append("confirm") @@ -10897,7 +10860,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertIn("3 BIOS files (1.0 MB) and 1 game data file (4 B).", text) def test_no_game_data_given_has_no_row(self): - """tui_audit_12 P3-5: --no-game-data given, the screen offered the + """--no-game-data given, the screen offered the game data back, line mode did not.""" state = _game_state() state.no_game_data = state.cli_no_game_data = True @@ -10906,7 +10869,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertIn("Game data: left out", [row.label for row in options]) def test_the_40_column_plan_keeps_its_folder(self): - """tui_audit_12 P3-10: at 40x12 and 40x15 the game data definition + """At 40x12 and 40x15 the game data definition pushed the BIOS folder off the plan.""" state = _game_state() for rows in (12, 15): @@ -10917,7 +10880,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Root cause 3: the version note. def test_the_version_note_is_on_the_plan_the_result_and_the_farewell(self): - """code_audit_19 P2-1, tui_audit_12 P2-4: line mode said it, the + """Line mode said it, the screen dropped the version event.""" said = ("This list was built for RetroBat 8.3.1, this machine runs 8.2.0.1. " "RetroBat's own BIOS check may report some files as wrong though they work.") @@ -10945,7 +10908,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Root cause 4: the commands the screen prints. def test_a_command_shown_keeps_offline_from_the_variable(self): - """code_audit_19 P2-2: sudo resets the environment, and the root + """Sudo resets the environment, and the root command the screen gave fetched what the offline run left out.""" state = checked_state({"free": 50 * 1024 ** 3, "writable": False, "cores": []}) with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}), \ @@ -10961,7 +10924,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Root cause 5: a chosen quit. def test_a_chosen_quit_exits_2_and_ctrl_c_130(self): - """code_audit_19 P3-1: q and Quit ended on 130, Ctrl-C's code.""" + """Q and Quit ended on 130, Ctrl-C's code.""" for keys, code in ((["q"], 2), (["esc", "enter"], 2), (["ctrl-c"], 130), (["ctrl-d"], 130)): with self.subTest(keys=keys): @@ -10983,7 +10946,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Root cause 6: paths and commands kept whole. def test_a_wrapped_command_still_keeps_the_mouse_off(self): - """code_audit_19 P3-5: the one-liner's URL wrapped in its middle, the + """The one-liner's URL wrapped in its middle, the launcher was not found in the joined text and the mouse stayed on.""" state = checked_state({"free": 50 * 1024 ** 3, "writable": False, "cores": []}) for bootstrap in ("sh", ""): @@ -10999,23 +10962,23 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertIn(url, words) def test_a_path_one_cell_too_wide_for_its_indent_loses_it(self): - """tui_audit_12 P3-7: "syste" / "m", folded by the terminal.""" + """"syste" / "m", folded by the terminal.""" path = "/home/moi/abcdefghijklmnopqrstuvw/.config/retroarch/system" width = len(path) + 1 lines = install._wrap(f"BIOS folder: {path}", width, whole="text") # Broken after a separator, the rest at the one indent of every - # folder line (tui_audit_15 P3-12): never inside a name. + # folder line: never inside a name. self.assertEqual(lines, ["BIOS folder: /home/moi/abcdefghijklmnopqrstuvw/.config/", " retroarch/system"]) # A command keeps the option with its value, the path whole where - # the line holds them (tui_audit_14 P3-8). + # the line holds them. command = install._wrap(f" python3 install.py --dest {path}", width + 10, whole="command") self.assertIn(f" --dest {path}", command) self.assertTrue(all(len(line) <= width + 10 for line in command), command) def test_the_result_spells_each_folder_one_way(self): - """tui_audit_12 P3-7: the save folder as ~/ beside full paths.""" + """The save folder as ~/ beside full paths.""" state = _installed_state(SYSTEM_DIR) state.done_saves = {"event": "saves", "files": 2, "folder": "/home/user/.config/retroarch/saves/"} @@ -11024,7 +10987,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertFalse(any(line.startswith("~") for line in lines)) def test_minui_names_the_folder_of_its_plan(self): - """tui_audit_12 P3-6: plan Bios, result the card's root.""" + """Plan Bios, result the card's root.""" card = self.root / "MINUI" state = _installed_state(card) state.platform = "minui" @@ -11067,7 +11030,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): "1;32") def test_nothing_a_beginner_looks_for_is_faint(self): - """tui_audit_12 P3-3: the filter row and Back, Quit on the bar.""" + """The filter row and Back, Quit on the bar.""" state = install.TuiState(os_type="linux", home=HOME) state.stack = ["platforms"] self.assertEqual(install._filter_row(state).style, "") @@ -11081,7 +11044,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): # Every other item. def test_a_legacy_report_past_column_161_is_read_from_the_bytes(self): - """code_audit_19 P3-2: column 163, row 137 typed [M#é, and a press + """Column 163, row 137 typed [M#é, and a press followed by q lost the q.""" press = b"\x1b[M" + bytes([32, 32 + 163, 32 + 137]) release = b"\x1b[M" + bytes([35, 32 + 163, 32 + 137]) @@ -11096,7 +11059,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertEqual(keys, want) def test_the_setup_list_aligns_its_devices(self): - """tui_audit_12 P3-1: three right edges at 120 columns, devices + """Three right edges at 120 columns, devices starting anywhere from column 20 to 70 at 80.""" state = install.TuiState(os_type="linux", home=HOME) state.stack = ["platforms"] @@ -11112,7 +11075,6 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertTrue(all(len(line.rstrip()) <= 80 for line in lines)) def test_the_copy_browser_never_offers_the_card_installed_to(self): - """tui_audit_12 P3-16.""" onion = self.root / "media" / "ONION" make_card(onion, "Onion") old = self.root / "media" / "OLD" @@ -11126,7 +11088,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertNotIn(onion, values) def test_a_card_two_systems_fit_is_offered_as_either(self): - """tui_audit_12 P2-5: the first screen said nothing was found, and + """The first screen said nothing was found, and with a KNULLI list "No KNULLI card is mounted" beside it.""" card = self.renamed()["renamed, no about.info"] with mock.patch.object(install, "_mounted_cards", return_value=[card]), \ @@ -11153,7 +11115,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertNotIn("Look again", text) def test_the_wsl_folder_question_offers_the_windows_side(self): - """tui_audit_12 P3-11: under WSL only the Linux home was offered.""" + """Under WSL only the Linux home was offered.""" sides = install.other_side("wsl", "retroarch") self.assertEqual(len(sides), 1) self.assertTrue(sides[0][0].startswith("Windows RetroArch: ")) @@ -11166,7 +11128,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertIn(sides[0][1], [row.value for row in rows if row.action == "drive"]) def test_named_by_sits_under_its_folder(self): - """tui_audit_12 P3-15: the offline remedy and the narrowing came + """The offline remedy and the narrowing came between the folder and what named it.""" cfg = self.root / "home" / ".config" / "retroarch" cfg.mkdir(parents=True) @@ -11186,7 +11148,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): if line.startswith(("For ", "Copy them")))) def test_options_name_a_save_folder_the_setup_knows(self): - """tui_audit_12 P3-15: Save folder: not known, beside a RetroArch + """Save folder: not known, beside a RetroArch whose save folder the same machine names.""" state = checked_state() state.manifest = {**state.manifest, "save_directory": {"folder": "saves", @@ -11199,7 +11161,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertEqual(label, "Save folder: ~/.config/retroarch/saves") def test_the_result_counts_what_it_replaced_and_its_kinds(self): - """tui_audit_12 P3-8: the plan said 2 wrong copies are replaced, the + """The plan said 2 wrong copies are replaced, the result counted none, and the old card's result split no kind.""" state = _installed_state(SYSTEM_DIR) state.summary = {**state.summary, "kept": [{"folder": "/x", "files": 2, "bytes": 3}]} @@ -11214,7 +11176,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): self.assertIn("Installed: 2 BIOS files.", lines) def test_the_wiki_says_where_clicks_are_off(self): - """code_audit_19 P3-6: the page promised the mouse on Windows.""" + """The page promised the mouse on Windows.""" page = (REPO_ROOT / "wiki" / "installer.md").read_text(encoding="utf-8") text = " ".join(page.split()) self.assertIn("Clicks are off in the Windows console the PowerShell command runs in", @@ -11241,7 +11203,7 @@ class AuditNineteenAndTwelve(_CardFixtures, unittest.TestCase): @unittest.skipUnless(pyte and pty and hasattr(pty, "fork"), "the pty runs need pyte and a pty") class TapsOnAPty(unittest.TestCase): - """tui_audit_12 P1-1 and P3-9 on the real install.py --tui.""" + """Taps on the real install.py --tui.""" repo = EndToEnd.repo start = EndToEnd.start @@ -11297,7 +11259,7 @@ class TapsOnAPty(unittest.TestCase): class AuditTwentyAndThirteen(unittest.TestCase): - """code_audit_20 and tui_audit_13: one choice for the run, taps that + """One choice for the run, taps that never commit what was not seen, and the words that fit.""" setUp = LineModeAndScreenDecideAlike.setUp @@ -11368,7 +11330,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): # Root cause 2: one choice for the whole run. def test_the_game_data_row_keeps_the_systems_ticked(self): - """tui_audit_13 P1-1: the plan's game data row set the ticks back to + """The plan's game data row set the ticks back to every system, and the install wrote all of them.""" state = self.game_plan() state.ticked = {"nintendo-ds"} @@ -11382,7 +11344,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn(("--no-game-data", None), install.tui_flags(state)) def test_every_check_of_the_same_list_keeps_the_choice(self): - """Root cause of tui_audit_13 P1-1: a folder to copy from added, the + """A folder to copy from added, the save folder chosen or Check again set the ticks back to every system too, as the game data row did.""" for how in ("from", "savedir", "recheck"): @@ -11404,7 +11366,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertEqual(state.ticked, {"nintendo-ds"}) def test_a_choice_the_toggle_empties_says_so_and_offers_choose_systems(self): - """tui_audit_13 P1-1: Dreamcast alone, game data left out: the plan + """Dreamcast alone, game data left out: the plan promised the whole list and Install refused.""" state = self.game_plan() state.ticked = {"sega-dreamcast"} @@ -11425,7 +11387,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertEqual(state.ticked, {"sega-dreamcast"}) def test_the_row_counts_the_list_the_check_read(self): - """code_audit_20 P2-1: under --emulator the row counted the game + """Under --emulator the row counted the game data of every system, line mode's g the emulator's alone.""" state = self.game_plan(only=("nintendo-ds",)) row = next(row for row in install.tui_rows(state) if row.action == "gamedata") @@ -11442,7 +11404,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("g) Game data: kept (1 file, 1000 B)", text) def test_line_mode_names_the_game_data_of_the_systems_chosen(self): - """tui_audit_13 P2-3: --system with --no-game-data named the game + """--system with --no-game-data named the game data of the whole list.""" files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"]), self.entry("doom/doom1.wad", b"wad" * 10, ["doom"], category="game_data")] @@ -11462,7 +11424,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertNotIn("unknown system", text) def test_the_run_head_counts_three_kinds_and_defines_them(self): - """code_audit_20 P3-5: a run without the menu split two kinds beside + """A run without the menu split two kinds beside the plan's three, from a second counting function.""" self.assertFalse(hasattr(install, "split_words")) files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"]), @@ -11476,7 +11438,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("Game data: files a game or a game engine reads", head) def test_the_cores_of_the_systems_chosen_come_first(self): - """tui_audit_13 P3-12: with --system sony-playstation, Cores opened + """With --system sony-playstation, Cores opened on every core of the list.""" state = checked_state() state.cli_systems = ["sony-playstation"] @@ -11492,7 +11454,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): if row.action == "core"], ["mesen", "pcsx_rearmed"]) def test_line_mode_counts_the_systems_that_hold_a_file(self): - """tui_audit_13 P3-11: "2 of 8" in line mode, "1 of 8" on the screen.""" + """"2 of 8" in line mode, "1 of 8" on the screen.""" files = [self.entry("ds.bin", b"ds", ["nintendo-ds"]), self.entry("dc/game.dat", b"dc", ["sega-dreamcast"], category="game_data"), self.entry("psx.bin", b"psx", ["sony-playstation"])] @@ -11519,7 +11481,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): # Root cause 3: copies and packs. def test_confirm_counts_the_copies_a_folder_holds(self): - """code_audit_20 P2-2: Confirm called the files packx holds + """Confirm called the files packx holds downloads, offline and online.""" state = checked_state() state.found = [found(event["dest"], "/media/old") for event in FILES] @@ -11533,7 +11495,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertNotIn("to download,", text) def test_an_old_card_holding_every_file_in_place_is_not_called_empty(self): - """tui_audit_13 P3-4: "packx holds none of these files" when all 22 + """"packx holds none of these files" when all 22 were in place.""" state = checked_state() state.check = {**CHECK, "present": 5, "missing": 0, "wrong_hash": 0, @@ -11545,7 +11507,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertNotIn("holds none of these files", text) def test_the_plan_says_what_the_pack_lacks_before_a_size(self): - """tui_audit_13 P3-8: "8358 files to install from the pack, 6.6 GB" + """"8358 files to install from the pack, 6.6 GB" from a pack that held none of them.""" state = checked_state() @@ -11566,7 +11528,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertNotIn("install", [row.action for row in install.tui_rows(state)]) def test_a_failed_pack_install_leaves_no_folder_behind(self): - """tui_audit_13 P3-8: 405 empty folders and a saves folder.""" + """405 empty folders and a saves folder.""" pack_dir = self.root / "downloads" pack_dir.mkdir() pack = pack_dir / "RetroArch_BIOS_Pack.zip" @@ -11585,7 +11547,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): # Root cause 4: Choose another folder. def test_choose_another_folder_opens_the_folder_screen(self): - """code_audit_20 P2-3: with --dest the create screen is alone on the + """With --dest the create screen is alone on the stack, and Choose another folder asked Quit?.""" state = fresh_state() state.platform, state.dest = "retroarch", self.root / "missing" / "bios" @@ -11600,7 +11562,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): # Root cause 5: text that fits. def test_the_version_note_stays_on_the_40x12_plan_and_in_every_farewell(self): - """tui_audit_13 P3-1.""" note = "This list was built for RetroBat 8.3.1, this machine runs 8.2.0.1." state = checked_state() state.version = note @@ -11615,7 +11576,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn(note, install.tui_farewell(state)) def test_the_help_defines_game_data_at_40_columns(self): - """tui_audit_13 P3-2: the row was a choice nothing explained on the + """The row was a choice nothing explained on the Miyoo's screen.""" state = _game_state() state.mouse = True @@ -11633,7 +11594,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("such as Dolphin's Sys and PPSSPP's assets.", text) def test_the_40_column_bar_keeps_help_and_the_help_its_tap_line(self): - """code_audit_20 P3-1.""" state = checked_state() state.mouse = True state.stack.append("systems") @@ -11645,7 +11605,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("Tap Tick or untick a row, as A", text) def test_one_spelling_of_a_folder_on_the_plan_and_the_result(self): - """tui_audit_13 P3-3: "/home...i_audit13/rb/bios" on the plan, the + """"/home...i_audit13/rb/bios" on the plan, the same folder whole and folded inside a name on the result.""" dest = Path("/home/moi/retroarch_system/tmp/tui_audit13/rb/bios") for cols in (40, 80): @@ -11672,7 +11632,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertEqual("".join(spelled[0]), f"BIOS folder: {dest}") def test_a_long_path_fits_without_its_indent(self): - """tui_audit_13 P3-3: a pack path of 75 cells folded at 80 columns + """A pack path of 75 cells folded at 80 columns under an indent of 6.""" path = "/home/moi/retroarch_system/tmp/tui_audit13/pack/MinUI_2025-11_BIOS_Pack.zip" self.assertEqual(len(path), 75) @@ -11681,7 +11641,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn(f" --from-pack {path}", lines) def test_the_definition_is_said_once_and_never_spliced(self): - """tui_audit_13 P3-5.""" state = checked_state() state.systems = [] state.manifest = {**MANIFEST, "categorized": True, "omitted_files": [ @@ -11694,7 +11653,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): "data its game reads.", text) def test_the_headline_counts_every_file_once(self): - """tui_audit_13 P3-6: "8358 files and 2636 data files", and the + """"8358 files and 2636 data files", and the definition dropped at 80 columns.""" state = _game_state() state.check = {**state.check, "data_missing": 7, "data_bytes": 2048} @@ -11705,7 +11664,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("Data files: the files an emulator reads", text) def test_the_save_line_never_ends_on_its_colon(self): - """tui_audit_13 P3-7: "...goes to a folder per core under:" with no + """"...goes to a folder per core under:" with no folder at 60x20.""" state = _game_state() state.saves = {"event": "saves", "files": 1, @@ -11721,7 +11680,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertGreater(shown, 0) def test_the_result_says_how_to_copy_and_counts_one_kind_once(self): - """tui_audit_13 P3-10 and P3-14.""" state = _installed_state(SYSTEM_DIR) state.manifest = {**MANIFEST, "categorized": True} state.mouse = True @@ -11736,7 +11694,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("Shift+drag", " ".join(install.tui_view(state, 80, 24))) def test_the_old_card_result_splits_what_is_missing(self): - """tui_audit_13 P3-14: "16 still missing" where 6 were game data.""" + """"16 still missing" where 6 were game data.""" state = _game_state() state.from_folders = [Path("/media/OLD")] state.local_dests = {"gba_bios.bin": ("/media/OLD", "")} @@ -11750,14 +11708,14 @@ class AuditTwentyAndThirteen(unittest.TestCase): install.OFFLINE_FLAG_VALUE}): _title, lines = install.tui_outcome(state) # The wrong copy the check found is left in place: named as one, - # never counted as missing (code_audit_23 P3-3). + # never counted as missing. self.assertIn("1 file copied from OLD, 2 still missing, 1 wrong copy left.", lines) self.assertIn("Still missing: 1 BIOS file and 1 game data file.", lines) # Root cause 6: every other word. def test_drives_are_named_once_under_wsl_and_windows(self): - """code_audit_20 P3-3: "D:: bios" and "D:\\: bios".""" + """"D:: bios" and "D:\\: bios".""" with mock.patch.dict(install._WSL, {"active": True}): mount = Path(install._WSL["root"]) / "d" self.assertEqual(install._drive_folder(mount, "bios"), "D:\\bios") @@ -11769,7 +11727,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertEqual(install._drive_folder(stick, "bios"), "USBSTICK: bios") def test_the_linux_side_is_named_by_its_side(self): - """code_audit_20 P3-3, tui_audit_13 P3-9.""" self.assertEqual(install.side_name("wsl", "retroarch"), "Linux RetroArch") self.assertEqual(install.side_name("linux", "retroarch"), "RetroArch") state = fresh_state() @@ -11783,7 +11740,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("(does not exist yet)", text) def test_a_folder_created_where_no_setup_is_says_so(self): - """tui_audit_13 P3-9: "system is created in C:\\RetroArch-Win64, where + """"system is created in C:\\RetroArch-Win64, where RetroArch reads it" with no RetroArch there.""" state = fresh_state() missing = self.root / "RetroArch-Win64" / "system" @@ -11797,14 +11754,13 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("where RetroArch reads it", state.card_note) def test_the_needed_list_counts_one_more_system_in_words(self): - """tui_audit_13 P3-13, on the list of files an emulator needs too.""" + """On the list of files an emulator needs too.""" entries = [{"dest": f"s{n}.bin", "system": f"system-{n}", "required": True} for n in range(9)] said = " ".join(install._needed_lines(entries, "Needed")) self.assertIn("... and 1 more system (--check --verbose lists them all)", said) def test_the_farewell_names_the_option_not_the_screen(self): - """code_audit_20 P3-4.""" state = _installed_state(SYSTEM_DIR) state.summary = {**state.summary, "skipped": [ {"reason": "no_save_directory", "label": "", "files": 1, "required": False}]} @@ -11813,7 +11769,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertNotIn("Options", farewell) def test_more_systems_is_counted_in_words(self): - """tui_audit_13 P3-13: "... and 1 more systems".""" + """"... and 1 more systems".""" entries = [{"dest": f"s{n}.bin", "size": 10, "systems": [f"system-{n:02d}"]} for n in range(install.PLAN_LARGEST_SYSTEMS + 1)] out = io.StringIO() @@ -11822,7 +11778,6 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("... and 1 more system:", out.getvalue()) def test_the_systems_question_aligns_and_explains_after_the_list(self): - """tui_audit_13 P3-13.""" rows = [("mattel-intellivision", []), ("nec-pc-engine", []), (install.OTHER_SYSTEMS, [])] labels = {"mattel-intellivision": "Mattel Intellivision mattel-intellivision", @@ -11839,7 +11794,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertGreater(lines.index("A note."), lines.index(listed[-1])) def test_the_yes_stop_says_one_thing_with_a_list_or_without(self): - """tui_audit_13 P3-13, code_audit_20 P3-6: "the file list" said of a + """"the file list" said of a pack, and two wordings for one stop.""" pack = self.root / "RetroArch_BIOS_Pack.zip" with zipfile.ZipFile(pack, "w") as archive: @@ -11851,7 +11806,7 @@ class AuditTwentyAndThirteen(unittest.TestCase): self.assertIn("No supported platform detected: RetroArch was not found here, and " "the pack does not say where it goes.", said.stderr) # The standalone emulators' lists come from the network: offline, - # no request leaves the machine (code_audit_24 P3-13). + # no request leaves the machine. alone = install_run("--yes", env={**env, install.OFFLINE_VARIABLE: "1"}) self.assertIn("No supported platform detected", alone.stdout + alone.stderr) hint = install._manual_usage_hint("linux") @@ -11886,7 +11841,7 @@ class TheUsageNamesTheInstaller(unittest.TestCase): class TapsSeenBeforeTheyAct(unittest.TestCase): - """code_audit_20 P3-2 and tui_audit_13 P2-1, P2-2: a tap acts on the + """A tap acts on the frame it was made on, and never commits on one tap.""" def test_a_release_on_a_later_frame_does_nothing(self): @@ -11956,7 +11911,7 @@ class TapsSeenBeforeTheyAct(unittest.TestCase): class DoubleTapsAcrossScreens(unittest.TestCase): - """tui_audit_14 P2-1: the second tap of a double tap acted on the screen + """The second tap of a double tap acted on the screen the first one opened, at every gap measured (0, 80, 150 and 250 ms). A press within TUI_TAP_SETTLE of a new screen is dropped, and a slow deliberate second tap still acts.""" @@ -12039,7 +11994,7 @@ class DoubleTapsAcrossScreens(unittest.TestCase): self.double_tap(slow, install.TUI_TAP_SETTLE + 0.2) self.assertEqual(once.screen, "systems") # On Choose systems the first entry ticks: the slow tap pressed it - # once more, and the box is back as it was (tui_audit_17 P3-1). + # once more, and the box is back as it was. self.assertEqual(slow.screen, "systems") self.assertEqual(slow.ticked, once.ticked ^ { install.tui_rows(once)[once.focus["systems"]].value}) @@ -12064,7 +12019,7 @@ class DoubleTapsAcrossScreens(unittest.TestCase): class TwoTapsOnlyWhereFilesAreWritten(unittest.TestCase): - """tui_audit_14 P3-2 and P3-4: with the settle time in place, a second + """With the settle time in place, a second tap is asked only of an entry that writes files with nothing to look at after it, drawn in the accent and said in the help at every size.""" @@ -12110,7 +12065,7 @@ class TwoTapsOnlyWhereFilesAreWritten(unittest.TestCase): install.tui_update(state, Key("enter")) self.assertEqual(state.screen, "systems") lines = drawn(state, 80, 24) - # A tap on the bar's first entry ticks (tui_audit_17 P3-1), B goes + # A tap on the bar's first entry ticks, B goes # back, and Install counts the choice on Confirm first. self.assertEqual(tap(state, 2, len(lines) - 1), []) self.assertEqual(state.screen, "systems") @@ -12146,7 +12101,8 @@ class TwoTapsOnlyWhereFilesAreWritten(unittest.TestCase): @unittest.skipUnless(pyte and pty and hasattr(pty, "fork"), "screen tests need pyte (pip install pyte==0.8.2) and a pty") class TapsOnAPtySeeFirst(unittest.TestCase): - """tui_audit_13 P1-1, P2-1, P2-2 on the real install.py --tui.""" + """Taps that never commit a row not yet seen, on the real install.py + --tui.""" repo = EndToEnd.repo start = EndToEnd.start @@ -12191,7 +12147,7 @@ class TapsOnAPtySeeFirst(unittest.TestCase): self.assertIn(term.close(), (install.QUIT_CODE, 0)) def test_a_double_tap_on_continue_stays_on_what_it_opened(self): - # tui_audit_14 P2-1: at 0, 80, 150 and 250 ms the second tap pressed + # at 0, 80, 150 and 250 ms the second tap pressed # B/Esc Back on the Checking screen, back to the first screen. for gap in (0.0, 0.08, 0.15, 0.25): with self.subTest(gap=gap): @@ -12231,8 +12187,7 @@ class TapsOnAPtySeeFirst(unittest.TestCase): col, line = self.bar_entry(term, "Done") report = sgr(col + 1, line + 1) + sgr(col + 1, line + 1, release=True) # A double tap: the first goes back to the plan, the second lands on - # its Back inside the settle time and does nothing (tui_audit_14 - # P2-1). + # its Back inside the settle time and does nothing. time.sleep(install.TUI_TAP_SETTLE) term.send(report + report) screen = term.wait("for 1 of 2 systems") @@ -12322,7 +12277,7 @@ class TapsOnAPtySeeFirst(unittest.TestCase): class AuditTwentyOneAndFourteen(unittest.TestCase): - """code_audit_21 and tui_audit_14: one choice state in both modes, the + """One choice state in both modes, the cards found first, packs that hold nothing, and words that fit.""" setUp = LineModeAndScreenDecideAlike.setUp @@ -12348,7 +12303,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): left_out=state.no_game_data)) def test_the_game_data_toggle_never_unticks_a_system_for_good(self): - """tui_audit_14 P2-2: DS and Dreamcast ticked, game data left out + """DS and Dreamcast ticked, game data left out then kept: Dreamcast was gone, and so was the row to turn it back.""" state = self.game_plan() state.ticked = {"nintendo-ds", "sega-dreamcast"} @@ -12380,7 +12335,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): for entry in manifest["files"]], categorized=True) def test_line_mode_offers_no_enter_for_an_emptied_choice(self): - """code_audit_21 P3-6: Dreamcast alone, game data left out: line mode + """Dreamcast alone, game data left out: line mode said "0 files, 0 B, for 0 of 2 systems", offered Enter and a command that installs nothing, then refused the Enter.""" text, asked = self.line_run(_args(manifest=self.game_listing(), dest=self.here, @@ -12397,7 +12352,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertEqual(asked[-1], "> ") def test_a_kept_choice_in_place_offers_no_install(self): - """code_audit_21 P3-4: one system ticked, its files in place, the + """One system ticked, its files in place, the plan said "About 0 files" over Install, and Confirm "Everything is in place" over Install too.""" state = checked_state() @@ -12418,7 +12373,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertEqual(state.exit_code, 0) def test_offline_the_plan_counts_the_systems_ticked(self): - """code_audit_21 P3-5: offline, one system ticked, the plan counted + """Offline, one system ticked, the plan counted every file of the list beside "For your 1 of 3 systems".""" state = checked_state() folder = str(self.root / "from1") @@ -12443,10 +12398,10 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): return games_part(self.root / "media" / name) def test_an_arkos_card_is_found_and_comes_first(self): - """tui_audit_14 P2-3: an EASYROMS partition mounted, "Nothing was + """An EASYROMS partition mounted, "Nothing was found here", and two presses of Enter filled this computer's ~/.config/retroarch/system for a RetroArch that was not there. An - AmberELEC GAMES is AmberELEC's own card (tui_audit_16 P2-1).""" + AmberELEC GAMES is AmberELEC's own card.""" for name in ("EASYROMS",): with self.subTest(card=name): card = self.easyroms(name) @@ -12457,8 +12412,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): mock.patch.object(install.Path, "home", return_value=home): state, _effects = install.tui_start(_args(), "linux") text = self.screen(state) - # Named on the first screen, its plan one Enter away - # (tui_audit_17 P2-3). + # Named on the first screen, its plan one Enter away. self.assertIn(f"> ArkOS SD card ({name}", text) self.assertNotIn("Nothing was found here", text) install.tui_update(state, Key("enter")) @@ -12479,7 +12433,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): return pack def test_line_mode_names_what_the_pack_lacks_before_its_plan(self): - """code_audit_21 P3-3: --dry-run promised 23 files, --check said to + """--dry-run promised 23 files, --check said to fetch them, the install counted 23 beside the size of 20 and advised retrying files that always fail.""" files = [self.entry(f"bios{n}.bin", b"x" * (n + 1), ["nintendo-gba"]) @@ -12514,7 +12468,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertFalse(dest.exists()) def test_a_pack_holding_none_offers_no_install_with_data_files(self): - """tui_audit_14 P3-1: data files left, the pack holding none of the + """Data files left, the pack holding none of the files nor the trees: Install was offered and failed every file, and the result never named the data files.""" state = checked_state() @@ -12550,7 +12504,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertIn("7 data files not installed: not in RetroArch_BIOS_Pack.zip.", lines) def test_a_command_at_40_columns_breaks_between_shell_words(self): - """tui_audit_14 P3-8: the terminal folded commands inside a word, + """The terminal folded commands inside a word, "--platform" ended a line with its value on the next.""" words = ["--platform", "retroarch", "--dest", "/a/b/c/system", "--manifest", "/home/moi/x.json", "--system", "nintendo-gba"] @@ -12583,7 +12537,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertIn("/home/moi/retroarch_system/tmp/tui_audit14/sb/a/b/bios", farewell) def test_a_folder_on_its_own_line_has_one_indent(self): - """tui_audit_14 P3-9: the save folder at the label's indent, the + """The save folder at the label's indent, the BIOS folder under it, a path's last piece without its indent.""" state = checked_state() state.dest = Path("/home/moi/retroarch_system/tmp/tui_audit14/sb/esmiyoo/home/" @@ -12607,7 +12561,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertEqual(indents, {3}, pieces) def test_no_shift_where_there_is_no_shift_key(self): - """tui_audit_14 P3-3: "Shift and a drag" on Android.""" + """"Shift and a drag" on Android.""" for os_type, said in (("linux", True), ("android", False)): with self.subTest(os_type=os_type): state = _installed_state(SYSTEM_DIR) @@ -12620,7 +12574,6 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertEqual("Shift+drag" in text, said) def test_the_40x12_setup_never_ends_mid_sentence(self): - """tui_audit_14 P3-5.""" state = fresh_state() state.notes = [install.TUI_ESDE_NOTE] text = [str(line).strip() for line in install.tui_view(state, 40, 12)] @@ -12630,7 +12583,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertIn(install.TUI_ESDE_NOTE, text) def test_the_40x12_plan_keeps_its_folder_and_version_note(self): - """tui_audit_14 P3-6: the plan named ~/.var/app/ as the folder, and + """The plan named ~/.var/app/ as the folder, and the version note was absent.""" state = checked_state() state.dest = HOME / ".var/app/org.libretro.RetroArch/config/retroarch/system" @@ -12643,7 +12596,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertIn("> Install", lines) def test_one_count_said_once_in_both_modes(self): - """tui_audit_14 P3-10: "22 files installed." over "22 files copied + """"22 files installed." over "22 files copied from packx.", and line mode's Location, wrong hash and zero count.""" state = _installed_state(SYSTEM_DIR) state.summary["installed"] = 5 @@ -12663,14 +12616,14 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertNotIn("already up to date.\")\n", source.split("\nDone.", 1)[-1][:300]) def test_quit_names_stay_once(self): - """tui_audit_14 P3-11: "A/Enter Stay B/Esc Stay".""" + """"A/Enter Stay B/Esc Stay".""" state = fresh_state() state.stack.append("quit") state.focus["quit"] = 1 self.assertEqual(str(install.tui_view(state, 80, 24)[-1]).count("Stay"), 1) def test_the_yes_stop_example_keeps_yes(self): - """tui_audit_14 P3-12: a script copying the example stopped at a + """A script copying the example stopped at a question.""" files = [self.entry("gba_bios.bin", b"gba", ["nintendo-gba"])] listing = self.listing("retroarch", files) @@ -12681,7 +12634,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertIn(" --yes", example) def test_the_systems_question_fits_the_terminal(self): - """code_audit_21 P3-9: 53 of 66 rows wider than 80 columns.""" + """53 of 66 rows wider than 80 columns.""" rows = [(f"system-{n}", [{"dest": f"{n}.bin", "size": 10 ** n}]) for n in range(6)] labels = {"system-0": "Sega Dreamcast-based arcade boards, each " "them sega-dreamcast-arcade", @@ -12700,13 +12653,12 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): self.assertEqual(len(sizes), 1, printed) def test_the_save_dir_sentence_is_written_once(self): - """code_audit_21 P3-10.""" source = (REPO_ROOT / "install.py").read_text(encoding="utf-8") self.assertEqual(source.count('"Name it with --save-dir next time."'), 1) self.assertEqual(source.count("args.declared_only or len(files) + game_data_cut"), 1) def test_a_missing_folder_does_not_exist_yet_on_every_row(self): - """code_audit_21 P3-7: line mode said "(created)" of folders nobody + """Line mode said "(created)" of folders nobody created, and the screen said "does not exist yet" of the Windows row alone.""" drives = [self.root / "media" / "D", self.root / "media" / "E"] @@ -12735,7 +12687,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): card = self.easyroms() text, asked = self.line_run(_args(manifest=self.game_listing(), dry_run=True, declared_only=False), [""], mounts=[card]) - # Found as the screen finds it, under Enter (tui_audit_17 P2-3). + # Found as the screen finds it, under Enter. self.assertIn(f"Found ArkOS at {card / 'bios'} (RetroArch files)", text) self.assertNotIn("Nothing was found here", text) self.assertIn("Enter for ArkOS SD card (EASYROMS)", asked[0]) @@ -12744,7 +12696,7 @@ class AuditTwentyOneAndFourteen(unittest.TestCase): class AuditTwentyTwoAndFifteen(unittest.TestCase): - """code_audit_22 and tui_audit_15: a drive is a handheld's card only by + """A drive is a handheld's card only by the files its system writes, one settle from the frame shown, one vocabulary and one count per run, and the focus after an action.""" @@ -12785,7 +12737,7 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): return state, self.screen(state, 80, 40), install.tui_rows(state) def test_a_data_drive_or_a_stick_is_no_card(self): - """code_audit_22 P2-1: a data drive holding bios/, snes/ and Music/ + """A data drive holding bios/, snes/ and Music/ was "a card in the reader", and three presses of Enter put the list on it. A stick with bios/ alone is no card either: both are listed, never under Enter, and a plain line says why.""" @@ -12818,8 +12770,7 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): def test_the_layouts_handhelds_write_are_cards(self): """ArkOS's EASYROMS, AmberELEC's GAMES and EmuELEC's EEROMS, each with the folders its own image writes there. ArkOS's reads - RetroArch's list, the two others are their systems' own cards - (tui_audit_16 P2-1).""" + RetroArch's list, the two others are their systems' own cards.""" arkos = games_part(self.root / "media" / "EASYROMS") amber = games_part(self.root / "media" / "GAMES") emuelec = self.drive("EEROMS", ("bios", "nes", "bezels")) @@ -12829,7 +12780,7 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): mock.patch.object(install, "_mount_points", return_value=frozenset()): self.assertEqual([install.games_part(mount).name for mount in mounts], ["ArkOS", "AmberELEC", "EmuELEC"]) - # The three are their systems' own cards (tui_audit_17 P2-3). + # The three are their systems' own cards. self.assertEqual([install.card_system(mount) for mount in mounts], [("retroarch", arkos / "bios", "ArkOS"), ("amberelec", amber, "AmberELEC"), @@ -12840,14 +12791,14 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): [None, None, None]) def test_a_card_beside_a_data_drive_comes_first(self): - """code_audit_22 P2-1: the ArkOS card and the data drive mounted, + """The ArkOS card and the data drive mounted, the data drive sorted first and took Enter. The card comes first in both modes, the drive listed after it with its note.""" data = self.drive("DATA", ("bios", "snes", "Music")) card = games_part(self.root / "media" / "EASYROMS") mounts = [data, card] state = self.first_screen(mounts) - # The card is the setup found, under Enter (tui_audit_17 P2-3). + # The card is the setup found, under Enter. text = self.screen(state) self.assertIn("> ArkOS SD card (EASYROMS", text) with mock.patch.object(install, "_mounted_cards", return_value=mounts), \ @@ -12860,14 +12811,13 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): self.assertIn(f"BIOS folder: {card / 'bios'}", text) def test_two_cards_are_spoken_of_in_the_plural(self): - """code_audit_22 P3-2: "Cards are in the reader (DATA, EASYROMS): + """"Cards are in the reader (DATA, EASYROMS): choose its system", then "The card in the reader" of one of two.""" arkos = games_part(self.root / "media" / "EASYROMS") second = games_part(self.root / "media" / "ROMS2") mounts = [arkos, second] state = self.first_screen(mounts) - # Each card its folders prove is a setup found, by its own name - # (tui_audit_17 P2-3). + # Each card its folders prove is a setup found, by its own name. text = self.screen(state) self.assertIn("ArkOS SD card (EASYROMS", text) self.assertIn("ArkOS SD card (ROMS2", text) @@ -12878,7 +12828,7 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): self.assertNotIn("in the reader", text) def test_a_fixed_partition_is_told_from_a_card(self): - """code_audit_22 P2-1: every mount under /media and /mnt, and on + """Every mount under /media and /mnt, and on Windows every drive letter, was a card. A whole partition of a disk sysfs calls fixed is not, a USB or MMC one is, a folder bound in place says nothing, and Windows answers by GetDriveTypeW.""" @@ -12921,7 +12871,7 @@ class AuditTwentyTwoAndFifteen(unittest.TestCase): # install.py whose tui_view takes SLOW seconds on the first frame of each -# screen, as a slower device takes to lay one out (code_audit_22 P3-1). +# screen, as a slower device takes to lay one out. SLOW_VIEW = """ import os, sys, time sys.argv[0] = {install!r} @@ -12943,7 +12893,7 @@ sys.exit(install.main()) @unittest.skipUnless(pyte and pty and hasattr(pty, "fork"), "screen tests need pyte (pip install pyte==0.8.2) and a pty") class TheSettleRunsFromTheFrameShown(unittest.TestCase): - """code_audit_22 P3-1: the settle was stamped before the layout, so on + """The settle was stamped before the layout, so on a slow one the second click of a double click on Options' Back reached the plan's Quit.""" @@ -12983,7 +12933,7 @@ class TheSettleRunsFromTheFrameShown(unittest.TestCase): class OnePowerShellRule(unittest.TestCase): - """code_audit_22 P3-5: the words of a command asked RETROBIOS_BOOTSTRAP + """The words of a command asked RETROBIOS_BOOTSTRAP or the detected system, its line ends RETROBIOS_BOOTSTRAP or os.name: with RETROBIOS_OS=windows on Linux one command had PowerShell's quotes and sh's line ends, and pasted into either shell it broke.""" @@ -13017,7 +12967,7 @@ class OnePowerShellRule(unittest.TestCase): class EachDataTreeReadOnce(unittest.TestCase): - """code_audit_22 P3-3: the count line, the check, the events and the + """The count line, the check, the events and the install each read and hashed every data tree in place, twice per run on an SD card through a reader.""" @@ -13075,7 +13025,7 @@ class EachDataTreeReadOnce(unittest.TestCase): class OneVocabularyOneCount(unittest.TestCase): - """code_audit_22 P3-4, tui_audit_15 P3-6 to P3-10: line mode said "in + """Line mode said "in place" then "up to date", "wrong copies" then "wrong hash", counted twice, left the data files out of its last line, and the screen focused Install for a pack holding none of the files.""" @@ -13164,7 +13114,7 @@ class OneVocabularyOneCount(unittest.TestCase): self.assertNotIn("A file with a", text) def test_line_mode_with_from_counts_once(self): - """tui_audit_15 P3-8 and P3-9: no found count before Enter, the + """No found count before Enter, the plan said again after it, Copying twice, the result's count twice, and no command on a Finished with files missing.""" listing, dest, old = self.two_files() @@ -13189,7 +13139,7 @@ class OneVocabularyOneCount(unittest.TestCase): self.assertNotIn("files installed", after) def test_the_last_offline_line_counts_the_data_files(self): - """tui_audit_15 P3-6: "0 in place, 10994 missing", then "Nothing + """"0 in place, 10994 missing", then "Nothing installed: 8358 files need the internet".""" listing, dest, _old = self.two_files() listed = json.loads(listing.read_text()) @@ -13204,7 +13154,7 @@ class OneVocabularyOneCount(unittest.TestCase): self.assertIn("Nothing installed: 3 files need the internet", text) def test_a_pack_holding_none_offers_no_install(self): - """tui_audit_15 P3-7: a data tree whose folder is the BIOS folder + """A data tree whose folder is the BIOS folder itself (blueMSX) made any pack hold a data file: Install focused, and the result counted 8252 failed beside 10888 missing.""" pack = self.root / "RetroArch_BIOS_Pack.zip" @@ -13229,7 +13179,7 @@ class OneVocabularyOneCount(unittest.TestCase): class FocusAfterAnAction(unittest.TestCase): - """tui_audit_15 P3-1, P3-3, P3-4 and P3-5: one tap on the focused + """One tap on the focused Install row armed nothing visible, the result's Put RetroBIOS on this card was cut at 40x12, the Game data row lost the focus once changed, and a choice already in place opened on Options.""" @@ -13341,7 +13291,7 @@ class FocusAfterAnAction(unittest.TestCase): class TextThatFits(unittest.TestCase): - """tui_audit_15 P3-2, P3-12, P3-13 and P3-11: a pack's name cut in a + """A pack's name cut in a command, folder lines at two indents, the 40x12 plan dropping the version note, and the --from plan without its kinds.""" @@ -13392,7 +13342,7 @@ class TextThatFits(unittest.TestCase): class TheFromPlanSaysItsKinds(unittest.TestCase): - """tui_audit_15 P3-11: every file found in the folder, the plan named + """Every file found in the folder, the plan named the Game data row and said neither the kinds nor what game data is.""" def test_the_kinds_and_the_definition_stay(self): @@ -13413,7 +13363,7 @@ class TheFromPlanSaysItsKinds(unittest.TestCase): class TheSystemsQuestionFits(unittest.TestCase): - """code_audit_22 P3-6, tui_audit_15 P3-14: the size column was placed + """The size column was placed for the longest size, so 60 of 66 systems took two lines and 26 still passed 80 columns.""" @@ -13449,7 +13399,7 @@ class TheSystemsQuestionFits(unittest.TestCase): # 80-column question took 127 lines for 66 systems. # At 40 columns a shared size takes a line more: its first # part alone was printed beside a long name, the shared - # files unsaid (tui_audit_16 P3-5). + # files unsaid. limit = (len(systems) + shared + 10 if cols == 80 else 2 * len(systems) + shared + 12) self.assertLessEqual(len(lines), limit) @@ -13466,7 +13416,7 @@ class TheSystemsQuestionFits(unittest.TestCase): class AuditTwentyThreeAndSixteen(unittest.TestCase): - """code_audit_23 and tui_audit_16: a card its markers prove is that + """A card its markers prove is that system's card everywhere, counts and states that tell the truth, one width for every layout, line mode's order and words as the screen's, and a tap that shows it was seen.""" @@ -13531,7 +13481,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): # Root cause 1: a card its markers prove is that system's card. def test_a_games_part_is_its_systems_card_in_both_modes(self): - """tui_audit_16 P2-1: the GAMES card AmberELEC's folders prove, and + """The GAMES card AmberELEC's folders prove, and the EEROMS card EmuELEC's prove, read "A card is in the reader: choose its system" with RetroArch focused, and two presses of Enter put RetroArch's list on them.""" @@ -13551,7 +13501,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): shutil.rmtree(card) def test_their_own_routes_take_the_card_they_prove(self): - """tui_audit_16 P2-1: --platform amberelec said it "cannot tell an + """--platform amberelec said it "cannot tell an AmberELEC card by its files" of the card holding gamedata/ and homebrew/, and line mode offered no Enter for it.""" for plat, name, make in (("amberelec", "AmberELEC", self.amberelec), @@ -13587,7 +13537,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): shutil.rmtree(stick) def test_an_arkos_card_from_any_year_is_a_card(self): - """code_audit_23 P3-1: ArkOS's default trees of 2020 hold no themes/ + """ArkOS's default trees of 2020 hold no themes/ (9664c869 none of themes and launchimages, 495eb210 and c14afbe5 launchimages only), and the 12262020 update skipped the themes of a card with under 1 GB free. Every tree holds bgmusic/. A data drive @@ -13636,7 +13586,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): return text, asked, dest def test_the_head_never_calls_a_wrong_copy_in_place(self): - """code_audit_23 P3-2: a wrong copy of the right size was in place + """A wrong copy of the right size was in place for the head, which said "1 found in old, nothing to download" over a run that left it.""" text, _asked, dest = self.wrong_copy_run([""]) @@ -13645,7 +13595,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertEqual((dest / "a.bin").read_bytes(), b"Z" * 64) def test_a_wrong_copy_left_is_said_as_one(self): - """code_audit_23 P3-3: the result said "1 still missing" of a file + """The result said "1 still missing" of a file --check counts as a wrong copy.""" text, _asked, _dest = self.wrong_copy_run([""]) self.assertIn("Finished with files missing.", text) @@ -13654,7 +13604,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertNotIn("still missing", text.rsplit("Finished", 1)[1]) def test_a_count_agrees_with_its_verb(self): - """code_audit_23 P3-4: "1 need the internet" on the plan, and on + """"1 need the internet" on the plan, and on line mode's data tree line.""" self.assertEqual(install.agree(1, "needs", "need"), "1 needs") self.assertEqual(install.agree(2, "needs", "need"), "2 need") @@ -13673,7 +13623,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertNotRegex(source, r"\} need the internet") def test_line_mode_says_what_is_still_missing_before_the_remedy(self): - """tui_audit_16 P3-3: "They are not in OLD" followed "Installed: 6 + """"They are not in OLD" followed "Installed: 6 BIOS files", where the screen puts "Still missing:" between them.""" bios, game = b"B" * 32, b"G" * 32 listing = self.listing("retroarch", [ @@ -13696,7 +13646,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertLess(end.index("Installed:"), end.index("Still missing:")) def test_a_rerun_with_everything_in_place_offers_nothing(self): - """tui_audit_16 P3-4: line mode offered "Enter) install what is + """Line mode offered "Enter) install what is found", then said "Everything is in place." twice.""" data = b"A" * 64 listing = self.listing("retroarch", [self.entry("a.bin", data, ["nintendo-gba"])]) @@ -13711,7 +13661,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertEqual(text.count(install.EVERYTHING_IN_PLACE), 1) def test_line_mode_names_the_files_it_cannot_supply(self): - """tui_audit_16 P3-6: "Not installable: 37 files (1 required, not + """"Not installable: 37 files (1 required, not found: 37)" read as a sum, and line mode never named the file the screen names, nor its folder.""" listing = self.listing("retroarch", [ @@ -13739,7 +13689,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): "no_save_directory": 2})) def test_a_system_emptied_by_no_game_data_is_named(self): - """tui_audit_16 P3-7: --system nintendo-ds,sega-dreamcast with + """--system nintendo-ds,sega-dreamcast with --no-game-data: "For 1 of 8 systems (--system)", Dreamcast unsaid until after Enter.""" manifest = self.game_manifest() @@ -13766,7 +13716,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertIn(words, self.screen(state, 100, 40)) def test_a_run_with_failures_counts_once(self): - """tui_audit_16 P3-11: "Done. 44 files installed." then "38 files + """"Done. 44 files installed." then "38 files copied from E:\\, 4 downloaded, 2 still missing." gave two counts, the two that failed as missing. Each mode says one, failures named.""" out = io.StringIO() @@ -13795,7 +13745,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertNotIn("1 installed, 1 failed.", lines) def test_check_never_says_a_missing_file_was_opened(self): - """tui_audit_16 P3-12: "missing: nintendo-ds_0.bin" then "opened at + """"missing: nintendo-ds_0.bin" then "opened at ..." read as a file that was opened.""" entry = {"dest": "a.bin", "systems": ["nintendo-gba"], "cores": None} self.assertEqual(install.opened_line(entry, {}, self.here), @@ -13807,7 +13757,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): # Root cause 3: one width with a floor. def test_a_terminal_of_no_size_has_the_fallback(self): - """code_audit_23 P3-5: Python 3.8 gives a pty of no size as 0 and 0. + """Python 3.8 gives a pty of no size as 0 and 0. The plan printed "0 systems, the largest first:" and the progress line lost every figure but its percentage.""" with mock.patch.object(install.shutil, "get_terminal_size", @@ -13843,7 +13793,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): return text[text.index("Systems:"):min(ends, default=len(text))].splitlines() def test_the_systems_question_stays_inside_the_terminal(self): - """tui_audit_16 P3-5: 6 lines of 81 cells at 80 columns, 16 of 41 at + """6 lines of 81 cells at 80 columns, 16 of 41 at 40, "shared" and "platform" alone on a line.""" for cols in (100, 80, 60, 40, 30): with self.subTest(cols=cols): @@ -13858,7 +13808,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertIn("this platform does not list", note) def test_the_setup_list_never_folds_inside_a_word(self): - """tui_audit_16 P3-15: at 39 columns "Miy" / "oo Flip".""" + """At 39 columns "Miy" / "oo Flip".""" for cols in (80, 39, 30): with self.subTest(cols=cols): with mock.patch.object(install.shutil, "get_terminal_size", @@ -13876,10 +13826,10 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): # Root cause 4: line mode in the screen's order and words. def test_on_wsl_the_card_comes_first_in_both_modes(self): - """code_audit_23 P3-6: line mode numbered Windows RetroArch 1) and + """Line mode numbered Windows RetroArch 1) and the card 2), where the screen put the card first. One order for both: the other side first, then the drives (an ArkOS card is now a - setup found, tui_audit_17 P2-3).""" + setup found).""" data = self.drive("DATA", ("bios", "snes")) windows = Path("/mnt/c/RetroArch-Win64/system") side = [("Windows RetroArch: C:\\RetroArch-Win64\\system", windows)] @@ -13902,7 +13852,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertEqual([row.value for row in rows], [windows, data / "bios"]) def test_nothing_found_is_said_once(self): - """tui_audit_16 P3-2: "Nothing was found here." twice, and after "A + """"Nothing was found here." twice, and after "A card is in the reader".""" # The standalone emulators' lists come from the network: none here. with mock.patch.object(install, "_install_standalone_folders", return_value=False): @@ -13910,12 +13860,12 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertEqual(text.count("Nothing was found here."), 1) card = games_part(self.root / "media" / "EASYROMS") text, _asked = self.line_run(_args(declared_only=False), [], mounts=[card]) - # The card its folders prove is found (tui_audit_17 P2-3). + # The card its folders prove is found. self.assertIn("ArkOS SD card (EASYROMS)", text) self.assertNotIn("Nothing was found here", text) def test_the_bios_only_drive_note_is_one_plain_sentence(self): - """tui_audit_16 P3-9: "listed, not chosen", "(card or drive)" under + """"listed, not chosen", "(card or drive)" under a note saying no card, two parentheses side by side, and "keeps them" after a title.""" data = self.drive("DATA", ("bios", "snes", "Music")) @@ -13936,7 +13886,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertNotIn("keeps them", said) def test_the_same_choice_is_one_command_in_both_modes(self): - """tui_audit_16 P3-14: the screen wrote --manifest before --from, + """The screen wrote --manifest before --from, line mode after it.""" hint = install.Invocation() hint.os_type = "linux" @@ -13961,7 +13911,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): # Root cause 5: interaction. def test_a_tap_on_a_focused_row_shows_it_was_seen(self): - """tui_audit_16 P3-8: one tap on the focused Onion row showed + """One tap on the focused Onion row showed nothing, a second continued.""" state = fresh_state() state.stack = ["setup"] @@ -13976,7 +13926,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertNotEqual(tap(state, 4, row), []) def test_a_phone_bar_names_the_enter_key(self): - """tui_audit_16 P3-13: Termux at 40 columns said "A Continue", and + """Termux at 40 columns said "A Continue", and the a key does nothing.""" state = install.TuiState(os_type="android", home=HOME) state.pad = install.tui_pad_route("android", {}) @@ -13989,7 +13939,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertRegex(str(install.tui_view(state, 40, 12)[-1]), r"(^| )A ") def test_which_folder_keeps_its_folder_at_40_by_12(self): - """tui_audit_16 P3-1: with two drives holding bios, Which folder? + """With two drives holding bios, Which folder? at 40x12 dropped the folder "Use this folder" stands for.""" data = self.drive("DATA", ("bios", "snes", "Music")) stick = self.drive("STICK", ("bios",)) @@ -14088,7 +14038,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): @unittest.skipIf(sys.version_info < (3, 9), "the site generator needs Python 3.9") def test_which_pack_names_the_first_screen(self): - """tui_audit_16 P3-10: which-pack said the command opens a screen + """Which-pack said the command opens a screen where Install and Choose systems are, the second screen.""" sys.path.insert(0, str(REPO_ROOT / "scripts")) self.addCleanup(sys.path.remove, str(REPO_ROOT / "scripts")) @@ -14102,7 +14052,7 @@ class AuditTwentyThreeAndSixteen(unittest.TestCase): self.assertLess(words.index(install.TUI_FOUND_TITLE), words.index(install.TUI_INSTALL_ROW)) self.assertNotIn("opens a screen", words) - # Nothing found, Which folder? comes before the plan (tui_audit_17 P3-9). + # Nothing found, Which folder? comes before the plan. self.assertIn(f"**{install.TUI_FOLDER_TITLE}**", words) self.assertLess(words.index(install.TUI_FOLDER_TITLE), words.index(install.TUI_INSTALL_ROW)) @@ -14117,7 +14067,7 @@ def core_list(path: Path, files: list) -> Path: class AuditTwentyFourAndSeventeen(unittest.TestCase): - """code_audit_24 and tui_audit_17: the cores the run accepts, one tick + """The cores the run accepts, one tick list, a folder failure said as it happened, every proven card named, reads that show, and tests that leave the host alone.""" @@ -14164,7 +14114,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): return state def test_cores_lists_what_the_run_accepts_and_an_untick_runs(self): - """tui_audit_17 P1-1: Cores listed 189 cores where --core accepted 181, + """Cores listed 189 cores where --core accepted 181, and an untick sent the 8 save-folder-only cores: "unknown core".""" events = self.check_events() self.assertEqual(next(e for e in events if e["event"] == "set_aside")["dests"], @@ -14185,7 +14135,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertNotIn("unknown core", done.stdout + done.stderr) def test_both_modes_count_out_of_the_cores_the_run_keeps(self): - """code_audit_24 P3-3: line mode said "1 of 181 cores", the screen + """Line mode said "1 of 181 cores", the screen "1 of 189", and 22 more under --no-game-data.""" for no_game_data in (False, True): with self.subTest(no_game_data=no_game_data): @@ -14217,7 +14167,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): return state def test_an_untick_keeps_the_other_systems_cores(self): - """code_audit_24 P3-1: with --system sony-playstation, one untick on + """With --system sony-playstation, one untick on pcsx_rearmed cleared mesen, drawn ticked under the other systems.""" state = checked_state() state.ticked = {"sony-playstation"} @@ -14233,7 +14183,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual([v for f, v in install.tui_flags(state) if f == "--core"], ["mesen"]) def test_a_core_of_another_system_is_not_all_cores(self): - """code_audit_24 P3-2: mesen ticked alone with the PlayStation chosen + """Mesen ticked alone with the PlayStation chosen read "Cores: all", the run keeping none of pcsx_rearmed's files.""" state = checked_state() state.ticked = {"sony-playstation"} @@ -14245,7 +14195,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual(install.core_count_words(["mesen"], ["pcsx_rearmed"]), "0 of 1 cores") def test_none_then_done_says_why_on_a_long_list(self): - """tui_audit_17 P2-4: on 189 cores the status and the sentence were + """On 189 cores the status and the sentence were dropped, Done with nothing ticked did nothing visible.""" state = checked_state() state.manifest = {**MANIFEST, "files": [ @@ -14267,7 +14217,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual(state.screen, "cores") def test_core_rows_say_what_each_core_adds(self): - """tui_audit_17 P3-2: line mode counted each core's files, the + """Line mode counted each core's files, the screen named the cores alone.""" state = checked_state() state.stack = ["setup", "plan", "options", "cores"] @@ -14278,7 +14228,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual(rows["mesen"], "1 file, 8.0 KB") def test_one_core_has_no_cores_row(self): - """tui_audit_17 P3-3: a list with one core offered Cores, where line + """A list with one core offered Cores, where line mode asks nothing.""" state = checked_state() state.manifest = {**MANIFEST, "files": [ @@ -14288,7 +14238,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 2: one tick list. def test_the_three_lists_open_and_answer_alike(self): - """tui_audit_17 P3-1: Choose systems opened on None, A unticking + """Choose systems opened on None, A unticking every system, Cores closed on A, regions ticked on A.""" for route in ("both", "gptokeyb", "muxterm", "miyoo"): for screen, opener in (("systems", ("plan", "systems")), @@ -14318,7 +14268,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 3: a folder failure as it happened. def test_a_folder_that_cannot_be_created_ends_on_its_reason(self): - """tui_audit_17 P2-1: the result said "22 files not fetched + """The result said "22 files not fetched (RETROBIOS_INSTALL_OFFLINE=1)" and sent the user for a pack.""" for os_type in ("linux", "android"): with self.subTest(os_type=os_type): @@ -14343,7 +14293,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertNotIn("sudo", text if os_type == "android" else "") def test_android_never_offers_sudo_and_a_phone_plan_says_why(self): - """tui_audit_17 P2-2: Termux was offered sudo, and at 40x12 the plan + """Termux was offered sudo, and at 40x12 the plan offered Install anyway with no word of why.""" hint = install.Invocation() hint.os_type = "android" @@ -14360,7 +14310,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 4: every proven card named, the real marker said. def test_an_arkos_card_is_found_beside_an_amberelec_card(self): - """tui_audit_17 P2-3, code_audit_24 P3-6: an ArkOS card its bgmusic + """An ArkOS card its bgmusic or launchimages prove was named nowhere, and its route said it could not tell it.""" games = games_part(self.root / "media" / "GAMES") @@ -14377,7 +14327,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertIn("AmberELEC SD card (GAMES)", text) def test_the_emuelec_refusal_names_its_file(self): - """code_audit_24 P3-7: the refusal named bezels, which AmberELEC's + """The refusal named bezels, which AmberELEC's card holds too.""" games = games_part(self.root / "media" / "GAMES") (games / "bezels").mkdir() @@ -14388,7 +14338,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 5: the reads before the menu show. def test_the_reads_before_the_menu_show_a_count(self): - """code_audit_24 P3-4: a rerun read every file before the menu, one at + """A rerun read every file before the menu, one at a time and with nothing on screen.""" payload = b"R" * 16 (self.here / "a.bin").write_bytes(payload) @@ -14403,7 +14353,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 6: every other item. def test_offline_the_plan_promises_no_replacement_it_cannot_make(self): - """code_audit_24 P3-5: offline, the plan said a wrong copy no folder + """Offline, the plan said a wrong copy no folder holds "is replaced".""" state = checked_state() with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}): @@ -14412,7 +14362,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertNotIn("wrong copy is replaced", text) def test_options_name_the_plans_bios_folder(self): - """tui_audit_17 P3-6: AmberELEC's Options read the games part, its + """AmberELEC's Options read the games part, its plan the bios folder below it.""" state = checked_state() state.manifest = {**MANIFEST, "files": [ @@ -14422,7 +14372,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual(row.label, "BIOS folder: /media/me/GAMES/bios") def test_finished_with_errors_says_a_rerun_retries(self): - """tui_audit_17 P3-7: the screen never said a rerun retries the files + """The screen never said a rerun retries the files that failed, and line mode named each failure twice.""" state = checked_state() install.tui_update(state, Key("enter")) @@ -14447,7 +14397,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertIn("Run the same command again to retry only those.", out.getvalue()) def test_below_40_columns_no_word_is_broken(self): - """tui_audit_17 P3-8: the reason line, Found and Install for were + """The reason line, Found and Install for were left to the terminal, which broke "/media/moi/" and "ONION/BIOS".""" with mock.patch.object(install, "terminal_size", return_value=(39, 11)), \ mock.patch.object(install, "_is_terminal", return_value=True): @@ -14459,7 +14409,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertEqual(" ".join(" ".join(lines).split()), " ".join(text.split())) def test_the_narrowing_line_is_a_sentence(self): - """tui_audit_17 P3-4: the plan read "--region." on a line alone.""" + """The plan read "--region." on a line alone.""" state = checked_state() state.regions = ["japan"] text = self.text(state, 100, 30) @@ -14467,7 +14417,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertNotIn(" --region.", text) def test_offline_choice_of_systems_is_never_about_0_files(self): - """tui_audit_17 P3-5: "About 0 files, 0 B, for 10 of 11 systems".""" + """"About 0 files, 0 B, for 10 of 11 systems".""" state = checked_state() state.ticked = {"sony-playstation"} with mock.patch.dict(os.environ, {install.OFFLINE_VARIABLE: "1"}): @@ -14476,7 +14426,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertIn("need the internet", text) def test_a_phone_bar_after_a_tap_keeps_quit_and_one_wording(self): - """tui_audit_17 P3-11: at 40 columns on Android the armed bar dropped + """At 40 columns on Android the armed bar dropped Esc Quit and said "click", the row "tap again".""" state = fresh_state() state.os_type = "android" @@ -14491,7 +14441,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): self.assertIn("Esc Quit", str(frame[-1])) def test_the_offline_screen_names_the_setups_list(self): - """tui_audit_17 P3-12: the offline screen said install/.json + """The offline screen said install/.json for AmberELEC, chosen one screen before.""" inbox: queue.Queue = queue.Queue() install.LOCAL.reset() @@ -14503,7 +14453,7 @@ class AuditTwentyFourAndSeventeen(unittest.TestCase): # Root cause 7: the tests leave the host alone. def test_no_connection_leaves_the_loopback_nor_a_card_comes_in(self): - """code_audit_24 P3-13: 261 connections to GitHub left this module, + """261 connections to GitHub left this module, and tests failed with an AmberELEC card in the reader.""" import socket # noqa: PLC0415 diff --git a/tests/test_prose_style.py b/tests/test_prose_style.py index d7fe7bf24..fe622e977 100644 --- a/tests/test_prose_style.py +++ b/tests/test_prose_style.py @@ -237,6 +237,31 @@ class NoToolingNames(unittest.TestCase): self.assertEqual(offenders, [], "\n".join(offenders[:20])) +class NoReviewTags(unittest.TestCase): + """A comment cites what the code does, never the private review that + asked for it. About 650 comments and test texts ended on a tag such as + "(tui review 13, P3-8)" written in its short form, which points at notes + no clone holds. The pattern is assembled so this file does not match.""" + + TAG = re.compile(r"[a-z]+_" + "aud" + r"it_\d+|\(rounds? \d") + + def test_the_pattern_matches_the_short_forms(self): + for text in ("tui_" + "aud" + "it_13 P3-8", "(" + "round 5, 6.3)", + "code_" + "aud" + "it_24"): + with self.subTest(text=text): + self.assertRegex(text, self.TAG) + self.assertNotRegex("test_" + "aud" + "it_regressions", self.TAG) + + def test_no_tracked_file_carries_one(self): + offenders = [] + for path in _tracked(): + text = path.read_text(encoding="utf-8", errors="replace") + for number, line in enumerate(text.splitlines(), 1): + if self.TAG.search(line): + offenders.append(f"{path.relative_to(ROOT)}:{number}") + self.assertEqual(offenders, [], "\n".join(offenders[:20])) + + class ProfilesStateFactsAboutOtherProjects(unittest.TestCase): """A profile says what another project's file declares and what the code does, never a verdict on that file. Ten notes and comments in ten profiles diff --git a/tests/test_site_bootstrap.py b/tests/test_site_bootstrap.py index 4d37f8700..ee41e51bb 100644 --- a/tests/test_site_bootstrap.py +++ b/tests/test_site_bootstrap.py @@ -57,8 +57,7 @@ class ServedCopies(unittest.TestCase): served = sitebootstrap.served_text(name, REPO_ROOT, self.commit).splitlines() self.assertEqual(len(original), len(served)) changed = [(a, b) for a, b in zip(original, served) if a != b] - # The address, and the advice a refusal gives (code_audit_21 - # P3-1). + # The address, and the advice a refusal gives. self.assertEqual(len(changed), 2, changed) advice = [pair for pair in changed if sitebootstrap.SERVED_ADVICE in pair[1]] self.assertEqual(len(advice), 1, changed) @@ -99,7 +98,7 @@ class ServedCopies(unittest.TestCase): sitebootstrap.served_text(path.name, REPO_ROOT, self.commit)) def test_the_served_copy_never_blames_a_cut_download_or_caches(self): - """code_audit_21 P3-1: the commit-pinned copy said "cut short, try + """The commit-pinned copy said "cut short, try again" and "waiting five minutes settles that", neither of which can happen to it.""" for name in sitebootstrap.SOURCES: @@ -116,7 +115,7 @@ class ServedCopies(unittest.TestCase): self.assertIn("something changed the file", answer) def test_a_stale_pin_stops_the_build(self): - """code_audit_21 P3-2: a pin that is not the installer's was served, + """A pin that is not the installer's was served, and refused every install until the next good deploy.""" with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp" if (REPO_ROOT / "tmp").is_dir() else None) as scratch: diff --git a/tests/test_site_exports.py b/tests/test_site_exports.py index 09b2240f8..25cfc2534 100644 --- a/tests/test_site_exports.py +++ b/tests/test_site_exports.py @@ -365,7 +365,7 @@ class AVariantShowsWhoPinsIt(unittest.TestCase): platforms={"c" * 40: {"batocera", "retrobat"}}, emulators={"a" * 40: {"mame"}}) page = generate_site.generate_system_page( "Entex", {"Adventure Vision": [primary, variant]}, consumers) - # Another revision of a set sits open beside it (round 5, 6.3). + # Another revision of a set sits open beside it. block = page[page.index('id="sha1-' + "c" * 12 + '"'):] self.assertIn("
Collection path
bios/Entex/Adventure Vision/" ".variants/advision.zip.1c086064", block) diff --git a/tests/test_site_funnel.py b/tests/test_site_funnel.py index 9f12b57cb..65a731e03 100644 --- a/tests/test_site_funnel.py +++ b/tests/test_site_funnel.py @@ -203,11 +203,11 @@ class DeepLinksCarryALabel(unittest.TestCase): A link right after the question it answers ("Have a file? [Check it]") says it too: there a label read as a broken crumb beside the Reference - tab (round 4).""" + tab.""" # Answers a start page sends its reader to on purpose: the arcade # version table opens on one plain sentence, and "Reference:" before - # its link read as a broken crumb (round 4, C4 and C9). + # its link read as a broken crumb. ANSWERS = ("/retrobios/wiki/technical-faq/#which-mame-version-do-the-arcade-bios-sets-match",) def test_start_and_setup_pages(self): diff --git a/tests/test_site_r2_components.py b/tests/test_site_r2_components.py index b69543b90..7fd89c035 100644 --- a/tests/test_site_r2_components.py +++ b/tests/test_site_r2_components.py @@ -86,7 +86,7 @@ class TablesStackWhenBuilt(unittest.TestCase): "short-start": {"labels": ["System", "Runs", "BIOS folder"], "rows": 8, "action": False, "level": "start"}, "long-setup": {"labels": ["System", "Files", "Status"], "rows": 97, "action": False, "level": "setup"}, "reference": {"labels": ["A", "B", "C"], "rows": 5, "action": False, "level": "reference"}, - # Four columns do not fit a phone column, on any page (round 3). + # Four columns do not fit a phone column, on any page. "wide": {"labels": ["File", "Region", "Required", "Hash"], "rows": 105, "action": False, "level": "reference"}, # A hash never breaks: three columns with one overflow a phone (NetherSX2). "hashes": {"labels": ["File", "Required", "Hash"], "rows": 40, "action": False, "level": "reference"}, @@ -172,7 +172,7 @@ def _title_block(html: str) -> str: class LevelBadgeOnlyWhereItAddsSomething(unittest.TestCase): def test_badge_follows_the_crumb(self): - # A tab root: the header tab already says it (round 3, 2.1). + # A tab root: the header tab already says it. self.assertNotIn('class="rb-level ', _title_block(_built("platforms"))) # Under the "Start here" or "Your setup" crumb the badge repeated it. for page in ("which-pack", "platforms/batocera"): diff --git a/tests/test_site_r2_emulators.py b/tests/test_site_r2_emulators.py index 47aeed53b..56c1b2e3b 100644 --- a/tests/test_site_r2_emulators.py +++ b/tests/test_site_r2_emulators.py @@ -1,4 +1,4 @@ -"""Emulator pages say what is needed first, in names (round 2, package 7). +"""Emulator pages say what is needed first, in names. 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 diff --git a/tests/test_site_r2_entry.py b/tests/test_site_r2_entry.py index c70bc16da..f19f1d3c9 100644 --- a/tests/test_site_r2_entry.py +++ b/tests/test_site_r2_entry.py @@ -1,4 +1,4 @@ -"""Entry pages and guides (round 2, package 4). +"""Entry pages and guides. The home page said the command "writes only in your BIOS folder" while install.py writes the entries a manifest files under `root: save` into the diff --git a/tests/test_site_r2_nav.py b/tests/test_site_r2_nav.py index 6e3f134a7..173b8ef99 100644 --- a/tests/test_site_r2_nav.py +++ b/tests/test_site_r2_nav.py @@ -1,4 +1,4 @@ -"""Navigation (round 2, package 3). +"""Navigation. The 404 page's sidebar read "0 1 2 3 4". A sidebar group label was a link to its first page ("Handhelds and TV boxes" opened AmberELEC), and a crumb diff --git a/tests/test_site_r2_p0.py b/tests/test_site_r2_p0.py index 9dd6f1b1b..da1103b97 100644 --- a/tests/test_site_r2_p0.py +++ b/tests/test_site_r2_p0.py @@ -1,4 +1,4 @@ -"""One display name per system id (round 2, package P0). +"""One display name per system id. An emulator page listed the folders a system's files were voted onto: nintendo-gba read "Nintendo Game Boy", camplynx "Arcade", and MAME diff --git a/tests/test_site_r2_reference.py b/tests/test_site_r2_reference.py index cd6f9aaee..28f1fc607 100644 --- a/tests/test_site_r2_reference.py +++ b/tests/test_site_r2_reference.py @@ -1,4 +1,4 @@ -"""Reference pages (round 2, package 8). +"""Reference pages. A reference page cites a hash, a source line or a count, and each citation has to hold when an expert checks it: the reader of a pinned dump is the diff --git a/tests/test_site_r2_systems.py b/tests/test_site_r2_systems.py index c24ec2212..fce06399c 100644 --- a/tests/test_site_r2_systems.py +++ b/tests/test_site_r2_systems.py @@ -1,4 +1,4 @@ -"""System pages and file cards (round 2, package 6). +"""System pages and file cards. The Sony page opened on LibPS.exe, its card titles read "scph5501.bin permalink" in the site search, the two setup lines of a card were defined @@ -115,7 +115,7 @@ class TheConsoleBiosComesFirst(unittest.TestCase): def test_a_long_list_names_the_first_and_counts_the_rest(self): files = [_file(f"rom{i}.bin", "abcdefgh"[i]) for i in range(8)] # One emulator requires all eight: files each required by another - # emulator are other names for one slot (round 5, 6.2). + # emulator are other names for one slot. consumers = _consumers({f["sha1"]: [{"required": True}] for f in files}) consumers.emulator_files = {"emu": [{"required": True}] * len(files)} consumers.emulator_entries = {f["sha1"]: {"emu": i} for i, f in enumerate(files)} @@ -172,7 +172,7 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase): def test_labels_and_display_names(self): text = "\n".join(self.lines) - # Grouped by where the setups put the file (round 4, 6.9). + # Grouped by where the setups put the file. self.assertIn("
On the setup's list
scph5501.bin: Batocera
", text) self.assertIn("
Packed for its emulators by
bios/scph5501.bin: " @@ -182,7 +182,7 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase): def test_the_facts_are_out_of_the_search(self): # The setup list made every card's excerpt a run of names and - # paths (round 4, V6): the card's title is what the search reads. + # paths: the card's title is what the search reads. # The facts shown open are one list, the others one fold, both # out of the search. shown = self.lines[:next(i for i, line in enumerate(self.lines) if line.startswith("scph5501.bin' '

a,b.bin

') meta = sitestarlight.file_names_meta(body) - # Each name as its parts, each part once (round 5, 3.2). + # Each name as its parts, each part once. self.assertIn('data-pagefind-meta="files:a b bin scph5501"', meta) self.assertRegex(meta, r"]*hidden>") @@ -94,7 +94,7 @@ class MetaFields(unittest.TestCase): class SystemPartsSitUnderTheirMaker(unittest.TestCase): """The crumbs say where a system part sits, read from its parent: field. - The "Part of" line under them said it again (round 5, 6.9).""" + The "Part of" line under them said it again.""" def test_every_part_names_its_maker_as_parent(self) -> None: pages = sorted((DOCS / "systems").glob("*.md")) diff --git a/tests/test_site_r3_p0.py b/tests/test_site_r3_p0.py index d4bf17d61..7622b495b 100644 --- a/tests/test_site_r3_p0.py +++ b/tests/test_site_r3_p0.py @@ -1,4 +1,4 @@ -"""Every system id with a section leads to it (rounds 3 and 4, package P0). +"""Every system id with a section leads to it. 260 of 636 system ids linked: a variant (WonderSwan Color, Neo Geo MVS) never matched a heading, twin folders (DS and Nintendo DS) made the exact @@ -112,7 +112,7 @@ class SystemLinks(unittest.TestCase): siterender.set_console_sections( cls.manufacturers, siterender.program_names(profiles)) # The system pages give every arcade board a section of its own - # (round 4, 6.4) and record it. The built pages are checked by + # and record it. The built pages are checked by # the round 4 gate. siterender.reset_console_pages() # The sections as the system pages hold them: each board, the diff --git a/tests/test_site_r3_reference.py b/tests/test_site_r3_reference.py index 4b15c11dd..471df355f 100644 --- a/tests/test_site_r3_reference.py +++ b/tests/test_site_r3_reference.py @@ -1,4 +1,4 @@ -"""Reference pages and data (round 3, package 8). +"""Reference pages and data. The CSV and SQLite dropped zipped_file, so a check built from them judged 106 good Batocera files wrong. The manifest a pack installs was nowhere on diff --git a/tests/test_site_r3_systems.py b/tests/test_site_r3_systems.py index 110d9cdeb..e91b23b66 100644 --- a/tests/test_site_r3_systems.py +++ b/tests/test_site_r3_systems.py @@ -1,4 +1,4 @@ -"""System pages and file cards (round 3, package 6). +"""System pages and file cards. The DS section opened on five DSi files, the Game Boy Advance line printed BizHawk's file name where eight setups write another, the Neo Geo section diff --git a/tests/test_site_r3_wiki.py b/tests/test_site_r3_wiki.py index 6a06f1ce0..8da1597be 100644 --- a/tests/test_site_r3_wiki.py +++ b/tests/test_site_r3_wiki.py @@ -1,4 +1,4 @@ -"""Wiki copy (round 3, package 5). +"""Wiki copy. Each class names the finding it holds: a legal page that opened on case law, no arcade answer where players look, a Dreamcast "yes" the Dreamcast diff --git a/tests/test_site_r4_entry.py b/tests/test_site_r4_entry.py index ec4d423dc..15ea8b1b9 100644 --- a/tests/test_site_r4_entry.py +++ b/tests/test_site_r4_entry.py @@ -1,4 +1,4 @@ -"""Entry pages and guides (round 4, package 4). +"""Entry pages and guides. Six handheld setups have no ZIP, and three of them offered SSH as root as the only route while their page already named a network folder. Six rows diff --git a/tests/test_site_r4_p0.py b/tests/test_site_r4_p0.py index 8b0259033..6f836cd8a 100644 --- a/tests/test_site_r4_p0.py +++ b/tests/test_site_r4_p0.py @@ -1,4 +1,4 @@ -"""Arcade boards and the ids that hold files (round 4, package P0). +"""Arcade boards and the ids that hold files. The Arcade pages were cut by storage folder, so NAOMI, ZN-1, PGM and the other boards had no section and stayed plain on 987 emulator rows. @@ -139,7 +139,7 @@ class Boards(unittest.TestCase): self.assertTrue(slug) self.assertEqual(slug, toc_slug(name)) # The board's page is its section: no heading repeats its - # title (round 5, 6.8). + # title. self.assertEqual( siterender.console_href(*siterender.system_section(board)), f"systems/arcade-{slug}.md") diff --git a/tests/test_site_r4_reference.py b/tests/test_site_r4_reference.py index 094880d45..c8aa3af10 100644 --- a/tests/test_site_r4_reference.py +++ b/tests/test_site_r4_reference.py @@ -1,4 +1,4 @@ -"""Reference pages and data (round 4, package 8). +"""Reference pages and data. The lookup answered a SHA1 without the setups that list the same file by MD5, the published folder check failed 134 EmuDeck entries a folder EmuDeck diff --git a/tests/test_site_r4_search.py b/tests/test_site_r4_search.py index 8d244baaf..993d411a5 100644 --- a/tests/test_site_r4_search.py +++ b/tests/test_site_r4_search.py @@ -1,4 +1,4 @@ -"""Search (round 4, package 3). +"""Search. The search gate listed the queries that missed and no workflow ran it: its browser runner could not even start from the repository root. Console and diff --git a/tests/test_site_r4_systems.py b/tests/test_site_r4_systems.py index 962ff4565..5064c936d 100644 --- a/tests/test_site_r4_systems.py +++ b/tests/test_site_r4_systems.py @@ -1,4 +1,4 @@ -"""System pages and file cards (round 4, package 6). +"""System pages and file cards. The Game Boy, NES and SNES sections said "Start with" a file one core of sixteen requires, under a home page saying they need none. The romset line @@ -167,7 +167,7 @@ class EachArcadeBoardHasASection(unittest.TestCase): """6.4: the Arcade page was cut by storage folder.""" def test_each_board_heads_its_page(self) -> None: - # The page's title names the board, no h2 says it again (round 5, 6.8). + # The page's title names the board, no h2 says it again. for name in BOARDS: slug = toc_slug(name) html = _page(DIST / "systems" / f"arcade-{slug}" / "index.html") diff --git a/tests/test_site_r4_wiki.py b/tests/test_site_r4_wiki.py index ec3d4aa1d..d299941d0 100644 --- a/tests/test_site_r4_wiki.py +++ b/tests/test_site_r4_wiki.py @@ -1,4 +1,4 @@ -"""Wiki and release docs (round 4, package 5). +"""Wiki and release docs. Each class names the finding it holds: an error message a reader types into search and no page that says it, an arcade answer written for diff --git a/tests/test_site_r5_emulators.py b/tests/test_site_r5_emulators.py index 66bdb3bc8..632e72bf9 100644 --- a/tests/test_site_r5_emulators.py +++ b/tests/test_site_r5_emulators.py @@ -1,4 +1,4 @@ -"""Emulator pages (round 5, package 7). +"""Emulator pages. 61 profiles cite the folder their app reads its data from (data_root) and no page printed it: AetherSX2's step said "inside the app's own data diff --git a/tests/test_site_r5_entry.py b/tests/test_site_r5_entry.py index 262cb905c..8bb2c33d7 100644 --- a/tests/test_site_r5_entry.py +++ b/tests/test_site_r5_entry.py @@ -1,4 +1,4 @@ -"""Entry pages, get/ and guides (round 5, package 4). +"""Entry pages, get/ and guides. The get/ page of a setup with no ZIP printed one command for three systems, with no --dest, so it failed on the computer most readers open diff --git a/tests/test_site_r5_reference.py b/tests/test_site_r5_reference.py index 618268bb2..fead7a785 100644 --- a/tests/test_site_r5_reference.py +++ b/tests/test_site_r5_reference.py @@ -1,4 +1,4 @@ -"""Reference pages and data (round 5, package 8). +"""Reference pages and data. The API said Lakka and RetroPie had a release pack while their pages said none, 50 nested manifest fields and the nine omission codes had no diff --git a/tests/test_site_r5_systems.py b/tests/test_site_r5_systems.py index ddfb8950b..fef0d8433 100644 --- a/tests/test_site_r5_systems.py +++ b/tests/test_site_r5_systems.py @@ -1,4 +1,4 @@ -"""System pages and boards (round 5, package 6). +"""System pages and boards. NAOMI opened on hod2bios.zip, a set 13 of the 19 emulators listing it read for one game. Lines read other names for one file as files to get: "Start diff --git a/tests/test_site_r5_wiki.py b/tests/test_site_r5_wiki.py index 5291fc4eb..4efc7837c 100644 --- a/tests/test_site_r5_wiki.py +++ b/tests/test_site_r5_wiki.py @@ -1,4 +1,4 @@ -"""Wiki (round 5, package 5). +"""Wiki. Each class names the finding it holds: a "no setup" command that sent macOS and Steam Deck files where RetroArch never reads, a level 0 rule that diff --git a/tests/test_site_render.py b/tests/test_site_render.py index 2abaf0809..4c68c1426 100644 --- a/tests/test_site_render.py +++ b/tests/test_site_render.py @@ -365,7 +365,7 @@ class TheSearchSkipsLinkLists(unittest.TestCase): for label in ("MD5", "Emulators", "Packed for its emulators by", "On the setup's list"): self.assertIn(f"
{label}
", skipped) self.assertNotIn(f">{label}", searched) - # The card's title is what the search reads (round 4, V6): the setup + # The card's title is what the search reads: the setup # list made every excerpt a run of names and paths. self.assertNotIn('
', searched)