From 790132668c4421c68c32bdc8fc9792b0d6028f97 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Tue, 8 Sep 2026 22:18:13 -0400 Subject: I really dont want to but here you go little guy --- tests/steamLaunchOptions.test.ts | 73 +++++++++++++++--- tests/test_flatpak_overrides.py | 158 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+), 11 deletions(-) create mode 100644 tests/test_flatpak_overrides.py (limited to 'tests') diff --git a/tests/steamLaunchOptions.test.ts b/tests/steamLaunchOptions.test.ts index 0662fbb..c4dede3 100644 --- a/tests/steamLaunchOptions.test.ts +++ b/tests/steamLaunchOptions.test.ts @@ -4,6 +4,7 @@ import { applyWorkaroundChange, applyWorkaroundState, cleanupLegacyLaunchOptions, + cleanupPluginLaunchOptions, cleanupLegacyWrapper, getDefaultWorkaroundState, isLegacyWrapperToken, @@ -17,6 +18,7 @@ test("maps the supported workarounds to current launch variables", () => { const options = applyWorkaroundState('gamemoderun %command% --profile "high quality"', { dxvkFrameRate: 30, disableGamescopeWsi: true, + disableHdr: true, disableSteamdeckMode: true, disableVkbasalt: true, enableZink: true, @@ -24,12 +26,13 @@ test("maps the supported workarounds to current launch variables", () => { assert.equal( options, - 'ENABLE_GAMESCOPE_WSI=0 SteamDeck=0 DISABLE_VKBASALT=1 MESA_LOADER_DRIVER_OVERRIDE=zink DXVK_CONFIG="dxvk.maxFrameRate = 30" gamemoderun %command% --profile "high quality"', + 'ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 SteamDeck=0 DISABLE_VKBASALT=1 MESA_LOADER_DRIVER_OVERRIDE=zink DXVK_CONFIG="dxvk.maxFrameRate = 30" gamemoderun %command% --profile "high quality"', ); assert.deepEqual(parseWorkaroundOptions(options), { state: { dxvkFrameRate: 30, disableGamescopeWsi: true, + disableHdr: true, disableSteamdeckMode: true, disableVkbasalt: true, enableZink: true, @@ -45,10 +48,24 @@ test("uses SteamDeck=0 before %command% without a wrapper", () => { ); }); -test("keeps WSI disable opt-in and does not add HDR assignments", () => { +test("defaults new profiles to disable Gamescope WSI and HDR", () => { const defaults = getDefaultWorkaroundState(); - assert.equal(applyWorkaroundState("%command%", defaults), ""); + assert.equal(defaults.disableGamescopeWsi, true); + assert.equal(defaults.disableHdr, true); + assert.equal( + applyWorkaroundState("%command%", defaults), + "ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 %command%", + ); assert.equal(parseWorkaroundOptions("%command%").state.disableGamescopeWsi, false); + assert.equal(parseWorkaroundOptions("%command%").state.disableHdr, false); + assert.equal( + parseWorkaroundOptions(applyWorkaroundState("%command%", defaults)).state.disableGamescopeWsi, + true, + ); + assert.equal( + parseWorkaroundOptions(applyWorkaroundState("%command%", defaults)).state.disableHdr, + true, + ); assert.equal( applyWorkaroundChange("%command%", "disableGamescopeWsi", true), "ENABLE_GAMESCOPE_WSI=0 %command%", @@ -58,14 +75,6 @@ test("keeps WSI disable opt-in and does not add HDR assignments", () => { "", ); - const legacy = parseWorkaroundOptions("ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 %command%"); - assert.equal(legacy.state.disableGamescopeWsi, true); - assert.deepEqual(legacy.issues, []); - assert.equal( - applyWorkaroundChange("ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 %command%", "disableGamescopeWsi", false), - "", - ); - const invalid = parseWorkaroundOptions("ENABLE_GAMESCOPE_WSI=maybe %command%"); assert.equal(invalid.state.disableGamescopeWsi, false); assert.equal(invalid.issues.length, 1); @@ -74,6 +83,27 @@ test("keeps WSI disable opt-in and does not add HDR assignments", () => { assert.match(conflicting.issues.join(" "), /conflicting/); }); +test("manages DXVK HDR independently from Gamescope WSI", () => { + assert.equal( + applyWorkaroundChange("%command%", "disableHdr", true), + "DXVK_HDR=0 %command%", + ); + assert.equal(parseWorkaroundOptions("DXVK_HDR=0 %command%").state.disableHdr, true); + assert.equal(parseWorkaroundOptions("DXVK_HDR=1 %command%").state.disableHdr, false); + assert.equal( + applyWorkaroundChange("DXVK_HDR=0 %command%", "disableHdr", false), + "", + ); + assert.equal( + applyWorkaroundChange("DXVK_HDR=0 %command%", "disableGamescopeWsi", true), + "ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 %command%", + ); + + const invalid = parseWorkaroundOptions("DXVK_HDR=maybe %command%"); + assert.equal(invalid.state.disableHdr, false); + assert.match(invalid.issues.join(" "), /Disable HDR has an unsupported value/); +}); + test("preserves unrelated prefixes, quoted tokens, suffix arguments, and dropped variables", () => { const options = applyWorkaroundChange( 'PROTON_USE_WOW64=1 MANGOHUD=1 MANGOHUD_CONFIG="alpha=0.01" ENABLE_VKBASALT=1 VK_INSTANCE_LAYERS="one:two" FOO="hello world" gamemoderun %command% --flag "two words"', @@ -203,6 +233,8 @@ test("cleans only the known legacy wrapper and preserves launch options", () => 'FOO=bar %command% --arg "~/lsfg"', ); assert.equal(cleanupLegacyWrapper("/home/deck/lsfg %command%"), ""); + assert.equal(cleanupLegacyWrapper("mako-run %command%"), ""); + assert.equal(cleanupLegacyWrapper("mako-launch %command%"), ""); assert.equal( cleanupLegacyWrapper("DXVK_FRAME_RATE=30 LSFG_PROCESS=decky-lsfg-vk %command%"), "DXVK_FRAME_RATE=30 LSFG_PROCESS=decky-lsfg-vk %command%", @@ -214,6 +246,25 @@ test("cleans only the known legacy wrapper and preserves launch options", () => assert.equal(isLegacyWrapperToken("/home/kurt/lsfg"), false); }); +test("removes plugin-managed launch options when a profile is removed", () => { + assert.equal( + cleanupPluginLaunchOptions( + 'FOO="keep this" ENABLE_GAMESCOPE_WSI=0 DXVK_HDR=0 SteamDeck=0 DISABLE_VKBASALT=1 MESA_LOADER_DRIVER_OVERRIDE=zink DXVK_CONFIG="dxgi.syncInterval = 0; dxvk.maxFrameRate = 30" ~/lsfg %command% --windowed', + ), + 'DXVK_CONFIG="dxgi.syncInterval = 0" FOO="keep this" %command% --windowed', + ); + assert.equal( + cleanupPluginLaunchOptions( + 'PROTON_USE_WOW64=1 MANGOHUD=1 MANGOHUD_CONFIG="alpha=0.01" LSFG_PROCESS=decky-lsfg-vk %command%', + ), + 'PROTON_USE_WOW64=1 MANGOHUD=1 MANGOHUD_CONFIG="alpha=0.01" LSFG_PROCESS=decky-lsfg-vk %command%', + ); + assert.equal( + cleanupPluginLaunchOptions('DXVK_CONFIG="dxvk.maxFrameRate = 30" %command%'), + "", + ); +}); + test("canonicalizes a bare command token without removing real arguments", () => { assert.equal(normalizeLaunchOptions("%command%"), ""); assert.equal(normalizeLaunchOptions("%COMMAND%"), ""); diff --git a/tests/test_flatpak_overrides.py b/tests/test_flatpak_overrides.py new file mode 100644 index 0000000..ed3ef6a --- /dev/null +++ b/tests/test_flatpak_overrides.py @@ -0,0 +1,158 @@ +import sys +import tempfile +import types +import unittest +from pathlib import Path +from unittest.mock import Mock + + +sys.modules.setdefault( + "decky", + types.SimpleNamespace(DECKY_USER_HOME="/home/deck", logger=Mock()), +) +sys.modules.setdefault("tomllib", types.SimpleNamespace(loads=Mock())) +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "py_modules")) + +from lsfg_vk.flatpak_service import FlatpakService + + +class FlatpakOverrideTests(unittest.TestCase): + def setUp(self): + self.tempdir = tempfile.TemporaryDirectory() + home = Path(self.tempdir.name) / "home" / "deck" + home.mkdir(parents=True) + self.service = FlatpakService() + self.service.user_home = home + self.service.config_dir = home / ".config/lsfg-vk" + self.service.config_file_path = self.service.config_dir / "conf.toml" + self.service.legacy_script_path = home / "lsfg" + self.service.check_flatpak_available = Mock(return_value=True) + self.service._run_flatpak_command = Mock( + return_value=types.SimpleNamespace(returncode=0, stderr="", stdout="") + ) + self.app_id = "com.example.Game" + self.override_path = self.service._override_file_path(self.app_id) + + def tearDown(self): + self.tempdir.cleanup() + sys.modules.pop("lsfg_vk.plugin", None) + sys.modules.pop("lsfg_vk", None) + + def _paths(self): + return self.service._override_paths() + + def _write_override(self, content): + self.override_path.parent.mkdir(parents=True, exist_ok=True) + self.override_path.write_text(content, encoding="utf-8") + + def _show_response(self, content): + return types.SimpleNamespace(returncode=0, stderr="", stdout=content) + + def test_set_cleans_legacy_entries_and_verifies_readback(self): + paths = self._paths() + self._write_override( + "[Context]\n" + f"filesystems=/home/deck/keep;{paths['config_dir']}:rw;!{paths['legacy_home']};" + f"{paths['legacy_script']};{paths['legacy_dll']}:ro;{paths['dll_dir']}:ro;\n" + "unset-environment=KEEP_UNSET;LSFG_CONFIG;\n\n" + "[Environment]\n" + "KEEP_ENV=1\n" + "LSFG_CONFIG=\n" + "LSFGVK_CONFIG=old\n" + "ENABLE_GAMESCOPE_WSI=1\n" + "DXVK_HDR=1\n" + ) + expected = ( + "[Context]\n" + f"filesystems={paths['config_dir']}:rw;{paths['dll_dir']}:ro\n" + "[Environment]\n" + f"LSFGVK_CONFIG={paths['config_file']}\n" + "ENABLE_GAMESCOPE_WSI=0\n" + "DXVK_HDR=0\n" + ) + self.service._run_flatpak_command.side_effect = [ + self._show_response(""), + self._show_response(expected), + ] + + response = self.service.set_app_override(self.app_id) + command_args = self.service._run_flatpak_command.call_args_list[0].args[0] + cleaned = self.override_path.read_text(encoding="utf-8") + + self.assertTrue(response["success"]) + self.assertIn("--env=ENABLE_GAMESCOPE_WSI=0", command_args) + self.assertIn("--env=DXVK_HDR=0", command_args) + self.assertNotIn("--nofilesystem=/home/deck", command_args) + self.assertNotIn("--unset-env=LSFG_CONFIG", command_args) + self.assertIn("/home/deck/keep", cleaned) + self.assertIn("KEEP_ENV=1", cleaned) + self.assertNotIn("LSFG_CONFIG", cleaned) + self.assertNotIn(paths["legacy_home"], cleaned) + + def test_set_reports_failed_readback(self): + paths = self._paths() + self.service._run_flatpak_command.side_effect = [ + self._show_response(""), + self._show_response( + f"[Context]\nfilesystems={paths['config_dir']};{paths['dll_dir']}\n" + f"[Environment]\nLSFGVK_CONFIG={paths['config_file']}\n" + ), + ] + + response = self.service.set_app_override(self.app_id) + + self.assertFalse(response["success"]) + self.assertIn("verified", response["error"]) + + def test_remove_cleans_known_entries_preserves_unrelated_and_verifies(self): + paths = self._paths() + self._write_override( + "[Context]\n" + f"filesystems=/home/deck/keep;{paths['config_dir']};!{paths['legacy_home']};" + f"{paths['legacy_dll']};{paths['legacy_script']}\n" + "unset-environment=KEEP_UNSET;LSFG_CONFIG;ENABLE_GAMESCOPE_WSI\n\n" + "[Environment]\n" + "KEEP_ENV=1\n" + "LSFGVK_CONFIG=/old/path\n" + "DXVK_HDR=0\n" + ) + self.service._run_flatpak_command.side_effect = [ + self._show_response( + "[Context]\nfilesystems=/home/deck/keep\n" + "[Environment]\nKEEP_ENV=1\n" + ) + ] + + response = self.service.remove_app_override(self.app_id) + cleaned = self.override_path.read_text(encoding="utf-8") + + self.assertTrue(response["success"]) + self.assertEqual(self.service._run_flatpak_command.call_count, 1) + self.assertIn("/home/deck/keep", cleaned) + self.assertIn("KEEP_UNSET", cleaned) + self.assertIn("KEEP_ENV", cleaned) + for name in ("LSFGVK_CONFIG", "LSFG_CONFIG", "ENABLE_GAMESCOPE_WSI", "DXVK_HDR"): + self.assertNotIn(name, cleaned) + for path in paths.values(): + if path != paths["config_file"]: + self.assertNotIn(path, cleaned) + + def test_remove_reports_failed_readback(self): + self._write_override("[Context]\nfilesystems=/home/deck/keep\n") + paths = self._paths() + self.service._run_flatpak_command.side_effect = [ + self._show_response( + f"[Context]\nfilesystems={paths['config_dir']};{paths['dll_dir']}\n" + f"[Environment]\nLSFGVK_CONFIG={paths['config_file']}\n" + "ENABLE_GAMESCOPE_WSI=0\nDXVK_HDR=0\n" + ) + ] + + response = self.service.remove_app_override(self.app_id) + + self.assertFalse(response["success"]) + self.assertIn("verified", response["error"]) + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3