add spec system: sdd/bdd/tdd loops, trace enforcement, envelope+config specs

This commit is contained in:
Oleksandr Kozachuk
2026-07-13 12:53:38 +02:00
parent 1879992b22
commit f1578cbd99
11 changed files with 682 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
"""Unit coverage for SPEC-008 (CFG-01..03)."""
import unittest
from unittest.mock import mock_open, patch
import toml
from fjerkroa_bot import FjerkroaBot
from fjerkroa_bot.ai_responder import AIMessage, AIResponder
class TestConfigLoad(unittest.TestCase):
def test_load_config_parses_toml(self):
"""CFG-01: load_config parses the TOML file into a plain dict."""
data = {"system": "prompt", "history-limit": 7, "additional-responders": []}
with patch("builtins.open", mock_open(read_data=toml.dumps(data))):
result = FjerkroaBot.load_config("config.toml")
self.assertEqual(result, data)
class TestPerChannelPrompt(unittest.TestCase):
def test_channel_override_wins(self):
"""CFG-02: responder bound to a channel uses config[channel] over config['system']."""
config = {"system": "Default prompt", "kitchen": "Kitchen prompt", "history-limit": 5}
responder = AIResponder(config, "kitchen")
system = responder.message(AIMessage("alice", "hei", "kitchen"))[0]["content"]
self.assertTrue(system.startswith("Kitchen prompt"))
def test_fallback_to_system(self):
"""CFG-02: without a channel key the shared system prompt is used."""
config = {"system": "Default prompt", "history-limit": 5}
responder = AIResponder(config, "kitchen")
system = responder.message(AIMessage("alice", "hei", "kitchen"))[0]["content"]
self.assertTrue(system.startswith("Default prompt"))
class TestNewsFileMissing(unittest.TestCase):
def test_missing_news_file_keeps_placeholder(self):
"""CFG-03: nonexistent news file -> {news} placeholder stays literal, no crash."""
config = {"system": "N: {news}", "history-limit": 5, "news": "/nonexistent/news.txt"}
responder = AIResponder(config, "chat")
system = responder.message(AIMessage("alice", "hei"))[0]["content"]
self.assertIn("{news}", system)