BuddAI/tests/test_fallback_client.py
JamesTheGiblet d4e09f6d13 Add unit tests for analytics, fallback client, and refactored validators
- 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.
2026-01-08 17:43:11 +00:00

105 lines
No EOL
4.3 KiB
Python

import unittest
from unittest.mock import MagicMock, patch
import sys
import os
from pathlib import Path
# 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_fallback import FallbackClient
class TestFallbackClient(unittest.TestCase):
@patch('core.buddai_fallback.genai')
def test_escalate_success(self, mock_genai):
"""Test successful escalation to Gemini"""
# Setup mocks
mock_model = MagicMock()
mock_response = MagicMock()
mock_response.text = "Fixed Code"
mock_model.generate_content.return_value = mock_response
mock_genai.GenerativeModel.return_value = mock_model
# Force HAS_GEMINI to True for this test
with patch('core.buddai_fallback.HAS_GEMINI', True):
with patch.dict('os.environ', {'GEMINI_API_KEY': 'fake_key'}):
client = FallbackClient()
# Inject mock client since __init__ might fail if real genai not installed
client.gemini_client = mock_model
client.build_fallback_prompt = MagicMock(return_value="Prompt")
result = client.escalate("gemini", "prompt", "bad code", 50)
self.assertIn("Gemini Fallback", result)
self.assertIn("Fixed Code", result)
def test_escalate_no_key(self):
"""Test behavior when API key is missing"""
with patch.dict('os.environ', {}, clear=True):
client = FallbackClient()
result = client.escalate("gemini", "prompt", "bad code", 50)
self.assertIn("fallback unavailable", result)
@patch('core.buddai_fallback.OpenAI')
def test_escalate_openai(self, mock_openai):
"""Test successful escalation to OpenAI"""
# Setup mocks
mock_client = MagicMock()
mock_response = MagicMock()
mock_message = MagicMock()
mock_message.content = "GPT Code"
mock_choice = MagicMock()
mock_choice.message = mock_message
mock_response.choices = [mock_choice]
mock_client.chat.completions.create.return_value = mock_response
mock_openai.return_value = mock_client
with patch('core.buddai_fallback.HAS_OPENAI', True):
with patch.dict('os.environ', {'OPENAI_API_KEY': 'fake_key'}):
client = FallbackClient()
client.openai_client = mock_client
client.build_fallback_prompt = MagicMock(return_value="Prompt")
result = client.escalate("gpt4", "prompt", "bad code", 50)
self.assertIn("GPT4 Fallback", result)
self.assertIn("GPT Code", result)
@patch('core.buddai_fallback.anthropic', create=True)
def test_escalate_claude(self, mock_anthropic):
"""Test successful escalation to Claude"""
# Setup mocks
mock_client = MagicMock()
mock_message = MagicMock()
mock_message.content = [MagicMock(text="Claude Code")]
mock_client.messages.create.return_value = mock_message
mock_anthropic.Anthropic.return_value = mock_client
with patch('core.buddai_fallback.HAS_CLAUDE', True, create=True):
with patch.dict('os.environ', {'ANTHROPIC_API_KEY': 'fake_key'}):
client = FallbackClient()
client.claude_client = mock_client
result = client.escalate("claude", "prompt", "bad code", 50)
self.assertIn("Claude Fallback", result)
self.assertIn("Claude Code", result)
def test_extract_learning_patterns(self):
"""Test extraction of patterns from code diffs"""
with patch.dict('os.environ', {}, clear=True):
client = FallbackClient()
buddai_code = "void setup() {\n pinMode(13, OUTPUT);\n}"
fallback_code = "void setup() {\n pinMode(13, OUTPUT);\n Serial.begin(115200);\n}"
patterns = client.extract_learning_patterns(buddai_code, fallback_code)
self.assertIn("Serial.begin(115200);", patterns)
self.assertNotIn("pinMode(13, OUTPUT);", patterns)
if __name__ == '__main__':
unittest.main()