Files
spotifast/packaging/test-launchers.py
T
Carmine Paolino 16a9dde2ca Drop the old name from packages, release scripts and docs
Packages no longer install a fastpotify command or declare that they
replace, provide or conflict with the old packages. Releases no longer
carry the 0.9.1 bridge files, the release script only checks and sums
Spotifast downloads, and the Flatpak, Homebrew, macOS and Windows
recipes lose their old-identity branches and clean-ups. Packaging CI
tests the v0.11.2 release instead of installing the 0.8.0 package first.
The Rename page and the notes pointing to it are gone.

Updates begun by 0.10.2 or earlier on Windows relaunch fastpotify.exe,
which the installer no longer provides; such an install updates, but
needs starting by hand once.
2026-10-03 14:18:23 +02:00

123 lines
6.2 KiB
Python

"""Exercise native and Flatpak launcher installs using a release payload.
Uses the actual AUR package() and Flatpak install commands, without compiling or
launching the app. Ruby provides the existing YAML parser; no Python packages.
"""
import configparser
import json
import os
from pathlib import Path
import shlex
import shutil
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parent.parent
def yaml(path):
return json.loads(subprocess.check_output([
"ruby", "-rjson", "-ryaml", "-e",
"puts JSON.generate(YAML.safe_load_file(ARGV.fetch(0), aliases: false))", str(path),
], text=True))
def payload(root):
(root / "packaging/applications").mkdir(parents=True)
(root / "packaging/icons").mkdir(parents=True)
shutil.copyfile(ROOT / "packaging/applications/spotifast.desktop",
root / "packaging/applications/spotifast.desktop")
shutil.copyfile(ROOT / "packaging/icons/spotifast.svg", root / "packaging/icons/spotifast.svg")
(root / "target/release").mkdir(parents=True)
for name in ["spotifast", "target/release/spotifast"]:
shutil.copyfile(shutil.which("true"), root / name)
for name in ["LICENSE", "README.md"]:
shutil.copyfile(ROOT / name, root / name)
shutil.copytree(ROOT / "contrib/omarchy", root / "contrib/omarchy")
(root / "packaging/flatpak").mkdir()
shutil.copyfile(ROOT / "packaging/flatpak/rocks.spotifast.Spotifast.metainfo.xml",
root / "packaging/flatpak/rocks.spotifast.Spotifast.metainfo.xml")
class LauncherInstallTest(unittest.TestCase):
def test_generated_aur_versions_start_at_the_requested_release(self):
for package in ["spotifast", "spotifast-bin", "spotifast-git"]:
with self.subTest(package=package), tempfile.TemporaryDirectory() as directory:
recipe = Path(directory) / "PKGBUILD"
template = (ROOT / f"packaging/arch/{package}/PKGBUILD.in").read_text()
recipe.write_text(template.replace("@VERSION@", "9.8.7"))
version = subprocess.check_output([
"bash", "-c", 'source "$1"; printf "%s" "$pkgver"', "check", str(recipe),
], text=True)
self.assertEqual(version, "9.8.7")
def check_launcher(self, prefix, desktop, window_class, icon):
entries = list((prefix / "share/applications").glob("*.desktop"))
self.assertEqual([p.name for p in entries], [desktop + ".desktop"])
parser = configparser.ConfigParser(interpolation=None)
parser.read(entries[0])
entry = parser["Desktop Entry"]
self.assertEqual(entry["Name"], "Spotifast")
self.assertEqual(entry["Icon"], icon)
self.assertEqual(entry["StartupWMClass"], window_class)
self.assertEqual(entry["Exec"], "spotifast %u")
self.assertIn("x-scheme-handler/spotify;", entry["MimeType"])
icons = list((prefix / "share/icons/hicolor/scalable/apps").glob("*.svg"))
self.assertEqual([p.name for p in icons], [icon + ".svg"])
self.assertEqual(icons[0].read_bytes(), (ROOT / "packaging/icons/spotifast.svg").read_bytes())
self.assertFalse((prefix / "bin/spotifast").is_symlink())
self.assertTrue((prefix / "bin/spotifast").is_file())
self.assertEqual([p.name for p in (prefix / "bin").iterdir()], ["spotifast"])
def test_aur_payloads_install_the_launcher(self):
for package in ["spotifast", "spotifast-bin", "spotifast-git"]:
with self.subTest(package=package), tempfile.TemporaryDirectory() as directory:
root = Path(directory)
if package.endswith("-bin"):
relative = "spotifast-v9.8.7-x86_64-unknown-linux-gnu"
elif package.endswith("-git"):
relative = package
else:
relative = "spotifast-9.8.7"
payload(root / "src" / relative)
template = ROOT / f"packaging/arch/{package}/PKGBUILD.in"
command = "source " + shlex.quote(str(template)) + "; pkgver=9.8.7; package"
subprocess.run(["bash", "-euc", command], check=True, cwd=root, env={
**os.environ, "CARCH": "x86_64", "srcdir": str(root / "src"),
"pkgdir": str(root / "pkg"),
})
self.check_launcher(root / "pkg/usr", "spotifast", "spotifast", "spotifast")
def test_flatpak_install_commands_keep_app_id_and_icon_aligned(self):
for manifest in ["rocks.spotifast.Spotifast.yml", "rocks.spotifast.Spotifast.bundle.yml"]:
config = yaml(ROOT / "packaging/flatpak" / manifest)
commands = config["modules"][-1]["build-commands"]
with self.subTest(manifest=manifest), tempfile.TemporaryDirectory() as directory:
root = Path(directory)
payload(root / "source")
# Exercise installation only. Cargo build coverage belongs to
# the app suites; this fixture supplies the completed input.
commands_to_run = [c for c in commands if not c.startswith("cargo ")]
command = "\n".join(c.replace("/app/", str(root / "app") + "/") for c in commands_to_run)
subprocess.run(["bash", "-euc", command], check=True, cwd=root / "source")
self.check_launcher(root / "app", config["id"], config["id"], config["id"])
def test_native_manifest_installs_the_launcher_and_icon(self):
config = yaml(ROOT / "native-packages.yaml")
entries = [c for c in config["nfpm"]["contents"] if "/packaging/" in c["src"]]
self.assertEqual(len(entries), 2)
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
payload(root / "spotifast-v9.8.7-linux-amd64")
for entry in entries:
pattern = entry["src"].replace("@PAYLOAD@/", "").replace("@VERSION@", "9.8.7").replace("@TARGET@", "linux-amd64")
files = list(root.glob(pattern))
self.assertEqual(len(files), 1)
self.assertEqual(files[0].stem, "spotifast")
self.assertTrue(entry["dst"].endswith("/"))
if __name__ == "__main__":
unittest.main()