From 4c0c0013caa069f877fb60620059d1d312b0dbe2 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 2 May 2026 18:53:06 -0400 Subject: [PATCH] Version bump. --- distro-packages/Arch-Linux/PKGBUILD | 2 +- meson.build | 2 +- src/cthulhu/cthulhuVersion.py | 2 +- tests/test_nvda2cthulhu_regressions.py | 47 ++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 tests/test_nvda2cthulhu_regressions.py diff --git a/distro-packages/Arch-Linux/PKGBUILD b/distro-packages/Arch-Linux/PKGBUILD index 15abe3b..e023fac 100644 --- a/distro-packages/Arch-Linux/PKGBUILD +++ b/distro-packages/Arch-Linux/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Storm Dragon pkgname=cthulhu -pkgver=2026.03.02 +pkgver=2026.05.02 pkgrel=1 pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca" url="https://git.stormux.org/storm/cthulhu" diff --git a/meson.build b/meson.build index 23f79e9..0713d84 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cthulhu', - version: '2026.03.02-master', + version: '2026.05.02-master', meson_version: '>= 1.0.0', ) diff --git a/src/cthulhu/cthulhuVersion.py b/src/cthulhu/cthulhuVersion.py index 99befca..d78e3b3 100644 --- a/src/cthulhu/cthulhuVersion.py +++ b/src/cthulhu/cthulhuVersion.py @@ -23,5 +23,5 @@ # Forked from Orca screen reader. # Cthulhu project: https://git.stormux.org/storm/cthulhu -version = "2026.03.02" +version = "2026.05.02" codeName = "master" diff --git a/tests/test_nvda2cthulhu_regressions.py b/tests/test_nvda2cthulhu_regressions.py new file mode 100644 index 0000000..91bcdb3 --- /dev/null +++ b/tests/test_nvda2cthulhu_regressions.py @@ -0,0 +1,47 @@ +import sys +import unittest +from pathlib import Path +from unittest import mock + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from cthulhu.plugins.nvda2cthulhu import plugin as nvda_plugin + + +class Nvda2CthulhuRegressionTests(unittest.TestCase): + def _make_plugin(self): + plugin = nvda_plugin.Nvda2Cthulhu.__new__(nvda_plugin.Nvda2Cthulhu) + plugin.interruptEnabled = True + plugin._dependencies_available = mock.Mock(return_value=True) + return plugin + + def test_text_cancel_speech_frame_is_cancel_request(self): + plugin = self._make_plugin() + + self.assertEqual(("CancelSpeech", None), plugin._parse_request("CancelSpeech")) + + def test_websocket_speech_is_queued_instead_of_handled_synchronously(self): + plugin = self._make_plugin() + plugin._translation_enabled = mock.Mock(return_value=False) + + with mock.patch.object(nvda_plugin.speech, "speak") as speak: + plugin.handle_message("hello") + + speak.assert_not_called() + + def test_queued_websocket_speech_runs_on_main_loop(self): + if not hasattr(nvda_plugin, "GLib"): + self.fail("nvda2cthulhu does not expose a GLib main-loop dispatcher") + + plugin = self._make_plugin() + plugin._translation_enabled = mock.Mock(return_value=False) + + with mock.patch.object(nvda_plugin.GLib, "idle_add", side_effect=lambda callback, *args: callback(*args)), \ + mock.patch.object(nvda_plugin.speech, "speak") as speak: + plugin.handle_message("hello") + + speak.assert_called_once_with("hello", interrupt=True) + + +if __name__ == "__main__": + unittest.main()