""" Auto-generates test cases for all cards with abilities. """ import json from pathlib import Path from typing import Any, Dict, List def load_card_database() -> Dict[str, Any]: """Load compiled card database.""" # Try multiple paths paths = [ Path("data/cards_compiled.json"), Path("engine/data/cards_compiled.json"), ] for p in paths: if p.exists(): with open(p, "r", encoding="utf-8") as f: return json.load(f) raise FileNotFoundError("Could not find cards_compiled.json") def generate_ability_test_cases() -> List[Dict[str, Any]]: """ Generate parametrized test cases for all cards with abilities. Returns list of dicts with: - card_id: int - card_name: str - card_type: 'member' or 'live' - ability_idx: int - trigger: str (e.g., 'ON_PLAY', 'LIVE_START') - effects: List[str] (e.g., ['DRAW_CARDS', 'DISCARD']) - has_cost: bool - is_optional: bool """ data = load_card_database() test_cases = [] # Process members from engine.models.ability import TriggerType for cid_str, card in data.get("member_db", {}).items(): cid = int(cid_str) abilities = card.get("abilities", []) for idx, ability in enumerate(abilities): raw_trigger = ability.get("trigger", "NONE") # Map int to Enum name if possible try: if isinstance(raw_trigger, int): trigger = TriggerType(raw_trigger).name else: trigger = raw_trigger except Exception: trigger = str(raw_trigger) effects = [e.get("effect_type", "UNKNOWN") for e in ability.get("effects", [])] costs = ability.get("costs", []) # Map condition enums from engine.models.ability import ConditionType, TriggerType conditions = [] for c in ability.get("conditions", []): # Compiled JSON uses 'type' for ConditionType ctype = c.get("type", c.get("condition_type", "NONE")) try: if isinstance(ctype, int): cname = ConditionType(ctype).name else: cname = ctype except Exception: cname = str(ctype) cond_copy = c.copy() cond_copy["condition_type"] = cname conditions.append(cond_copy) test_cases.append( { "card_id": cid, "card_name": card.get("name", f"Unknown_{cid}"), "card_type": "member", "ability_idx": idx, "trigger": trigger, "effects": effects, "conditions": conditions, "has_cost": len(costs) > 0, "is_optional": any(c.get("is_optional", False) for c in costs), "raw_text": ability.get("raw_text", "")[:50], } ) # Process lives for cid_str, card in data.get("live_db", {}).items(): cid = int(cid_str) abilities = card.get("abilities", []) for idx, ability in enumerate(abilities): trigger = ability.get("trigger", "NONE") effects = [e.get("effect_type", "UNKNOWN") for e in ability.get("effects", [])] test_cases.append( { "card_id": cid, "card_name": card.get("name", f"Unknown_{cid}"), "card_type": "live", "ability_idx": idx, "trigger": trigger, "effects": effects, "has_cost": False, "is_optional": False, "raw_text": ability.get("raw_text", "")[:50], } ) return test_cases def get_cards_by_trigger(trigger: str) -> List[Dict[str, Any]]: """Get all test cases with a specific trigger type.""" return [tc for tc in generate_ability_test_cases() if tc["trigger"] == trigger] def get_cards_by_effect(effect: str) -> List[Dict[str, Any]]: """Get all test cases that include a specific effect type.""" return [tc for tc in generate_ability_test_cases() if effect in tc["effects"]] def get_complex_cards(min_effects: int = 3) -> List[Dict[str, Any]]: """Get cards with complex abilities (multiple effects).""" return [tc for tc in generate_ability_test_cases() if len(tc["effects"]) >= min_effects] def get_cards_with_condition(condition_type: str) -> List[Dict[str, Any]]: """Get all test cases that have a specific condition type.""" cases = [] for tc in generate_ability_test_cases(): for cond in tc.get("conditions", []): if cond.get("condition_type") == condition_type: cases.append(tc) break return cases # Summary statistics def print_ability_summary(): """Print summary of ability coverage.""" cases = generate_ability_test_cases() # Count by trigger triggers = {} for tc in cases: triggers[tc["trigger"]] = triggers.get(tc["trigger"], 0) + 1 # Count by effect effects = {} for tc in cases: for e in tc["effects"]: effects[e] = effects.get(e, 0) + 1 print(f"Total abilities: {len(cases)}") print("\nBy Trigger:") for t, c in sorted(triggers.items(), key=lambda x: -x[1]): print(f" {t}: {c}") print("\nBy Effect (top 15):") for e, c in sorted(effects.items(), key=lambda x: -x[1])[:15]: print(f" {e}: {c}") if __name__ == "__main__": print_ability_summary()