Say true things in every language, and stop paying twice

doctor judged the local provider by the API key it does not use, so a
fully local machine always saw a red mark, and it crashed outright with
local cleanup picked; both lines now ask readiness. config list printed
the Groq key in plaintext while masking the other two. The one subprocess
decoded with the locale codepage gets its UTF-8 back, so a Turkish
filename cannot hang a file transcription, and a redirected stdout on
Windows replaces what it cannot encode instead of failing after the work
succeeded. meeting-cancel stops advertising a --wait the server never
honoured. "you" and "bye" leave the hallucination list: people dictate
them. The minutes stage failing no longer burns the transcription
checkpoint, and an untouched meeting-length dial no longer rewrites a
value the command line set in seconds. A prompt box compared against the
wrong language's default after a switch no longer fossilizes the old
default as a custom prompt.

The 67 strings of the local-model box, the whole first-run screen of the
shipped default, get their Turkish. The hub cache moves to the platform's
cache directory instead of ~/.cache on every system; the old directory is
a few orphaned kilobytes with a six-hour shelf life. The last NO_WINDOW
spellings collapse into the constant paths already carries, one
windowed-executable lookup, one session-file reader, one install-record
reader, one download progress signal carrying its destination, and the
KDE conflict scan loses the branch its other branch already covered.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
huseyin-emre-tigci
2026-08-22 23:17:22 +03:00
co-authored by Claude Fable 5
parent 6f79e93d53
commit e8147f49f8
14 changed files with 403 additions and 88 deletions
+1
View File
@@ -17,6 +17,7 @@ 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")
os.environ["XDG_CACHE_HOME"] = os.path.join(_SANDBOX, "cache")
# Home goes with them: the shortcut file, the applications directory and every
# macOS path start from it rather than from an XDG variable, and a test run is
# not allowed to touch the real one.
+22
View File
@@ -223,6 +223,28 @@ class ChunkSeconds(DikteTest):
self.assertEqual(ft.chunk_seconds(self.file(ft.UPLOAD_LIMIT * 2), 0), 0.0)
class Ffmpeg(DikteTest):
"""How the converter process is started."""
def test_its_output_is_read_as_utf8_whatever_the_locale_says(self):
"""ffmpeg writes UTF-8; read as the locale codepage its messages
mojibake, and a byte the codepage cannot place raises from inside
communicate itself."""
out = str(self.path("out.wav"))
with open(out, "wb") as fh:
fh.write(b"\x00")
proc = mock.Mock()
proc.communicate.return_value = ("", "")
proc.returncode = 0
proc.poll.return_value = 0
with mock.patch.object(ft.subprocess, "Popen", return_value=proc) as popen:
ft._ffmpeg(["-i", "in.mp4", out], out)
kwargs = popen.call_args.kwargs
self.assertTrue(kwargs["text"])
self.assertEqual(kwargs["encoding"], "utf-8")
self.assertEqual(kwargs["errors"], "replace")
class Chunks(DikteTest):
"""What each provider is handed, and in how many pieces."""
+10
View File
@@ -3,6 +3,7 @@
import json
from dikte import hub
from dikte import paths
from tests.support import DikteTest, fake_urlopen, http_error, url_error
RELEASE = {
@@ -165,6 +166,15 @@ def os_utime(path):
os.utime(path, (old, old))
class CacheLocation(DikteTest):
"""Resolved at import, like every other path constant."""
def test_the_cache_lives_in_the_system_cache_directory(self):
# One answer for both, the same way ggml and config share DATA_DIR:
# hub asked paths once, at import, and kept what it was told.
self.assertEqual(hub.CACHE_DIR, paths.cache_dir())
class CacheOnDisk(DikteTest):
def setUp(self):
super().setUp()
+28
View File
@@ -61,6 +61,34 @@ class Directories(unittest.TestCase):
self.assertTrue(data_dir.as_posix().endswith("/AppData/Local/Dikte"))
class CacheDir(unittest.TestCase):
"""The third place: files whose whole point is that they can be lost."""
def test_linux_follows_xdg(self):
with mock.patch.dict(os.environ, {"XDG_CACHE_HOME": "/k"}):
self.assertEqual(paths.cache_dir("linux").as_posix(), "/k/dikte")
def test_linux_without_the_variable_set(self):
with mock.patch.dict(os.environ, {}, clear=True):
self.assertTrue(paths.cache_dir("linux").as_posix()
.endswith("/.cache/dikte"))
def test_a_mac_caches_under_library_caches(self):
"""Where Time Machine already knows not to look."""
self.assertTrue(paths.cache_dir("darwin").as_posix()
.endswith("/Library/Caches/Dikte"))
def test_windows_caches_outside_the_roaming_profile(self):
with mock.patch.dict(os.environ, {"LOCALAPPDATA": "C:/local"}):
self.assertEqual(paths.cache_dir("win32").as_posix(),
"C:/local/Dikte/cache")
def test_windows_without_the_variable_set(self):
with mock.patch.dict(os.environ, {}, clear=True):
self.assertTrue(paths.cache_dir("win32").as_posix()
.endswith("/AppData/Local/Dikte/cache"))
class OnePlace(unittest.TestCase):
"""The programs and the models go where everything else goes.
+11 -2
View File
@@ -692,12 +692,21 @@ class LocalModels(DikteTest):
# Qt's int is C++'s 32-bit one, and a 2.3 GB model is more than fits in
# it: the count came out the far side negative, at "-1%".
box = self.window(cfg.Config()).local_llm
box._downloading = True
box._report(1_048_576, 2_489_757_856)
box._report("model", 1_048_576, 2_489_757_856)
_app.processEvents()
self.assertIn("2.3 GB", box.status.text())
self.assertNotIn("-", box.status.text())
def test_each_download_reports_into_its_own_label(self):
"""The two can run at once; the tag, not a flag read later, says
which label the bytes belong to."""
box = self.window(cfg.Config()).local_llm
box._report("program", 10, 100)
box._report("model", 20, 100)
_app.processEvents()
self.assertIn("10", box.program_label.text())
self.assertIn("20", box.status.text())
def test_a_long_model_name_is_not_cut_in_half(self):
# The list under a combo box takes the box's width and elides what does
# not fit, in the middle: "ggml-org/Qwen....7B-Base-GGUF".
+8 -2
View File
@@ -128,6 +128,12 @@ class Hallucinations(DikteTest):
self.assertFalse(vad.looks_like_hallucination("Bugün toplantı var.", 2.0))
self.assertFalse(vad.looks_like_hallucination("Send it on Thursday.", 2.0))
def test_a_one_word_answer_is_believed(self):
# Whisper invents both over silence, but people dictate both as whole
# answers, and losing a real answer costs more than passing a fake one.
self.assertFalse(vad.looks_like_hallucination("You.", 1.5))
self.assertFalse(vad.looks_like_hallucination("Bye.", 1.5))
def test_an_empty_transcript_counts_as_invented(self):
self.assertTrue(vad.looks_like_hallucination(" ", 2.0))
self.assertTrue(vad.looks_like_hallucination("...", 2.0))
@@ -138,8 +144,8 @@ class Hallucinations(DikteTest):
self.assertTrue(vad.looks_like_hallucination(text, 2.0))
def test_the_boundary_is_the_max_duration(self):
self.assertTrue(vad.looks_like_hallucination("you", 6.0))
self.assertFalse(vad.looks_like_hallucination("you", 6.1))
self.assertTrue(vad.looks_like_hallucination("thanks for watching", 6.0))
self.assertFalse(vad.looks_like_hallucination("thanks for watching", 6.1))
if __name__ == "__main__":