Files
tft/backend/tests/test_statsheet.py
2026-07-24 11:24:24 +02:00

85 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from tft.model import statsheet
def unit(spell=None, scaling="ap", **overrides):
stats = {"hp": 700, "armor": 30, "magicResist": 30, "damage": 50,
"attackSpeed": 0.7, "mana": 60, "initialMana": 10,
"critChance": 0.25, "critMultiplier": 1.4}
stats.update(overrides)
return {"stats": stats, "spell_damage": spell, "spell_scaling": scaling}
ITEMS = {
"sword": {"effects": {"AD": 0.35, "CritChance": 35.0}},
"vest": {"effects": {"Armor": 20.0}},
"rod": {"effects": {"AP": 10.0}},
"unmodeled": {"effects": {"BurnPercent": 1.0}},
}
def test_star_scaling():
one = statsheet.unit_stats(unit(), 1, [], ITEMS, None, None)
two = statsheet.unit_stats(unit(), 2, [], ITEMS, None, None)
assert two["ehp"] == pytest.approx(one["ehp"] * 1.8)
assert two["dps"] == pytest.approx(one["dps"] * 1.5)
def test_spell_damage_uses_star_index_and_ap():
spell = [0, 200, 300, 450, 0, 0, 0]
bare = statsheet.unit_stats(unit(spell=spell), 1, [], ITEMS, None, None)
with_rod = statsheet.unit_stats(unit(spell=spell), 1, ["rod"], ITEMS, None, None)
no_spell = statsheet.unit_stats(unit(), 1, [], ITEMS, None, None)
assert bare["dps"] > no_spell["dps"]
assert with_rod["dps"] > bare["dps"] # +10 AP skaliert den Spell
def test_items_change_profile():
base = statsheet.unit_stats(unit(), 1, [], ITEMS, None, None)
sword = statsheet.unit_stats(unit(), 1, ["sword"], ITEMS, None, None)
vest = statsheet.unit_stats(unit(), 1, ["vest"], ITEMS, None, None)
assert sword["dps"] > base["dps"]
assert vest["ehp"] > base["ehp"]
assert statsheet.item_is_modeled(ITEMS["sword"])
assert not statsheet.item_is_modeled(ITEMS["unmodeled"])
def test_on_attack_spell_scales_with_attack_speed():
# Pro-Attacke-Passive: DPS = Schaden × AS, unabhängig vom Mana-Zyklus.
spell = [0, 50, 75, 110, 0, 0, 0]
u = unit(spell=spell)
u["spell_on_attack"] = True
on_attack = statsheet.unit_stats(u, 1, [], ITEMS, None, None)
assert on_attack["spell_dps"] == pytest.approx(50 * 0.7)
cast = statsheet.unit_stats(unit(spell=spell), 1, [], ITEMS, None, None)
assert on_attack["spell_dps"] > cast["spell_dps"]
def test_frontline_casts_more():
spell = [0, 300, 450, 700, 0, 0, 0]
tank = statsheet.unit_stats(unit(spell=spell), 1, [], ITEMS, None, "frontline")
carry = statsheet.unit_stats(unit(spell=spell), 1, [], ITEMS, None, "ad_carry")
assert tank["dps"] > carry["dps"]
def test_trait_buffs_keyword_mapping():
traits = {
"T_AD": {"breakpoints": [{"min_units": 2, "style": 1,
"variables": {"BonusAD": 0.15}}]},
"T_Mech": {"breakpoints": [{"min_units": 2, "style": 1,
"variables": {"Wolf_Gold": 1.0}}]},
"T_Skip": {"breakpoints": [{"min_units": 2, "style": 1,
"variables": {"StunDuration": 1.5}}]},
}
buffs, recognized = statsheet.trait_buffs(
{"T_AD": 1, "T_Mech": 1, "T_Skip": 1}, traits
)
assert recognized == {"T_AD"}
assert buffs["ad_pct"] == pytest.approx(0.15)
def test_fraction_normalization():
assert statsheet._fraction(0.15) == 0.15
assert statsheet._fraction(15.0) == 0.15