139 lines
4.4 KiB
Python
139 lines
4.4 KiB
Python
"""Behavioral coverage for the CS Major autochess 0.6.7 pacing rewrite."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
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 Release067AutochessTests(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
|
|
response = self.engine.accept(
|
|
{
|
|
"event_id": event_id or f"autochess-067-{self.counter}",
|
|
"group_fingerprint": "group-a",
|
|
"sender": sender,
|
|
"text": "@JWeBot " + question,
|
|
"mention_bot": True,
|
|
"confidence": 1.0,
|
|
"sender_confidence": 1.0,
|
|
"body_confidence": 1.0,
|
|
}
|
|
)
|
|
self.assertEqual(response["status"], "reply")
|
|
return list(response.get("texts") or [response["text"]])
|
|
|
|
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 ready_all(self):
|
|
state = self.state()
|
|
replies = []
|
|
for key in list(state.get("ready_keys") or []):
|
|
replies.extend(
|
|
self.command(
|
|
"/结束回合",
|
|
sender=state["players"][key]["display_name"],
|
|
)
|
|
)
|
|
return replies
|
|
|
|
def start_two_human_two_ai(self):
|
|
self.command("/自走棋开始")
|
|
self.command("/自走棋报名", sender="Bob")
|
|
self.command("/自走棋加AI战队")
|
|
self.command("/自走棋开赛")
|
|
|
|
def finish_draft(self):
|
|
self.command("/选1")
|
|
self.command("/选1", sender="Bob")
|
|
self.command("/选1", sender="Bob")
|
|
self.command("/选1")
|
|
self.command("/选1")
|
|
self.command("/选1", sender="Bob")
|
|
|
|
def test_narrative_inventory_and_training_round_robin(self):
|
|
self.assertGreaterEqual(AUTOCHESS._narrative_inventory_size(), 120)
|
|
|
|
self.start_two_human_two_ai()
|
|
self.finish_draft()
|
|
training = "\n".join(self.ready_all())
|
|
state = self.state()
|
|
|
|
self.assertEqual(len(state["training_rounds"]), 3)
|
|
self.assertEqual(state["training_round_cursor"], 1)
|
|
self.assertIn("训练赛第 1/3 轮对阵", training)
|
|
self.assertIn("Team", training)
|
|
self.assertIn("AI 战队", training)
|
|
self.assertNotIn("目标", training)
|
|
self.assertNotIn("发挥", training)
|
|
|
|
def test_round_simulation_produces_natural_score_variety(self):
|
|
self.start_two_human_two_ai()
|
|
self.finish_draft()
|
|
state = self.state()
|
|
key_a, key_b = state["seed_order"][:2]
|
|
|
|
scores = set()
|
|
for index in range(12):
|
|
result = AUTOCHESS._battle(
|
|
state,
|
|
key_a,
|
|
key_b,
|
|
f"score-variety-{index}",
|
|
best_of=1,
|
|
)
|
|
score = result["maps"][0]["score"]
|
|
self.assertRegex(score, r"^\d+-\d+$")
|
|
self.assertGreaterEqual(result["maps"][0]["rounds_played"], 16)
|
|
scores.add(score)
|
|
|
|
old_fixed = {"16-6", "16-9", "16-12", "16-14", "19-17"}
|
|
self.assertGreaterEqual(len(scores), 3)
|
|
self.assertTrue(scores - old_fixed)
|
|
|
|
def test_group_report_is_paced_and_hides_raw_calculation_terms(self):
|
|
self.start_two_human_two_ai()
|
|
self.finish_draft()
|
|
self.ready_all()
|
|
self.ready_all()
|
|
self.ready_all()
|
|
self.ready_all()
|
|
|
|
report = "\n".join(self.ready_all())
|
|
self.assertIn("图1", report)
|
|
self.assertIn("系列赛结束", report)
|
|
self.assertNotIn("目标", report)
|
|
self.assertNotIn("发挥", report)
|
|
self.assertNotIn("克制修正", report)
|
|
self.assertIsNotNone(re.search(r"\b\d{2}-\d{1,2}\b", report))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|