require 'state' require 'set' require 'test/unit' def put_states foo = State.send(:class_variable_get, :@@states).map{ |x| x.to_s_color } puts foo.sort.join(", ") end class TC_State < Test::Unit::TestCase include UpState Foo = State.new_type("foo", [Event.new("gimmefoo", {:bob => /^...$/})], [], [:bob]) Bar = State.new_type("bar", [], [Dependency.new(Foo)]) Baz = State.new_type("baz", [], [Dependency.new(Foo, {:bob => "abc"}, {:bob => :tom}), Dependency.new(Bar)]) Bam = State.new_type("bam", [Event::Epsilon], [Dependency.new(Baz)]) Bang = State.new_type("bang", [], [Dependency.new(Bam)]) def assert_have_states(*s) assert_equal(s.sort, State.get_all.map{ |x| x.to_s }.sort) end def assert_only_states(*s) assert_have_states *s assert_equal(State.get_all.size, s.size) end def setup assert_only_states "FooState{} (down)" end def teardown State.release(:user) State.release(:system) end def test_ignored_event State.process_event(Event.new("gimmefoo", {:bob => "1234"})) assert_only_states "FooState{} (down)" end def test_responded_event State.process_event(Event.new("gimmefoo", {:bob => "123"})) assert_only_states('FooState{} (down)', 'FooState{:bob=>"123"} (up)', "BarState{} (down)") end def test_hold_with_dependent test_responded_event Bar.get_all.first.hold(:user) assert_only_states('FooState{} (down)', 'FooState{:bob=>"123"} (up)', "BarState{} (up)") end def test_hold_non_existant_state Bar.hold(:user) assert_only_states "FooState{} (down)" end def test_pattern_matched_param_dep State.process_event(Event.new("gimmefoo", {:bob => "abc"})) Bar.hold(:user) assert_only_states( 'BazState{:tom=>"abc"} (down)', 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', "BarState{} (up)" ) end def test_duplicitous_state_by_deps test_pattern_matched_param_dep State.process_event(Event.new("gimmefoo", {:bob => "123"})) assert_only_states( 'BazState{:tom=>"abc"} (down)', 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', 'FooState{:bob=>"123"} (up)', "BarState{} (up)", "BarState{} (down)" ) end def test_identity_uniqueness test_pattern_matched_param_dep State.process_event(Event.new("gimmefoo", {:bob => "abc"})) assert_only_states( 'BazState{:tom=>"abc"} (down)', 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', "BarState{} (up)" ) end def test_epsilon test_pattern_matched_param_dep Baz.hold(:user) assert_only_states( 'BazState{:tom=>"abc"} (up)', 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', "BarState{} (up)", "BamState{} (up)", "BangState{} (down)" ) end def test_release_noop test_epsilon Bar.release(:user) assert_only_states( 'BazState{:tom=>"abc"} (up)', 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', "BarState{} (up)", "BamState{} (up)", "BangState{} (down)" ) end def test_drop_cleanup test_release_noop Bar.get_all.each{ |x| x.drop } assert_only_states( 'FooState{} (down)', 'FooState{:bob=>"abc"} (up)', "BarState{} (down)" ) end end