LovecaSim / compiler /tests /test_card_parsing.py
trioskosmos's picture
Upload folder using huggingface_hub
2113a6a verified
from compiler.parser import AbilityParser
from engine.models.ability import (
AbilityCostType,
ConditionType,
EffectType,
TriggerType,
)
def test_nico_dual_trigger():
"""Test PL!-PR-009-PR: Dual trigger ON_PLAY / ON_LIVE_START"""
text = "{{toujyou.png|登場}}/{{live_start.png|ライブ開始時}}このメンバーをウェイトにしてもよい:相手のステージにいるコスト4以下のメンバー1人をウェイトにする。"
abilities = AbilityParser.parse_ability_text(text)
assert len(abilities) == 2, "Should parse into 2 abilities"
assert abilities[0].trigger == TriggerType.ON_PLAY
assert abilities[1].trigger == TriggerType.ON_LIVE_START
for abi in abilities:
assert len(abi.costs) == 1
assert abi.costs[0].type == AbilityCostType.TAP_SELF
assert len(abi.effects) == 1
assert abi.effects[0].effect_type == EffectType.TAP_OPPONENT
def test_kanata_reveal_hand():
"""Test PL!N-PR-008-PR: Reveal hand cost + condition"""
text = "{{kidou.png|起動}}{{turn1.png|ターン1回}}手札をすべて公開する:自分のステージにほかのメンバーがおり、かつこれにより公開した手札の中にライブカードがない場合、自分のデッキの上からカードを5枚見る。その中からライブカードを1枚公開して手札に加えてもよい。残りを控え室に置く。"
abilities = AbilityParser.parse_ability_text(text)
assert len(abilities) == 1
abi = abilities[0]
# Check Cost
assert any(c.type == AbilityCostType.REVEAL_HAND_ALL for c in abi.costs), "Should have REVEAL_HAND_ALL cost"
# Check Condition
assert any(c.type == ConditionType.HAND_HAS_NO_LIVE for c in abi.conditions), (
"Should have HAND_HAS_NO_LIVE condition"
)
# Check Effect
assert abi.effects[0].effect_type == EffectType.LOOK_DECK
assert abi.effects[0].value == 5
def test_ginko_parsing():
"""Test PL!N-PR-012-PR: Look 5, Choose 1 Member"""
text = "【登場時】手札を1枚捨ててもよい:そうしたら、デッキの上から5枚見る。その中からメンバーを1枚まで公開し、手札に加える。残りを山札の一番下に望む順番で置く。"
abilities = AbilityParser.parse_ability_text(text)
assert len(abilities) == 1
abi = abilities[0]
# Check Effects chain
# 1. Look Deck 5
assert abi.effects[0].effect_type == EffectType.LOOK_DECK
assert abi.effects[0].value == 5
# 2. Look and Choose (Member)
assert abi.effects[1].effect_type == EffectType.LOOK_AND_CHOOSE
assert abi.effects[1].params.get("filter") == "member", "Should capture member filter"
# 3. Order Deck (Remainder to bottom)
assert any(e.effect_type in (EffectType.ORDER_DECK, EffectType.MOVE_TO_DECK) for e in abi.effects), (
"Should handle remainder"
)
def test_honoka_parsing():
"""Test PL!-sd1-001-SD: Count Success Live Condition & Recover Live Effect"""
text = "【登場時】自分の成功ライブカード置き場にカードが2枚以上ある場合、自分の控え室からライブカードを1枚手札に加える。"
abilities = AbilityParser.parse_ability_text(text)
print(f"DEBUG: Honoka abilities: {abilities}")
assert len(abilities) == 1
abi = abilities[0]
# Verify Trigger
assert abi.trigger == TriggerType.ON_PLAY
# Verify Condition
assert len(abi.conditions) == 1, f"Expected 1 condition, found {len(abi.conditions)}: {abi.conditions}"
assert abi.conditions[0].type == ConditionType.COUNT_SUCCESS_LIVE
assert abi.conditions[0].params.get("min") == 2
# Verify Effect
assert len(abi.effects) == 1, f"Expected 1 effect, found {len(abi.effects)}: {abi.effects}"
assert abi.effects[0].effect_type == EffectType.RECOVER_LIVE