Files
PortProtonQt/tests/test_cli.py
2026-07-22 20:32:25 +05:00

218 lines
6.7 KiB
Python

"""Tests for cli.py — URL parsing, path normalization, file detection, resolution parsing."""
import os
import sys
from pathlib import Path
from portprotonqt.cli import (
normalize_launch_path,
is_autoinstall_file,
is_launch_file,
is_prefix_backup_file,
parse_portproton_url,
parse_portprotonqt_theme_url,
parse_resolution,
LAUNCH_FILE_EXTENSIONS,
PP_EXTENSIONS,
PREFIX_BACKUP_EXTENSION,
parse_args,
)
class TestParseArgs:
def test_log_silent_launch(self, monkeypatch):
monkeypatch.setattr(
sys,
"argv",
["portprotonqt", "--log", "--silent", "file:///tmp/game.exe"],
)
args = parse_args()
assert args.log is True
assert args.silent is True
assert args.file_or_url == "file:///tmp/game.exe"
class TestNormalizeLaunchPath:
def test_plain_path(self):
assert normalize_launch_path("/tmp/game.exe") == "/tmp/game.exe"
def test_expanduser(self):
result = normalize_launch_path("~/game.exe")
assert result.startswith(os.path.expanduser("~"))
assert result.endswith("game.exe")
def test_file_uri(self):
result = normalize_launch_path("file:///tmp/game.exe")
assert result == "/tmp/game.exe"
def test_file_uri_with_spaces(self):
result = normalize_launch_path("file:///tmp/my%20game.exe")
assert result == "/tmp/my game.exe"
def test_file_uri_with_tilde(self):
result = normalize_launch_path("file:///~/game.exe")
assert result == "/~/game.exe"
def test_relative_path_becomes_absolute(self):
result = normalize_launch_path("game.exe")
assert os.path.isabs(result)
class TestIsLaunchFile:
def test_exe_file(self, tmp_path: Path):
exe = tmp_path / "game.exe"
exe.touch()
assert is_launch_file(str(exe)) is True
def test_bat_file(self, tmp_path: Path):
bat = tmp_path / "setup.bat"
bat.touch()
assert is_launch_file(str(bat)) is True
def test_cmd_file(self, tmp_path: Path):
cmd = tmp_path / "launch.cmd"
cmd.touch()
assert is_launch_file(str(cmd)) is True
def test_msi_file(self, tmp_path: Path):
msi = tmp_path / "installer.msi"
msi.touch()
assert is_launch_file(str(msi)) is True
def test_iso_file(self, tmp_path: Path):
iso = tmp_path / "game.iso"
iso.touch()
assert is_launch_file(str(iso)) is True
def test_not_launch_file(self, tmp_path: Path):
txt = tmp_path / "readme.txt"
txt.touch()
assert is_launch_file(str(txt)) is False
def test_nonexistent_file(self):
assert is_launch_file("/nonexistent/game.exe") is False
def test_launch_file_extensions_complete(self):
assert ".exe" in LAUNCH_FILE_EXTENSIONS
assert ".bat" in LAUNCH_FILE_EXTENSIONS
assert ".cmd" in LAUNCH_FILE_EXTENSIONS
assert ".msi" in LAUNCH_FILE_EXTENSIONS
assert ".reg" in LAUNCH_FILE_EXTENSIONS
assert ".iso" in LAUNCH_FILE_EXTENSIONS
assert ".mdf" in LAUNCH_FILE_EXTENSIONS
assert ".nrg" in LAUNCH_FILE_EXTENSIONS
class TestIsPrefixBackupFile:
def test_ppack_file(self, tmp_path: Path):
ppack = tmp_path / "backup.ppack"
ppack.touch()
assert is_prefix_backup_file(str(ppack)) is True
def test_not_ppack(self, tmp_path: Path):
txt = tmp_path / "backup.zip"
txt.touch()
assert is_prefix_backup_file(str(txt)) is False
def test_nonexistent_file(self):
assert is_prefix_backup_file("/nonexistent/backup.ppack") is False
def test_ppack_extension_constant(self):
assert PREFIX_BACKUP_EXTENSION == ".ppack"
class TestIsAutoinstallFile:
def test_ppai_file(self, tmp_path: Path):
ppai = tmp_path / "installer.ppai"
ppai.touch()
assert is_autoinstall_file(str(ppai)) is True
def test_not_ppai(self, tmp_path: Path):
txt = tmp_path / "installer.txt"
txt.touch()
assert is_autoinstall_file(str(txt)) is False
def test_ppai_extension_constant(self):
assert PP_EXTENSIONS == (".ppack", ".ppai")
class TestParsePortprotonUrl:
def test_https_url(self):
url = "portproton://https//linux-gaming.ru/api/games/130127/ppdb/download"
result = parse_portproton_url(url)
assert result == "https://linux-gaming.ru/api/games/130127/ppdb/download"
def test_http_url(self):
url = "portproton://http//example.com/download"
result = parse_portproton_url(url)
assert result == "http://example.com/download"
def test_bare_url_without_protocol(self):
url = "portproton://example.com/game"
result = parse_portproton_url(url)
assert result == "https://example.com/game"
def test_url_with_existing_protocol(self):
url = "portproton://https://example.com/game"
result = parse_portproton_url(url)
assert result == "https://example.com/game"
def test_invalid_prefix(self):
assert parse_portproton_url("http://example.com") is None
def test_empty_string(self):
assert parse_portproton_url("") is None
class TestParsePortprotonqtThemeUrl:
def test_theme_url(self):
assert parse_portprotonqt_theme_url("portprotonqt://theme/6") == 6
def test_theme_url_trailing_slash(self):
assert parse_portprotonqt_theme_url("portprotonqt://theme/42/") == 42
def test_invalid_prefix(self):
assert parse_portprotonqt_theme_url("portproton://theme/6") is None
def test_invalid_theme_id(self):
assert parse_portprotonqt_theme_url("portprotonqt://theme/mix") is None
class TestParseResolution:
def test_standard_1080p(self):
assert parse_resolution("1920x1080") == (1920, 1080)
def test_standard_4k(self):
assert parse_resolution("3840x2160") == (3840, 2160)
def test_case_insensitive(self):
assert parse_resolution("1920X1080") == (1920, 1080)
def test_invalid_format(self):
assert parse_resolution("1920") is None
def test_invalid_letters(self):
assert parse_resolution("abcxdef") is None
def test_too_small_width(self):
assert parse_resolution("100x1080") is None
def test_too_small_height(self):
assert parse_resolution("1920x100") is None
def test_too_large_width(self):
assert parse_resolution("9999x1080") is None
def test_too_large_height(self):
assert parse_resolution("1920x9999") is None
def test_min_valid(self):
assert parse_resolution("320x200") == (320, 200)
def test_max_valid(self):
assert parse_resolution("7680x4320") == (7680, 4320)
def test_empty_string(self):
assert parse_resolution("") is None