class MachineRunner(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.machine = FiniteStateMachine() self._start_keyboard_listener() def run(self): self.machine.set_current_state(MachineCommand.START) data = self.machine.collect_data(size=SQUARE_ARRAY_LENGTH) print('Data collected!') processed_data = self.machine.process_data(data) print(processed_data) def _on_press(self, key): if key == keyboard.Key.enter: print(self.machine.get_current_state()) def _start_keyboard_listener(self): print('Press ENTER to get machine state') listener = keyboard.Listener(on_press=self._on_press) listener.daemon = True listener.start()
class FiniteStateMachineTests(unittest.TestCase): def setUp(self): self.finite_state_machine = FiniteStateMachine() def test_createNewMachine_withoutParameters_initialStateMustBeStopped(self): actual_state = self.finite_state_machine.get_current_state() assert_that(actual_state).is_equal_to(MachineState.STOPPED) def test_setCurrentState_withInvalidCommand_exceptionMustBeRaised(self): with self.assertRaises(ValueError): self.finite_state_machine.set_current_state('foo') def test_setCurrentState_withValidCommand_stateMustBeSetted(self): self.finite_state_machine.set_current_state(MachineCommand.START) actual_state = self.finite_state_machine.get_current_state() assert_that(actual_state).is_equal_to(MachineState.STARTED) def test_setCollectInStartedMachine_thenGetPreviousState_previousStateMustBeStarted(self): self.finite_state_machine.set_current_state(MachineCommand.START) self.finite_state_machine.set_current_state(MachineCommand.COLLECT) previous_state = self.finite_state_machine.get_previous_state() assert_that(previous_state).is_equal_to(MachineState.STARTED) def test_collectData_mustReturnMultidimensionalArray(self): expected_array_rows = 3 expected_array_columns = 3 expected_min_value = 0 expected_max_value = 9 self.finite_state_machine.set_current_state(MachineCommand.START) actual = self.finite_state_machine.collect_data() assert_that(actual).is_not_empty() assert_that(actual).is_length(expected_array_rows) for row in actual: assert_that(row).is_length(expected_array_columns) for column in row: assert_that(column).is_less_than_or_equal_to(expected_max_value) assert_that(column).is_greater_than_or_equal_to(expected_min_value) def test_processData_mustReturnScalar5TransposedArray(self): target_array = numpy.array( [[1, 2, 3], [4, 5, 6], [7, 8, 9]]) expected_array = numpy.array([[5, 20, 35], [10, 25, 40], [15, 30, 45]]) self.finite_state_machine.set_current_state(MachineCommand.START) self.finite_state_machine.set_current_state(MachineCommand.COLLECT) actual_array = self.finite_state_machine.process_data(target_array) for actual_row, expected_row in zip(actual_array.tolist(), expected_array.tolist()): assert_that(actual_row).is_equal_to(expected_row)