lgbot: interactive setup script
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
062ea6468a
commit
fda3a795bb
3 files changed
+282
No files matched your search
@@ -137,5 +137,116 @@ class Misc(unittest.TestCase):
|
||||
self.assertIsNone(pick_target((0, 0), []))
|
||||
|
||||
|
||||
import json, tempfile
|
||||
import lgbot_setup as setup
|
||||
|
||||
STATUS_WITH_BOT = """map: thunderstruck
|
||||
num score ping name lastmsg address qport rate steamid
|
||||
--- ----- ---- --------------- ------- --------------------- ----- ----- -----------------
|
||||
0 3 0 lgbot 0 bot 0 16384 0
|
||||
1 7 48 player 0 100.64.1.2:27960 354 25000 76561198000000000
|
||||
"""
|
||||
|
||||
|
||||
def feeder(*answers):
|
||||
it = iter(answers)
|
||||
def inp(prompt=""):
|
||||
a = next(it)
|
||||
if isinstance(a, BaseException):
|
||||
raise a
|
||||
return a
|
||||
return inp
|
||||
|
||||
|
||||
class State(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.dir = tempfile.mkdtemp()
|
||||
self.path = os.path.join(self.dir, "lgbot.json")
|
||||
|
||||
def test_missing_file_gives_defaults(self):
|
||||
self.assertEqual(setup.load_state(self.path), {"aim": 3, "move": 3, "details": {}})
|
||||
|
||||
def test_corrupt_file_gives_defaults(self):
|
||||
with open(self.path, "w") as f:
|
||||
f.write("{not json")
|
||||
self.assertEqual(setup.load_state(self.path), {"aim": 3, "move": 3, "details": {}})
|
||||
|
||||
def test_bad_values_are_dropped(self):
|
||||
with open(self.path, "w") as f:
|
||||
json.dump({"aim": 9, "move": "x", "details": {"fake": 50, "range": 99999, "bogus": 1}}, f)
|
||||
self.assertEqual(setup.load_state(self.path), {"aim": 3, "move": 3, "details": {"fake": 50}})
|
||||
|
||||
def test_round_trip(self):
|
||||
st = {"aim": 1, "move": 5, "details": {"fake": 60, "range_play": 0}}
|
||||
setup.save_state(self.path, st)
|
||||
self.assertEqual(setup.load_state(self.path), st)
|
||||
|
||||
|
||||
class Parsing(unittest.TestCase):
|
||||
def test_parse_int(self):
|
||||
self.assertEqual(setup.parse_int("", 1, 5, 3), 3)
|
||||
self.assertEqual(setup.parse_int(" 4 ", 1, 5, 3), 4)
|
||||
self.assertIsNone(setup.parse_int("6", 1, 5, 3))
|
||||
self.assertIsNone(setup.parse_int("abc", 1, 5, 3))
|
||||
|
||||
def test_parse_yn(self):
|
||||
self.assertTrue(setup.parse_yn("", True))
|
||||
self.assertTrue(setup.parse_yn("Y", False))
|
||||
self.assertFalse(setup.parse_yn("no", True))
|
||||
self.assertIsNone(setup.parse_yn("maybe", True))
|
||||
|
||||
def test_ask_reasks_until_valid(self):
|
||||
said = []
|
||||
v = setup.ask("Aim: ", lambda t: setup.parse_int(t, 1, 5, 3), feeder("x", "7", "2"), said.append)
|
||||
self.assertEqual(v, 2)
|
||||
self.assertEqual(len(said), 2)
|
||||
|
||||
def test_bot_present(self):
|
||||
self.assertTrue(setup.bot_present(STATUS_WITH_BOT))
|
||||
self.assertFalse(setup.bot_present(STATUS_WITH_BOT.replace("lgbot ", "Hunter")))
|
||||
self.assertFalse(setup.bot_present("(no output)"))
|
||||
|
||||
|
||||
class Commands(unittest.TestCase):
|
||||
def test_no_details_resets_to_minus_one(self):
|
||||
cmds = setup.build_commands({"aim": 2, "move": 4, "details": {}}, readd=False, bot_in=True)
|
||||
self.assertEqual(cmds[0], "set lgbot_move 4")
|
||||
self.assertIn("set lgbot_fake -1", cmds)
|
||||
self.assertEqual(len(cmds), 1 + len(KEYS))
|
||||
|
||||
def test_details_and_readd(self):
|
||||
cmds = setup.build_commands({"aim": 1, "move": 5, "details": {"fake": 50}}, readd=True, bot_in=True)
|
||||
self.assertIn("set lgbot_fake 50", cmds)
|
||||
self.assertEqual(cmds[-2:], ["kick lgbot", "addbot lgbot 1"])
|
||||
|
||||
def test_readd_without_bot_does_not_kick(self):
|
||||
cmds = setup.build_commands({"aim": 4, "move": 3, "details": {}}, readd=True, bot_in=False)
|
||||
self.assertNotIn("kick lgbot", cmds)
|
||||
self.assertEqual(cmds[-1], "addbot lgbot 4")
|
||||
|
||||
|
||||
class Prompts(unittest.TestCase):
|
||||
def test_enter_keeps_everything(self):
|
||||
old = {"aim": 2, "move": 4, "details": {"fake": 70}}
|
||||
new = setup.prompt_setup(old, feeder("", "", "", "", "", "", "", "", ""), lambda *_: None)
|
||||
self.assertEqual(new, old)
|
||||
|
||||
def test_poor_aim_best_movement_custom(self):
|
||||
new = setup.prompt_setup({"aim": 3, "move": 3, "details": {}},
|
||||
feeder("1", "5", "y", "", "300", "60", "", "n", "90"), lambda *_: None)
|
||||
self.assertEqual(new, {"aim": 1, "move": 5,
|
||||
"details": {"strafe_max": 300, "fake": 60, "range_play": 0, "speed": 90}})
|
||||
# only values that differ from the movement preset are stored as overrides
|
||||
|
||||
def test_no_details_clears_them(self):
|
||||
new = setup.prompt_setup({"aim": 3, "move": 3, "details": {"fake": 70}},
|
||||
feeder("", "", "n"), lambda *_: None)
|
||||
self.assertEqual(new["details"], {})
|
||||
|
||||
def test_ctrl_c_propagates(self):
|
||||
with self.assertRaises(KeyboardInterrupt):
|
||||
setup.prompt_setup({"aim": 3, "move": 3, "details": {}}, feeder("1", KeyboardInterrupt()), lambda *_: None)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user