update
This commit is contained in:
113
backend/tests/test_pairs.py
Normal file
113
backend/tests/test_pairs.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""Gruppen: Bindung aus den Pro-Comps, Stärke aus den Boards."""
|
||||
|
||||
from tft.model import pairs
|
||||
from tft.staticdata import procomps
|
||||
|
||||
UNITS = {a: {"cost": 1, "traits": ["T"], "asset_names": [f"DA_{a}"]}
|
||||
for a in "ABCDEF"}
|
||||
|
||||
|
||||
def board(place, *units):
|
||||
return {"place": place, "cell": (9, 3),
|
||||
"entities": [(u, 2, 0) for u in units]}
|
||||
|
||||
|
||||
def cell(b):
|
||||
return b["cell"]
|
||||
|
||||
|
||||
def test_bond_asks_about_the_rarer_unit():
|
||||
"""Nicht "wie oft zusammen", sondern "wie oft zusammen, wenn möglich".
|
||||
|
||||
B steht nie ohne A. C steht halb so oft bei A. Rohe Zählung sähe C
|
||||
vorne, weil C öfter vorkommt.
|
||||
"""
|
||||
groups = [["A", "B", "X", "Y"]] * 3 + [["A", "C", "X", "Y"]] * 2 \
|
||||
+ [["C", "D", "X", "Y"]] * 2
|
||||
w = pairs.weights(groups, pseudo=0)
|
||||
assert w[("A", "B")] == 1.0
|
||||
assert w[("A", "C")] == 0.5
|
||||
|
||||
|
||||
def test_pseudo_counts_hold_back_single_sightings():
|
||||
"""Ein Paar mit einer Nennung darf nicht wie eine Regel aussehen."""
|
||||
groups = [["A", "B", "C", "D"]]
|
||||
assert pairs.weights(groups, pseudo=0)[("A", "B")] == 1.0
|
||||
assert pairs.weights(groups, pseudo=3)[("A", "B")] == 0.25
|
||||
|
||||
|
||||
def test_every_pair_in_a_group_must_clear_the_threshold():
|
||||
"""Ein Dritter darf nicht an nur einem der beiden hängen.
|
||||
|
||||
C bindet stark an A, aber gar nicht an B. Also kein Trio.
|
||||
"""
|
||||
bond = {("A", "B"): 0.9, ("A", "C"): 0.9, ("B", "C"): 0.1}
|
||||
out = pairs.candidates(bond, UNITS, min_bond=0.4)
|
||||
assert ("A", "B") in out and ("A", "C") in out
|
||||
assert ("A", "B", "C") not in out
|
||||
|
||||
|
||||
def test_a_group_needs_a_shared_trait():
|
||||
"""Ohne das kommt Unsinn heraus: eine Comp hat acht bis neun Units,
|
||||
zwei davon stehen nebeneinander, ohne etwas miteinander zu tun.
|
||||
"""
|
||||
units = {"A": {"traits": ["T"]}, "B": {"traits": ["T"]},
|
||||
"C": {"traits": ["U"]}}
|
||||
bond = {("A", "B"): 0.9, ("A", "C"): 0.9, ("B", "C"): 0.9}
|
||||
out = pairs.candidates(bond, units, min_bond=0.4)
|
||||
assert ("A", "B") in out
|
||||
assert ("A", "C") not in out and ("A", "B", "C") not in out
|
||||
|
||||
|
||||
def test_strength_is_measured_against_comparable_boards():
|
||||
boards = [board(1, "A", "B", "C") for _ in range(400)] \
|
||||
+ [board(7, "D", "E", "F") for _ in range(400)]
|
||||
out = pairs.strength(boards, {(9, 3): 4.0}, cell,
|
||||
[("A", "B"), ("D", "E")], min_boards=10)
|
||||
assert out[("A", "B")]["edge"] > 0 > out[("D", "E")]["edge"]
|
||||
assert out[("A", "B")]["boards"] == 400
|
||||
|
||||
|
||||
def test_rare_groups_are_dropped():
|
||||
boards = [board(1, "A", "B") for _ in range(5)]
|
||||
assert pairs.strength(boards, {(9, 3): 4.0}, cell, [("A", "B")],
|
||||
min_boards=10) == {}
|
||||
|
||||
|
||||
def test_select_drops_overlapping_and_negative_groups():
|
||||
"""Sonst steht dieselbe Gruppe zwanzigmal leicht abgewandelt da."""
|
||||
scored = {("A", "B", "C"): {"edge": 0.5}, ("A", "B"): {"edge": 0.4},
|
||||
("D", "E"): {"edge": 0.2}, ("A", "F"): {"edge": -0.1}}
|
||||
assert pairs.select(scored) == [("A", "B", "C"), ("D", "E")]
|
||||
|
||||
|
||||
def test_build_is_empty_without_input():
|
||||
assert pairs.build([], [board(1, "A", "B")], {}, cell, UNITS) == {}
|
||||
assert pairs.build([["A", "B", "C", "D"]], [], {}, cell, UNITS) == {}
|
||||
|
||||
|
||||
def test_comps_reads_every_stage():
|
||||
"""Level 4 bis 9 sind eigene Stufen — jede zählt als Beobachtung."""
|
||||
doc = {
|
||||
"content": {"comps": [{"data": {"$ref": "#/comp/x"}, "tier": "S"}]},
|
||||
"refs": [{
|
||||
"content_id": "x",
|
||||
"metadata": {"title": "Test"},
|
||||
"content": {
|
||||
"unit_positions": {str(i): {"apiName": f"DA_{a}"}
|
||||
for i, a in enumerate("ABCD")},
|
||||
"variations": [
|
||||
{"type": "comp",
|
||||
"unit_positions": {str(i): {"apiName": f"DA_{a}"}
|
||||
for i, a in enumerate("ABCDE")}},
|
||||
{"type": "tierlist"},
|
||||
# zu klein, fliegt raus
|
||||
{"type": "comp",
|
||||
"unit_positions": {"0": {"apiName": "DA_A"}}},
|
||||
],
|
||||
},
|
||||
}],
|
||||
}
|
||||
out = procomps.comps(doc, UNITS)
|
||||
assert [len(c["units"]) for c in out] == [4, 5]
|
||||
assert all(c["tier"] == "S" for c in out)
|
||||
Reference in New Issue
Block a user