fix: format error handling

This commit is contained in:
OhMyApps
2025-06-23 23:56:30 +02:00
parent a46f8c2fad
commit bf628f23ec
3 changed files with 110 additions and 126 deletions

View File

@@ -285,53 +285,53 @@ def test_mcp_tools_integration():
response_data = { response_data = {
"status": "success", "status": "success",
"content_type": "markdown", "content_type": "markdown",
"content": """# Analysis Completed Successfully "content": """# Analyse Terminée avec Succès
## Analysis Summary ## Résumé de l'Analyse
The architectural analysis of the project has been **successfully** completed. Here are the main results: L'analyse architecturale du projet a été **terminée** avec succès. Voici les principaux résultats :
### 🎯 Achieved Goals ### 🎯 Objectifs Atteints
- ✅ Complete code review - ✅ Révision complète du code
- ✅ Identification of performance issues - ✅ Identification des problèmes de performance
- ✅ Improvement recommendations generated - ✅ Recommandations d'amélioration générées
### 📊 Analyzed Metrics ### 📊 Métriques Analysées
| Metric | Value | Status | | Métrique | Valeur | Statut |
|--------|-------|--------| |----------|--------|--------|
| Cyclomatic complexity | 12 | 🟡 Acceptable | | Complexité cyclomatique | 12 | 🟡 Acceptable |
| Test coverage | 85% | 🟢 Good | | Couverture de tests | 85% | 🟢 Bon |
| External dependencies | 23 | 🟠 To be reviewed | | Dépendances externes | 23 | 🟠 À réviser |
### 🔍 Identified Issues ### 🔍 Problèmes Identifiés
#### 🔴 Critical #### 🔴 Critique
No critical issues detected. Aucun problème critique détecté.
#### 🟠 High #### 🟠 Élevé
1. **Query performance**: Optimization needed 1. **Performance des requêtes** : Optimisation nécessaire
2. **Memory management**: Potential leaks detected 2. **Gestion mémoire** : Fuites potentielles détectées
#### 🟡 Medium #### 🟡 Moyen
1. **Documentation**: Some functions lack comments 1. **Documentation** : Certaines fonctions manquent de commentaires
2. **Unit tests**: Coverage to be improved 2. **Tests unitaires** : Couverture à améliorer
### 🚀 Priority Recommendations ### 🚀 Recommandations Prioritaires
1. **DB Optimization**: Implement Redis cache 1. **Optimisation DB** : Implémenter un cache Redis
2. **Refactoring**: Separate responsibilities 2. **Refactoring** : Séparer les responsabilités
3. **Documentation**: Add missing docstrings 3. **Documentation** : Ajouter les docstrings manquantes
4. **Tests**: Increase coverage to 90%+ 4. **Tests** : Augmenter la couverture à 90%+
### 📈 Next Steps ### 📈 Prochaines Étapes
- [ ] Implement caching system - [ ] Implémenter le système de cache
- [ ] Refactor identified modules - [ ] Refactorer les modules identifiés
- [ ] Complete documentation - [ ] Compléter la documentation
- [ ] Run regression tests - [ ] Exécuter les tests de régression
--- ---
*Analysis automatically generated by MCP Zen* 🤖 *Analyse générée automatiquement par MCP Zen* 🤖
""", """,
"metadata": { "metadata": {
"tool_name": "analyze", "tool_name": "analyze",

View File

@@ -384,16 +384,10 @@ class TestLocalizationIntegration(unittest.TestCase):
# English # English
os.environ["LOCALE"] = "en-US" os.environ["LOCALE"] = "en-US"
instruction_en = tool.get_language_instruction() instruction_en = tool.get_language_instruction()
self.assertIn("en-US", instruction_en) self.assertIn("en-US", instruction_en) # Spanish
# Spanish
os.environ["LOCALE"] = "es-ES"
instruction_es = tool.get_language_instruction() # Spanish
os.environ["LOCALE"] = "es-ES" os.environ["LOCALE"] = "es-ES"
instruction_es = tool.get_language_instruction() instruction_es = tool.get_language_instruction()
self.assertIn("es-ES", instruction_es) self.assertIn("es-ES", instruction_es) # Chinese
# Chinese
os.environ["LOCALE"] = "zh-CN" os.environ["LOCALE"] = "zh-CN"
instruction_zh = tool.get_language_instruction() instruction_zh = tool.get_language_instruction()
self.assertIn("zh-CN", instruction_zh) self.assertIn("zh-CN", instruction_zh)

View File

@@ -6,14 +6,14 @@ and the generation of properly encoded JSON responses.
import json import json
import os import os
import unittest import unittest
from unittest.mock import Mock, patch from unittest.mock import AsyncMock, Mock, patch
from tools.analyze import AnalyzeTool from tools.analyze import AnalyzeTool
from tools.codereview import CodeReviewTool from tools.codereview import CodeReviewTool
from tools.debug import DebugIssueTool from tools.debug import DebugIssueTool
class TestWorkflowToolsUTF8(unittest.TestCase): class TestWorkflowToolsUTF8(unittest.IsolatedAsyncioTestCase):
"""Tests for UTF-8 encoding in workflow tools.""" """Tests for UTF-8 encoding in workflow tools."""
def setUp(self): def setUp(self):
@@ -48,7 +48,7 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
# Test JSON serialization with ensure_ascii=False # Test JSON serialization with ensure_ascii=False
json_str = json.dumps(test_response, indent=2, ensure_ascii=False) json_str = json.dumps(test_response, indent=2, ensure_ascii=False)
# UTF-8 checks # Check UTF-8 characters are preserved
self.assertIn("🔍", json_str) self.assertIn("🔍", json_str)
# No escaped characters # No escaped characters
@@ -60,22 +60,24 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
self.assertEqual(len(parsed["issues_found"]), 1) self.assertEqual(len(parsed["issues_found"]), 1)
@patch("tools.shared.base_tool.BaseTool.get_model_provider") @patch("tools.shared.base_tool.BaseTool.get_model_provider")
def test_analyze_tool_utf8_response(self, mock_get_provider): async def test_analyze_tool_utf8_response(self, mock_get_provider):
"""Test that the analyze tool returns correct UTF-8 responses.""" """Test that the analyze tool returns correct UTF-8 responses."""
# Mock provider # Mock provider
mock_provider = Mock() mock_provider = Mock()
mock_provider.get_provider_type.return_value = Mock(value="test") mock_provider.get_provider_type.return_value = Mock(value="test")
mock_provider.generate_content.return_value = Mock( mock_provider.generate_content = AsyncMock(
return_value=Mock(
content="Architectural analysis complete. Recommendations: improve modularity.", content="Architectural analysis complete. Recommendations: improve modularity.",
usage={}, usage={},
model_name="test-model", model_name="test-model",
metadata={}, metadata={},
) )
)
mock_get_provider.return_value = mock_provider mock_get_provider.return_value = mock_provider
# Test the tool # Test the tool
analyze_tool = AnalyzeTool() analyze_tool = AnalyzeTool()
result = analyze_tool.execute( result = await analyze_tool.execute(
{ {
"step": "Analyze system architecture to identify issues", "step": "Analyze system architecture to identify issues",
"step_number": 1, "step_number": 1,
@@ -106,13 +108,14 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
self.assertIn("fr-FR", system_prompt) self.assertIn("fr-FR", system_prompt)
@patch("tools.shared.base_tool.BaseTool.get_model_provider") @patch("tools.shared.base_tool.BaseTool.get_model_provider")
def test_codereview_tool_french_findings(self, mock_get_provider): async def test_codereview_tool_french_findings(self, mock_get_provider):
"""Test that the codereview tool produces findings in French.""" """Test that the codereview tool produces findings in French."""
# Mock with analysis in French # Mock with analysis in French
mock_provider = Mock() mock_provider = Mock()
mock_provider.get_provider_type.return_value = Mock(value="test") mock_provider.get_provider_type.return_value = Mock(value="test")
mock_provider.supports_thinking_mode.return_value = False mock_provider.supports_thinking_mode.return_value = False
mock_provider.generate_content.return_value = Mock( mock_provider.generate_content = AsyncMock(
return_value=Mock(
content=json.dumps( content=json.dumps(
{ {
"status": "analysis_complete", "status": "analysis_complete",
@@ -139,11 +142,12 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
model_name="test-model", model_name="test-model",
metadata={}, metadata={},
) )
)
mock_get_provider.return_value = mock_provider mock_get_provider.return_value = mock_provider
# Test the tool # Test the tool
codereview_tool = CodeReviewTool() codereview_tool = CodeReviewTool()
result = codereview_tool.execute( result = await codereview_tool.execute(
{ {
"step": "Complete review of Python code", "step": "Complete review of Python code",
"step_number": 1, "step_number": 1,
@@ -177,22 +181,24 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
self.assertIn("", analysis) self.assertIn("", analysis)
@patch("tools.shared.base_tool.BaseTool.get_model_provider") @patch("tools.shared.base_tool.BaseTool.get_model_provider")
def test_debug_tool_french_error_analysis(self, mock_get_provider): async def test_debug_tool_french_error_analysis(self, mock_get_provider):
"""Test that the debug tool analyzes errors in French.""" """Test that the debug tool analyzes errors in French."""
# Mock provider # Mock provider
mock_provider = Mock() mock_provider = Mock()
mock_provider.get_provider_type.return_value = Mock(value="test") mock_provider.get_provider_type.return_value = Mock(value="test")
mock_provider.generate_content.return_value = Mock( mock_provider.generate_content = AsyncMock(
return_value=Mock(
content="Error analyzed: variable 'données' not defined. Probable cause: missing import.", content="Error analyzed: variable 'données' not defined. Probable cause: missing import.",
usage={}, usage={},
model_name="test-model", model_name="test-model",
metadata={}, metadata={},
) )
)
mock_get_provider.return_value = mock_provider mock_get_provider.return_value = mock_provider
# Test the debug tool # Test the debug tool
debug_tool = DebugIssueTool() debug_tool = DebugIssueTool()
result = debug_tool.execute( result = await debug_tool.execute(
{ {
"step": "Analyze NameError in data processing file", "step": "Analyze NameError in data processing file",
"step_number": 1, "step_number": 1,
@@ -220,67 +226,51 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
response_str = json.dumps(response_data, ensure_ascii=False) response_str = json.dumps(response_data, ensure_ascii=False)
self.assertIn("données", response_str) self.assertIn("données", response_str)
def test_json_utf8_serialization(self): def test_utf8_emoji_preservation_in_workflow_responses(self):
"""Test UTF-8 serialization with ensure_ascii=False.""" """Test that emojis are preserved in workflow tool responses."""
# Test data with French characters and emojis # Mock workflow response with various emojis
test_data = { test_data = {
"analyse": { "status": "analysis_complete",
"statut": "terminée", "severity_indicators": {
"résultat": "Aucun problème critique détecté", "critical": "🔴",
"recommandations": [ "high": "🟠",
"Améliorer la documentation", "medium": "🟡",
"Optimiser les performances", "low": "🟢",
"Ajouter des tests unitaires", "success": "",
"error": "",
"warning": "⚠️",
},
"progress": "Analysis completed 🎉",
"recommendations": [
"Optimize performance 🚀",
"Improve documentation 📚",
"Add unit tests 🧪",
], ],
"métadonnées": {
"créé_par": "Développeur Principal",
"date_création": "2024-01-01",
"dernière_modification": "2024-01-15",
},
"émojis_status": {
"critique": "🔴",
"élevé": "🟠",
"moyen": "🟡",
"faible": "🟢",
"succès": "",
"erreur": "",
},
}
} }
# Test with ensure_ascii=False # Test JSON encoding with ensure_ascii=False
json_correct = json.dumps(test_data, ensure_ascii=False, indent=2) json_str = json.dumps(test_data, ensure_ascii=False, indent=2)
# Checks # Check emojis are preserved
utf8_terms = [ self.assertIn("🔴", json_str)
"terminée", self.assertIn("🟠", json_str)
"résultat", self.assertIn("🟡", json_str)
"détecté", self.assertIn("🟢", json_str)
"Améliorer", self.assertIn("", json_str)
"créé_par", self.assertIn("", json_str)
"Développeur", self.assertIn("⚠️", json_str)
"création", self.assertIn("🎉", json_str)
"métadonnées", self.assertIn("🚀", json_str)
"dernière", self.assertIn("📚", json_str)
"émojis_status", self.assertIn("🧪", json_str)
"élevé",
]
emojis = ["🔴", "🟠", "🟡", "🟢", "", ""] # No escaped Unicode
self.assertNotIn("\\u", json_str)
for term in utf8_terms: # Test parsing preserves emojis
self.assertIn(term, json_correct) parsed = json.loads(json_str)
self.assertEqual(parsed["severity_indicators"]["critical"], "🔴")
for emoji in emojis: self.assertEqual(parsed["progress"], "Analysis completed 🎉")
self.assertIn(emoji, json_correct)
# Check for escaped characters
self.assertNotIn("\\u", json_correct)
# Test parsing
parsed = json.loads(json_correct)
self.assertEqual(parsed["analyse"]["statut"], "terminée")
self.assertEqual(parsed["analyse"]["émojis_status"]["critique"], "🔴")
if __name__ == "__main__": if __name__ == "__main__":