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, 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": {}, "augments": {}}, "roles": {}, "learned": {}} 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_active_trait_beats_inactive(): pair = [{"api_name": "TFT17_A", "stars": 1, "items": []}, {"api_name": "TFT17_B", "stars": 1, "items": []}] solo_sum = score_board(pair[:1], [], ARTIFACT) + score_board(pair[1:], [], ARTIFACT) assert score_board(pair, [], ARTIFACT) > solo_sum 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_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 test_stat_mults_rank_within_cost(): from tft.model.baseline import compute_stat_mults def unit(hp, armor, ad, aspd): return {"cost": 2, "traits": [], "role": "Tank", "stats": {"hp": hp, "armor": armor, "magicResist": armor, "damage": ad, "attackSpeed": aspd, "mana": 60, "initialMana": 0, "range": 1}} units = {"tanky": unit(900, 60, 45, 0.6), "avg": unit(700, 40, 55, 0.7), "weak": unit(550, 25, 45, 0.6)} mults = compute_stat_mults(units) assert mults["tanky"] > mults["avg"] > mults["weak"] assert all(0.9 <= m <= 1.1 for m in mults.values()) def test_stat_mults_identical_units_are_neutral(): from tft.model.baseline import compute_stat_mults from tests.test_sim import make_static mults = compute_stat_mults(make_static()["units"]) assert all(m == 1.0 for m in mults.values()) def test_stat_mult_raises_score(): art = {**ARTIFACT, "stat_mults": {"TFT17_B": 1.1}} board = [{"api_name": "TFT17_B", "stars": 1, "items": []}] assert score_board(board, [], art) > score_board(board, [], ARTIFACT)