#!/usr/bin/env python3 """ Common validation utilities for Bubble Tea maintenance agent. """ from typing import Dict, List, Any, Optional def validate_result_structure(result: Dict[str, Any], required_keys: List[str]) -> Dict[str, Any]: """ Validate that a result dictionary has required keys. Args: result: Result dictionary to validate required_keys: List of required key names Returns: Validation dict with status, summary, and checks """ if 'error' in result: return { "status": "error", "summary": result['error'], "valid": False } checks = {} for key in required_keys: checks[f"has_{key}"] = key in result and result[key] is not None all_pass = all(checks.values()) status = "pass" if all_pass else "fail" summary = "Validation passed" if all_pass else f"Missing required keys: {[k for k, v in checks.items() if not v]}" return { "status": status, "summary": summary, "checks": checks, "valid": all_pass } def validate_issue_list(issues: List[Dict[str, Any]]) -> Dict[str, Any]: """ Validate a list of issues has proper structure. Expected issue structure: - severity: CRITICAL, HIGH, WARNING, or INFO - category: performance, layout, reliability, etc. - issue: Description - location: File path and line number - explanation: Why it's a problem - fix: How to fix it """ if not isinstance(issues, list): return { "status": "error", "summary": "Issues must be a list", "valid": False } required_fields = ["severity", "issue", "location", "explanation"] valid_severities = ["CRITICAL", "HIGH", "MEDIUM", "WARNING", "LOW", "INFO"] checks = { "is_list": True, "all_have_severity": True, "valid_severity_values": True, "all_have_issue": True, "all_have_location": True, "all_have_explanation": True } for issue in issues: if not isinstance(issue, dict): checks["is_list"] = False continue if "severity" not in issue: checks["all_have_severity"] = False elif issue["severity"] not in valid_severities: checks["valid_severity_values"] = False if "issue" not in issue or not issue["issue"]: checks["all_have_issue"] = False if "location" not in issue or not issue["location"]: checks["all_have_location"] = False if "explanation" not in issue or not issue["explanation"]: checks["all_have_explanation"] = False all_pass = all(checks.values()) status = "pass" if all_pass else "warning" failed = [k for k, v in checks.items() if not v] summary = "All issues properly structured" if all_pass else f"Issues have problems: {failed}" return { "status": status, "summary": summary, "checks": checks, "valid": all_pass, "issue_count": len(issues) } def validate_score(score: int, min_val: int = 0, max_val: int = 100) -> bool: """Validate a numeric score is in range.""" return isinstance(score, (int, float)) and min_val <= score <= max_val def validate_health_score(health_score: int) -> Dict[str, Any]: """Validate health score and categorize.""" if not validate_score(health_score): return { "status": "error", "summary": "Invalid health score", "valid": False } if health_score >= 90: category = "excellent" status = "pass" elif health_score >= 75: category = "good" status = "pass" elif health_score >= 60: category = "fair" status = "warning" elif health_score >= 40: category = "poor" status = "warning" else: category = "critical" status = "critical" return { "status": status, "summary": f"{category.capitalize()} health ({health_score}/100)", "category": category, "valid": True, "score": health_score } def validate_file_path(file_path: str) -> bool: """Validate file path format.""" from pathlib import Path try: path = Path(file_path) return path.exists() except Exception: return False def validate_best_practices_compliance(compliance: Dict[str, Dict[str, Any]]) -> Dict[str, Any]: """Validate best practices compliance structure.""" if not isinstance(compliance, dict): return { "status": "error", "summary": "Compliance must be a dictionary", "valid": False } required_tip_fields = ["status", "score", "message"] valid_statuses = ["pass", "fail", "warning", "info"] checks = { "has_tips": len(compliance) > 0, "all_tips_valid": True, "valid_statuses": True, "valid_scores": True } for tip_name, tip_data in compliance.items(): if not isinstance(tip_data, dict): checks["all_tips_valid"] = False continue for field in required_tip_fields: if field not in tip_data: checks["all_tips_valid"] = False if tip_data.get("status") not in valid_statuses: checks["valid_statuses"] = False if not validate_score(tip_data.get("score", -1)): checks["valid_scores"] = False all_pass = all(checks.values()) status = "pass" if all_pass else "warning" return { "status": status, "summary": f"Validated {len(compliance)} tips", "checks": checks, "valid": all_pass, "tip_count": len(compliance) } def validate_bottlenecks(bottlenecks: List[Dict[str, Any]]) -> Dict[str, Any]: """Validate performance bottleneck list.""" if not isinstance(bottlenecks, list): return { "status": "error", "summary": "Bottlenecks must be a list", "valid": False } required_fields = ["severity", "category", "issue", "location", "explanation", "fix"] valid_severities = ["CRITICAL", "HIGH", "MEDIUM", "LOW"] valid_categories = ["performance", "memory", "io", "rendering"] checks = { "is_list": True, "all_have_severity": True, "valid_severities": True, "all_have_category": True, "valid_categories": True, "all_have_fix": True } for bottleneck in bottlenecks: if not isinstance(bottleneck, dict): checks["is_list"] = False continue if "severity" not in bottleneck: checks["all_have_severity"] = False elif bottleneck["severity"] not in valid_severities: checks["valid_severities"] = False if "category" not in bottleneck: checks["all_have_category"] = False elif bottleneck["category"] not in valid_categories: checks["valid_categories"] = False if "fix" not in bottleneck or not bottleneck["fix"]: checks["all_have_fix"] = False all_pass = all(checks.values()) status = "pass" if all_pass else "warning" return { "status": status, "summary": f"Validated {len(bottlenecks)} bottlenecks", "checks": checks, "valid": all_pass, "bottleneck_count": len(bottlenecks) } def validate_architecture_analysis(result: Dict[str, Any]) -> Dict[str, Any]: """Validate architecture analysis result.""" required_keys = ["current_pattern", "complexity_score", "recommended_pattern", "refactoring_steps"] checks = {} for key in required_keys: checks[f"has_{key}"] = key in result and result[key] is not None # Validate complexity score if "complexity_score" in result: checks["valid_complexity_score"] = validate_score(result["complexity_score"]) else: checks["valid_complexity_score"] = False # Validate refactoring steps if "refactoring_steps" in result: checks["has_refactoring_steps"] = isinstance(result["refactoring_steps"], list) and len(result["refactoring_steps"]) > 0 else: checks["has_refactoring_steps"] = False all_pass = all(checks.values()) status = "pass" if all_pass else "warning" return { "status": status, "summary": "Architecture analysis validated" if all_pass else "Architecture analysis incomplete", "checks": checks, "valid": all_pass } def validate_layout_fixes(fixes: List[Dict[str, Any]]) -> Dict[str, Any]: """Validate layout fix list.""" if not isinstance(fixes, list): return { "status": "error", "summary": "Fixes must be a list", "valid": False } required_fields = ["location", "original", "fixed", "explanation"] checks = { "is_list": True, "all_have_location": True, "all_have_explanation": True, "all_have_fix": True } for fix in fixes: if not isinstance(fix, dict): checks["is_list"] = False continue if "location" not in fix or not fix["location"]: checks["all_have_location"] = False if "explanation" not in fix or not fix["explanation"]: checks["all_have_explanation"] = False if "fixed" not in fix or not fix["fixed"]: checks["all_have_fix"] = False all_pass = all(checks.values()) status = "pass" if all_pass else "warning" return { "status": status, "summary": f"Validated {len(fixes)} fixes", "checks": checks, "valid": all_pass, "fix_count": len(fixes) } # Example usage if __name__ == "__main__": # Test validation functions test_issues = [ { "severity": "CRITICAL", "category": "performance", "issue": "Blocking operation", "location": "main.go:45", "explanation": "HTTP call blocks event loop", "fix": "Move to tea.Cmd" } ] result = validate_issue_list(test_issues) print(f"Issue validation: {result}") health_result = validate_health_score(75) print(f"Health validation: {health_result}")