kards-env/tests/test_card_loader.py

304 lines
11 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
卡牌加载器测试
"""
import pytest
from pathlib import Path
from kards_battle.core.enums import Nation, Rarity
from kards_battle.cards.card_loader import CardLoader, CardLoadError
from kards_battle.cards.card import UnitCard
class TestCardLoader:
"""卡牌加载器测试"""
def test_card_loader_initialization(self):
"""测试卡牌加载器初始化"""
loader = CardLoader()
assert loader.cards_dir is not None
assert loader.cards_dir.exists()
def test_parse_nation(self):
"""测试国家解析"""
loader = CardLoader()
assert loader._parse_nation("germany") == Nation.GERMANY
assert loader._parse_nation("GERMANY") == Nation.GERMANY
assert loader._parse_nation("usa") == Nation.USA
assert loader._parse_nation("italy") == Nation.ITALY
with pytest.raises(CardLoadError, match="未知的国家"):
loader._parse_nation("invalid_nation")
def test_parse_rarity(self):
"""测试稀有度解析"""
loader = CardLoader()
assert loader._parse_rarity(1) == Rarity.ELITE
assert loader._parse_rarity(2) == Rarity.RARE
assert loader._parse_rarity(3) == Rarity.UNCOMMON
assert loader._parse_rarity(4) == Rarity.COMMON
with pytest.raises(CardLoadError, match="无效的稀有度"):
loader._parse_rarity(5)
with pytest.raises(CardLoadError, match="无效的稀有度"):
loader._parse_rarity(0)
def test_parse_exile_nations(self):
"""测试流亡国家解析"""
loader = CardLoader()
# 空列表
assert loader._parse_exile_nations([]) is None
assert loader._parse_exile_nations(None) is None
# 单个国家
exile_nations = loader._parse_exile_nations(["germany"])
assert exile_nations == {Nation.GERMANY}
# 多个国家
exile_nations = loader._parse_exile_nations(["germany", "italy"])
assert exile_nations == {Nation.GERMANY, Nation.ITALY}
def test_validate_card_data(self):
"""测试卡牌数据验证"""
loader = CardLoader()
# 有效卡牌数据
valid_card = {
"id": "test_card",
"name": "Test Card",
"type": "unit",
"cost": 2,
"nation": "germany",
"rarity": 2,
"unit_definition_id": "test_unit"
}
errors = loader.validate_card_data(valid_card)
assert len(errors) == 0
# 缺少必需字段
invalid_card = {
"name": "Test Card",
"type": "unit"
# 缺少其他必需字段
}
errors = loader.validate_card_data(invalid_card)
assert len(errors) > 0
assert any("缺少必需字段" in error for error in errors)
# 无效的卡牌类型
invalid_type_card = valid_card.copy()
invalid_type_card["type"] = "invalid_type"
errors = loader.validate_card_data(invalid_type_card)
assert any("无效的卡牌类型" in error for error in errors)
# 无效的费用
invalid_cost_card = valid_card.copy()
invalid_cost_card["cost"] = -1
errors = loader.validate_card_data(invalid_cost_card)
assert any("费用必须是非负整数" in error for error in errors)
# 无效的稀有度
invalid_rarity_card = valid_card.copy()
invalid_rarity_card["rarity"] = 5
errors = loader.validate_card_data(invalid_rarity_card)
assert any("稀有度必须是1-4的整数" in error for error in errors)
# 无效的国家
invalid_nation_card = valid_card.copy()
invalid_nation_card["nation"] = "invalid_nation"
errors = loader.validate_card_data(invalid_nation_card)
assert any("未知的国家" in error for error in errors)
# 单位卡缺少unit_definition_id
unit_card_no_def = valid_card.copy()
del unit_card_no_def["unit_definition_id"]
errors = loader.validate_card_data(unit_card_no_def)
assert any("单位卡必须包含 unit_definition_id 字段" in error for error in errors)
def test_load_germany_cards(self):
"""测试加载德国卡牌"""
loader = CardLoader()
try:
cards = loader.load_nation_cards(Nation.GERMANY)
# 应该能成功加载一些卡牌
assert isinstance(cards, list)
assert len(cards) > 0
# 检查卡牌属性
for card in cards:
assert isinstance(card, UnitCard)
assert card.stats.nation == Nation.GERMANY
assert card.name is not None
assert card.stats.cost >= 0
assert card.stats.rarity in [Rarity.ELITE, Rarity.RARE, Rarity.UNCOMMON, Rarity.COMMON]
assert card.unit_definition_id is not None
except CardLoadError:
# 如果文件不存在,测试通过
pass
def test_load_usa_cards(self):
"""测试加载美国卡牌"""
loader = CardLoader()
try:
cards = loader.load_nation_cards(Nation.USA)
assert isinstance(cards, list)
if cards: # 如果有卡牌
assert len(cards) > 0
for card in cards:
assert isinstance(card, UnitCard)
assert card.stats.nation == Nation.USA
except CardLoadError:
# 如果文件不存在,测试通过
pass
def test_load_italy_cards(self):
"""测试加载意大利卡牌"""
loader = CardLoader()
try:
cards = loader.load_nation_cards(Nation.ITALY)
assert isinstance(cards, list)
if cards: # 如果有卡牌
assert len(cards) > 0
for card in cards:
assert isinstance(card, UnitCard)
assert card.stats.nation == Nation.ITALY
except CardLoadError:
# 如果文件不存在,测试通过
pass
def test_load_all_available_cards(self):
"""测试加载所有可用卡牌"""
loader = CardLoader()
all_cards = loader.load_all_available_cards()
assert isinstance(all_cards, dict)
# 检查已知存在的国家
for nation, cards in all_cards.items():
assert isinstance(nation, Nation)
assert isinstance(cards, list)
assert len(cards) > 0
for card in cards:
assert isinstance(card, UnitCard)
assert card.stats.nation == nation
def test_load_nonexistent_nation(self):
"""测试加载不存在的国家卡牌文件"""
loader = CardLoader()
# 测试一个可能没有卡牌文件的国家
cards = loader.load_nation_cards(Nation.FINLAND)
assert isinstance(cards, list)
# 应该返回空列表而不是抛出异常
def test_create_unit_card_from_data(self):
"""测试从数据创建单位卡"""
loader = CardLoader()
card_data = {
"id": "test_grenadier",
"name": "Test Grenadier",
"type": "unit",
"cost": 2,
"nation": "germany",
"rarity": 2,
"description": "Test German infantry unit",
"unit_definition_id": "ger_infantry_grenadier"
}
card = loader._create_unit_card(card_data)
assert isinstance(card, UnitCard)
assert card.name == "Test Grenadier"
assert card.stats.cost == 2
assert card.stats.nation == Nation.GERMANY
assert card.stats.rarity == Rarity.RARE
assert card.unit_definition_id == "ger_infantry_grenadier"
assert card.description == "Test German infantry unit"
assert card.card_id == "test_grenadier"
def test_create_unit_card_with_exile_nations(self):
"""测试创建带流亡国家的单位卡"""
loader = CardLoader()
card_data = {
"id": "test_exile_card",
"name": "Test Exile Unit",
"type": "unit",
"cost": 3,
"nation": "poland",
"rarity": 3,
"description": "Test exile unit",
"unit_definition_id": "pol_infantry_test",
"exile_nations": ["uk", "soviet"]
}
card = loader._create_unit_card(card_data)
assert card.stats.exile_nations == {Nation.UK, Nation.SOVIET}
assert card.stats.can_be_used_by_nation(Nation.POLAND)
assert card.stats.can_be_used_by_nation(Nation.UK)
assert card.stats.can_be_used_by_nation(Nation.SOVIET)
assert not card.stats.can_be_used_by_nation(Nation.GERMANY)
class TestCardLoaderIntegration:
"""卡牌加载器集成测试"""
def test_integration_with_placeholder_cards(self):
"""测试与占位卡牌系统的集成"""
from kards_battle.cards.placeholder_cards import create_test_deck_cards
# 创建德国-意大利测试卡组
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
assert len(cards) == 39
# 检查是否有德国卡牌
german_cards = [c for c in cards if c.stats.nation == Nation.GERMANY]
assert len(german_cards) >= 20 # 应该有足够的主国卡
# 检查是否有意大利卡牌
italian_cards = [c for c in cards if c.stats.nation == Nation.ITALY or
(c.stats.exile_nations and Nation.ITALY in c.stats.exile_nations)]
assert len(italian_cards) >= 5 # 应该有一些盟国卡
def test_yaml_cards_priority(self):
"""测试YAML卡牌优先于占位卡牌"""
loader = CardLoader()
# 尝试加载德国卡牌
try:
yaml_cards = loader.load_nation_cards(Nation.GERMANY)
if yaml_cards: # 如果成功加载了YAML卡牌
# 卡牌应该有card_id来自YAML
for card in yaml_cards[:3]: # 检查前3张
assert hasattr(card, 'card_id')
assert card.card_id is not None
# 卡牌名称应该是英文YAML格式
assert card.name is not None
except CardLoadError:
# 如果YAML加载失败这也是正常的测试情况
pass