Files
markitect-main/test_complete_integration.py
tegwick 8f1cc0faf9 feat: complete CLI integration with plugin system
**CLI Integration:**
- Added --engine parameter to md-render command
- Default engine selection: testdrive-jsui for edit/insert, standard for view
- Graceful fallback to standard rendering when plugin unavailable
- Engine validation and mode compatibility checking

**Plugin Discovery:**
- Enhanced RenderingEngineManager with builtin plugin registration
- Automatic discovery and registration of testdrive-jsui engine
- Support for both plugin system discovery and direct registration

**Configuration Management:**
- Production-ready RenderingConfig for CLI usage
- Asset deployment to _markitect/plugins/ structure
- Configurable asset base URLs and deployment strategies

**Testing Infrastructure:**
- Comprehensive test suite for plugin discovery
- CLI integration testing without Click framework dependencies
- Complete scenario testing (default, explicit, fallback, unknown engines)
- Integration verification scripts

**Documentation:**
- Complete PLUGIN_SYSTEM.md documentation
- Architecture overview and development workflows
- JavaScript-first development guide
- Asset management and deployment strategies
- CLI usage examples and troubleshooting guide

**Key Features:**
- `markitect md-render --edit` now uses testdrive-jsui by default
- `markitect md-render --engine testdrive-jsui --edit` for explicit selection
- `markitect md-render --engine standard --edit` for legacy behavior
- Automatic fallback with user-friendly error messages

This completes the plugin infrastructure implementation, enabling
independent JavaScript development with seamless CLI integration.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 08:47:30 +01:00

152 lines
5.7 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Complete integration test demonstrating all CLI plugin functionality
"""
import sys
from pathlib import Path
# Add current directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))
def test_engine_scenarios():
"""Test different engine scenarios."""
print("🚀 Complete CLI Plugin Integration Test")
print("=" * 60)
scenarios = [
("Default (edit mode)", None, True, False),
("Explicit testdrive-jsui", "testdrive-jsui", True, False),
("Standard engine", "standard", True, False),
("Unknown engine", "unknown-engine", True, False),
("Default (view mode)", None, False, False),
]
results = []
for scenario_name, engine, edit, insert in scenarios:
print(f"\n🧪 Testing: {scenario_name}")
print("-" * 50)
try:
# Import the core logic components
from markitect.plugins import PluginManager, RenderingEngineManager, RenderingConfig
input_file = "test_cli_plugin.md"
if not Path(input_file).exists():
print(f" ❌ Test file {input_file} not found")
continue
content = Path(input_file).read_text(encoding='utf-8')
# Initialize plugin system
plugin_manager = PluginManager()
rendering_manager = RenderingEngineManager(plugin_manager)
# Engine selection logic (copied from CLI)
selected_engine = engine
if selected_engine is None:
# Default engine selection
if edit or insert:
selected_engine = 'testdrive-jsui' # Default to testdrive-jsui for interactive modes
else:
selected_engine = 'standard' # Use standard CleanDocumentManager for non-interactive
print(f" 🎯 Selected engine: {selected_engine}")
# Check if engine is available
if selected_engine != 'standard':
rendering_engine = rendering_manager.get_engine(selected_engine)
if rendering_engine is None:
print(f" ⚠️ Engine '{selected_engine}' not found, would fallback to standard")
selected_engine = 'standard'
rendering_engine = None
else:
# Check mode support
current_mode = 'edit' if edit else ('insert' if insert else 'view')
if not rendering_engine.validate_mode(current_mode):
print(f" ⚠️ Engine '{selected_engine}' doesn't support '{current_mode}', would fallback to standard")
selected_engine = 'standard'
rendering_engine = None
else:
print(f" ✅ Engine supports mode '{current_mode}'")
# Perform rendering if plugin engine is available
if selected_engine != 'standard' and rendering_engine:
current_mode = 'edit' if edit else ('insert' if insert else 'view')
render_config = RenderingConfig(
asset_base_url="_markitect",
development_mode=False,
output_directory=Path("/tmp")
)
html_content = rendering_engine.render_document(content, current_mode, render_config)
# Save output
output_file = f"/tmp/test_scenario_{scenario_name.lower().replace(' ', '_').replace('(', '').replace(')', '')}.html"
Path(output_file).write_text(html_content, encoding='utf-8')
output_size = Path(output_file).stat().st_size
print(f" ✅ Rendered using plugin engine ({output_size:,} bytes)")
print(f" 📄 Output: {output_file}")
results.append({
'scenario': scenario_name,
'engine': selected_engine,
'status': 'success',
'output_file': output_file,
'size': output_size
})
else:
print(f" Would use standard CleanDocumentManager")
results.append({
'scenario': scenario_name,
'engine': 'standard',
'status': 'fallback',
'output_file': None,
'size': 0
})
except Exception as e:
print(f" ❌ Failed: {e}")
results.append({
'scenario': scenario_name,
'engine': selected_engine,
'status': 'error',
'output_file': None,
'size': 0
})
# Summary
print(f"\n📊 Test Summary")
print("=" * 60)
successful = sum(1 for r in results if r['status'] == 'success')
fallback = sum(1 for r in results if r['status'] == 'fallback')
failed = sum(1 for r in results if r['status'] == 'error')
for result in results:
status_icon = {
'success': '',
'fallback': '🔄',
'error': ''
}[result['status']]
size_info = f"({result['size']:,} bytes)" if result['size'] > 0 else ""
print(f" {status_icon} {result['scenario']:<25}{result['engine']:<15} {size_info}")
print(f"\n🎯 Results: {successful} successful, {fallback} fallback, {failed} failed")
if successful > 0:
print(f"\n🌐 Generated files can be opened in browser:")
for result in results:
if result['output_file']:
print(f" file://{Path(result['output_file']).absolute()}")
return failed == 0
if __name__ == "__main__":
success = test_engine_scenarios()
sys.exit(0 if success else 1)