""" 卡牌加载器测试 """ 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