mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-10-09 00:03:00 -07:00
* Correct Bounce Target logic, write unit tests tmp * that is not correct * What was I smoking * explicitly document None * What was I smoking * fix weakref syntax * ruff * fix magicmoc * Address Berserker's comments * comment * consistently use self.assertEqual * make slot 2 on team 3 not use deathlink to test different tags for the same slot on different teams * Improve error message
274 lines
10 KiB
Python
274 lines
10 KiB
Python
import unittest
|
|
from unittest.mock import MagicMock
|
|
|
|
from MultiServer import BounceTarget
|
|
|
|
|
|
def create_mock_client(team: int, game: str, tags: set[str], slot: int):
|
|
client = MagicMock()
|
|
client.team = team
|
|
client.tags = tags
|
|
client.slot = slot
|
|
|
|
ctx = MagicMock()
|
|
ctx.games = {slot: game}
|
|
|
|
client.ctx = lambda: ctx
|
|
|
|
return client
|
|
|
|
|
|
TEAM_1_SLOT_1 = create_mock_client(1, "TestGame", set(), 1)
|
|
TEAM_1_SLOT_2 = create_mock_client(1, "TestGame", {"DeathLink", "TrapLink"}, 2)
|
|
TEAM_1_SLOT_3 = create_mock_client(1, "TestGame 2", {"DeathLink"}, 3)
|
|
TEAM_2_SLOT_1 = create_mock_client(2, "TestGame", set(), 1)
|
|
TEAM_2_SLOT_2 = create_mock_client(2, "TestGame", {"TrapLink"}, 2)
|
|
TEAM_2_SLOT_3 = create_mock_client(2, "TestGame 2", {"DeathLink"}, 3)
|
|
|
|
ALL_CLIENTS = [TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_1, TEAM_2_SLOT_2, TEAM_2_SLOT_3]
|
|
|
|
|
|
class TestBounceTargetLegacy(unittest.TestCase):
|
|
"""
|
|
Test various BounceTarget configurations against six mock clients with different teams, games, tags and slots.
|
|
|
|
Uses the "legacy" operator, which is defined as: "team and (game or tags or slot)".
|
|
"""
|
|
|
|
def test_legacy_bounce_target_default(self):
|
|
bounce_target = BounceTarget(None, None, None, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [])
|
|
|
|
def test_legacy_bounce_team_only(self):
|
|
bounce_target = BounceTarget({1}, None, None, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [])
|
|
|
|
def test_legacy_tags_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, {"DeathLink"}, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_legacy(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_3],
|
|
)
|
|
|
|
def test_legacy_slot_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, None, {2})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_1_SLOT_2, TEAM_2_SLOT_2])
|
|
|
|
def test_legacy_empty_conditions(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), set())
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [])
|
|
|
|
def test_legacy_empty_conditions_except_slot(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), {3})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [])
|
|
|
|
def test_legacy_empty_conditions_except_tags_and_team(self):
|
|
bounce_target = BounceTarget({1}, set(), {"DeathLink"}, set())
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_1_SLOT_2, TEAM_1_SLOT_3])
|
|
|
|
def test_legacy_all(self):
|
|
bounce_target = BounceTarget({2}, {"TestGame 2"}, {"TrapLink"}, {1})
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_2_SLOT_1, TEAM_2_SLOT_2, TEAM_2_SLOT_3]
|
|
)
|
|
|
|
def test_legacy_multiple_games(self):
|
|
bounce_target = BounceTarget({1}, {"TestGame", "TestGame 2"}, None, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3]
|
|
)
|
|
|
|
def test_legacy_multiple_tags(self):
|
|
bounce_target = BounceTarget({2}, None, {"DeathLink", "TrapLink"}, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_2_SLOT_2, TEAM_2_SLOT_3])
|
|
|
|
def test_legacy_multiple_slots(self):
|
|
bounce_target = BounceTarget(None, None, None, {1, 2})
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_legacy(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_2_SLOT_1, TEAM_2_SLOT_2],
|
|
)
|
|
|
|
def test_legacy_multiple_teams(self):
|
|
bounce_target = BounceTarget({1, 2}, None, None, {1})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_legacy(ALL_CLIENTS)), [TEAM_1_SLOT_1, TEAM_2_SLOT_1])
|
|
|
|
|
|
class TestBounceTargetOr(unittest.TestCase):
|
|
"""
|
|
Test various BounceTarget configurations against six mock clients with different teams, games, tags and slots.
|
|
|
|
Uses the "or" operator, which is defined as: "any(team, game, tags, slot)".
|
|
|
|
A missing condition (None) or an empty set is treated as always False.
|
|
"""
|
|
|
|
def test_or_bounce_target_default(self):
|
|
bounce_target = BounceTarget(None, None, None, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), [])
|
|
|
|
def test_or_bounce_team_only(self):
|
|
bounce_target = BounceTarget({1}, None, None, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_or(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3],
|
|
)
|
|
|
|
def test_or_tags_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, {"DeathLink"}, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_or(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_3],
|
|
)
|
|
|
|
def test_or_slot_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, None, {2})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), [TEAM_1_SLOT_2, TEAM_2_SLOT_2])
|
|
|
|
def test_or_empty_conditions(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), set())
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), [])
|
|
|
|
def test_or_empty_conditions_except_slot(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), {3})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), [TEAM_1_SLOT_3, TEAM_2_SLOT_3])
|
|
|
|
def test_or_empty_conditions_except_tags_and_team(self):
|
|
bounce_target = BounceTarget({1}, set(), {"DeathLink"}, set())
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_or(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_3],
|
|
)
|
|
|
|
def test_or_all(self):
|
|
bounce_target = BounceTarget({2}, {"TestGame 2"}, {"DeathLink"}, {1})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), ALL_CLIENTS)
|
|
|
|
def test_or_multiple_games(self):
|
|
bounce_target = BounceTarget({1}, {"TestGame", "TestGame 2"}, None, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), ALL_CLIENTS)
|
|
|
|
def test_or_multiple_tags(self):
|
|
bounce_target = BounceTarget({2}, None, {"DeathLink", "TrapLink"}, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_or(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_1, TEAM_2_SLOT_2, TEAM_2_SLOT_3],
|
|
)
|
|
|
|
def test_or_multiple_slots(self):
|
|
bounce_target = BounceTarget(None, None, None, {1, 2})
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_or(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_2_SLOT_1, TEAM_2_SLOT_2],
|
|
)
|
|
|
|
def test_or_multiple_teams(self):
|
|
bounce_target = BounceTarget({1, 2}, None, None, {1})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_or(ALL_CLIENTS)), ALL_CLIENTS)
|
|
|
|
|
|
class TestBounceTargetAnd(unittest.TestCase):
|
|
"""
|
|
Test various BounceTarget configurations against six mock clients with different teams, games, tags and slots.
|
|
|
|
Uses the "and" operator, which is defined as: "all(team, game, tags, slot)".
|
|
|
|
A missing condition (None) is interpreted as always True, where an empty set is treated as always False.
|
|
This means that for an "and"-type bounce packet, a single empty set means the whole condition selects no clients.
|
|
"""
|
|
|
|
def test_and_bounce_target_default(self):
|
|
bounce_target = BounceTarget(None, None, None, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), ALL_CLIENTS)
|
|
|
|
def test_and_bounce_team_only(self):
|
|
bounce_target = BounceTarget({1}, None, None, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_and(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3],
|
|
)
|
|
|
|
def test_and_tags_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, {"DeathLink"}, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_and(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_2, TEAM_1_SLOT_3, TEAM_2_SLOT_3],
|
|
)
|
|
|
|
def test_and_slot_condition_only(self):
|
|
bounce_target = BounceTarget(None, None, None, {2})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_1_SLOT_2, TEAM_2_SLOT_2])
|
|
|
|
def test_and_empty_conditions(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), set())
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [])
|
|
|
|
def test_and_empty_conditions_except_slot(self):
|
|
bounce_target = BounceTarget(set(), set(), set(), {3})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [])
|
|
|
|
def test_and_empty_conditions_except_tags_and_team(self):
|
|
bounce_target = BounceTarget({1}, None, {"DeathLink"}, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_1_SLOT_2, TEAM_1_SLOT_3])
|
|
|
|
def test_and_all(self):
|
|
bounce_target = BounceTarget({2}, {"TestGame 2"}, {"DeathLink"}, {3})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_2_SLOT_3])
|
|
|
|
def test_and_multiple_games(self):
|
|
bounce_target = BounceTarget({1}, {"TestGame", "TestGame 2"}, None, None)
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_1_SLOT_3]
|
|
)
|
|
|
|
def test_and_multiple_tags(self):
|
|
bounce_target = BounceTarget({2}, None, {"DeathLink", "TrapLink"}, None)
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_2_SLOT_2, TEAM_2_SLOT_3])
|
|
|
|
def test_and_multiple_slots(self):
|
|
bounce_target = BounceTarget(None, None, None, {1, 2})
|
|
|
|
self.assertEqual(
|
|
list(bounce_target.match_clients_and(ALL_CLIENTS)),
|
|
[TEAM_1_SLOT_1, TEAM_1_SLOT_2, TEAM_2_SLOT_1, TEAM_2_SLOT_2],
|
|
)
|
|
|
|
def test_and_multiple_teams(self):
|
|
bounce_target = BounceTarget({1, 2}, None, None, {1})
|
|
|
|
self.assertEqual(list(bounce_target.match_clients_and(ALL_CLIENTS)), [TEAM_1_SLOT_1, TEAM_2_SLOT_1])
|