dcadenas-state_pattern 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
data/lib/state_pattern.rb CHANGED
@@ -3,73 +3,67 @@ require 'state_pattern/invalid_transition_exception'
3
3
 
4
4
  module StatePattern
5
5
  def self.included(base)
6
- base.instance_eval do
7
- def state_classes
8
- @state_classes ||= []
9
- end
6
+ base.extend ClassMethods
7
+ end
10
8
 
11
- def initial_state_class
12
- @initial_state_class
13
- end
9
+ module ClassMethods
10
+ def state_classes
11
+ @state_classes ||= []
12
+ end
14
13
 
15
- def set_initial_state(state_class)
16
- @initial_state_class = state_class
17
- end
14
+ def initial_state_class
15
+ @initial_state_class
16
+ end
18
17
 
19
- def add_states(*state_classes)
20
- state_classes.each do |state_class|
21
- add_state_class(state_class)
22
- end
23
- end
18
+ def set_initial_state(state_class)
19
+ @initial_state_class = state_class
20
+ end
24
21
 
25
- def add_state_class(state_class)
26
- state_classes << state_class
22
+ def add_states(*state_classes)
23
+ state_classes.each do |state_class|
24
+ add_state_class(state_class)
27
25
  end
26
+ end
28
27
 
29
- def valid_transitions(transitions_hash)
30
- @transitions_hash = transitions_hash
31
- end
28
+ def add_state_class(state_class)
29
+ state_classes << state_class
30
+ end
32
31
 
33
- def transitions_hash
34
- @transitions_hash
32
+ def valid_transitions(transitions_hash)
33
+ @transitions_hash = transitions_hash
34
+ @transitions_hash.each do |key, value|
35
+ if !value.respond_to?(:to_ary)
36
+ @transitions_hash[key] = [value]
37
+ end
35
38
  end
39
+ end
40
+
41
+ def transitions_hash
42
+ @transitions_hash
43
+ end
36
44
 
37
- def delegate_all_state_events
38
- state_methods.each do |state_method|
39
- define_method state_method do |*args|
40
- delegate_to_event(state_method)
41
- end
45
+ def delegate_all_state_events
46
+ state_methods.each do |state_method|
47
+ define_method state_method do |*args|
48
+ delegate_to_event(state_method)
42
49
  end
43
50
  end
51
+ end
44
52
 
45
- def state_methods
46
- state_classes.map{|state_class| state_class.public_instance_methods(false)}.flatten.uniq
47
- end
53
+ def state_methods
54
+ state_classes.map{|state_class| state_class.public_instance_methods(false)}.flatten.uniq
48
55
  end
49
56
  end
50
57
 
51
- attr_accessor :current_state, :current_event, :states
58
+ attr_accessor :current_state, :current_event
52
59
  def initialize(*args)
53
60
  super(*args)
54
- self.states = {}
55
- add_state_instances
56
61
  set_state(self.class.initial_state_class)
57
62
  self.class.delegate_all_state_events
58
63
  end
59
64
 
60
65
  def set_state(state_class)
61
- add_state_instance(state_class)
62
- self.current_state = self.states[state_class]
63
- end
64
-
65
- def add_state_instances
66
- self.class.state_classes.map do |state_class|
67
- add_state_instance(state_class)
68
- end
69
- end
70
-
71
- def add_state_instance(state_class)
72
- self.states[state_class] = state_class.new(self) if !self.states.has_key?(state_class) || self.states[state_class].nil?
66
+ self.current_state = state_class.new(self)
73
67
  end
74
68
 
75
69
  def delegate_to_event(method_name, *args)
@@ -85,13 +79,9 @@ module StatePattern
85
79
  def valid_transition?(from_module, to_module)
86
80
  trans = self.class.transitions_hash
87
81
  return true if trans.nil?
88
-
89
- #TODO: ugly
90
- trans.has_key?(from_module) &&
91
- (trans[from_module] == to_module ||
92
- trans[from_module].include?(to_module)) ||
93
- trans.has_key?([from_module, current_event]) &&
94
- (trans[[from_module, current_event]] == to_module || trans[[from_module, current_event]].include?(to_module))
82
+
83
+ valid_transition_targets = trans[from_module] || trans[[from_module, current_event]]
84
+ valid_transition_targets && valid_transition_targets.include?(to_module)
95
85
  end
96
86
 
97
87
  def state
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{state_pattern}
5
- s.version = "1.0.0"
5
+ s.version = "1.0.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Daniel Cadenas"]
@@ -87,6 +87,16 @@ Expectations do
87
87
  button2.press
88
88
  end
89
89
  end
90
+
91
+ expect ["ping", "on", "pong", "off"] do
92
+ with_test_class("PingPong", :states => ["Ping", "Pong"], :initial_state => "Pong", :transitions => {["Ping", :do_it] => "Pong", ["Pong", :do_it] => "Ping"}) do
93
+ with_test_class("Button", :states => ["On", "Off"], :initial_state => "Off", :transitions => {["On", :press] => "Off", ["Off", :press] => "On"}) do
94
+ pingpong = PingPong.new
95
+ button = Button.new
96
+ [pingpong.do_it, button.press, pingpong.do_it, button.press]
97
+ end
98
+ end
99
+ end
90
100
  end
91
101
 
92
102
 
@@ -4,9 +4,9 @@ Expectations do
4
4
  expect "up" do
5
5
  with_test_class("Switch", :states => ["Up", "Down", "Middle"], :initial_state => "Middle",
6
6
  :transitions => {["Up", :push_down] => "Middle",
7
- ["Down", :push_up] => "Middle",
8
- ["Middle", :push_up] => "Up",
9
- ["Middle", :push_down] => "Down"}) do
7
+ ["Down", :push_up] => "Middle",
8
+ ["Middle", :push_up] => "Up",
9
+ ["Middle", :push_down] => "Down"}) do
10
10
  switch = Switch.new
11
11
  switch.push_up
12
12
  end
@@ -15,13 +15,13 @@ Expectations do
15
15
  expect "up" do
16
16
  with_test_class("Switch", :states => ["Up", "Down", "Middle"], :initial_state => "Middle",
17
17
  :transitions => {["Up", :push_down] => "Middle",
18
- ["Down", :push_up] => "Middle",
19
- ["Middle", :push_up] => "Up",
20
- ["Middle", :push_down] => "Down"},
21
- :valid_transitions => {["Up", :push_down] => "Middle",
22
- ["Down", :push_up] => "Middle",
23
- ["Middle", :push_up] => "Up",
24
- ["Middle", :push_down] => "Down"}) do
18
+ ["Down", :push_up] => "Middle",
19
+ ["Middle", :push_up] => "Up",
20
+ ["Middle", :push_down] => "Down"},
21
+ :valid_transitions => {["Up", :push_down] => "Middle",
22
+ ["Down", :push_up] => "Middle",
23
+ ["Middle", :push_up] => "Up",
24
+ ["Middle", :push_down] => "Down"}) do
25
25
  switch = Switch.new
26
26
  switch.push_up
27
27
  end
@@ -30,12 +30,24 @@ Expectations do
30
30
  expect StatePattern::InvalidTransitionException do
31
31
  with_test_class("Switch", :states => ["Up", "Down", "Middle"], :initial_state => "Middle",
32
32
  :transitions => {["Up", :push_down] => "Middle",
33
- ["Down", :push_up] => "Middle",
34
- ["Middle", :push_up] => "Up",
35
- ["Middle", :push_down] => "Down"},
36
- :valid_transitions => {["Up", :push_down] => "Middle",
37
- ["Down", :push_up] => "Middle",
38
- ["Middle", :push_down] => "Down"}) do
33
+ ["Down", :push_up] => "Middle",
34
+ ["Middle", :push_up] => "Up",
35
+ ["Middle", :push_down] => "Down"},
36
+ :valid_transitions => {["Up", :push_down] => "Middle",
37
+ ["Down", :push_up] => "Middle",
38
+ ["Middle", :push_down] => "Down"}) do
39
+ switch = Switch.new
40
+ switch.push_up
41
+ end
42
+ end
43
+
44
+ expect StatePattern::InvalidTransitionException do
45
+ with_test_class("Switch", :states => ["Up", "Down", "Middle"], :initial_state => "Middle",
46
+ :transitions => {["Up", :push_down] => "Middle",
47
+ ["Down", :push_up] => "Middle",
48
+ ["Middle", :push_up] => "Up",
49
+ ["Middle", :push_down] => "Down"},
50
+ :valid_transitions => {"Up" => "Middle", "Down" => "Middle", "Middle" => "Down"}) do
39
51
  switch = Switch.new
40
52
  switch.push_up
41
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dcadenas-state_pattern
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Cadenas