Test what the application does, and run it on every pull request

570 tests over the standard library's unittest, so there is nothing to
install beyond the PyQt6 the application already needs. They reach neither
the network, the microphone, nor the real ~/.config/dikte: urllib is faked at
one function, the tools are faked at shutil.which, and every test is handed
its own config and data directory.

What they hold onto is what a change is most likely to move without meaning
to. The request each provider is sent, field by field. A settings window that
loads a value into a widget and writes it back, which is where a setting
added to one half and not the other is silently reset. The dictation chain
end to end: what is transcribed, what is pasted, what lands in the history,
and what happens to the audio afterwards. A config file written by an older
version. A meeting whose two channels heard the same sentence.

59 of them carry @linux_only, because they cover what Dikte is on this
desktop rather than what it does: PipeWire, wl-clipboard, ydotool, KDE's
shortcut file. The other 511 pass on any platform, and that line is worth
holding as the ports arrive.

CONTRIBUTING.md says how to run them, what support.py offers, and the three
things about this codebase that trip up a new test.
This commit is contained in:
yusufipk
2026-08-01 20:06:47 +07:00
parent 1b12ae0c2f
commit 80a4832818
18 changed files with 4541 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
"""Test-wide safety net, applied before anything under test is imported.
Every module resolves its paths at import time from the XDG variables, so those
are redirected here: a test that forgets to ask for a throwaway directory writes
into a temporary one instead of into the real ~/.config/dikte. The Qt platform
is pinned for the same reason, so that a machine with no display and a CI runner
behave the way a desktop does.
"""
import atexit
import os
import shutil
import tempfile
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
_SANDBOX = tempfile.mkdtemp(prefix="dikte-tests-")
os.environ["XDG_CONFIG_HOME"] = os.path.join(_SANDBOX, "config")
os.environ["XDG_DATA_HOME"] = os.path.join(_SANDBOX, "data")
atexit.register(shutil.rmtree, _SANDBOX, True)
# A key sitting in the environment would otherwise reach the code that falls
# back to it, and the tests for "there is no key" would pass only on a machine
# without one.
for _var in ("OPENAI_API_KEY", "OPENROUTER_API_KEY"):
os.environ.pop(_var, None)
# The interface language leaks through module-level state, so the tests fix it
# rather than inherit whatever the developer's locale says.
for _var in ("LC_ALL", "LC_MESSAGES", "LANG"):
os.environ.pop(_var, None)