def test_from_number_error(self): for i in [-1, 0, MAX_BELL + 1, MAX_BELL + 2, 100, -1100]: with self.assertRaises(ValueError): Bell.from_number(i) # This should be disallowed by the type checker, but may as well test that it does fail with self.assertRaises(TypeError): Bell.from_number(None)
def generate_starting_row(number_of_bells: int, start_row_string: Optional[str] = None) -> Row: """Generate the starting row as rounds or a custom input.""" if start_row_string is None: return rounds(number_of_bells) start_row = [Bell.from_str(i) for i in start_row_string] if len(start_row) > len(set(start_row)): raise ValueError(f"starting row '{start_row_string}' contains the same bell multiple times") # If there are more bells than given in the starting row # add the missing ones in sequential order as cover bells for i in range(1, number_of_bells + 1): if Bell.from_number(i) not in start_row: start_row.append(Bell.from_number(i)) return Row(start_row)
def _on_assign_user(self, data: JSON) -> None: """ Callback called when a bell assignment is changed. """ raw_bell: int = data["bell"] bell: Bell = Bell.from_number(raw_bell) user: Optional[int] = data["user"] or None assert isinstance(user, int) or user is None, \ f"User ID {user} is not an integer (it has type {type(user)})." if user is None: self.logger.info(f"RECEIVED: Unassigned bell '{bell}'") if bell in self._assigned_users: del self._assigned_users[bell] else: self._assigned_users[bell] = user self.logger.info( f"RECEIVED: Assigned bell '{bell}' to '{self.user_name_from_id(user)}'" )
def _on_bell_rung(self, data: JSON) -> None: """ Callback called when the client receives a signal that a bell has been rung. """ # Unpack the data and assign it expected types global_bell_state: List[bool] = data['global_bell_state'] who_rang_raw: int = data["who_rang"] # Run callbacks for updating the bell state self._update_bell_state([Stroke(b) for b in global_bell_state]) # Convert 'who_rang' to a Bell who_rang = Bell.from_number(who_rang_raw) # Only run the callbacks if the bells exist for bell_ring_callback in self.invoke_on_bell_rung: new_stroke = self.get_stroke(who_rang) if new_stroke is None: self.logger.warning( f"Bell {who_rang} rang, but the tower only has {self.number_of_bells} bells." ) else: bell_ring_callback(who_rang, new_stroke)
def rounds(number_of_bells: int) -> Row: """Generate rounds on the given number of bells.""" return Row([Bell.from_number(i) for i in range(1, number_of_bells + 1)])
import time import unittest from threading import Thread from unittest.mock import Mock from wheatley.stroke import HANDSTROKE, BACKSTROKE from wheatley.bell import Bell from wheatley.rhythm import Rhythm, WaitForUserRhythm treble = Bell.from_number(1) second = Bell.from_number(2) class WaitForUserRhythmTests(unittest.TestCase): def setUp(self): self.mock_inner_rhythm = Mock(spec=Rhythm) self.wait_rhythm = WaitForUserRhythm(self.mock_inner_rhythm) self.wait_rhythm.sleep = self._patched_sleep self.waiting_for_bell_time = False self._finished_test = False self._sleeping = False self._return_from_sleep = False self.total_sleep_calls = 0 self.total_sleep_delay = 0 def tearDown(self): self._finished_test = True
def test_from_number_success(self): for i in range(1, MAX_BELL + 1): self.assertEqual(Bell.from_number(i).number, i)
def as_bells(nums: List[int]) -> List[Bell]: return [Bell.from_number(x) for x in nums]