import json from tft.model.learn import learn def board_row(placement, unit="TFT17_A", item="TFT_Item_X", trait_tier=1): units = [{"character_id": unit, "tier": 2, "itemNames": [item]}] traits = [{"name": "TFT17_T", "num_units": 2, "tier_current": trait_tier}] return (placement, json.dumps(units), json.dumps(traits), json.dumps([])) def test_strong_item_gets_multiplier_above_1(): rows = [board_row(1, item="TFT_Item_Good") for _ in range(200)] rows += [board_row(8, item="TFT_Item_Bad") for _ in range(200)] learned = learn(rows) assert learned["items"]["TFT_Item_Good"] > 1.05 assert learned["items"]["TFT_Item_Bad"] < 0.95 def test_shrinkage_with_thin_data(): rows = [board_row(1, item="TFT_Item_Rare") for _ in range(3)] learned = learn(rows) assert abs(learned["items"]["TFT_Item_Rare"] - 1.0) < 0.06 def test_trait_keys_match_score_format(): rows = [board_row(2, trait_tier=3) for _ in range(50)] learned = learn(rows) assert "TFT17_T@3" in learned["traits"] def test_pair_lift_for_cooccurring_units(): def pair_row(placement): units = [ {"character_id": "TFT17_A", "tier": 2, "itemNames": []}, {"character_id": "TFT17_B", "tier": 2, "itemNames": []}, ] return (placement, json.dumps(units), json.dumps([]), json.dumps([])) # A und B stehen immer zusammen in Top-4-Boards; C ist überall. rows = [pair_row(1) for _ in range(100)] solo = [{"character_id": "TFT17_C", "tier": 1, "itemNames": []}] rows += [(1, json.dumps(solo), json.dumps([]), json.dumps([])) for _ in range(100)] learned = learn(rows) assert learned["pairs"]["TFT17_A|TFT17_B"] > 0.5 def test_empty_rows(): learned = learn([]) assert learned["traits"] == {} assert learned["pairs"] == {} assert learned["n_boards"] == 0