78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
import json
|
|||
|
|
import unittest
|
||
|
|
|
||
|
|
import lotus_mc_status as s
|
||
|
|
|
||
|
|
|
||
|
|
def packet(players: dict) -> bytes:
|
||
|
|
body = json.dumps({"version": {"name": "1.21.1"}, "players": players}).encode()
|
||
|
|
return s.varint(0) + s.varint(len(body)) + body
|
||
|
|
|
||
|
|
|
||
|
|
class FormatStatus(unittest.TestCase):
|
||
|
|
def test_nobody(self):
|
||
|
|
self.assertEqual(s.format_status(0, []), "Nobody online")
|
||
|
|
|
||
|
|
def test_one(self):
|
||
|
|
self.assertEqual(s.format_status(1, ["Honnehh"]), "1 online: Honnehh")
|
||
|
|
|
||
|
|
def test_sorted_regardless_of_server_order(self):
|
||
|
|
self.assertEqual(s.format_status(3, ["b_x", "C", "a"]), "3 online: a, b_x, C")
|
||
|
|
|
||
|
|
def test_long_names_collapse_and_stay_within_the_limit(self):
|
||
|
|
names = [f"Player{i}_abcdefghi"[:16] for i in range(10)]
|
||
|
|
got = s.format_status(10, names)
|
||
|
|
self.assertLessEqual(len(got), s.MAX_LEN)
|
||
|
|
self.assertRegex(got, r"^10 online: .+ \+\d+ more$")
|
||
|
|
shown = got.split(": ")[1].split(" +")[0].split(", ")
|
||
|
|
self.assertEqual(int(got.split("+")[1].split()[0]), 10 - len(shown))
|
||
|
|
|
||
|
|
def test_exact_fit_has_no_more_suffix(self):
|
||
|
|
got = s.format_status(1, ["A" * 16], max_len=len("1 online: ") + 16)
|
||
|
|
self.assertEqual(got, "1 online: " + "A" * 16)
|
||
|
|
|
||
|
|
def test_more_players_than_the_sample(self):
|
||
|
|
self.assertEqual(s.format_status(14, ["a", "b"]), "14 online: a, b +12 more")
|
||
|
|
|
||
|
|
def test_placeholders_are_not_shown_as_players(self):
|
||
|
|
self.assertEqual(s.format_status(2, ["Anonymous Player", "a"]), "2 online: a +1 more")
|
||
|
|
self.assertEqual(s.format_status(1, ["§cinjected name"]), "1 online")
|
||
|
|
|
||
|
|
def test_count_only_when_nothing_fits(self):
|
||
|
|
self.assertEqual(s.format_status(2, ["abcdefgh"], max_len=9), "2 online")
|
||
|
|
|
||
|
|
def test_duplicates_and_stale_extras_do_not_overcount(self):
|
||
|
|
self.assertEqual(s.format_status(1, ["a", "a", "b"]), "1 online: a")
|
||
|
|
|
||
|
|
|
||
|
|
class ParseStatus(unittest.TestCase):
|
||
|
|
def test_with_sample(self):
|
||
|
|
p = packet({"max": 20, "online": 2, "sample": [{"name": "a", "id": "x"}, {"name": "b", "id": "y"}]})
|
||
|
|
self.assertEqual(s.parse_status(p), (2, ["a", "b"]))
|
||
|
|
|
||
|
|
def test_without_sample(self):
|
||
|
|
self.assertEqual(s.parse_status(packet({"max": 20, "online": 0})), (0, []))
|
||
|
|
|
||
|
|
def test_rejects_other_packets_and_truncation(self):
|
||
|
|
with self.assertRaises(ValueError):
|
||
|
|
s.parse_status(s.varint(1) + b"xx")
|
||
|
|
with self.assertRaises(ValueError):
|
||
|
|
s.parse_status(packet({"max": 20, "online": 0})[:-3])
|
||
|
|
|
||
|
|
def test_varint_round_trip(self):
|
||
|
|
for n in (0, 1, 127, 128, 300, 6087, 2097151):
|
||
|
|
data = iter([s.varint(n)])
|
||
|
|
buf = next(data)
|
||
|
|
pos = [0]
|
||
|
|
|
||
|
|
def read(k, buf=buf, pos=pos):
|
||
|
|
out = buf[pos[0] : pos[0] + k]
|
||
|
|
pos[0] += k
|
||
|
|
return out
|
||
|
|
|
||
|
|
self.assertEqual(s.read_varint(read), n)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main()
|