129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
"""Behavioral coverage for the alpha 0.6.2 latency and blackjack fixes."""
|
||
|
||
import json
|
||
import tempfile
|
||
import unittest
|
||
from pathlib import Path
|
||
from unittest import mock
|
||
|
||
from test_jwebot_edge import MODULE, config
|
||
|
||
|
||
class Release062BlackjackTests(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.ledger.connection.close()
|
||
self.temp.cleanup()
|
||
|
||
def command(self, question, *, event_id=None, sender="Alice"):
|
||
self.counter += 1
|
||
row = {
|
||
"question": question,
|
||
"sender": sender,
|
||
"group_fingerprint": "group-a",
|
||
"event_id": event_id or f"test-{self.counter}",
|
||
}
|
||
return self.engine.local.handle(row, {})
|
||
|
||
def state(self, sender="Alice"):
|
||
key = self.engine.ledger.resolve_person("group-a", sender)["person_key"]
|
||
row = self.engine.ledger.connection.execute(
|
||
"""
|
||
SELECT state_json FROM player_accounts
|
||
WHERE group_fingerprint = ? AND person_key = ?
|
||
""",
|
||
("group-a", key),
|
||
).fetchone()
|
||
return json.loads(row[0])
|
||
|
||
@staticmethod
|
||
def hit_deck(cards):
|
||
first = [4, 5, 8, 7]
|
||
cards[:] = (
|
||
first
|
||
+ [card for card in cards if card not in first and card != 1]
|
||
+ [1]
|
||
)
|
||
|
||
def test_compact_start_sets_stake_then_separate_hit_replays_once(self):
|
||
with mock.patch.object(
|
||
self.engine.local.players.rng,
|
||
"shuffle",
|
||
side_effect=self.hit_deck,
|
||
):
|
||
start = self.command("/21点开始100", event_id="compact-start")
|
||
self.assertTrue(start.startswith("alice #1:"))
|
||
self.assertIn("下注 100", start)
|
||
self.assertEqual(self.state()["balance"], 900)
|
||
self.assertEqual(len(self.state()["game"]["player"]), 2)
|
||
|
||
first = self.command("/21点要牌", event_id="separate-hit")
|
||
replay = self.command(
|
||
"/21点 要牌",
|
||
event_id="separate-hit",
|
||
sender="a1",
|
||
)
|
||
|
||
self.assertEqual(replay, first)
|
||
self.assertTrue(first.startswith("alice #1:"))
|
||
self.assertIn("13点", first)
|
||
self.assertEqual(self.state()["balance"], 900)
|
||
self.assertEqual(len(self.state()["game"]["player"]), 3)
|
||
|
||
def test_spaced_chinese_and_compact_english_start_use_bet(self):
|
||
def tied_deck(cards):
|
||
first = [9, 6, 8, 7]
|
||
cards[:] = first + [card for card in cards if card not in first]
|
||
|
||
for command, sender in (
|
||
("/21点 开始 50", "Alice"),
|
||
("/blackjackstart50", "Bob"),
|
||
):
|
||
with self.subTest(command=command):
|
||
with mock.patch.object(
|
||
self.engine.local.players.rng,
|
||
"shuffle",
|
||
side_effect=tied_deck,
|
||
):
|
||
started = self.command(command, sender=sender)
|
||
self.assertTrue(
|
||
started.startswith(
|
||
"alice #1:" if sender == "Alice" else "bob #1:"
|
||
)
|
||
)
|
||
self.assertIn("下注 50", started)
|
||
self.assertEqual(self.state(sender)["balance"], 950)
|
||
self.assertIsNotNone(self.state(sender)["game"])
|
||
self.command("/21点 结束", sender=sender)
|
||
self.assertIsNone(self.state(sender)["game"])
|
||
|
||
def test_default_bet_can_start_without_spaces(self):
|
||
with mock.patch.object(
|
||
self.engine.local.players.rng,
|
||
"shuffle",
|
||
side_effect=self.hit_deck,
|
||
):
|
||
reply = self.command("/21点开始")
|
||
|
||
self.assertTrue(reply.startswith("alice #1:"))
|
||
self.assertIn("下注 50", reply)
|
||
self.assertEqual(self.state()["balance"], 950)
|
||
|
||
def test_combined_start_and_action_explains_two_step_flow(self):
|
||
reply = self.command("/21点开始100要牌")
|
||
|
||
self.assertIn("分两步", reply)
|
||
self.assertIn("100 是本局下注", reply)
|
||
self.assertIn("再单独发送", reply)
|
||
wallet = self.command("/摩拉")
|
||
self.assertIn("摩拉 1000", wallet)
|
||
self.assertIn("无进行中的牌局", wallet)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|