144 lines
6.3 KiB
Python
144 lines
6.3 KiB
Python
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 |