SuperClaude/Framework-Hooks/hooks/shared/tests/test_framework_logic.py

476 lines
20 KiB
Python
Raw Normal View History

feat: Implement YAML-first declarative intelligence architecture Revolutionary transformation from hardcoded Python intelligence to hot-reloadable YAML patterns, enabling dynamic configuration without code changes. ## Phase 1: Foundation Intelligence Complete ### YAML Intelligence Patterns (6 files) - intelligence_patterns.yaml: Multi-dimensional pattern recognition with adaptive learning - mcp_orchestration.yaml: Server selection decision trees with load balancing - hook_coordination.yaml: Parallel execution patterns with dependency resolution - performance_intelligence.yaml: Resource zones and auto-optimization triggers - validation_intelligence.yaml: Health scoring and proactive diagnostic patterns - user_experience.yaml: Project detection and smart UX adaptations ### Python Infrastructure Enhanced (4 components) - intelligence_engine.py: Generic YAML pattern interpreter with hot-reload - learning_engine.py: Enhanced with YAML intelligence integration - yaml_loader.py: Added intelligence configuration helper methods - validate_system.py: New YAML-driven validation with health scoring ### Key Features Implemented - Hot-reload intelligence: Update patterns without code changes or restarts - Declarative configuration: All intelligence logic expressed in YAML - Graceful fallbacks: System works correctly even with missing YAML files - Multi-pattern coordination: Intelligent recommendations from multiple sources - Health scoring: Component-weighted validation with predictive diagnostics - Generic architecture: Single engine consumes all intelligence pattern types ### Testing Results ✅ All components integrate correctly ✅ Hot-reload mechanism functional ✅ Graceful error handling verified ✅ YAML-driven validation operational ✅ Health scoring system working (detected real system issues) This enables users to modify intelligence behavior by editing YAML files, add new pattern types without coding, and hot-reload improvements in real-time. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-06 13:26:04 +02:00
#!/usr/bin/env python3
"""
Comprehensive tests for framework_logic.py
Tests all core functionality including:
- RULES.md compliance validation
- PRINCIPLES.md application
- ORCHESTRATOR.md decision logic
- Risk assessment and complexity scoring
- Performance estimation and optimization
"""
import unittest
import sys
from pathlib import Path
# Add the shared directory to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
from framework_logic import (
FrameworkLogic, OperationType, RiskLevel, OperationContext,
ValidationResult
)
class TestFrameworkLogic(unittest.TestCase):
"""Comprehensive tests for FrameworkLogic."""
def setUp(self):
"""Set up test environment."""
self.framework = FrameworkLogic()
# Create test contexts
self.simple_context = OperationContext(
operation_type=OperationType.READ,
file_count=1,
directory_count=1,
has_tests=False,
is_production=False,
user_expertise='intermediate',
project_type='web',
complexity_score=0.2,
risk_level=RiskLevel.LOW
)
self.complex_context = OperationContext(
operation_type=OperationType.REFACTOR,
file_count=15,
directory_count=5,
has_tests=True,
is_production=True,
user_expertise='expert',
project_type='api',
complexity_score=0.8,
risk_level=RiskLevel.HIGH
)
def test_read_before_write_rule(self):
"""Test RULES.md: Always use Read tool before Write or Edit operations."""
# Write and Edit operations should require read
write_context = OperationContext(
operation_type=OperationType.WRITE,
file_count=1, directory_count=1, has_tests=False,
is_production=False, user_expertise='beginner',
project_type='web', complexity_score=0.3, risk_level=RiskLevel.LOW
)
edit_context = OperationContext(
operation_type=OperationType.EDIT,
file_count=1, directory_count=1, has_tests=False,
is_production=False, user_expertise='beginner',
project_type='web', complexity_score=0.3, risk_level=RiskLevel.LOW
)
self.assertTrue(self.framework.should_use_read_before_write(write_context))
self.assertTrue(self.framework.should_use_read_before_write(edit_context))
# Read operations should not require read
self.assertFalse(self.framework.should_use_read_before_write(self.simple_context))
def test_complexity_score_calculation(self):
"""Test complexity score calculation algorithm."""
# Simple operation
simple_data = {
'file_count': 1,
'directory_count': 1,
'operation_type': 'read',
'multi_language': False,
'framework_changes': False
}
simple_score = self.framework.calculate_complexity_score(simple_data)
self.assertLess(simple_score, 0.3)
# Complex operation
complex_data = {
'file_count': 20,
'directory_count': 5,
'operation_type': 'refactor',
'multi_language': True,
'framework_changes': True
}
complex_score = self.framework.calculate_complexity_score(complex_data)
self.assertGreater(complex_score, 0.7)
# Score should be capped at 1.0
extreme_data = {
'file_count': 1000,
'directory_count': 100,
'operation_type': 'system-wide',
'multi_language': True,
'framework_changes': True
}
extreme_score = self.framework.calculate_complexity_score(extreme_data)
self.assertEqual(extreme_score, 1.0)
def test_risk_assessment(self):
"""Test risk level assessment logic."""
# Production context should be high risk
prod_context = OperationContext(
operation_type=OperationType.DEPLOY,
file_count=5, directory_count=2, has_tests=True,
is_production=True, user_expertise='expert',
project_type='api', complexity_score=0.5, risk_level=RiskLevel.MEDIUM
)
risk = self.framework.assess_risk_level(prod_context)
self.assertEqual(risk, RiskLevel.HIGH)
# High complexity should be high risk
high_complexity_context = OperationContext(
operation_type=OperationType.BUILD,
file_count=5, directory_count=2, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.8, risk_level=RiskLevel.LOW
)
risk = self.framework.assess_risk_level(high_complexity_context)
self.assertEqual(risk, RiskLevel.HIGH)
# Many files should be medium risk
many_files_context = OperationContext(
operation_type=OperationType.EDIT,
file_count=15, directory_count=2, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.3, risk_level=RiskLevel.LOW
)
risk = self.framework.assess_risk_level(many_files_context)
self.assertEqual(risk, RiskLevel.MEDIUM)
# Simple operations should be low risk
risk = self.framework.assess_risk_level(self.simple_context)
self.assertEqual(risk, RiskLevel.LOW)
def test_validation_enablement(self):
"""Test when validation should be enabled."""
# High risk operations should enable validation
self.assertTrue(self.framework.should_enable_validation(self.complex_context))
# Production operations should enable validation
prod_context = OperationContext(
operation_type=OperationType.WRITE,
file_count=1, directory_count=1, has_tests=False,
is_production=True, user_expertise='beginner',
project_type='web', complexity_score=0.2, risk_level=RiskLevel.LOW
)
self.assertTrue(self.framework.should_enable_validation(prod_context))
# Deploy operations should enable validation
deploy_context = OperationContext(
operation_type=OperationType.DEPLOY,
file_count=1, directory_count=1, has_tests=False,
is_production=False, user_expertise='expert',
project_type='web', complexity_score=0.2, risk_level=RiskLevel.LOW
)
self.assertTrue(self.framework.should_enable_validation(deploy_context))
# Simple operations should not require validation
self.assertFalse(self.framework.should_enable_validation(self.simple_context))
def test_delegation_logic(self):
"""Test delegation decision logic."""
# Multiple files should trigger delegation
should_delegate, strategy = self.framework.should_enable_delegation(self.complex_context)
self.assertTrue(should_delegate)
self.assertEqual(strategy, "files")
# Multiple directories should trigger delegation
multi_dir_context = OperationContext(
operation_type=OperationType.ANALYZE,
file_count=2, directory_count=4, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.3, risk_level=RiskLevel.LOW
)
should_delegate, strategy = self.framework.should_enable_delegation(multi_dir_context)
self.assertTrue(should_delegate)
self.assertEqual(strategy, "folders")
# High complexity should trigger auto delegation
high_complexity_context = OperationContext(
operation_type=OperationType.BUILD,
file_count=2, directory_count=1, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.7, risk_level=RiskLevel.MEDIUM
)
should_delegate, strategy = self.framework.should_enable_delegation(high_complexity_context)
self.assertTrue(should_delegate)
self.assertEqual(strategy, "auto")
# Simple operations should not require delegation
should_delegate, strategy = self.framework.should_enable_delegation(self.simple_context)
self.assertFalse(should_delegate)
self.assertEqual(strategy, "none")
def test_operation_validation(self):
"""Test operation validation against PRINCIPLES.md."""
# Valid operation with all requirements
valid_operation = {
'operation_type': 'write',
'evidence': 'User explicitly requested file creation',
'has_error_handling': True,
'affects_logic': True,
'has_tests': True,
'is_public_api': False,
'handles_user_input': False
}
result = self.framework.validate_operation(valid_operation)
self.assertTrue(result.is_valid)
self.assertEqual(len(result.issues), 0)
self.assertGreaterEqual(result.quality_score, 0.7)
# Invalid operation missing error handling
invalid_operation = {
'operation_type': 'write',
'evidence': 'User requested',
'has_error_handling': False,
'affects_logic': True,
'has_tests': False,
'is_public_api': True,
'has_documentation': False,
'handles_user_input': True,
'has_input_validation': False
}
result = self.framework.validate_operation(invalid_operation)
self.assertFalse(result.is_valid)
self.assertGreater(len(result.issues), 0)
self.assertLess(result.quality_score, 0.7)
# Check specific validation issues
issue_texts = ' '.join(result.issues).lower()
self.assertIn('error handling', issue_texts)
self.assertIn('input', issue_texts)
warning_texts = ' '.join(result.warnings).lower()
self.assertIn('tests', warning_texts)
self.assertIn('documentation', warning_texts)
def test_thinking_mode_determination(self):
"""Test thinking mode determination based on complexity."""
# Very high complexity should trigger ultrathink
ultra_context = OperationContext(
operation_type=OperationType.REFACTOR,
file_count=20, directory_count=5, has_tests=True,
is_production=True, user_expertise='expert',
project_type='system', complexity_score=0.85, risk_level=RiskLevel.HIGH
)
mode = self.framework.determine_thinking_mode(ultra_context)
self.assertEqual(mode, "--ultrathink")
# High complexity should trigger think-hard
hard_context = OperationContext(
operation_type=OperationType.BUILD,
file_count=10, directory_count=3, has_tests=True,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.65, risk_level=RiskLevel.MEDIUM
)
mode = self.framework.determine_thinking_mode(hard_context)
self.assertEqual(mode, "--think-hard")
# Medium complexity should trigger think
medium_context = OperationContext(
operation_type=OperationType.ANALYZE,
file_count=5, directory_count=2, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.4, risk_level=RiskLevel.LOW
)
mode = self.framework.determine_thinking_mode(medium_context)
self.assertEqual(mode, "--think")
# Low complexity should not trigger thinking mode
mode = self.framework.determine_thinking_mode(self.simple_context)
self.assertIsNone(mode)
def test_efficiency_mode_enablement(self):
"""Test token efficiency mode enablement logic."""
# High resource usage should enable efficiency mode
high_resource_session = {
'resource_usage_percent': 80,
'conversation_length': 50,
'user_requests_brevity': False
}
self.assertTrue(self.framework.should_enable_efficiency_mode(high_resource_session))
# Long conversation should enable efficiency mode
long_conversation_session = {
'resource_usage_percent': 60,
'conversation_length': 150,
'user_requests_brevity': False
}
self.assertTrue(self.framework.should_enable_efficiency_mode(long_conversation_session))
# User requesting brevity should enable efficiency mode
brevity_request_session = {
'resource_usage_percent': 50,
'conversation_length': 30,
'user_requests_brevity': True
}
self.assertTrue(self.framework.should_enable_efficiency_mode(brevity_request_session))
# Normal session should not enable efficiency mode
normal_session = {
'resource_usage_percent': 40,
'conversation_length': 20,
'user_requests_brevity': False
}
self.assertFalse(self.framework.should_enable_efficiency_mode(normal_session))
def test_quality_gates_selection(self):
"""Test quality gate selection for different operations."""
# All operations should have syntax validation
gates = self.framework.get_quality_gates(self.simple_context)
self.assertIn('syntax_validation', gates)
# Write/Edit operations should have additional gates
write_context = OperationContext(
operation_type=OperationType.WRITE,
file_count=1, directory_count=1, has_tests=False,
is_production=False, user_expertise='intermediate',
project_type='web', complexity_score=0.3, risk_level=RiskLevel.LOW
)
gates = self.framework.get_quality_gates(write_context)
self.assertIn('syntax_validation', gates)
self.assertIn('type_analysis', gates)
self.assertIn('code_quality', gates)
# High-risk operations should have security and performance gates
gates = self.framework.get_quality_gates(self.complex_context)
self.assertIn('security_assessment', gates)
self.assertIn('performance_analysis', gates)
# Operations with tests should include test validation
test_context = OperationContext(
operation_type=OperationType.BUILD,
file_count=5, directory_count=2, has_tests=True,
is_production=False, user_expertise='expert',
project_type='api', complexity_score=0.5, risk_level=RiskLevel.MEDIUM
)
gates = self.framework.get_quality_gates(test_context)
self.assertIn('test_validation', gates)
# Deploy operations should have integration testing
deploy_context = OperationContext(
operation_type=OperationType.DEPLOY,
file_count=3, directory_count=1, has_tests=True,
is_production=True, user_expertise='expert',
project_type='web', complexity_score=0.4, risk_level=RiskLevel.HIGH
)
gates = self.framework.get_quality_gates(deploy_context)
self.assertIn('integration_testing', gates)
self.assertIn('deployment_validation', gates)
def test_performance_impact_estimation(self):
"""Test performance impact estimation."""
# Simple operation should have low estimated time
simple_estimate = self.framework.estimate_performance_impact(self.simple_context)
self.assertLess(simple_estimate['estimated_time_ms'], 300)
self.assertEqual(simple_estimate['performance_risk'], 'low')
self.assertEqual(len(simple_estimate['suggested_optimizations']), 0)
# Complex operation should have higher estimated time and optimizations
complex_estimate = self.framework.estimate_performance_impact(self.complex_context)
self.assertGreater(complex_estimate['estimated_time_ms'], 400)
self.assertGreater(len(complex_estimate['suggested_optimizations']), 2)
# Should suggest appropriate optimizations
optimizations = complex_estimate['suggested_optimizations']
opt_text = ' '.join(optimizations).lower()
self.assertIn('parallel', opt_text)
self.assertIn('delegation', opt_text)
# Very high estimated time should be high risk
if complex_estimate['estimated_time_ms'] > 1000:
self.assertEqual(complex_estimate['performance_risk'], 'high')
def test_superclaude_principles_application(self):
"""Test application of SuperClaude core principles."""
# Test Evidence > assumptions principle
assumption_heavy_data = {
'operation_type': 'analyze',
'assumptions': ['This should work', 'Users will like it'],
'evidence': None
}
enhanced = self.framework.apply_superclaude_principles(assumption_heavy_data)
self.assertIn('recommendations', enhanced)
rec_text = ' '.join(enhanced['recommendations']).lower()
self.assertIn('evidence', rec_text)
# Test Code > documentation principle
doc_heavy_data = {
'operation_type': 'document',
'has_working_code': False
}
enhanced = self.framework.apply_superclaude_principles(doc_heavy_data)
self.assertIn('warnings', enhanced)
warning_text = ' '.join(enhanced['warnings']).lower()
self.assertIn('working code', warning_text)
# Test Efficiency > verbosity principle
verbose_data = {
'operation_type': 'generate',
'output_length': 2000,
'justification_for_length': None
}
enhanced = self.framework.apply_superclaude_principles(verbose_data)
self.assertIn('efficiency_suggestions', enhanced)
eff_text = ' '.join(enhanced['efficiency_suggestions']).lower()
self.assertIn('token efficiency', eff_text)
def test_performance_targets_loading(self):
"""Test that performance targets are loaded correctly."""
# Should have performance targets loaded
self.assertIsInstance(self.framework.performance_targets, dict)
# Should have hook-specific targets (with defaults if config not available)
expected_targets = [
'session_start_ms',
'tool_routing_ms',
'validation_ms',
'compression_ms'
]
for target in expected_targets:
self.assertIn(target, self.framework.performance_targets)
self.assertIsInstance(self.framework.performance_targets[target], (int, float))
self.assertGreater(self.framework.performance_targets[target], 0)
def test_edge_cases_and_error_handling(self):
"""Test edge cases and error handling."""
# Empty operation data
empty_score = self.framework.calculate_complexity_score({})
self.assertGreaterEqual(empty_score, 0.0)
self.assertLessEqual(empty_score, 1.0)
# Negative file counts (shouldn't happen but should be handled)
negative_data = {
'file_count': -1,
'directory_count': -1,
'operation_type': 'unknown'
}
negative_score = self.framework.calculate_complexity_score(negative_data)
self.assertGreaterEqual(negative_score, 0.0)
# Very large file counts
large_data = {
'file_count': 1000000,
'directory_count': 10000,
'operation_type': 'system-wide'
}
large_score = self.framework.calculate_complexity_score(large_data)
self.assertEqual(large_score, 1.0) # Should be capped
# Empty validation operation
empty_validation = self.framework.validate_operation({})
self.assertIsInstance(empty_validation, ValidationResult)
self.assertIsInstance(empty_validation.quality_score, float)
if __name__ == '__main__':
# Run the tests
unittest.main(verbosity=2)