mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
Merge branch 'main' into perf/indium-cpu-shadow
This commit is contained in:
commit
a0b152f53c
11 files changed
+396
-228
No files matched your search
@@ -0,0 +1,157 @@
|
||||
"""Verify the desktop-entry helper against a disposable HOME."""
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
HELPER = ROOT / 'tools/desktop-entry.py'
|
||||
FLAKE = ROOT / 'flake.nix'
|
||||
OLD_SVG = '<svg><linearGradient id="goldGrad"/><path d="M172 108 L242 108"/></svg>'
|
||||
IDENTITY_KEYS = ('Name', 'GenericName', 'Comment', 'Icon', 'Keywords', 'Categories', 'StartupWMClass')
|
||||
|
||||
|
||||
def parse_entry(text):
|
||||
entry = {}
|
||||
for line in text.splitlines():
|
||||
if '=' in line and not line.startswith(('#', '[')):
|
||||
key, value = line.split('=', 1)
|
||||
entry[key] = value
|
||||
return entry
|
||||
|
||||
|
||||
class DesktopEntryTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory(prefix='desktop entry ', dir=os.environ.get('TMPDIR'))
|
||||
self.addCleanup(self.tmp.cleanup)
|
||||
self.root = Path(self.tmp.name)
|
||||
self.home = self.root / 'home'
|
||||
self.home.mkdir()
|
||||
|
||||
def project(self, name='project'):
|
||||
project = self.root / name
|
||||
project.mkdir(parents=True)
|
||||
shutil.copy2(ROOT / 'darling-lol.svg', project / 'darling-lol.svg')
|
||||
shutil.copy2(ROOT / 'darling-lol.png', project / 'darling-lol.png')
|
||||
return project
|
||||
|
||||
def install(self, project):
|
||||
script = project / 'desktop-entry.py'
|
||||
script.write_text(HELPER.read_text()
|
||||
.replace('@PROJECT_ROOT@', str(project))
|
||||
.replace('@HOST_HOME@', str(self.home)))
|
||||
return subprocess.run([sys.executable, str(script)], capture_output=True, text=True,
|
||||
env=dict(os.environ, HOME=str(self.home)), check=False)
|
||||
|
||||
def entry(self):
|
||||
return self.home / '.local/share/applications/darling-launcher.desktop'
|
||||
|
||||
def icons(self):
|
||||
base = self.home / '.local/share/icons'
|
||||
return base / 'hicolor/scalable/apps/darling-launcher.svg', base / 'hicolor/128x128/apps/darling-launcher.png'
|
||||
|
||||
def test_installs_neutral_entry_and_icons(self):
|
||||
project = self.project()
|
||||
result = self.install(project)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
text = self.entry().read_text()
|
||||
self.assertIn('Name=Darling Launcher\n', text)
|
||||
self.assertIn('Icon=darling-launcher\n', text)
|
||||
self.assertIn(f'Path={project}\n', text)
|
||||
for field in ('Name', 'Comment', 'GenericName', 'Keywords'):
|
||||
line = next(line for line in text.splitlines() if line.startswith(field + '='))
|
||||
for brand in ('League', 'LoL', 'Riot', 'Vanguard', 'anti-cheat'):
|
||||
self.assertNotIn(brand.lower(), line.lower())
|
||||
svg, png = self.icons()
|
||||
self.assertTrue(svg.is_file())
|
||||
self.assertTrue(png.is_file())
|
||||
self.assertEqual(png.read_bytes(), (project / 'darling-lol.png').read_bytes())
|
||||
|
||||
def test_preserves_entries_and_icons_it_did_not_create(self):
|
||||
project = self.project()
|
||||
other = self.root / 'elsewhere'
|
||||
(self.home / '.local/share/applications').mkdir(parents=True)
|
||||
legacy_entry = self.home / '.local/share/applications/league-of-legends.desktop'
|
||||
legacy_entry.write_text(f'[Desktop Entry]\nExec={other}/scripts/desktop-run.sh\n')
|
||||
(self.home / 'Desktop').mkdir()
|
||||
desktop_entry = self.home / 'Desktop/league-of-legends.desktop'
|
||||
desktop_entry.write_text(f'[Desktop Entry]\nExec={other}/scripts/desktop-run.sh\n')
|
||||
icons = self.home / '.local/share/icons'
|
||||
icons.mkdir(parents=True)
|
||||
(icons / 'league-of-legends.png').write_text('user icon')
|
||||
result = self.install(project)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertTrue(legacy_entry.is_file())
|
||||
self.assertTrue(desktop_entry.is_file())
|
||||
self.assertEqual((icons / 'league-of-legends.png').read_text(), 'user icon')
|
||||
self.assertTrue(self.entry().is_file())
|
||||
|
||||
def test_removes_legacy_artifacts_it_created(self):
|
||||
project = self.project()
|
||||
applications = self.home / '.local/share/applications'
|
||||
applications.mkdir(parents=True)
|
||||
owned = f'[Desktop Entry]\nExec="{project}/scripts/desktop-run.sh"\n'
|
||||
legacy_entry = applications / 'league-of-legends.desktop'
|
||||
legacy_entry.write_text(owned)
|
||||
(self.home / 'Desktop').mkdir()
|
||||
desktop_link = self.home / 'Desktop/league-of-legends.desktop'
|
||||
desktop_link.symlink_to(project / 'scripts/desktop-run.sh')
|
||||
icons = self.home / '.local/share/icons'
|
||||
scalable = icons / 'hicolor/scalable/apps'
|
||||
legacy_png_dir = icons / 'hicolor/512x512/apps'
|
||||
scalable.mkdir(parents=True)
|
||||
legacy_png_dir.mkdir(parents=True)
|
||||
legacy_svg = scalable / 'league-of-legends.svg'
|
||||
legacy_svg.write_text(OLD_SVG)
|
||||
legacy_png = legacy_png_dir / 'league-of-legends.png'
|
||||
legacy_png.write_bytes(b'old client icon')
|
||||
result = self.install(project)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertFalse(legacy_entry.exists())
|
||||
self.assertFalse(desktop_link.is_symlink())
|
||||
self.assertFalse(legacy_svg.exists())
|
||||
self.assertFalse(legacy_png.exists())
|
||||
self.assertTrue(self.entry().is_file())
|
||||
|
||||
def test_quotes_exec_arguments_with_reserved_characters(self):
|
||||
project = self.project('proj $dollar#hash\'quote')
|
||||
result = self.install(project)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
text = self.entry().read_text()
|
||||
exec_line = next(line for line in text.splitlines() if line.startswith('Exec='))
|
||||
self.assertTrue(exec_line.startswith('Exec="'), exec_line)
|
||||
self.assertTrue(exec_line.endswith('"'), exec_line)
|
||||
self.assertIn('\\$dollar', exec_line)
|
||||
if shutil.which('desktop-file-validate'):
|
||||
check = subprocess.run(['desktop-file-validate', str(self.entry())],
|
||||
capture_output=True, text=True, check=False)
|
||||
self.assertEqual(check.returncode, 0, check.stdout + check.stderr)
|
||||
|
||||
def test_identity_fields_match_the_packaged_entry(self):
|
||||
project = self.project()
|
||||
result = self.install(project)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
rendered = parse_entry(self.entry().read_text())
|
||||
packaged_here = re.search(
|
||||
r"cat << 'DESKTOP_EOF' > \$out/share/applications/darling-launcher\.desktop\n(.*?)\n\s*DESKTOP_EOF",
|
||||
FLAKE.read_text(), re.S)
|
||||
self.assertIsNotNone(packaged_here, 'packaged desktop entry not found in flake.nix')
|
||||
packaged = parse_entry(packaged_here.group(1))
|
||||
for key in IDENTITY_KEYS:
|
||||
self.assertIn(key, packaged)
|
||||
self.assertEqual(rendered.get(key), packaged[key], key)
|
||||
|
||||
def test_missing_icon_fails(self):
|
||||
project = self.project()
|
||||
(project / 'darling-lol.png').unlink()
|
||||
result = self.install(project)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn('launcher icon is missing', result.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user