LovecaSim / compiler /tests /reproduce_failures.py
trioskosmos's picture
Upload folder using huggingface_hub
2113a6a verified
import os
import sys
from dataclasses import dataclass
from typing import List
# Add project root to path
if __name__ == "__main__":
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
from compiler.parser_v2 import AbilityParserV2
@dataclass
class ExpectedAbility:
trigger: str
effects: List[str] # Just types for simple check, or dicts for detailed
costs: List[str] = None
conditions: List[str] = None
effect_values: List[int] = None # Optional: check values of effects in order
def check_parser_strict(text: str, expected: ExpectedAbility, name: str = "") -> bool:
parser = AbilityParserV2()
print(f"Test: {name}")
try:
abilities = parser.parse(text)
if not abilities:
print(" FAILURE: No abilities parsed")
return False
ab = abilities[0] # Assuming single ability
# Verify Trigger
if ab.trigger.name != expected.trigger:
print(f" FAILURE: Trigger mismatch. Expected {expected.trigger}, got {ab.trigger.name}")
return False
# Verify Effects
actual_effects = [e.effect_type.name for e in ab.effects]
missing_effects = [e for e in expected.effects if e not in actual_effects]
if missing_effects:
print(f" FAILURE: Missing effects. Expected {expected.effects}, got {actual_effects}")
return False
# Verify Effect Values
if expected.effect_values:
actual_values = [e.value for e in ab.effects]
# Check length first
if len(actual_values) < len(expected.effect_values):
print(
f" FAILURE: Effect value count mismatch. Expected {len(expected.effect_values)}, got {len(actual_values)}"
)
return False
for i, val in enumerate(expected.effect_values):
if actual_values[i] != val:
print(f" FAILURE: Effect value mismatch at index {i}. Expected {val}, got {actual_values[i]}")
return False
# Verify Costs
if expected.costs:
actual_costs = [c.type.name for c in ab.costs]
missing_costs = [c for c in expected.costs if c not in actual_costs]
if missing_costs:
print(f" FAILURE: Missing costs. Expected {expected.costs}, got {actual_costs}")
return False
print(" SUCCESS")
return True
except Exception as e:
import traceback
traceback.print_exc()
print(f" ERROR: {e}")
return False
def run_tests():
tests = [
(
"Mill Effect (PL!-sd1-007-SD)",
"{{toujyou.png|登場}}自分のデッキの上からカードを5枚控え室に置く。",
ExpectedAbility(
trigger="ON_PLAY",
effects=["SWAP_CARDS"],
effect_values=[5], # Should be 5
),
),
(
"Reveal Cost (PL!-sd1-006-SD)",
"{{toujyou.png|登場}}手札のライブカードを1枚公開してもよい:自分の成功ライブカード置き場にあるカードを1枚手札に加える。",
ExpectedAbility(trigger="ON_PLAY", effects=["RECOVER_LIVE"], costs=["REVEAL_HAND"]),
),
(
"Optional Cost (PL!-sd1-003-SD)",
"{{live_start.png|ライブ開始時}}手札を1枚控え室に置いてもよい:{{heart_01.png|heart01}}か{{heart_03.png|heart03}}か{{heart_06.png|heart06}}のうち、1つを選ぶ。",
ExpectedAbility(trigger="ON_LIVE_START", effects=["SELECT_MODE"], costs=["DISCARD_HAND"]),
),
(
"Swap 10 Cards (PL!-sd1-008-SD)",
"{{kidou.png|起動}}{{turn1.png|ターン1回}}{{icon_energy.png|E}}{{icon_energy.png|E}}:自分のデッキの上からカードを10枚控え室に置く。",
ExpectedAbility(trigger="ACTIVATED", effects=["SWAP_CARDS"], costs=["ENERGY"], effect_values=[10]),
),
(
"Search Deck (Generic)",
"{{toujyou.png|登場}}自分のデッキから『μ's』のメンバーカードを1枚まで手札に加える。デッキをシャッフルする。",
ExpectedAbility(
trigger="ON_PLAY",
effects=["SEARCH_DECK", "META_RULE"],
),
),
(
"Score Boost",
"{{jyouji.png|常時}}ライブの合計スコアを+1する。",
ExpectedAbility(trigger="CONSTANT", effects=["BOOST_SCORE"], effect_values=[1]),
),
(
"Add Blades",
"{{live_start.png|ライブ開始時}}{{icon_blade.png|ブレード}}を1つ得る。",
ExpectedAbility(trigger="ON_LIVE_START", effects=["ADD_BLADES"], effect_values=[1]),
),
(
"Recover Member",
"{{toujyou.png|登場}}自分の控え室からメンバーカードを1枚まで手札に加える。",
ExpectedAbility(trigger="ON_PLAY", effects=["RECOVER_MEMBER"], effect_values=[1]),
),
(
"Recover Live",
"{{toujyou.png|登場}}自分の控え室からライブカードを1枚まで手札に加える。",
ExpectedAbility(trigger="ON_PLAY", effects=["RECOVER_LIVE"], effect_values=[1]),
),
]
print(f"Running {len(tests)} parser tests...")
print("=" * 60)
passed = 0
failed = 0
for name, text, expected in tests:
if check_parser_strict(text, expected, name):
passed += 1
else:
failed += 1
print("=" * 60)
print(f"Passed: {passed}")
print(f"Failed: {failed}")
if failed > 0:
sys.exit(1)
if __name__ == "__main__":
run_tests()