mirror of
https://github.com/JamesTheGiblet/BuddAI.git
synced 2026-01-08 21:58:40 +00:00
- Implemented comprehensive unit tests for the BuddAI Analytics module, covering fallback statistics calculations. - Created tests for the FallbackClient to ensure proper escalation to various AI models and handling of missing API keys. - Developed unit tests for the refactored validator system, validating various hardware and coding standards. - Established a base validator interface and implemented specific validators for ESP32, Arduino, motor control, memory safety, and more. - Enhanced the validator registry to auto-discover and manage validators effectively. - Included detailed validation logic for common issues in embedded systems programming, such as unused variables, safety timeouts, and coding style violations.
125 lines
4 KiB
Python
125 lines
4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for BuddAI Analytics
|
|
Verifies calculation of accuracy, trends, and fallback statistics.
|
|
"""
|
|
|
|
import unittest
|
|
import sqlite3
|
|
import tempfile
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
# Setup path
|
|
REPO_ROOT = Path(__file__).parent.parent
|
|
if str(REPO_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(REPO_ROOT))
|
|
|
|
from core.buddai_analytics import LearningMetrics
|
|
|
|
class TestAnalytics(unittest.TestCase):
|
|
def setUp(self):
|
|
# Create temp DB
|
|
self.db_fd, self.db_path = tempfile.mkstemp(suffix=".db")
|
|
os.close(self.db_fd)
|
|
self.db_path_obj = Path(self.db_path)
|
|
|
|
# Patch DB_PATH in analytics module
|
|
self.db_patcher = patch('core.buddai_analytics.DB_PATH', self.db_path_obj)
|
|
self.db_patcher.start()
|
|
|
|
# Initialize DB tables
|
|
conn = sqlite3.connect(self.db_path)
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
role TEXT,
|
|
content TEXT,
|
|
timestamp TIMESTAMP
|
|
)
|
|
""")
|
|
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS code_rules (
|
|
id INTEGER PRIMARY KEY,
|
|
rule_text TEXT,
|
|
learned_from TEXT
|
|
)
|
|
""")
|
|
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS feedback (
|
|
message_id INTEGER,
|
|
positive BOOLEAN
|
|
)
|
|
""")
|
|
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS corrections (
|
|
id INTEGER PRIMARY KEY,
|
|
original_code TEXT
|
|
)
|
|
""")
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
self.metrics = LearningMetrics()
|
|
|
|
def tearDown(self):
|
|
self.db_patcher.stop()
|
|
try:
|
|
os.unlink(self.db_path)
|
|
except:
|
|
pass
|
|
|
|
def test_fallback_stats(self):
|
|
"""Test calculation of fallback statistics"""
|
|
conn = sqlite3.connect(self.db_path)
|
|
cursor = conn.cursor()
|
|
|
|
# 1. Insert Messages (10 total assistant, 4 fallbacks)
|
|
# 6 normal responses
|
|
for _ in range(6):
|
|
cursor.execute("INSERT INTO messages (role, content) VALUES (?, ?)", ("assistant", "Normal response"))
|
|
# 4 fallback responses
|
|
for _ in range(4):
|
|
cursor.execute("INSERT INTO messages (role, content) VALUES (?, ?)", ("assistant", "Response with Fallback Triggered inside"))
|
|
# Some user messages (should be ignored)
|
|
cursor.execute("INSERT INTO messages (role, content) VALUES (?, ?)", ("user", "Help me"))
|
|
|
|
# 2. Insert Rules (2 from fallback)
|
|
cursor.execute("INSERT INTO code_rules (rule_text, learned_from) VALUES (?, ?)", ("Rule 1", "fallback_claude"))
|
|
cursor.execute("INSERT INTO code_rules (rule_text, learned_from) VALUES (?, ?)", ("Rule 2", "fallback_gpt4"))
|
|
cursor.execute("INSERT INTO code_rules (rule_text, learned_from) VALUES (?, ?)", ("Rule 3", "user_correction"))
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
# Calculate stats
|
|
stats = self.metrics.get_fallback_stats()
|
|
|
|
# Assertions
|
|
# Total escalations: 4
|
|
self.assertEqual(stats['total_escalations'], 4)
|
|
|
|
# Fallback rate: 4 / 10 = 40.0%
|
|
self.assertEqual(stats['fallback_rate'], 40.0)
|
|
|
|
# Learning success: 2 rules / 4 escalations = 50.0%
|
|
self.assertEqual(stats['learning_success'], 50.0)
|
|
|
|
def test_fallback_stats_empty(self):
|
|
"""Test stats with empty database"""
|
|
stats = self.metrics.get_fallback_stats()
|
|
|
|
self.assertEqual(stats['total_escalations'], 0)
|
|
self.assertEqual(stats['fallback_rate'], 0.0)
|
|
self.assertEqual(stats['learning_success'], 0.0)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|