304 lines
11 KiB
Python
304 lines
11 KiB
Python
|
|
"""
|
|||
|
|
卡牌加载器测试
|
|||
|
|
"""
|
|||
|
|
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
|