Files
tft/backend/tests/test_score.py
2026-07-23 11:54:46 +02:00

147 lines
5.5 KiB
Python

import pytest
from tft.model.baseline import classify_role, unit_value
from tft.model.calibrate import spearman
from tft.model.score import active_trait_tiers, board_profiles, score_board
STATIC = {
"units": {
"TFT17_A": {
"cost": 1,
"traits": ["TFT17_Tank"],
"role": "Tank",
"stats": {"hp": 650, "armor": 40, "magicResist": 40, "damage": 50,
"attackSpeed": 0.6, "mana": 60, "initialMana": 0, "range": 1},
},
"TFT17_B": {
"cost": 4,
"traits": ["TFT17_Tank"],
"role": "Marksman",
"stats": {"hp": 700, "armor": 25, "magicResist": 25, "damage": 75,
"attackSpeed": 0.75, "mana": 100, "initialMana": 20, "range": 4},
},
},
"traits": {
"TFT17_Tank": {
"breakpoints": [{"min_units": 2, "style": 1}, {"min_units": 4, "style": 3}],
},
},
}
ARTIFACT = {
"meta": {"set": 17},
"static": {
**STATIC,
"items": {"TFT_Item_InfinityEdge": {"effects": {"AD": 0.35, "CritChance": 35.0}}},
"augments": {},
},
"roles": {},
}
def test_unit_value():
assert unit_value(1, 1) == 1
assert unit_value(4, 2) == 12
assert unit_value(3, 3) == 27
def test_classify_role_from_cdragon_role():
assert classify_role(STATIC["units"]["TFT17_A"]) == "frontline"
assert classify_role(STATIC["units"]["TFT17_B"]) == "ad_carry"
def test_trait_activation():
board = [{"api_name": "TFT17_A", "stars": 1, "items": []},
{"api_name": "TFT17_B", "stars": 1, "items": []}]
tiers = active_trait_tiers(board, STATIC["traits"], STATIC["units"])
assert tiers == {"TFT17_Tank": 1}
assert active_trait_tiers(board[:1], STATIC["traits"], STATIC["units"]) == {}
def test_score_ordering():
weak = [{"api_name": "TFT17_A", "stars": 1, "items": []}]
strong = [{"api_name": "TFT17_B", "stars": 2, "items": []}]
assert score_board(strong, [], ARTIFACT) > score_board(weak, [], ARTIFACT)
def test_items_increase_score():
bare = [{"api_name": "TFT17_B", "stars": 1, "items": []}]
with_item = [{"api_name": "TFT17_B", "stars": 1, "items": ["TFT_Item_InfinityEdge"]}]
assert score_board(with_item, [], ARTIFACT) > score_board(bare, [], ARTIFACT)
def test_augments_ignored():
board = [{"api_name": "TFT17_B", "stars": 1, "items": []}]
assert score_board(board, ["TFT17_Augment_X"], ARTIFACT) == \
score_board(board, [], ARTIFACT)
def test_board_profiles_roles_and_unknown_units():
board = [{"api_name": "TFT17_A", "stars": 1, "items": []},
{"api_name": "TFT17_B", "stars": 1, "items": []},
{"api_name": "UNKNOWN", "stars": 1, "items": []}]
profiles = board_profiles(board, ARTIFACT)
assert len(profiles) == 2 # unbekannte Units fallen raus
tank, carry = profiles
assert tank["defensive"] and not carry["defensive"]
assert tank["def"] > carry["def"]
assert carry["off"] > tank["off"]
def test_spearman():
assert spearman([1, 2, 3, 4], [10, 20, 30, 40]) == pytest.approx(1.0)
assert spearman([1, 2, 3, 4], [40, 30, 20, 10]) == pytest.approx(-1.0)
assert spearman([1, 2, 3, 4], [10, 10, 10, 10]) == 0.0
def test_craftable_item_pool():
from tft.model.artifact import craftable_items
items = {
"TFT_Item_InfinityEdge": {"composition": ["TFT_Item_BFSword", "TFT_Item_SparringGloves"]},
"TFT_Item_BFSword": {"composition": []},
"TFT_Item_Emblem": {"composition": ["TFT_Item_Spatula", "TFT_Item_BFSword"]},
"TFT17_Item_Weird": {"composition": ["TFT_Item_BFSword", "TFT_Item_BFSword"]},
"TFT_Item_Radiant": {"composition": None},
}
assert craftable_items(items) == ["TFT_Item_InfinityEdge"]
def _built_artifact():
from tft.model import artifact as artifact_mod
static = {
"meta": {"set": 17, "patch": "test"},
"units": {
"TANK": {"cost": 2, "traits": ["T_AD"], "role": "Tank",
"stats": {"hp": 900, "armor": 50, "magicResist": 50, "damage": 45,
"attackSpeed": 0.6, "mana": 60, "initialMana": 0},
"spell_damage": None, "spell_scaling": None},
"CARRY": {"cost": 2, "traits": ["T_AD"], "role": "Marksman",
"stats": {"hp": 600, "armor": 20, "magicResist": 20, "damage": 70,
"attackSpeed": 0.8, "mana": 50, "initialMana": 0},
"spell_damage": [0, 250, 375, 560, 0, 0, 0], "spell_scaling": "ad"},
},
"traits": {"T_AD": {"breakpoints": [
{"min_units": 2, "style": 1, "variables": {"BonusAP": 20.0}}]}},
"items": {"SWORD": {"effects": {"AD": 0.35}}},
"augments": {},
}
return artifact_mod.build(static)
def test_balanced_beats_lopsided():
art = _built_artifact()
balanced = [{"api_name": "TANK", "stars": 1, "items": []},
{"api_name": "CARRY", "stars": 1, "items": []}]
tanks = [{"api_name": "TANK", "stars": 1, "items": []} for _ in range(2)]
assert score_board(balanced, [], art) > score_board(tanks, [], art)
def test_items_and_stars_raise_strength():
art = _built_artifact()
base = [{"api_name": "CARRY", "stars": 1, "items": []}]
starred = [{"api_name": "CARRY", "stars": 2, "items": []}]
equipped = [{"api_name": "CARRY", "stars": 1, "items": ["SWORD"]}]
assert score_board(starred, [], art) > score_board(base, [], art)
assert score_board(equipped, [], art) > score_board(base, [], art)