From 8d1973df4d3ccb0bd39c167098395c8ade80c0aa Mon Sep 17 00:00:00 2001 From: fy59 Date: Thu, 8 Oct 2026 22:30:37 +0200 Subject: [PATCH] fix(quickshell): handle checkupdates with no available updates --- .../labfy-sway/bin/check-updates.py | 4 ++ tests/test_quickshell_updates.py | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/test_quickshell_updates.py diff --git a/quickshell/.config/quickshell/labfy-sway/bin/check-updates.py b/quickshell/.config/quickshell/labfy-sway/bin/check-updates.py index 4f8c88de0..de454e73f 100644 --- a/quickshell/.config/quickshell/labfy-sway/bin/check-updates.py +++ b/quickshell/.config/quickshell/labfy-sway/bin/check-updates.py @@ -13,6 +13,10 @@ import tempfile def count(command): # CONTRACT: aucune mise à jour n'est appliquée ; chaque vérification est bornée. result = subprocess.run(command, capture_output=True, text=True, timeout=120, check=False) + # CONTRACT: checkupdates utilise le code 2 pour « aucune mise à jour » ; + # INVARIANT: une sortie inattendue garde le chemin d'erreur existant. + if command[0] == "checkupdates" and result.returncode == 2 and not result.stdout.strip() and not result.stderr.strip(): + return 0 # yay -Qua retourne 1 avec stdout/stderr vides quand aucune entrée AUR n'existe. if command[0] == "yay" and result.returncode == 1 and not result.stdout.strip() and not result.stderr.strip(): return 0 diff --git a/tests/test_quickshell_updates.py b/tests/test_quickshell_updates.py new file mode 100644 index 000000000..d2aad21d6 --- /dev/null +++ b/tests/test_quickshell_updates.py @@ -0,0 +1,45 @@ +import importlib.util +import subprocess +import unittest +from pathlib import Path +from unittest import mock + + +SOURCE = Path(__file__).resolve().parents[1] / "quickshell/.config/quickshell/labfy-sway/bin/check-updates.py" +SPEC = importlib.util.spec_from_file_location("quickshell_updates", SOURCE) +updates = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(updates) + + +class CountTests(unittest.TestCase): + def check_count(self, command, returncode, stdout, stderr, expected): + result = subprocess.CompletedProcess(command, returncode, stdout, stderr) + with mock.patch.object(updates.subprocess, "run", return_value=result) as run: + if isinstance(expected, type) and issubclass(expected, Exception): + with self.assertRaises(expected): + updates.count(command) + else: + self.assertEqual(updates.count(command), expected) + run.assert_called_once_with(command, capture_output=True, text=True, timeout=120, check=False) + + def test_checkupdates_counts_lines(self): + self.check_count(["checkupdates"], 0, "pkg-a 1 -> 2\npkg-b 3 -> 4\n", "", 2) + + def test_checkupdates_no_updates(self): + self.check_count(["checkupdates"], 2, "", "", 0) + + def test_checkupdates_code_one_is_error(self): + self.check_count(["checkupdates"], 1, "", "", RuntimeError) + + def test_checkupdates_code_two_with_stderr_is_error(self): + self.check_count(["checkupdates"], 2, "", "erreur inattendue", RuntimeError) + + def test_yay_no_updates(self): + self.check_count(["yay", "-Qua"], 1, "", "", 0) + + def test_yay_counts_lines(self): + self.check_count(["yay", "-Qua"], 0, "aur-a 1 -> 2\naur-b 3 -> 4\n", "", 2) + + +if __name__ == "__main__": + unittest.main()