aman/tests/test_config.py

224 lines
8.5 KiB
Python

import json
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
if str(SRC) not in sys.path:
sys.path.insert(0, str(SRC))
from config import load
class ConfigTests(unittest.TestCase):
def test_defaults_when_file_missing(self):
missing = Path(tempfile.gettempdir()) / "lel_missing_config_test.json"
if missing.exists():
missing.unlink()
cfg = load(str(missing))
self.assertEqual(cfg.daemon.hotkey, "Cmd+m")
self.assertEqual(cfg.recording.input, "")
self.assertEqual(cfg.stt.model, "base")
self.assertEqual(cfg.stt.device, "cpu")
self.assertEqual(cfg.injection.backend, "clipboard")
self.assertFalse(cfg.injection.remove_transcription_from_clipboard)
self.assertEqual(cfg.vocabulary.replacements, [])
self.assertEqual(cfg.vocabulary.terms, [])
self.assertTrue(cfg.domain_inference.enabled)
def test_loads_nested_config(self):
payload = {
"daemon": {"hotkey": "Ctrl+space"},
"recording": {"input": 3},
"stt": {"model": "small", "device": "cuda"},
"injection": {
"backend": "injection",
"remove_transcription_from_clipboard": True,
},
"vocabulary": {
"replacements": [
{"from": "Martha", "to": "Marta"},
{"from": "docker", "to": "Docker"},
],
"terms": ["Systemd", "Kubernetes"],
},
"domain_inference": {"enabled": True},
}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
cfg = load(str(path))
self.assertEqual(cfg.daemon.hotkey, "Ctrl+space")
self.assertEqual(cfg.recording.input, 3)
self.assertEqual(cfg.stt.model, "small")
self.assertEqual(cfg.stt.device, "cuda")
self.assertEqual(cfg.injection.backend, "injection")
self.assertTrue(cfg.injection.remove_transcription_from_clipboard)
self.assertEqual(len(cfg.vocabulary.replacements), 2)
self.assertEqual(cfg.vocabulary.replacements[0].source, "Martha")
self.assertEqual(cfg.vocabulary.replacements[0].target, "Marta")
self.assertEqual(cfg.vocabulary.terms, ["Systemd", "Kubernetes"])
self.assertTrue(cfg.domain_inference.enabled)
def test_loads_legacy_keys(self):
payload = {
"hotkey": "Alt+m",
"input": "Mic",
"whisper_model": "tiny",
"whisper_device": "cpu",
"injection_backend": "clipboard",
}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
cfg = load(str(path))
self.assertEqual(cfg.daemon.hotkey, "Alt+m")
self.assertEqual(cfg.recording.input, "Mic")
self.assertEqual(cfg.stt.model, "tiny")
self.assertEqual(cfg.stt.device, "cpu")
self.assertEqual(cfg.injection.backend, "clipboard")
self.assertFalse(cfg.injection.remove_transcription_from_clipboard)
self.assertEqual(cfg.vocabulary.replacements, [])
def test_invalid_injection_backend_raises(self):
payload = {"injection": {"backend": "invalid"}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "injection.backend"):
load(str(path))
def test_invalid_clipboard_remove_option_raises(self):
payload = {"injection": {"remove_transcription_from_clipboard": "yes"}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "injection.remove_transcription_from_clipboard"):
load(str(path))
def test_removed_ai_section_raises(self):
payload = {"ai": {"enabled": True}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "ai section is no longer supported"):
load(str(path))
def test_removed_legacy_ai_enabled_raises(self):
payload = {"ai_enabled": True}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "ai_enabled is no longer supported"):
load(str(path))
def test_removed_logging_section_raises(self):
payload = {"logging": {"log_transcript": True}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "no longer supported"):
load(str(path))
def test_removed_legacy_log_transcript_raises(self):
payload = {"log_transcript": True}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "no longer supported"):
load(str(path))
def test_conflicting_replacements_raise(self):
payload = {
"vocabulary": {
"replacements": [
{"from": "Martha", "to": "Marta"},
{"from": "martha", "to": "Martha"},
]
}
}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "conflicting"):
load(str(path))
def test_duplicate_rules_and_terms_are_deduplicated(self):
payload = {
"vocabulary": {
"replacements": [
{"from": "docker", "to": "Docker"},
{"from": "DOCKER", "to": "Docker"},
],
"terms": ["Systemd", "systemd"],
}
}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
cfg = load(str(path))
self.assertEqual(len(cfg.vocabulary.replacements), 1)
self.assertEqual(cfg.vocabulary.replacements[0].source, "docker")
self.assertEqual(cfg.vocabulary.replacements[0].target, "Docker")
self.assertEqual(cfg.vocabulary.terms, ["Systemd"])
def test_wildcard_term_raises(self):
payload = {
"vocabulary": {
"terms": ["Dock*"],
}
}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "wildcard"):
load(str(path))
def test_removed_domain_mode_raises(self):
payload = {"domain_inference": {"mode": "heuristic"}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "domain_inference.mode is no longer supported"):
load(str(path))
def test_removed_vocabulary_max_rules_raises(self):
payload = {"vocabulary": {"max_rules": 100}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "vocabulary.max_rules is no longer supported"):
load(str(path))
def test_removed_vocabulary_max_terms_raises(self):
payload = {"vocabulary": {"max_terms": 100}}
with tempfile.TemporaryDirectory() as td:
path = Path(td) / "config.json"
path.write_text(json.dumps(payload), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "vocabulary.max_terms is no longer supported"):
load(str(path))
if __name__ == "__main__":
unittest.main()