class Person(): name = 'Billy' sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before('sleep') def do_one_thing(self): print("{} is sleepy".format(self.name)) @before('sleep') def do_another_thing(self): print("{} is REALLY sleepy".format(self.name)) @after('sleep') def snore(self): print("Zzzzzzzzzzzz") @after('sleep') def big_snore(self): print("Zzzzzzzzzzzzzzzzzzzzzz")
def test_notify_splits_streams_correctly(self): sm = StateMachine('test machine') src = sm.create_state('src') tgt1 = sm.create_state('tgt1') tgt2 = sm.create_state('tgt2') src.add_transition_to(tgt1, 'stream1') src.add_transition_to(tgt2, 'stream2') # Test1 sm.set_state(src) sm.notify(Event('stream1')) self.assertEqual(tgt1, sm.current_state) # Test2 sm.set_state(src) sm.notify(Event('stream2')) self.assertEqual(tgt2, sm.current_state) # Test3 sm.set_state(src) sm.notify(Event()) self.assertEqual(src, sm.current_state)
def setUp(self): chatbot = StateMachine('chatbot') active_state = chatbot.create_state('active', CompositeState) sleeping_state = chatbot.create_state('sleeping', State) chatbot.initial_state = active_state active_state.add_transition_to(sleeping_state, 'sunset') sleeping_state.add_transition_to(active_state, 'sunrise') happy_state = active_state.create_state('happy') sad_state = active_state.create_state('sad') happy_state.add_transition_to(sad_state, 'criticism') sad_state.add_transition_to(happy_state, 'praise') active_state.initial_state = happy_state active_state.initialise() chatbot.initialise() self.chatbot = chatbot self.active_state = active_state self.sleeping_state = sleeping_state self.happy_state = happy_state self.sad_state = sad_state self.sunrise = Event('sunrise') self.sunset = Event('sunset') self.criticism = Event('criticism') self.praise = Event('praise')
class Puppy(Base): __tablename__ = 'puppies' id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) name = sqlalchemy.Column(sqlalchemy.String) sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before('sleep') def do_one_thing(self): print("{} is sleepy".format(self.name)) @before('sleep') def do_another_thing(self): print("{} is REALLY sleepy".format(self.name)) @after('sleep') def snore(self): print("Zzzzzzzzzzzz") @after('sleep') def snore(self): print("Zzzzzzzzzzzzzzzzzzzzzz")
class TicketState: arrived = State(initial=True) waiting = State() running = State() stopped = State() wait = Event(from_states=(arrived, running, stopped), to_state=waiting) run = Event(from_states=waiting, to_state=running) stop = Event(from_states=(running, waiting, arrived), to_state=stopped) def __init__(self, name): self.name = name @after('wait') def wait_info(self): print(f'{self.name} WAITINGUJE') @after('run') def run_info(self): print(f'{self.name} RUNNINGUJE') @after('terminate') def block_info(self): print(f'{self.name} TERMINATORUJE')
def test_notify_with_PseudoState_can_make_choice(self): ''' Test that pseudo choice can make a choice using on_start result ''' def on_start(event, state): state.vars['payload'] = event.payload sm = StateMachine('test machine') src = sm.create_state('src') ps = sm.create_state('ps', PseudoState) tgt1 = sm.create_state('tgt1') tgt2 = sm.create_state('tgt2') src.add_transition_to(ps) ps.on_start = on_start guard1 = lambda evt, st: st.vars['payload'] == 'tgt1' ps.add_transition_to(tgt1, guard=guard1) guard2 = lambda evt, st: st.vars['payload'] == 'tgt2' ps.add_transition_to(tgt2, guard=guard2) # Test1 sm.set_state(src) e = Event('test', 'tgt1') sm.notify(e) self.assertEqual(tgt1, sm.current_state) # Test2 sm.set_state(src) e = Event('test', 'tgt2') sm.notify(e) self.assertEqual(tgt2, sm.current_state)
class Person(mongoengine.Document): name = mongoengine.StringField(default='Billy') sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before('sleep') def do_one_thing(self): print("{} is sleepy".format(self.name)) @before('sleep') def do_another_thing(self): print("{} is REALLY sleepy".format(self.name)) @after('sleep') def snore(self): print("Zzzzzzzzzzzz") @after('sleep') def snore(self): print("Zzzzzzzzzzzzzzzzzzzzzz")
class Person: name = "Jim" sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before("sleep") def sleep_before(self): print("After the busy day start. {} is going to sleep.".format( self.name)) @after("sleep") def sleep_after(self): print("After finish the whole day. {} sleep well".format(self.name)) @before('run') def run_before(self): print('exec before_run') @after('run') def run_after(self): print('exec after_run') @before("cleanup") def cleanup_before(self): print("exec before_cleanup") @after("cleanup") def cleanup_after(self): print("exec after_cleanup")
class Dog(object): sleeping = State(initial=True) running = State() run = Event(from_states=sleeping, to_state=running) sleep = Event(from_states=(running,), to_state=sleeping) @before('run') def on_run(self): things_done.append("Dog.ran")
class Robot(): name = 'R2-D2' sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping)
class Person(mongoengine.Document): name = mongoengine.StringField(default='Billy') sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping)
class Person(object): sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before('run') def on_run(self): things_done.append("Person.ran")
class Penguin(Base): __tablename__ = 'penguins' id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) name = sqlalchemy.Column(sqlalchemy.String) sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping)
class TrafficLightFSM(StateMachine): go_state = Go() prepare_to_stop_state = PrepareToStop() stop_state = Stop() prepare_to_start_state = PrepareToStart() button_pressed_event = Event("button pressed") light_change_timer_elapsed_event = Event("light change timer elapsed") pedestrian_green_timer_elapsed_event = Event( "pedestrian green timer elapsed") def __init__(self): # Initial state StateMachine.__init__(self, TrafficLightFSM.go_state)
class Runner(mongoengine.Document): name = mongoengine.StringField(default='Billy') sleeping = State(initial=True) running = State() cleaning = State() run = Event(from_states=sleeping, to_state=running) cleanup = Event(from_states=running, to_state=cleaning) sleep = Event(from_states=(running, cleaning), to_state=sleeping) @before('run') def check_sneakers(self): return False
def test_is_child_final_true(self): m = StateMachine() s = m.create_state('final', CompositeState) f = s.create_state('sfinal', FinalState) s.set_state(f) e = Event() self.assertTrue(guards.is_child_final(e, s))
def test_notify_child(self): m = StateMachine() composite_state = m.create_state('composite', CompositeState) target_state = m.create_state('target') composite_state.add_transition_to(target_state, 'tick') substate_source = composite_state.create_state('substate1') substate_target = composite_state.create_state('substate2') substate_source.add_transition_to(substate_target, 'tick') substate_source.on_end = MagicMock() substate_target.on_start = MagicMock() composite_state.initial_state = substate_source composite_state.initialise() m.initial_state = composite_state m.initialise() # Test, expecting the composite state's machine to transition e = Event('tick') m.notify(e) # Verify self.assertEqual(composite_state, m.current_state) self.assertEqual(substate_target, composite_state.current_state) self.assertEqual(1, substate_source.on_end.call_count) self.assertEqual(1, substate_target.on_start.call_count)
def test_tick_before(self): dt = datetime.datetime.utcnow() dtp1 = dt + datetime.timedelta(1) dtm1 = dt - datetime.timedelta(1) state = None g = guards.tick_before(dt) e = Event('tick', dtp1) r = g(e, state) self.assertFalse(r) e = Event('tick', dtm1) r = g(e, state) self.assertTrue(r)
def test_is_child_final_false(self): m = StateMachine() s = m.create_state('final', CompositeState) c = s.create_state('s') s.set_state(c) e = Event() self.assertFalse(guards.is_child_final(e, s))
def test_is_final_state_using_subclass(self): class AnotherFinalState(FinalState): pass m = StateMachine() s = m.create_state('final', AnotherFinalState) e = Event() self.assertTrue(guards.is_final_state(e, s))
def test_start_stores_event(self): m = StateMachine() s = m.create_state(name='test state') e = Event() s.start(e) self.assertEqual(e, s.start_event)
class Process: created = State(initial=True) running = State() terminated = State() run = Event(from_states=created, to_state=running) terminate = Event(from_states=running, to_state=terminated) def __init__(self, name): self.name = name @after('run') def run_info(self): print(f'{self.name} is running') @before('terminate') def terminate_info(self): print(f'{self.name} terminated')
def test_notify_observers(self): m = StateMachine() m.notify_observers = MagicMock() s = State('test state', m) e = Event() s.notify_observers(e) self.assertEqual(1, m.notify_observers.call_count) self.assertEqual(e, m.notify_observers.call_args[0][0])
def test_is_triggered_true_with_trigger(self): current_state = MagicMock() source = MagicMock() target = MagicMock() event = Event('test_event') t = Transition(source, target, trigger='test_event') r = t.is_triggered(event) self.assertTrue(r)
class Process: created = State(initial=True) waiting = State() running = State() terminated = State() blocked = State() swapped_out_waiting = State() swapped_out_blocked = State() wait = Event(from_states=(created, running, blocked, swapped_out_waiting), to_state=waiting) run = Event(from_states=waiting, to_state=running) terminate = Event(from_states=running, to_state=terminated) block = Event(from_states=(running, swapped_out_blocked), to_state=blocked) swap_block = Event(from_states=blocked, to_state=swapped_out_blocked) def __init__(self, name): self.name = name @after('wait') def wait_info(self): print('{} entered waiting mode'.format(self.name)) @after('run') def run_info(self): print('{} is running'.format(self.name)) @before('terminate') def terminate_info(self): print('{} terminated'.format(self.name)) @after('block') def block_info(self): print('{} is blocked'.format(self.name)) @after('swap_wait') def swap_wait_info(self): print('{} is swapped out and waiting'.format(self.name)) @after('swap_block') def swap_block_info(self): print('{} is swapped out and blocked'.format(self.name))
def test_on_start(self): # SETUP m = StateMachine() bs = BaseState('name', m) bs.on_start = MagicMock() # TEST e = Event() bs.start(e) # VERIFY bs.on_start.assert_called_once_with(e, bs)
def test_on_end(self): # SETUp m = StateMachine() bs = BaseState('name', m) bs.on_end = MagicMock() #TEST e = Event() bs.end(e) #VERIFY bs.on_end.assert_called_once_with(e, bs)
class Elevator: """ 定义状态机 状态有:运行,等待,终止,故障 """ created = State(initial=True) running = State() waiting = State() terminated = State() malfunctioned = State() wait = Event(from_states=(created, running, waiting, terminated), to_state=waiting) run = Event(from_states=waiting, to_state=running) terminate = Event(from_states=(running, waiting), to_state=terminated) malfunction = Event(from_states=(waiting, running, terminated), to_state=malfunctioned) def __init__(self, name): # 一个名字 self.name = name @after("wait") def wait_info(self): print("the {} elevator entered waiting mode".format(self.name)) @after("run") def run_info(self): print("the {} elevator is running".format(self.name)) @before("terminate") def terminate_info(self): print("the {} elevator terminated".format(self.name)) @after("malfunction") def malfunction_info(self): print("the {} elevator malfunctioned".format(self.name))
def test_self_transition(self): def store_var(event, state): state.machine.vars['v1'] = 1 sm = StateMachine() s = sm.create_state('s1') s.add_transition_to(s, 'tick', action=store_var) sm.initial_state = s sm.initialise() e = Event('tick') sm.notify(e) self.assertEqual(1, s.machine.vars['v1'])
def test_on_tick(self): has_ticked = False def on_tick(event, state): nonlocal has_ticked has_ticked = True state.logger.info('loop') self.machine.on_tick = on_tick e = Event('tick', datetime.datetime.utcnow()) self.machine.notify(e) self.assertTrue(has_ticked)