fix: format error handling
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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(
|
||||||
content="Architectural analysis complete. Recommendations: improve modularity.",
|
return_value=Mock(
|
||||||
usage={},
|
content="Architectural analysis complete. Recommendations: improve modularity.",
|
||||||
model_name="test-model",
|
usage={},
|
||||||
metadata={},
|
model_name="test-model",
|
||||||
|
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,17 +108,18 @@ 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(
|
||||||
content=json.dumps(
|
return_value=Mock(
|
||||||
{
|
content=json.dumps(
|
||||||
"status": "analysis_complete",
|
{
|
||||||
"raw_analysis": """
|
"status": "analysis_complete",
|
||||||
|
"raw_analysis": """
|
||||||
🔴 CRITIQUE: Aucun problème critique trouvé.
|
🔴 CRITIQUE: Aucun problème critique trouvé.
|
||||||
|
|
||||||
🟠 ÉLEVÉ: Fichier example.py:42 - Fonction trop complexe
|
🟠 ÉLEVÉ: Fichier example.py:42 - Fonction trop complexe
|
||||||
@@ -132,18 +135,19 @@ class TestWorkflowToolsUTF8(unittest.TestCase):
|
|||||||
• Nomenclature cohérente
|
• Nomenclature cohérente
|
||||||
• Tests unitaires présents
|
• Tests unitaires présents
|
||||||
""",
|
""",
|
||||||
},
|
},
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
),
|
),
|
||||||
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
|
||||||
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(
|
||||||
content="Error analyzed: variable 'données' not defined. Probable cause: missing import.",
|
return_value=Mock(
|
||||||
usage={},
|
content="Error analyzed: variable 'données' not defined. Probable cause: missing import.",
|
||||||
model_name="test-model",
|
usage={},
|
||||||
metadata={},
|
model_name="test-model",
|
||||||
|
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": "❌",
|
||||||
"métadonnées": {
|
"warning": "⚠️",
|
||||||
"créé_par": "Développeur Principal",
|
},
|
||||||
"date_création": "2024-01-01",
|
"progress": "Analysis completed 🎉",
|
||||||
"dernière_modification": "2024-01-15",
|
"recommendations": [
|
||||||
},
|
"Optimize performance 🚀",
|
||||||
"émojis_status": {
|
"Improve documentation 📚",
|
||||||
"critique": "🔴",
|
"Add unit tests 🧪",
|
||||||
"é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__":
|
||||||
|
|||||||
Reference in New Issue
Block a user