# ABOUT ME # Tests for tools/steam_paths.py, the Steam library discovery shared by # install.sh and tests/test_mod.py. # # Why this exists: the discovery must work on machines the author does not # own -- Flatpak Steam, a second library on another disk, Windows profiles. # Each test builds a fake filesystem under a temporary HOME, so no real Steam # install is needed and every layout is exercised on every run. # # Run: python3 tests/test_steam_paths.py import os import sys import tempfile sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tools")) import steam_paths _failures = [] _checks = 0 def check(condition, message): global _checks _checks += 1 if not condition: _failures.append(message) PROTON_MODS = "steamapps/compatdata/799600/pfx/drive_c/users/steamuser/Saved Games/Cosmoteer/76561190000000000/Mods" def make_library(root, with_game=True, with_mods=True): os.makedirs(os.path.join(root, "steamapps"), exist_ok=True) if with_game: os.makedirs(os.path.join(root, "steamapps/common/Cosmoteer/Data")) if with_mods: os.makedirs(os.path.join(root, PROTON_MODS)) def write_vdf(steam_root, library_paths): entries = "".join( f'\t"{i}"\n\t{{\n\t\t"path"\t\t"{p}"\n\t\t"label"\t\t""\n\t}}\n' for i, p in enumerate(library_paths) ) os.makedirs(os.path.join(steam_root, "steamapps"), exist_ok=True) with open(os.path.join(steam_root, "steamapps/libraryfolders.vdf"), "w") as f: f.write('"libraryfolders"\n{\n' + entries + "}\n") def test_second_library_from_vdf(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".local/share/Steam") second = os.path.join(home, "disk2/SteamLibrary") make_library(steam, with_game=False, with_mods=False) make_library(second) write_vdf(steam, [steam, second]) env = {"HOME": home} check( steam_paths.find_data_dir(env) == os.path.join(second, "steamapps/common/Cosmoteer/Data"), "Data dir in a second library listed in libraryfolders.vdf was not found", ) check( steam_paths.find_mods_dir(env) == os.path.join(second, PROTON_MODS), "Proton Mods dir in a second library was not found", ) def test_flatpak_steam_root(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".var/app/com.valvesoftware.Steam/.local/share/Steam") make_library(steam) env = {"HOME": home} check( steam_paths.find_data_dir(env) == os.path.join(steam, "steamapps/common/Cosmoteer/Data"), "Flatpak Steam root was not searched for the Data dir", ) check( steam_paths.find_mods_dir(env) == os.path.join(steam, PROTON_MODS), "Flatpak Steam root was not searched for the Mods dir", ) def test_steam_root_without_vdf_still_works(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".steam/debian-installation") make_library(steam) env = {"HOME": home} check( steam_paths.find_data_dir(env) == os.path.join(steam, "steamapps/common/Cosmoteer/Data"), "A Steam root with no libraryfolders.vdf should still be searched itself", ) def test_legacy_steam_root_symlink(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".steam/root") make_library(steam) env = {"HOME": home} check( steam_paths.find_data_dir(env) == os.path.join(steam, "steamapps/common/Cosmoteer/Data"), "~/.steam/root was not searched", ) def test_flatpak_data_dir_layout(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".var/app/com.valvesoftware.Steam/data/Steam") make_library(steam) env = {"HOME": home} check( steam_paths.find_mods_dir(env) == os.path.join(steam, PROTON_MODS), "Flatpak XDG_DATA_HOME layout (.var/app/.../data/Steam) was not searched", ) def test_library_path_with_spaces(): with tempfile.TemporaryDirectory() as home: steam = os.path.join(home, ".local/share/Steam") second = os.path.join(home, "my games/Steam Library") make_library(steam, with_game=False, with_mods=False) make_library(second) write_vdf(steam, [steam, second]) env = {"HOME": home} check( steam_paths.find_mods_dir(env) == os.path.join(second, PROTON_MODS), "Library path containing spaces was not handled", ) def test_windows_profile_mods_dir(): with tempfile.TemporaryDirectory() as profile: mods = os.path.join(profile, "Saved Games/Cosmoteer/76561190000000000/Mods") os.makedirs(mods) env = {"USERPROFILE": profile} check(steam_paths.find_mods_dir(env) == mods, "Windows Saved Games Mods dir was not found") def test_env_overrides_win(): with tempfile.TemporaryDirectory() as home: env = {"HOME": home, "COSMOTEER_DATA": "/override/Data", "COSMOTEER_MODS_DIR": "/override/Mods"} check(steam_paths.find_data_dir(env) == "/override/Data", "COSMOTEER_DATA override ignored") check(steam_paths.find_mods_dir(env) == "/override/Mods", "COSMOTEER_MODS_DIR override ignored") def test_nothing_found_returns_none_and_lists_roots(): with tempfile.TemporaryDirectory() as home: env = {"HOME": home} check(steam_paths.find_data_dir(env) is None, "Empty HOME must yield None for Data") check(steam_paths.find_mods_dir(env) is None, "Empty HOME must yield None for Mods") roots = steam_paths.steam_roots(env) check(any(r.startswith(home) for r in roots), "steam_roots must report the candidates it would try") def main(): for name, test in sorted(globals().items()): if name.startswith("test_") and callable(test): before = len(_failures) test() print(f" [{'PASS' if len(_failures) == before else 'FAIL'}] {name}") print(f"\n{_checks} checks run.") if _failures: print(f"{len(_failures)} FAILED:\n") for failure in _failures: print(f" - {failure}") return 1 print("All checks passed.") return 0 if __name__ == "__main__": sys.exit(main())