kards-env/tests/test_card_loader.py

304 lines
11 KiB
Python
Raw Permalink Normal View History

2025-09-05 17:05:43 +08:00
"""
卡牌加载器测试
"""
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