- Move enhanced_mcp package to src/enhanced_mcp/ (Python best practice) - Update pyproject.toml for src-layout configuration - Fix test imports and paths for new structure - Remove unnecessary directories: config/, scripts/ - Update CLAUDE.md documentation for src-layout - Maintain full functionality with 50+ tools across 14 modules Benefits: - Better separation between source and development files - Prevents accidental imports of development versions - Follows modern Python packaging standards - Improved testing isolation - Professional package structure ready for distribution
176 lines
5.3 KiB
Python
176 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script to validate Enhanced MCP Tools package structure and dependencies.
|
|
"""
|
|
|
|
import sys
|
|
import importlib.util
|
|
from pathlib import Path
|
|
|
|
def test_package_structure():
|
|
"""Test that the package structure is correct."""
|
|
print("=== Package Structure Test ===")
|
|
|
|
# Check core files exist in src-layout
|
|
required_files = [
|
|
"src/enhanced_mcp/__init__.py",
|
|
"src/enhanced_mcp/base.py",
|
|
"src/enhanced_mcp/mcp_server.py",
|
|
"pyproject.toml"
|
|
]
|
|
|
|
for file_path in required_files:
|
|
if Path(file_path).exists():
|
|
print(f"✅ {file_path}")
|
|
else:
|
|
print(f"❌ {file_path} missing")
|
|
return False
|
|
|
|
return True
|
|
|
|
def test_imports():
|
|
"""Test that all imports work correctly."""
|
|
print("\n=== Import Test ===")
|
|
|
|
# Test core imports
|
|
try:
|
|
from enhanced_mcp import create_server, MCPToolServer
|
|
print("✅ Core package imports")
|
|
except Exception as e:
|
|
print(f"❌ Core imports failed: {e}")
|
|
return False
|
|
|
|
# Test individual modules
|
|
modules = [
|
|
("file_operations", "EnhancedFileOperations"),
|
|
("archive_compression", "ArchiveCompression"),
|
|
("git_integration", "GitIntegration"),
|
|
("asciinema_integration", "AsciinemaIntegration"),
|
|
("sneller_analytics", "SnellerAnalytics"),
|
|
("intelligent_completion", "IntelligentCompletion"),
|
|
("diff_patch", "DiffPatchOperations"),
|
|
]
|
|
|
|
for module_name, class_name in modules:
|
|
try:
|
|
module = importlib.import_module(f"enhanced_mcp.{module_name}")
|
|
getattr(module, class_name)
|
|
print(f"✅ {module_name}.{class_name}")
|
|
except Exception as e:
|
|
print(f"❌ {module_name}.{class_name}: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def test_optional_dependencies():
|
|
"""Test optional dependency handling."""
|
|
print("\n=== Optional Dependencies Test ===")
|
|
|
|
dependencies = {
|
|
"aiofiles": "Async file operations",
|
|
"watchdog": "File system monitoring",
|
|
"psutil": "Process monitoring",
|
|
"requests": "HTTP requests"
|
|
}
|
|
|
|
available_count = 0
|
|
for dep_name, description in dependencies.items():
|
|
try:
|
|
importlib.import_module(dep_name)
|
|
print(f"✅ {dep_name}: Available")
|
|
available_count += 1
|
|
except ImportError:
|
|
print(f"⚠️ {dep_name}: Not available (graceful fallback active)")
|
|
|
|
print(f"\n📊 {available_count}/{len(dependencies)} optional dependencies available")
|
|
return True
|
|
|
|
def test_pyproject_toml():
|
|
"""Test pyproject.toml configuration."""
|
|
print("\n=== pyproject.toml Configuration Test ===")
|
|
|
|
try:
|
|
import tomllib
|
|
except ImportError:
|
|
try:
|
|
import tomli as tomllib
|
|
except ImportError:
|
|
print("⚠️ No TOML parser available, skipping pyproject.toml validation")
|
|
return True
|
|
|
|
try:
|
|
with open("pyproject.toml", "rb") as f:
|
|
config = tomllib.load(f)
|
|
|
|
# Check required sections
|
|
required_sections = ["build-system", "project"]
|
|
for section in required_sections:
|
|
if section in config:
|
|
print(f"✅ {section} section present")
|
|
else:
|
|
print(f"❌ {section} section missing")
|
|
return False
|
|
|
|
# Check project metadata
|
|
project = config["project"]
|
|
required_fields = ["name", "version", "description", "dependencies"]
|
|
for field in required_fields:
|
|
if field in project:
|
|
print(f"✅ project.{field}")
|
|
else:
|
|
print(f"❌ project.{field} missing")
|
|
return False
|
|
|
|
print(f"✅ Project name: {project['name']}")
|
|
print(f"✅ Project version: {project['version']}")
|
|
print(f"✅ Python requirement: {project.get('requires-python', 'not specified')}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ pyproject.toml validation failed: {e}")
|
|
return False
|
|
|
|
def main():
|
|
"""Run all tests."""
|
|
print("🧪 Enhanced MCP Tools Package Validation")
|
|
print("=" * 50)
|
|
|
|
tests = [
|
|
test_package_structure,
|
|
test_imports,
|
|
test_optional_dependencies,
|
|
test_pyproject_toml
|
|
]
|
|
|
|
results = []
|
|
for test_func in tests:
|
|
try:
|
|
result = test_func()
|
|
results.append(result)
|
|
except Exception as e:
|
|
print(f"❌ {test_func.__name__} crashed: {e}")
|
|
results.append(False)
|
|
|
|
print("\n" + "=" * 50)
|
|
print("📋 Test Results Summary")
|
|
print("=" * 50)
|
|
|
|
all_passed = all(results)
|
|
if all_passed:
|
|
print("🎉 ALL TESTS PASSED!")
|
|
print("✅ Package structure is correct")
|
|
print("✅ All imports work with graceful fallbacks")
|
|
print("✅ pyproject.toml is properly configured")
|
|
print("🚀 Enhanced MCP Tools is ready for use!")
|
|
else:
|
|
print("❌ Some tests failed")
|
|
for i, (test_func, result) in enumerate(zip(tests, results)):
|
|
status = "✅" if result else "❌"
|
|
print(f"{status} {test_func.__name__}")
|
|
|
|
return 0 if all_passed else 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|