state_pattern 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +67 -23
- data/VERSION +1 -1
- data/lib/state_pattern.rb +64 -47
- data/lib/state_pattern/state.rb +8 -4
- data/state_pattern.gemspec +9 -3
- data/test/arguments_of_event_delegation_test.rb +44 -0
- data/test/hook_test.rb +83 -0
- data/test/querying_test.rb +87 -0
- data/test/state_pattern_test.rb +8 -1
- data/test/test_class_creation_helper.rb +1 -1
- data/test/test_helper.rb +0 -3
- metadata +8 -2
data/README.rdoc
CHANGED
@@ -2,40 +2,69 @@
|
|
2
2
|
|
3
3
|
A Ruby state pattern implementation.
|
4
4
|
|
5
|
+
== Example
|
6
|
+
|
7
|
+
Let's use one nice example from the AASM documentation and translate it to state_pattern (but keep in mind state_pattern is a generic gem, AASM is a Rails plugin):
|
8
|
+
|
5
9
|
require 'rubygems'
|
6
10
|
require 'state_pattern'
|
7
11
|
|
8
|
-
class
|
9
|
-
def
|
10
|
-
transition_to(
|
11
|
-
|
12
|
+
class Dating < StatePattern::State
|
13
|
+
def get_intimate
|
14
|
+
transition_to(Intimate) if stateable.drunk?
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_married
|
18
|
+
transition_to(Married) if stateable.willing_to_give_up_manhood?
|
19
|
+
end
|
20
|
+
|
21
|
+
def enter
|
22
|
+
stateable.make_happy
|
23
|
+
end
|
24
|
+
|
25
|
+
def exit
|
26
|
+
stateable.make_depressed
|
12
27
|
end
|
13
28
|
end
|
14
|
-
|
15
|
-
class
|
16
|
-
def
|
17
|
-
transition_to(
|
18
|
-
|
29
|
+
|
30
|
+
class Intimate < StatePattern::State
|
31
|
+
def get_married
|
32
|
+
transition_to(Married) if stateable.willing_to_give_up_manhood?
|
33
|
+
end
|
34
|
+
|
35
|
+
def enter
|
36
|
+
stateable.make_very_happy
|
37
|
+
end
|
38
|
+
|
39
|
+
def exit
|
40
|
+
stateable.never_speak_again
|
19
41
|
end
|
20
42
|
end
|
21
|
-
|
22
|
-
class
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def
|
28
|
-
|
43
|
+
|
44
|
+
class Married < StatePattern::State
|
45
|
+
def enter
|
46
|
+
stateable.give_up_intimacy
|
47
|
+
end
|
48
|
+
|
49
|
+
def exit
|
50
|
+
stateable.buy_exotic_car_and_wear_a_combover
|
29
51
|
end
|
30
52
|
end
|
31
53
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
54
|
+
class Relationship
|
55
|
+
include StatePattern
|
56
|
+
set_initial_state Dating
|
57
|
+
valid_transitions [Dating, :get_intimate] => Intimate, [Dating, :get_married] => Married, [Intimate, :get_married] => Married
|
36
58
|
|
37
|
-
|
38
|
-
|
59
|
+
def drunk?; @drunk; end
|
60
|
+
def willing_to_give_up_manhood?; @give_up_manhood; end
|
61
|
+
def make_happy; end
|
62
|
+
def make_depressed; end
|
63
|
+
def make_very_happy; end
|
64
|
+
def never_speak_again; end
|
65
|
+
def give_up_intimacy; end
|
66
|
+
def buy_exotic_car_and_wear_a_combover; end
|
67
|
+
end
|
39
68
|
|
40
69
|
== Validations
|
41
70
|
|
@@ -53,6 +82,21 @@ With more than one target state
|
|
53
82
|
Using event names to gain more detail
|
54
83
|
valid_transitions [Up, :switch] => [Middle, Down], [Down, :switch] => Middle, [Middle, :switch] => Up
|
55
84
|
|
85
|
+
== Enter and exit hooks
|
86
|
+
|
87
|
+
Inside your state classes, any code that you put inside the enter method will be executed when the state is instantiated.
|
88
|
+
You can also use the exit hook which is triggered when a successfull transition to another state takes place.
|
89
|
+
|
90
|
+
== Querying
|
91
|
+
|
92
|
+
The state pattern is a very dynamic way of representing a state machine, very few things are hard-coded and everything can change on runtime.
|
93
|
+
This means that the only way (apart from parsing ruby code) to get a list of the state classes and events that are used, is inspecting the valid_transitions array.
|
94
|
+
So assuming that you completely draw your state machine with valid_transitions (which is always recommended) you can use the class methods state_classes and state_events to get a list of states and events respectively.
|
95
|
+
|
96
|
+
== Installation
|
97
|
+
|
98
|
+
sudo gem install state_pattern
|
99
|
+
|
56
100
|
== Collaborate
|
57
101
|
|
58
102
|
http://github.com/dcadenas/state_pattern
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/lib/state_pattern.rb
CHANGED
@@ -7,87 +7,104 @@ module StatePattern
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
def state_classes
|
11
|
-
state_classes_in_transisions_hash = []
|
12
|
-
|
13
|
-
if transitions_hash
|
14
|
-
state_classes_in_transisions_hash = transitions_hash.map do |from, to|
|
15
|
-
from_class = from.respond_to?(:to_ary) ? from.first : from
|
16
|
-
to_classes = to.respond_to?(:to_ary) ? to : [to]
|
17
|
-
to_classes + [from_class]
|
18
|
-
end.flatten
|
19
|
-
end
|
20
|
-
|
21
|
-
state_classes_in_transisions_hash << initial_state_class
|
22
|
-
state_classes_in_transisions_hash.uniq
|
23
|
-
end
|
24
|
-
|
25
10
|
def initial_state_class
|
26
11
|
@initial_state_class
|
27
12
|
end
|
28
13
|
|
29
14
|
def set_initial_state(state_class)
|
30
15
|
@initial_state_class = state_class
|
16
|
+
create_methods
|
17
|
+
end
|
18
|
+
|
19
|
+
def state_methods
|
20
|
+
state_classes_with_their_bases = state_classes.map{|c| c.ancestors.select{|a| a.ancestors.include?(StatePattern::State) && a != StatePattern::State}}.flatten.uniq
|
21
|
+
(state_classes_with_their_bases.map{|state_class| state_class.public_instance_methods(false)}.flatten.uniq - ["enter", "exit"]).map{|s| s.to_sym}
|
22
|
+
end
|
23
|
+
|
24
|
+
def state_events
|
25
|
+
transitions_hash.to_a.flatten.uniq.select{|t| t.respond_to?(:to_sym)}.map{|s| s.to_sym}
|
26
|
+
end
|
27
|
+
|
28
|
+
def state_classes
|
29
|
+
(transitions_hash.to_a << initial_state_class).flatten.uniq.select{|t| t.respond_to?(:ancestors) && t.ancestors.include?(StatePattern::State)}
|
31
30
|
end
|
32
31
|
|
33
32
|
def valid_transitions(transitions_hash)
|
34
33
|
@transitions_hash = transitions_hash
|
35
34
|
@transitions_hash.each do |key, value|
|
36
|
-
if !value.respond_to?(:to_ary)
|
37
|
-
@transitions_hash[key] = [value]
|
38
|
-
end
|
35
|
+
@transitions_hash[key] = [value] if !value.respond_to?(:to_ary)
|
39
36
|
end
|
37
|
+
create_methods
|
40
38
|
end
|
41
39
|
|
42
40
|
def transitions_hash
|
43
41
|
@transitions_hash
|
44
42
|
end
|
45
43
|
|
46
|
-
|
44
|
+
private
|
45
|
+
def create_methods
|
46
|
+
delegate_all_state_methods
|
47
|
+
create_query_methods
|
48
|
+
end
|
49
|
+
|
50
|
+
def delegate_all_state_methods
|
47
51
|
state_methods.each do |state_method|
|
48
52
|
define_method state_method do |*args|
|
49
|
-
|
50
|
-
end
|
53
|
+
delegate_to_state(state_method, *args)
|
54
|
+
end unless respond_to?(state_method)
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
def
|
55
|
-
state_classes.
|
58
|
+
def create_query_methods
|
59
|
+
state_classes.each do |state_class|
|
60
|
+
method_name = "#{underscore(state_class.name.split("::").last)}?"
|
61
|
+
define_method method_name do
|
62
|
+
current_state_instance.class == state_class
|
63
|
+
end unless respond_to?(method_name)
|
64
|
+
end
|
56
65
|
end
|
57
|
-
end
|
58
66
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
67
|
+
def underscore(camel_cased_word)
|
68
|
+
camel_cased_word.to_s.gsub(/\W/, "_")
|
69
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
70
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
71
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
72
|
+
tr("-", "_").
|
73
|
+
downcase
|
74
|
+
end
|
64
75
|
end
|
65
76
|
|
66
|
-
def set_state(state_class)
|
67
|
-
|
77
|
+
def set_state(state_class = nil)
|
78
|
+
state_class ||= self.class.initial_state_class
|
79
|
+
return @current_state_instance if @current_state_instance.class == state_class
|
80
|
+
@current_state_instance = state_class.new(self, @current_state_instance)
|
68
81
|
end
|
69
|
-
|
70
|
-
def
|
71
|
-
|
72
|
-
|
82
|
+
|
83
|
+
def current_state_instance
|
84
|
+
set_state if @current_state_instance.nil?
|
85
|
+
@current_state_instance
|
73
86
|
end
|
74
87
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
88
|
+
def delegate_to_state(state_method_name, *args, &block)
|
89
|
+
@current_method = state_method_name.to_sym
|
90
|
+
self.current_state_instance.send(@current_method, *args, &block)
|
78
91
|
end
|
79
92
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
valid_transition_targets = trans[from_module] || trans[[from_module, current_event]]
|
85
|
-
valid_transition_targets && valid_transition_targets.include?(to_module)
|
93
|
+
def transition_to(next_state_class)
|
94
|
+
raise_invalid_transition_to(next_state_class) unless valid_transition?(current_state_instance.class, next_state_class)
|
95
|
+
current_state_instance.exit
|
96
|
+
set_state(next_state_class)
|
86
97
|
end
|
87
98
|
|
88
|
-
def
|
89
|
-
|
99
|
+
def raise_invalid_transition_to(state_class)
|
100
|
+
raise InvalidTransitionException.new(current_state_instance.class, state_class, @current_method)
|
90
101
|
end
|
91
|
-
end
|
92
102
|
|
103
|
+
def valid_transition?(from_state, to_state)
|
104
|
+
transitions = self.class.transitions_hash
|
105
|
+
return true if transitions.nil?
|
93
106
|
|
107
|
+
valid_transition_targets = transitions[from_state] || transitions[[from_state, @current_method]]
|
108
|
+
valid_transition_targets && valid_transition_targets.include?(to_state)
|
109
|
+
end
|
110
|
+
end
|
data/lib/state_pattern/state.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
module StatePattern
|
2
2
|
class State
|
3
|
-
attr_reader :stateable
|
4
|
-
def initialize(stateable)
|
3
|
+
attr_reader :stateable, :previous_state
|
4
|
+
def initialize(stateable, previous_state)
|
5
5
|
@stateable = stateable
|
6
|
+
@previous_state = previous_state
|
7
|
+
enter
|
6
8
|
end
|
7
9
|
|
8
10
|
def transition_to(state_class)
|
9
11
|
@stateable.transition_to(state_class)
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
+
def enter
|
15
|
+
end
|
16
|
+
|
17
|
+
def exit
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
data/state_pattern.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{state_pattern}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.2.0"
|
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"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-10-12}
|
10
10
|
s.email = %q{dcadenas@gmail.com}
|
11
11
|
s.extra_rdoc_files = [
|
12
12
|
"LICENSE",
|
@@ -23,6 +23,9 @@ Gem::Specification.new do |s|
|
|
23
23
|
"lib/state_pattern/invalid_transition_exception.rb",
|
24
24
|
"lib/state_pattern/state.rb",
|
25
25
|
"state_pattern.gemspec",
|
26
|
+
"test/arguments_of_event_delegation_test.rb",
|
27
|
+
"test/hook_test.rb",
|
28
|
+
"test/querying_test.rb",
|
26
29
|
"test/state_pattern_test.rb",
|
27
30
|
"test/test_class_creation_helper.rb",
|
28
31
|
"test/test_helper.rb",
|
@@ -35,7 +38,10 @@ Gem::Specification.new do |s|
|
|
35
38
|
s.rubygems_version = %q{1.3.3}
|
36
39
|
s.summary = %q{A Ruby state pattern implementation}
|
37
40
|
s.test_files = [
|
38
|
-
"test/
|
41
|
+
"test/arguments_of_event_delegation_test.rb",
|
42
|
+
"test/hook_test.rb",
|
43
|
+
"test/querying_test.rb",
|
44
|
+
"test/state_pattern_test.rb",
|
39
45
|
"test/test_class_creation_helper.rb",
|
40
46
|
"test/test_helper.rb",
|
41
47
|
"test/transition_validations_test.rb"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SampleClass
|
4
|
+
def event(arg1, arg2)
|
5
|
+
block_value = block_given? ? yield : nil
|
6
|
+
[arg1, arg2, block_value].compact.join(", ")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class SampleState < StatePattern::State
|
11
|
+
def event(arg1, arg2)
|
12
|
+
block_value = block_given? ? yield : nil
|
13
|
+
"state event args == " + [arg1, arg2, block_value].compact.join(", ")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SampleClassWithStatePattern < SampleClass
|
18
|
+
include StatePattern
|
19
|
+
set_initial_state SampleState
|
20
|
+
end
|
21
|
+
|
22
|
+
Expectations do
|
23
|
+
expect "arg1, arg2" do
|
24
|
+
sample_class_instance = ::SampleClass.new
|
25
|
+
sample_class_instance.event("arg1", "arg2")
|
26
|
+
end
|
27
|
+
|
28
|
+
expect "state event args == arg1, arg2" do
|
29
|
+
sample_class_instance = ::SampleClassWithStatePattern.new
|
30
|
+
sample_class_instance.event("arg1", "arg2")
|
31
|
+
end
|
32
|
+
|
33
|
+
=begin
|
34
|
+
PENDING
|
35
|
+
Currently using class_eval to define the delegation method (so we can pass a block)
|
36
|
+
is causing a segmention fault on 1.8.6 so we only use define_method to do the delegation
|
37
|
+
if you want to pass a block do so as a normal variable, do use yield
|
38
|
+
|
39
|
+
expect "state event args == arg1, arg2, arg3" do
|
40
|
+
sample_class_instance = ::SampleClassWithStatePattern.new
|
41
|
+
sample_class_instance.event("arg1", "arg2"){"arg3"}
|
42
|
+
end
|
43
|
+
=end
|
44
|
+
end
|
data/test/hook_test.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Hooks
|
4
|
+
class On < StatePattern::State
|
5
|
+
def press
|
6
|
+
transition_to(Off)
|
7
|
+
stateable.messages << "#{stateable.button_name} is off"
|
8
|
+
end
|
9
|
+
|
10
|
+
def enter
|
11
|
+
stateable.messages << "Entered the On state"
|
12
|
+
end
|
13
|
+
|
14
|
+
def exit
|
15
|
+
stateable.messages << "Exited the On state"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def private_method
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Off < StatePattern::State
|
24
|
+
def press
|
25
|
+
transition_to(On)
|
26
|
+
stateable.messages << "#{stateable.button_name} is on"
|
27
|
+
end
|
28
|
+
|
29
|
+
def enter
|
30
|
+
stateable.messages << "Entered the Off state"
|
31
|
+
end
|
32
|
+
|
33
|
+
def exit
|
34
|
+
stateable.messages << "Exited the Off state"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Button
|
39
|
+
include StatePattern
|
40
|
+
set_initial_state Off
|
41
|
+
valid_transitions [On, :press] => Off, [Off, :press] => On
|
42
|
+
|
43
|
+
def button_name
|
44
|
+
"Button"
|
45
|
+
end
|
46
|
+
|
47
|
+
def messages
|
48
|
+
@messages ||= []
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Expectations do
|
54
|
+
expect ["Entered the Off state", "Exited the Off state", "Entered the On state", "Button is on"] do
|
55
|
+
button = Hooks::Button.new
|
56
|
+
button.press
|
57
|
+
button.messages
|
58
|
+
end
|
59
|
+
|
60
|
+
expect ["Entered the Off state", "Exited the Off state", "Entered the On state", "Button is on", "Exited the On state", "Entered the Off state", "Button is off"] do
|
61
|
+
button = Hooks::Button.new
|
62
|
+
button.press
|
63
|
+
button.press
|
64
|
+
button.messages
|
65
|
+
end
|
66
|
+
|
67
|
+
expect false do
|
68
|
+
Hooks::Button.new.respond_to?(:enter)
|
69
|
+
end
|
70
|
+
|
71
|
+
expect false do
|
72
|
+
Hooks::Button.new.respond_to?(:exit)
|
73
|
+
end
|
74
|
+
|
75
|
+
expect false do
|
76
|
+
Hooks::Button.new.respond_to?(:private_method)
|
77
|
+
end
|
78
|
+
|
79
|
+
expect true do
|
80
|
+
Hooks::Button.new.respond_to?(:press)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Querying
|
4
|
+
class StateBaseBase < StatePattern::State
|
5
|
+
def common_event
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class StateBase < StateBaseBase
|
10
|
+
def another_common_event
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class On < StateBase
|
15
|
+
def press
|
16
|
+
transition_to(Off)
|
17
|
+
end
|
18
|
+
|
19
|
+
def one_event
|
20
|
+
end
|
21
|
+
|
22
|
+
def another_event
|
23
|
+
end
|
24
|
+
|
25
|
+
def enter
|
26
|
+
end
|
27
|
+
|
28
|
+
def exit
|
29
|
+
end
|
30
|
+
private
|
31
|
+
def not_an_event
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Off < StateBase
|
36
|
+
def press
|
37
|
+
transition_to(On)
|
38
|
+
end
|
39
|
+
|
40
|
+
def one_event
|
41
|
+
end
|
42
|
+
|
43
|
+
def another_event
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Button
|
48
|
+
include StatePattern
|
49
|
+
set_initial_state On
|
50
|
+
valid_transitions [On, :press] => Off, [Off, :press] => On
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Expectations do
|
55
|
+
expect %w(Querying::Off Querying::On) do
|
56
|
+
Querying::Button.state_classes.map{|c| c.name}.sort
|
57
|
+
end
|
58
|
+
|
59
|
+
expect ["another_common_event", "another_event", "common_event", "one_event", "press"] do
|
60
|
+
Querying::Button.state_methods.map{|s| s.to_s}.sort
|
61
|
+
end
|
62
|
+
|
63
|
+
expect [:press] do
|
64
|
+
Querying::Button.state_events
|
65
|
+
end
|
66
|
+
|
67
|
+
expect true do
|
68
|
+
Querying::Button.new.on?
|
69
|
+
end
|
70
|
+
|
71
|
+
expect false do
|
72
|
+
Querying::Button.new.off?
|
73
|
+
end
|
74
|
+
|
75
|
+
expect false do
|
76
|
+
button = Querying::Button.new
|
77
|
+
button.press
|
78
|
+
button.on?
|
79
|
+
end
|
80
|
+
|
81
|
+
expect true do
|
82
|
+
button = Querying::Button.new
|
83
|
+
button.press
|
84
|
+
button.off?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
data/test/state_pattern_test.rb
CHANGED
@@ -6,6 +6,9 @@ module Family
|
|
6
6
|
transition_to(Lynn)
|
7
7
|
"James #{stateable.last_name}"
|
8
8
|
end
|
9
|
+
|
10
|
+
def james_method
|
11
|
+
end
|
9
12
|
end
|
10
13
|
|
11
14
|
class Lynn < StatePattern::State
|
@@ -22,7 +25,7 @@ module Family
|
|
22
25
|
|
23
26
|
#notice this method is optional, it will be delegated automatically if removed
|
24
27
|
def name
|
25
|
-
|
28
|
+
delegate_to_state :name
|
26
29
|
end
|
27
30
|
|
28
31
|
def last_name
|
@@ -50,6 +53,10 @@ Expectations do
|
|
50
53
|
member.name
|
51
54
|
end
|
52
55
|
|
56
|
+
expect true do
|
57
|
+
Family::Member.new.respond_to?(:james_method)
|
58
|
+
end
|
59
|
+
|
53
60
|
expect "on" do
|
54
61
|
with_test_class("Button", :states => ["On", "Off"], :initial_state => "Off",
|
55
62
|
:transitions => {["On", :press] => "Off", ["Off", :press] => "On"}) do
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: state_pattern
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Cadenas
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-12 00:00:00 -02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,6 +33,9 @@ files:
|
|
33
33
|
- lib/state_pattern/invalid_transition_exception.rb
|
34
34
|
- lib/state_pattern/state.rb
|
35
35
|
- state_pattern.gemspec
|
36
|
+
- test/arguments_of_event_delegation_test.rb
|
37
|
+
- test/hook_test.rb
|
38
|
+
- test/querying_test.rb
|
36
39
|
- test/state_pattern_test.rb
|
37
40
|
- test/test_class_creation_helper.rb
|
38
41
|
- test/test_helper.rb
|
@@ -66,6 +69,9 @@ signing_key:
|
|
66
69
|
specification_version: 3
|
67
70
|
summary: A Ruby state pattern implementation
|
68
71
|
test_files:
|
72
|
+
- test/arguments_of_event_delegation_test.rb
|
73
|
+
- test/hook_test.rb
|
74
|
+
- test/querying_test.rb
|
69
75
|
- test/state_pattern_test.rb
|
70
76
|
- test/test_class_creation_helper.rb
|
71
77
|
- test/test_helper.rb
|