couple cleanups and unit tests for acro

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
2026-02-12 08:34:13 -06:00
parent cd79a97f06
commit 025cf58b91
2 changed files with 78 additions and 37 deletions
+32 -37
View File
@@ -3,7 +3,6 @@
SPDX-FileCopyrightText: © 2026 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0
"""
import logging
import random
import threading
@@ -47,41 +46,16 @@ class AcroGame(object):
"""Provide access to the current round of the game."""
return self.rounds[-1]
def end_current_round(self):
"""Clean up and output for ending the current round."""
self.state = AcroGameState.round_results
self.bot.reply(None, "voting's over! here are the scores for the round:", explicit_target=self.channel)
self._print_round_scores()
self._add_round_scores_to_game_scores()
# delay a bit
time.sleep(self.current_round.seconds_to_pause)
self._continue_or_quit()
def start_new_game(self, channel):
def start_new_game(self):
"""Begin a new game, which will have multiple rounds."""
if self.state != AcroGameState.stopped:
return "the game is already running."
self.state = AcroGameState.game_start
self.channel = channel
self.bot.reply(None, "starting a new game of acro. it will run until you tell it to quit.",
explicit_target=self.channel)
self.start_new_round()
def start_new_round(self):
"""Start a new round for play."""
self.state = AcroGameState.round_submission
self.rounds.append(AcroRound())
acro = self._generate_acro()
self.current_round.acro = acro
sleep_time = self.current_round.seconds_to_submit + (self.current_round.seconds_to_submit_step * (len(acro)-3))
self.bot.reply(None, "the round has started! your acronym is '{0:s}'. "
"submit within {1:d} seconds via !acro submit [meaning]".format(acro, sleep_time),
explicit_target=self.channel)
t = threading.Thread(target=self.thread_do_process_submissions, args=(sleep_time,))
t.daemon = True
t.start()
self._start_new_round()
def start_voting(self):
"""Begin the voting period."""
@@ -130,7 +104,7 @@ class AcroGame(object):
def thread_do_process_votes(self):
"""Wait for players to provide votes, and then continue or quit."""
time.sleep(self.current_round.seconds_to_vote)
self.end_current_round()
self._end_current_round()
def _add_round_scores_to_game_scores(self):
"""Apply the final round scores to the total scores for the game."""
@@ -147,7 +121,15 @@ class AcroGame(object):
if self.should_quit:
self._end_game()
else:
self.start_new_round()
self._start_new_round()
def _end_current_round(self):
"""Clean up and output for ending the current round."""
self.state = AcroGameState.round_results
self.bot.reply(None, "voting's over! here are the scores for the round:", explicit_target=self.channel)
self._print_round_scores()
self._add_round_scores_to_game_scores()
self._continue_or_quit()
def _end_game(self):
"""Clean up the entire game."""
@@ -245,6 +227,22 @@ class AcroGame(object):
explicit_target=self.channel)
i += 1
def _start_new_round(self):
"""Start a new round for play."""
self.state = AcroGameState.round_submission
self.rounds.append(AcroRound())
acro = self._generate_acro()
self.current_round.acro = acro
sleep_time = self.current_round.seconds_to_submit + (self.current_round.seconds_to_submit_step * (len(acro)-3))
self.bot.reply(None, "the round has started! your acronym is '{0:s}'. "
"submit within {1:d} seconds via !acro submit [meaning]".format(acro, sleep_time),
explicit_target=self.channel)
t = threading.Thread(target=self.thread_do_process_submissions, args=(sleep_time,))
t.daemon = True
t.start()
@staticmethod
def _turn_text_into_acro(text):
"""Turn text into an acronym."""
@@ -325,10 +323,7 @@ class Acro(Plugin):
except KeyError:
game = AcroGame(self.bot, event.target)
self.games[event.target] = game
if game.state != AcroGameState.stopped:
return self.bot.reply(event, "the game is already running.")
game.start_new_game(event.target)
return self.bot.reply(event, game.start_new_game())
else:
return self.bot.reply(event, "you must start the game from a channel.")
+46
View File
@@ -0,0 +1,46 @@
"""Tests for the acromania game module.
SPDX-FileCopyrightText: © 2026 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0
"""
from unittest import mock
from django.test import TestCase
from acro.ircplugin import AcroGame, AcroGameState, AcroRound
class AcroGameTestCase(TestCase):
"""Test game state transition stuff."""
def test_game_creation(self):
"""Test the initial state of a created game."""
game = self._create_game()
assert game.state == AcroGameState.stopped
assert game.should_quit is False
assert game.channel == '#test'
def test_game_start(self):
"""Start the game."""
game = self._create_game()
with mock.patch('acro.ircplugin.AcroGame._start_new_round') as round_mock:
resp = game.start_new_game()
assert game.state == AcroGameState.game_start
assert round_mock.called_exactly_once()
assert resp is None
def test_game_start_double_start_error(self):
"""Start the game."""
game = self._create_game()
with mock.patch('acro.ircplugin.AcroGame._start_new_round') as round_mock:
resp = game.start_new_game()
resp = game.start_new_game()
assert round_mock.called_exactly_once()
assert resp == "the game is already running."
def _create_game(self):
"""Create a game, either for a direct test or for subsequent tests.
The bot is mocked out and can be used for validation.
"""
return AcroGame(mock.MagicMock(), '#test')