"""Behavioral coverage for the two-human plus two-AI test mode.""" from __future__ import annotations import json import tempfile import unittest from pathlib import Path from test_jwebot_edge import MODULE, config from jwebot_official_extensions import cs_autochess as AUTOCHESS class Release065TwoHumanAiTests(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory() self.engine = MODULE.EdgeApplication(config(Path(self.temp.name))) self.counter = 0 def tearDown(self): self.engine.close() self.temp.cleanup() def command(self, question, *, sender="Alice", event_id=None): self.counter += 1 return self.engine.local.handle( { "question": question, "sender": sender, "group_fingerprint": "group-a", "event_id": event_id or f"two-ai-{self.counter}", }, {}, ) def state(self): row = self.engine.ledger.connection.execute( """ SELECT state_json FROM autochess_runs WHERE group_fingerprint = 'group-a' ORDER BY season_number DESC LIMIT 1 """ ).fetchone() self.assertIsNotNone(row) return json.loads(row[0]) def test_two_humans_add_two_ai_and_use_four_seed_bracket(self): self.command("/自走棋开始") self.command("/自走棋报名", sender="Bob") added = self.command("/自走棋加AI战队") self.assertIn("AI 战队 A、AI 战队 B", added) self.assertIn("第 3、4 种子", added) self.assertIn("2 人+2 AI", added) self.assertIn( "已经锁定参赛名单", self.command("/自走棋报名", sender="Carol"), ) launch = self.command("/自走棋开赛") state = self.state() self.assertIn("2 人+2 AI 测试赛", launch) self.assertEqual(state["ai_test_variant"], "two_plus_two") self.assertEqual( state["seed_order"][2:], [ AUTOCHESS.AI_PERSON_KEY, AUTOCHESS.AI_SECOND_PERSON_KEY, ], ) self.assertEqual( state["preparation_order"], state["seed_order"][:2], ) self.assertTrue( state["players"][AUTOCHESS.AI_PERSON_KEY]["is_ai"] ) self.assertTrue( state["players"][AUTOCHESS.AI_SECOND_PERSON_KEY]["is_ai"] ) semifinal = state["round_plan"][-2] self.assertEqual( semifinal["pairs"], [ [state["seed_order"][0], state["seed_order"][3]], [state["seed_order"][1], state["seed_order"][2]], ], ) self.assertIn("到 bob 做准备了", self.command("/结束回合")) self.assertIn( "全员准备完毕", self.command("/结束回合", sender="Bob"), ) settled = self.command("/自走棋结算") self.assertIn("AI 战队 A 自动运营", settled) self.assertIn("AI 战队 B 自动运营", settled) self.assertEqual( self.engine.ledger.connection.execute( """ SELECT COUNT(*) FROM autochess_story_logs WHERE story_type = 'ai_operation' """ ).fetchone()[0], 2, ) def test_add_two_ai_is_idempotent_and_cannot_be_repeated(self): self.command("/自走棋开始") self.command("/自走棋报名", sender="Bob") first = self.command( "/自走棋加AI战队", event_id="same-add-two-ai", ) replay = self.command( "/自走棋加AI战队", event_id="same-add-two-ai", ) self.assertEqual(first, replay) self.assertIn( "已经加入", self.command("/自走棋加AI战队"), ) state = self.state() self.assertEqual( sum( bool(player.get("is_ai")) for player in state["players"].values() ), 2, ) if __name__ == "__main__": unittest.main()