Files
rpa_vision_v3/tests/property/test_circular_imports_property.py
Dom a27b74cf22 v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40)
- Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard)
- Ollama GPU fonctionnel
- Self-healing interactif
- Dashboard confiance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:23:51 +01:00

122 lines
4.3 KiB
Python

"""
Test de propriété pour l'absence d'imports circulaires.
Propriété 3: Absence d'imports circulaires
Pour tout module du système, l'importation ne doit pas créer de dépendances cycliques.
Auteur: Dom, Alice Kiro
Date: 20 décembre 2024
"""
import sys
from pathlib import Path
from hypothesis import given, strategies as st, settings
import pytest
# Ajouter le répertoire racine au path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from validate_circular_imports import CircularImportDetector
class TestCircularImportsProperty:
"""Tests de propriété pour l'absence d'imports circulaires"""
@settings(max_examples=10, deadline=30000) # 10 exemples, 30s timeout
@given(st.just("core")) # On teste toujours le répertoire core
def test_property_no_circular_imports(self, directory_name):
"""
Propriété 3: Absence d'imports circulaires
Pour tout module du système, l'importation ne doit pas créer
de dépendances cycliques.
Cette propriété garantit que:
1. Aucun cycle n'existe dans le graphe d'imports
2. Les imports peuvent être résolus dans un ordre topologique
3. Le système peut démarrer sans erreurs d'import
"""
root_path = Path(__file__).parent.parent.parent
target_path = root_path / directory_name
# Vérifier que le répertoire existe
assert target_path.exists(), f"Répertoire {directory_name} non trouvé"
# Analyser les imports
detector = CircularImportDetector(root_path)
detector.analyze_directory(target_path)
# Détecter les cycles
cycles = detector.find_cycles()
# Propriété: Aucun cycle ne doit exister
assert len(cycles) == 0, (
f"Imports circulaires détectés dans {directory_name}:\n" +
"\n".join([
f"Cycle {i+1}: {''.join(cycle)}"
for i, cycle in enumerate(cycles)
]) +
"\n\nCeci viole la Propriété 3: Absence d'imports circulaires"
)
# Propriété additionnelle: Le graphe doit être analysable
assert len(detector.module_paths) > 0, "Aucun module analysé"
# Propriété additionnelle: Les dépendances doivent être cohérentes
total_deps = sum(len(deps) for deps in detector.module_graph.values())
assert total_deps >= 0, "Nombre de dépendances invalide"
def test_property_lazy_imports_work(self):
"""
Propriété: Les imports lazy doivent fonctionner correctement
Cette propriété garantit que:
1. Les fonctions de lazy loading retournent les bonnes classes
2. Les imports conditionnels ne créent pas de cycles
3. TYPE_CHECKING fonctionne comme attendu
"""
from core.models import (
get_workflow,
get_workflow_node,
get_action,
get_target_spec
)
# Propriété: Les fonctions lazy doivent retourner des classes valides
classes = [
get_workflow(),
get_workflow_node(),
get_action(),
get_target_spec()
]
for cls in classes:
assert hasattr(cls, '__name__'), "Classe sans nom"
assert callable(cls), "Objet non callable"
def test_property_interfaces_are_abstract(self):
"""
Propriété: Les interfaces doivent être abstraites
Cette propriété garantit que:
1. Les interfaces ne peuvent pas être instanciées directement
2. Elles définissent des méthodes abstraites
3. Elles permettent le découplage
"""
from core.interfaces import ITargetResolver, IActionExecutor, IErrorHandler
interfaces = [ITargetResolver, IActionExecutor, IErrorHandler]
for interface in interfaces:
# Propriété: Doit avoir des méthodes abstraites
assert hasattr(interface, '__abstractmethods__'), (
f"{interface.__name__} n'a pas de méthodes abstraites"
)
# Propriété: Ne peut pas être instanciée directement
with pytest.raises(TypeError):
interface()
if __name__ == "__main__":
pytest.main([__file__, "-v"])