From 91d5afd1cf7b11aace1885d8d735de8df4c3f622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Gonz=C3=A1lez=20Santamarta?= Date: Tue, 29 Oct 2024 20:18:15 +0100 Subject: [PATCH] exceptions for set_start_state --- yasmin/src/yasmin/state_machine.cpp | 15 +++++++++++---- yasmin/tests/python/test_state_machine.py | 12 ++++++++++++ yasmin/yasmin/state_machine.py | 13 ++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/yasmin/src/yasmin/state_machine.cpp b/yasmin/src/yasmin/state_machine.cpp index 43c8d6a..c5deb80 100644 --- a/yasmin/src/yasmin/state_machine.cpp +++ b/yasmin/src/yasmin/state_machine.cpp @@ -83,6 +83,15 @@ void StateMachine::add_state(std::string name, std::shared_ptr state) { } void StateMachine::set_start_state(std::string state_name) { + + if (state_name.empty()) { + throw std::invalid_argument("Initial state cannot be empty"); + + } else if (this->states.find(state_name) == this->states.end()) { + throw std::invalid_argument("Initial state '" + state_name + + "' is not in the state machine"); + } + this->start_state = state_name; } @@ -117,10 +126,6 @@ void StateMachine::validate() { // check initial state if (this->start_state.empty()) { throw std::runtime_error("No initial state set"); - - } else if (this->states.find(this->start_state) == this->states.end()) { - throw std::runtime_error("Initial state label: '" + this->start_state + - "' is not in the state machine"); } std::set terminal_outcomes; @@ -189,6 +194,8 @@ void StateMachine::validate() { std::string StateMachine::execute(std::shared_ptr blackboard) { + this->validate(); + this->current_state_mutex->lock(); this->current_state = this->start_state; this->current_state_mutex->unlock(); diff --git a/yasmin/tests/python/test_state_machine.py b/yasmin/tests/python/test_state_machine.py index c40a56d..758f09d 100644 --- a/yasmin/tests/python/test_state_machine.py +++ b/yasmin/tests/python/test_state_machine.py @@ -77,6 +77,18 @@ def test_state_machine_get_current_state(self): def test_state_call(self): self.assertEqual("outcome4", self.sm()) + def test_set_start_state_empty(self): + with self.assertRaises(Exception) as context: + self.sm.set_start_state("") + self.assertEqual(str(context.exception), "Initial state cannot be empty") + + def test_set_start_state_wrong_state(self): + with self.assertRaises(Exception) as context: + self.sm.set_start_state("FOO1") + self.assertEqual( + str(context.exception), "Initial state 'FOO1' is not in the state machine" + ) + def test_add_repeated_state(self): with self.assertRaises(Exception) as context: self.sm.add_state( diff --git a/yasmin/yasmin/state_machine.py b/yasmin/yasmin/state_machine.py index 66cc7ba..a115e5c 100644 --- a/yasmin/yasmin/state_machine.py +++ b/yasmin/yasmin/state_machine.py @@ -63,6 +63,13 @@ def add_state( self._start_state = name def set_start_state(self, name: str) -> None: + + if not name: + raise Exception("Initial state cannot be empty") + + elif name not in self._states: + raise Exception(f"Initial state '{name}' is not in the state machine") + self._start_state = name def get_start_state(self) -> str: @@ -77,12 +84,8 @@ def cancel_state(self) -> None: def validate(self) -> None: # check initial state - if self._start_state is None: + if not self._start_state: raise Exception("No initial state set") - elif self._start_state not in self._states: - raise Exception( - f"Initial state label: '{self._start_state}' is not in the state machine" - ) terminal_outcomes = []