import pytest import sys from pathlib import Path # Добавляем родительскую директорию в sys.path для импорта модулей sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from wwn_mechanics import ( calc_hp_max, calc_income, calc_xp_cost_to_raise, calc_asset_upkeep, calc_repair_heal, calc_faction_repair_heal, get_available_upgrades, get_attack_extra_die_flags, has_antimagical_penalty, check_massive_auto_win ) # ----------------------------------------------- HP Tests ------------------------------------------------------------ def test_calc_hp_max(): """Проверяет корректность расчета максимального HP фракции на основе атрибутов.""" assert calc_hp_max(2, 4, 5) == 17 assert calc_hp_max(3, 3, 3) == 12 assert calc_hp_max(1, 1, 1) == 3 assert calc_hp_max(8, 8, 8) == 60 # ----------------------------------------------- Income Tests ------------------------------------------------------------ def test_calc_income(): """Проверяет правильность расчета дохода фракции (Treasure income) за один ход.""" assert calc_income(4, 2, 5) == 4 assert calc_income(2, 1, 1) == 2 assert calc_income(8, 7, 6) == 8 # ----------------------------------------------- XP Tests ------------------------------------------------------------ def test_calc_xp_cost_to_raise(): """Проверяет получение стоимости в XP для повышения значения атрибута.""" assert calc_xp_cost_to_raise(1) == 2 assert calc_xp_cost_to_raise(4) == 9 assert calc_xp_cost_to_raise(7) == 20 assert calc_xp_cost_to_raise(8) is None # ----------------------------------------------- Upkeep Tests ------------------------------------------------------------ def test_calc_asset_upkeep(): """Проверяет расчет апкипа фракции за превышение лимитов активов.""" faction_fm = { "force": 1, "wealth": 1, "cunning": 1, "assets": [ {"name": "Infantry", "attribute": "Force", "is_base_of_influence": False}, {"name": "Thugs", "attribute": "Force", "is_base_of_influence": False}, # Excess {"name": "Free Company", "attribute": "Wealth", "is_base_of_influence": False}, # special upkeep {"name": "Farmers", "attribute": "Wealth", "is_base_of_influence": False}, # Excess {"name": "BoI", "attribute": "Wealth", "is_base_of_influence": True} # Not counted ] } upkeep = calc_asset_upkeep(faction_fm) assert upkeep["excess_force"] == 1 assert upkeep["excess_wealth"] == 1 assert upkeep["free_company_count"] == 1 assert upkeep["total_upkeep"] == 3 # 1 (Force) + 1 (Wealth) + 1 (Free Company) assert "Thugs" in upkeep["excess_assets"] # ----------------------------------------------- Repair Tests ------------------------------------------------------------ def test_calc_repair_heal(): """Проверяет расчет стоимости и объема лечения актива.""" fm = {"force": 5, "wealth": 2, "cunning": 4} res1 = calc_repair_heal(fm, "Force", 1) assert res1["cost"] == 1 assert res1["heal"] == 3 # ceil(5/2) res2 = calc_repair_heal(fm, "Cunning", 3) assert res2["cost"] == 3 assert res2["heal"] == 2 # ceil(4/2) def test_calc_faction_repair_heal(): """Проверяет расчет лечения самой фракции.""" fm = {"force": 8, "wealth": 2, "cunning": 4} res = calc_faction_repair_heal(fm) assert res["cost"] == 1 assert res["heal"] == 5 # ceil((8+2)/2) assert res["highest_attr"] == "force" assert res["lowest_attr"] == "wealth" # ----------------------------------------------- Faction Tags Tests ------------------------------------------------------------ def test_get_attack_extra_die_flags(): """Проверяет флаги бонусных кубиков при атаке.""" atk_fm = {"faction_tags": ["Martial", "Machiavellian"]} def_fm = {"faction_tags": ["Rich"]} # Martial дает бонус на Force a_extra, d_extra = get_attack_extra_die_flags(atk_fm, def_fm, "Force") assert a_extra is True assert d_extra is False # Rich дает бонус на Wealth a_extra, d_extra = get_attack_extra_die_flags(atk_fm, def_fm, "Wealth") assert a_extra is False assert d_extra is True def test_has_antimagical_penalty(): """Проверяет применение штрафа Antimagical.""" def_fm = {"faction_tags": ["Antimagical"]} assert has_antimagical_penalty(def_fm, "High") is True assert has_antimagical_penalty(def_fm, "Medium") is True assert has_antimagical_penalty(def_fm, "Low") is False def test_check_massive_auto_win(): """Проверяет автопобеду тега Massive.""" atk_fm = {"faction_tags": ["Massive"], "force": 7} def_fm = {"force": 3} # Атакующий > 2 * защитника assert check_massive_auto_win(atk_fm, def_fm, "Force") is True def_fm["force"] = 4 # Не более чем в 2 раза assert check_massive_auto_win(atk_fm, def_fm, "Force") is None # Защитник Massive atk_fm2 = {"force": 2} def_fm2 = {"faction_tags": ["Massive"], "force": 5} assert check_massive_auto_win(atk_fm2, def_fm2, "Force") is False # ----------------------------------------------- Upgrades Tests ------------------------------------------------------------ def test_get_available_upgrades(): """Проверяет получение доступных для повышения атрибутов.""" fm = {"force": 2, "wealth": 7, "cunning": 8, "xp": 15} upgrades = get_available_upgrades(fm) # Cunning 8 не должно быть в списке assert len(upgrades) == 2 force_upg = next(u for u in upgrades if u["attribute"] == "force") assert force_upg["current_value"] == 2 assert force_upg["next_value"] == 3 assert force_upg["xp_cost"] == 4 assert force_upg["can_afford"] is True wealth_upg = next(u for u in upgrades if u["attribute"] == "wealth") assert wealth_upg["xp_cost"] == 20 assert wealth_upg["can_afford"] is False