thenuke02/cs2-analyzer
0
1#!/usr/bin/env python32"""3Runtime contract validator — parse a real demo and check output matches contract.4 5Usage:6 PYTHONPATH=src python scripts/validate_contract.py path/to/demo.dem7 8Run this before every push to catch field mismatches early.9"""10 11from __future__ import annotations12 13import sys14from pathlib import Path15 16 17def main() -> int:18 if len(sys.argv) < 2:19 print("Usage: python scripts/validate_contract.py <demo.dem>")20 print(" Parses a real demo, runs full pipeline, validates output against contract.")21 return 122 23 demo_path = Path(sys.argv[1])24 if not demo_path.exists():25 print(f"ERROR: Demo file not found: {demo_path}")26 return 127 28 print(f"Parsing {demo_path.name}...")29 from opensight.pipeline.orchestrator import DemoOrchestrator30 31 orchestrator = DemoOrchestrator()32 result = orchestrator.analyze(demo_path)33 34 print(f"Analysis complete: {result['demo_info']['map']}, "35 f"{result['demo_info']['rounds']} rounds, "36 f"{len(result['players'])} players")37 38 from opensight.pipeline.contract import validate_result39 40 errors = validate_result(result)41 42 if errors:43 print(f"\nCONTRACT VIOLATIONS ({len(errors)}):")44 for e in errors:45 print(f" ✗ {e}")46 return 147 48 print(f"\n✓ Contract validated — all fields present and correctly typed")49 print(f" Players: {len(result['players'])}")50 print(f" Timeline rounds: {len(result.get('round_timeline', []))}")51 52 # Print a sample player for visual inspection53 first_player = next(iter(result["players"].values()))54 print(f"\n Sample player: {first_player['name']}")55 print(f" stats.kills={first_player['stats']['kills']}")56 print(f" rating.hltv_rating={first_player['rating']['hltv_rating']}")57 print(f" advanced.opening_kills={first_player['advanced']['opening_kills']}")58 print(f" trades.trade_kill_success={first_player['trades']['trade_kill_success']}")59 print(f" clutches.total_situations={first_player['clutches']['total_situations']}")60 print(f" duels.opening_win_rate={first_player['duels']['opening_win_rate']}")61 print(f" utility.he_team_damage={first_player['utility']['he_team_damage']}")62 print(f" utility.unused_utility_value={first_player['utility']['unused_utility_value']}")63 64 return 065 66 67if __name__ == "__main__":68 sys.exit(main())69 