Files
markitect-main/examples/issue-demos/issue_59_prevention_demo.py
tegwick ed33766c91 refactor: reorganize examples directory with topic-based subdirectories
Reorganize examples directory into logical topic-based subdirectories with
comprehensive documentation:

- templates/: ISO/ARC42 documentation templates
- asset-management/: Asset management prototypes and demos
- essays/: Long-form content examples
- invoicing/: Invoice generation examples
- plugins/: Plugin development examples
- issue-demos/: Issue prevention demonstrations
- design-patterns/: Design pattern examples

Each subdirectory includes a README.txt file with topic description and
contributor signatures based on file creation timestamps.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 22:31:52 +01:00

261 lines
9.8 KiB
Python

#!/usr/bin/env python3
"""
Issue #59 Prevention Demonstration
This example shows how the Requirements Engineering Agent would have prevented
the interface compatibility issues and mock object mismatches encountered
during Issue #59 development.
"""
import sys
from pathlib import Path
from unittest.mock import Mock
from datetime import datetime, timezone
# Add project root to path for imports
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from domain.issues.models import Issue, IssueState, Label
from tools.requirements_engineering_toolkit import RequirementsEngineeringAgent
def demonstrate_issue_59_problems():
"""Demonstrate the actual problems encountered in Issue #59."""
print("🚨 DEMONSTRATING ISSUE #59 PROBLEMS")
print("=" * 50)
print("\n❌ PROBLEM 1: Mock object didn't match domain model")
print("-" * 50)
# This is what was done in the original tests (WRONG)
mock_issue_wrong = Mock()
mock_issue_wrong.number = 59
mock_issue_wrong.title = "Test Issue"
mock_issue_wrong.state = "open" # ❌ String instead of enum!
mock_issue_wrong.labels = []
print(f"Mock state type: {type(mock_issue_wrong.state)} (should be IssueState enum)")
print(f"Mock state value: {mock_issue_wrong.state}")
# The real domain model uses enums
real_issue = Issue(
number=59,
title="Test Issue",
state=IssueState.OPEN, # ✅ Actual enum
labels=[],
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
print(f"Real state type: {type(real_issue.state)}")
print(f"Real state value: {real_issue.state}")
print("\n❌ PROBLEM 2: Missing required attributes")
print("-" * 50)
# Original mock was missing critical attributes
print("Mock attributes:", [attr for attr in dir(mock_issue_wrong) if not attr.startswith('_')])
print("Real attributes:", [attr for attr in dir(real_issue) if not attr.startswith('_')])
missing_attrs = set(dir(real_issue)) - set(dir(mock_issue_wrong))
print(f"Missing attributes in mock: {[attr for attr in missing_attrs if not attr.startswith('_')]}")
def demonstrate_requirements_engineering_solution():
"""Demonstrate how the Requirements Engineering Agent would prevent these problems."""
print("\n\n✅ REQUIREMENTS ENGINEERING AGENT SOLUTION")
print("=" * 50)
agent = RequirementsEngineeringAgent(project_root)
print("\n🔍 STEP 1: Foundation Analysis")
print("-" * 30)
# Analyze existing domain models first
foundation_analysis = agent.analyze_project_foundations()
print(f"Found {foundation_analysis['foundation_analysis']['summary']['total_domain_models']} domain models")
# Show Issue model details
if 'Issue' in foundation_analysis['foundation_analysis']['domain_models']:
issue_model = foundation_analysis['foundation_analysis']['domain_models']['Issue']
print(f"Issue model attributes: {list(issue_model.attributes.keys())}")
print(f"Issue model methods: {issue_model.methods}")
print("\n📋 STEP 2: Generate Development Checklist")
print("-" * 30)
checklist = agent.generate_development_checklist("Issue Management CLI", {
"requires_issue_model": True,
"creates_new_interface": True
})
for phase in checklist:
print(f"\n{phase['phase']}:")
for task in phase['tasks']:
print(f"{task}")
print("\n🧪 STEP 3: Correct Mock Creation")
print("-" * 30)
# This is how mocks should be created with the agent's guidance
mock_issue_correct = Mock(spec=Issue) # ✅ Use spec= parameter
mock_issue_correct.number = 59
mock_issue_correct.title = "Test Issue"
mock_issue_correct.state = IssueState.OPEN # ✅ Use actual enum
mock_issue_correct.labels = []
mock_issue_correct.created_at = datetime.now(timezone.utc) # ✅ Include all required attributes
mock_issue_correct.updated_at = datetime.now(timezone.utc)
print("✅ Correctly created mock with spec=Issue")
print(f"✅ State is proper enum: {type(mock_issue_correct.state)}")
print(f"✅ All required attributes included")
# Validate the mock
validation_result = agent.mock_validator.validate_mock_against_model(mock_issue_correct, "Issue")
if validation_result.is_valid:
print("✅ Mock validation passed!")
else:
print(f"❌ Mock validation failed: {validation_result.errors}")
def demonstrate_interface_compatibility_checking():
"""Demonstrate interface compatibility checking."""
print("\n\n🔌 INTERFACE COMPATIBILITY DEMONSTRATION")
print("=" * 50)
agent = RequirementsEngineeringAgent(project_root)
print("\n📊 Interface Analysis")
print("-" * 20)
# This would check if new plugin interface is compatible with existing repository
# In the actual Issue #59, this would have caught the mismatch between
# what the tests expected and what the actual GiteaIssueRepository provided
print("✅ Would verify that IssueBackend interface matches GiteaIssueRepository methods")
print("✅ Would catch async/sync mismatch (repository is async, plugin interface is sync)")
print("✅ Would identify missing adapter layer needed")
# Example compatibility check result
compatibility_result = {
"compatible": False,
"issues": [
"GiteaIssueRepository.get_issues() is async, but IssueBackend.list_issues() is sync",
"Parameter mismatch: repository uses issue_number (int), interface uses issue_id (str)",
"Repository returns additional attributes not defined in interface"
],
"recommendations": [
"Add async adapter layer",
"Standardize parameter types",
"Extend interface to include all repository attributes"
]
}
print("\nCompatibility check would have found:")
for issue in compatibility_result["issues"]:
print(f"{issue}")
print("\nRecommendations:")
for rec in compatibility_result["recommendations"]:
print(f" 💡 {rec}")
def demonstrate_correct_development_workflow():
"""Demonstrate the correct development workflow using the agent."""
print("\n\n🎯 CORRECT DEVELOPMENT WORKFLOW")
print("=" * 50)
print("\n📋 Phase 1: Foundation Analysis")
print("-" * 30)
print("✅ Analyze existing Issue domain model")
print("✅ Map GiteaIssueRepository interface")
print("✅ Understand async/sync requirements")
print("✅ Document existing infrastructure patterns")
print("\n📋 Phase 2: Interface Contract Definition")
print("-" * 30)
print("✅ Define IssueBackend abstract base class")
print("✅ Plan async adapter pattern")
print("✅ Ensure compatibility with existing infrastructure")
print("✅ Document interface contracts")
print("\n📋 Phase 3: Test Architecture Design")
print("-" * 30)
print("✅ Create mocks with Mock(spec=Issue)")
print("✅ Use actual enums and types")
print("✅ Include all required attributes")
print("✅ Plan integration test strategy")
print("\n📋 Phase 4: Implementation")
print("-" * 30)
print("✅ Implement IssueBackend base class")
print("✅ Create GiteaPlugin with async adapter")
print("✅ Add CLI commands using plugin manager")
print("✅ Maintain backward compatibility")
print("\n📋 Phase 5: Validation")
print("-" * 30)
print("✅ Validate all mocks match real objects")
print("✅ Test interface compatibility")
print("✅ Run integration tests")
print("✅ Verify end-to-end workflows")
def create_agent_usage_example():
"""Show actual agent usage commands."""
print("\n\n🛠️ AGENT USAGE COMMANDS")
print("=" * 50)
print("\n# Before starting Issue #59 development:")
print("python tools/requirements_engineering_toolkit.py analyze")
print("")
print("# Plan new interface evolution:")
print("python tools/requirements_engineering_toolkit.py plan-interface --interface IssueBackend")
print("")
print("# Generate development checklist:")
print("python tools/requirements_engineering_toolkit.py checklist --feature 'Issue Management CLI'")
print("")
print("# Validate test mocks:")
print("python tools/requirements_engineering_toolkit.py validate-mocks --test-file tests/test_issue_59_cli_interface.py")
print("\n📝 Integration with existing workflow:")
print("# Add to Makefile:")
print("validate-requirements:")
print("\tpython tools/requirements_engineering_toolkit.py analyze")
print("")
print("tdd-start: validate-requirements")
print("\t# Existing TDD start process")
def main():
"""Run the complete demonstration."""
print("ISSUE #59 PREVENTION DEMONSTRATION")
print("Requirements Engineering Agent")
print("=" * 60)
try:
demonstrate_issue_59_problems()
demonstrate_requirements_engineering_solution()
demonstrate_interface_compatibility_checking()
demonstrate_correct_development_workflow()
create_agent_usage_example()
print("\n\n🎉 SUMMARY")
print("=" * 20)
print("The Requirements Engineering Agent would have prevented Issue #59 problems by:")
print("1. ✅ Analyzing existing domain models before writing tests")
print("2. ✅ Ensuring mocks match actual object interfaces")
print("3. ✅ Catching enum vs string type mismatches")
print("4. ✅ Identifying missing async adapter layer")
print("5. ✅ Planning interface evolution with backward compatibility")
print("6. ✅ Providing clear development workflow guidance")
except Exception as e:
print(f"Error in demonstration: {e}")
print("Note: This demo requires the full project structure to run completely.")
print("The concepts and workflow are demonstrated above.")
if __name__ == "__main__":
main()