summaryrefslogtreecommitdiffstatshomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/fixtures/display-lifecycle.js56
-rw-r--r--tests/test_canonical.py2
-rw-r--r--tests/test_canonical_displays.py28
3 files changed, 86 insertions, 0 deletions
diff --git a/tests/fixtures/display-lifecycle.js b/tests/fixtures/display-lifecycle.js
new file mode 100644
index 0000000..2173c47
--- /dev/null
+++ b/tests/fixtures/display-lifecycle.js
@@ -0,0 +1,56 @@
+import assert from 'node:assert/strict';
+
+class Extension {}
+const Meta = {MonitorSwitchConfigType: {EXTERNAL: 2}};
+let callback;
+let requests = 0;
+let switchable = true;
+let builtinOn = true;
+const manager = {
+ has_builtin_panel: true,
+ connect(signal, handler) {
+ assert.equal(signal, 'monitors-changed');
+ callback = handler;
+ return 1;
+ },
+ disconnect(id) {
+ assert.equal(id, 1);
+ callback = null;
+ },
+ can_switch_config: () => switchable,
+ get_is_builtin_display_on: () => builtinOn,
+ switch_config(type) {
+ assert.equal(type, Meta.MonitorSwitchConfigType.EXTERNAL);
+ requests++;
+ builtinOn = false;
+ },
+};
+globalThis.global = {backend: {get_monitor_manager: () => manager}};
+
+// EXTENSION
+
+const extension = new ExternalDisplay();
+extension.enable();
+assert.equal(requests, 1);
+callback();
+assert.equal(requests, 1);
+
+// One connected display, or a closed lid, prevents switching.
+switchable = false;
+builtinOn = true;
+callback();
+assert.equal(requests, 1);
+switchable = true;
+callback();
+assert.equal(requests, 2);
+
+manager.has_builtin_panel = false;
+builtinOn = true;
+callback();
+assert.equal(requests, 2);
+extension.disable();
+assert.equal(callback, null);
+manager.has_builtin_panel = true;
+extension.enable();
+assert.equal(requests, 3);
+extension.disable();
diff --git a/tests/test_canonical.py b/tests/test_canonical.py
index 848bf6c..fb0bff9 100644
--- a/tests/test_canonical.py
+++ b/tests/test_canonical.py
@@ -183,6 +183,7 @@ class RoleTests(unittest.TestCase):
".config/ghostty/config",
".local/bin/rqr",
".local/share/gnome-shell/extensions/corporate-panel@dotfiles/extension.js",
+ ".local/share/gnome-shell/extensions/external-display@dotfiles/extension.js",
]:
self.assertIn(required, files)
for path in files:
@@ -281,6 +282,7 @@ class RoleTests(unittest.TestCase):
self.assertNotIn(".config/autostart/dotfiles-", files)
self.assertNotIn("gpg-agent.service.d/canonical.conf", files)
self.assertNotIn("corporate-panel@dotfiles", files)
+ self.assertNotIn("external-display@dotfiles", files)
if __name__ == "__main__":
diff --git a/tests/test_canonical_displays.py b/tests/test_canonical_displays.py
new file mode 100644
index 0000000..627e3a0
--- /dev/null
+++ b/tests/test_canonical_displays.py
@@ -0,0 +1,28 @@
+import json
+import subprocess
+import unittest
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parents[1]
+EXTENSION = ROOT / "dot_local/share/gnome-shell/extensions/external-display@dotfiles"
+
+
+class DisplayTests(unittest.TestCase):
+ def test_metadata(self):
+ metadata = json.loads((EXTENSION / "metadata.json").read_text())
+ self.assertEqual(metadata["uuid"], "external-display@dotfiles")
+ self.assertIn("50", metadata["shell-version"])
+
+ def test_connection_changes_and_lifecycle(self):
+ code = "\n".join(
+ line
+ for line in (EXTENSION / "extension.js").read_text().splitlines()
+ if not line.startswith("import ")
+ ).replace("export default class", "class")
+ harness = (ROOT / "tests/fixtures/display-lifecycle.js").read_text()
+ subprocess.run(
+ ["node", "--input-type=module"],
+ input=harness.replace("// EXTENSION", code),
+ text=True,
+ check=True,
+ )