state_pattern 1.3.0 → 2.0.0

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.
Files changed (29) hide show
  1. data/README.rdoc +17 -41
  2. data/Rakefile +0 -1
  3. data/examples/rails_2_3_8_button_example/app/models/button/off.rb +1 -1
  4. data/examples/rails_2_3_8_button_example/app/models/button/on.rb +1 -1
  5. data/examples/rails_3_button_example/app/models/button/off.rb +1 -1
  6. data/examples/rails_3_button_example/app/models/button/on.rb +1 -1
  7. data/examples/rails_3_button_example/app/views/buttons/_form.html.erb +21 -0
  8. data/examples/rails_3_button_example/app/views/buttons/edit.html.erb +6 -0
  9. data/examples/rails_3_button_example/app/views/buttons/index.html.erb +23 -0
  10. data/examples/rails_3_button_example/app/views/buttons/new.html.erb +5 -0
  11. data/examples/rails_3_button_example/config/environments/production.rb +49 -0
  12. data/examples/rails_3_button_example/config/environments/test.rb +35 -0
  13. data/examples/rails_3_button_example/public/javascripts/controls.js +965 -0
  14. data/examples/rails_3_button_example/public/javascripts/dragdrop.js +974 -0
  15. data/examples/rails_3_button_example/public/javascripts/effects.js +1123 -0
  16. data/examples/rails_3_button_example/public/robots.txt +5 -0
  17. data/lib/state_pattern.rb +10 -78
  18. data/lib/state_pattern/active_record.rb +2 -2
  19. data/lib/state_pattern/state.rb +8 -4
  20. data/rails/init.rb +0 -1
  21. data/test/hook_test.rb +6 -7
  22. data/test/state_pattern/active_record/active_record_test.rb +2 -3
  23. data/test/state_pattern/active_record/test_helper.rb +2 -1
  24. data/test/state_pattern_test.rb +12 -11
  25. data/test/test_class_creation_helper.rb +0 -11
  26. metadata +24 -9
  27. data/lib/state_pattern/invalid_transition_exception.rb +0 -14
  28. data/test/querying_test.rb +0 -87
  29. data/test/transition_validations_test.rb +0 -55
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
data/lib/state_pattern.rb CHANGED
@@ -1,5 +1,5 @@
1
+ require 'forwardable'
1
2
  require 'state_pattern/state'
2
- require 'state_pattern/invalid_transition_exception'
3
3
 
4
4
  module StatePattern
5
5
  def self.included(base)
@@ -13,100 +13,32 @@ module StatePattern
13
13
 
14
14
  def set_initial_state(state_class)
15
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)}
30
- end
31
-
32
- def valid_transitions(transitions_hash)
33
- @transitions_hash = transitions_hash
34
- @transitions_hash.each do |key, value|
35
- @transitions_hash[key] = [value] if !value.respond_to?(:to_ary)
36
- end
37
- create_methods
38
- end
39
-
40
- def transitions_hash
41
- @transitions_hash
42
- end
43
-
44
- private
45
- def create_methods
46
- delegate_all_state_methods
47
- create_query_methods
48
- end
49
-
50
- def delegate_all_state_methods
51
- state_methods.each do |state_method|
52
- define_method state_method do |*args|
53
- delegate_to_state(state_method, *args)
54
- end unless respond_to?(state_method)
55
- end
16
+ include ::StatePattern::Delegation
56
17
  end
18
+ end
57
19
 
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
65
- end
20
+ module Delegation
21
+ extend Forwardable
66
22
 
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
23
+ def self.included(base)
24
+ def_delegators :current_state_instance, *base.initial_state_class.state_methods
74
25
  end
75
26
  end
76
27
 
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)
81
- end
82
-
83
28
  def current_state_instance
84
29
  set_state if @current_state_instance.nil?
85
30
  @current_state_instance
86
31
  end
87
32
 
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)
33
+ def set_state(state_class = self.class.initial_state_class)
34
+ return @current_state_instance if @current_state_instance.class == state_class
35
+ @current_state_instance = state_class.new(self, @current_state_instance)
91
36
  end
92
37
 
93
38
  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
39
  current_state_instance.exit
96
40
  set_state(next_state_class)
97
41
  end
98
-
99
- def raise_invalid_transition_to(state_class)
100
- raise InvalidTransitionException.new(current_state_instance.class, state_class, @current_method)
101
- end
102
-
103
- def valid_transition?(from_state, to_state)
104
- transitions = self.class.transitions_hash
105
- return true if transitions.nil?
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
42
  end
111
43
 
112
44
  require 'state_pattern/active_record' if defined? ActiveRecord::Base
@@ -6,7 +6,7 @@ module StatePattern
6
6
 
7
7
  after_initialize :set_state_from_db
8
8
  def set_state_from_db
9
- set_state(state_string_as_class)
9
+ set_state(state_string_as_class || self.class.initial_state_class)
10
10
  end
11
11
 
12
12
  #enable after_initialize callback
@@ -16,7 +16,7 @@ module StatePattern
16
16
  def after_initialize; end
17
17
  end
18
18
 
19
- def set_state_with_active_record_attribute(state_class = nil)
19
+ def set_state_with_active_record_attribute(state_class)
20
20
  set_state_without_active_record_attribute(state_class)
21
21
  write_attribute(self.class.state_attribute, @current_state_instance.class.name)
22
22
  end
@@ -1,14 +1,18 @@
1
1
  module StatePattern
2
2
  class State
3
- attr_reader :stateable, :previous_state
4
- def initialize(stateable, previous_state)
5
- @stateable = stateable
3
+ attr_reader :stateful, :previous_state
4
+ def initialize(stateful, previous_state)
5
+ @stateful = stateful
6
6
  @previous_state = previous_state
7
7
  enter
8
8
  end
9
9
 
10
+ def self.state_methods
11
+ public_instance_methods - State.public_instance_methods
12
+ end
13
+
10
14
  def transition_to(state_class)
11
- @stateable.transition_to(state_class)
15
+ @stateful.transition_to(state_class)
12
16
  end
13
17
 
14
18
  def enter
data/rails/init.rb CHANGED
@@ -1,3 +1,2 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'vendor/state_pattern/lib'))
2
1
  require 'state_pattern'
3
2
 
data/test/hook_test.rb CHANGED
@@ -4,15 +4,15 @@ module Hooks
4
4
  class On < StatePattern::State
5
5
  def press
6
6
  transition_to(Off)
7
- stateable.messages << "#{stateable.button_name} is off"
7
+ stateful.messages << "#{stateful.button_name} is off"
8
8
  end
9
9
 
10
10
  def enter
11
- stateable.messages << "Entered the On state"
11
+ stateful.messages << "Entered the On state"
12
12
  end
13
13
 
14
14
  def exit
15
- stateable.messages << "Exited the On state"
15
+ stateful.messages << "Exited the On state"
16
16
  end
17
17
 
18
18
  private
@@ -23,22 +23,21 @@ module Hooks
23
23
  class Off < StatePattern::State
24
24
  def press
25
25
  transition_to(On)
26
- stateable.messages << "#{stateable.button_name} is on"
26
+ stateful.messages << "#{stateful.button_name} is on"
27
27
  end
28
28
 
29
29
  def enter
30
- stateable.messages << "Entered the Off state"
30
+ stateful.messages << "Entered the Off state"
31
31
  end
32
32
 
33
33
  def exit
34
- stateable.messages << "Exited the Off state"
34
+ stateful.messages << "Exited the Off state"
35
35
  end
36
36
  end
37
37
 
38
38
  class Button
39
39
  include StatePattern
40
40
  set_initial_state Off
41
- valid_transitions [On, :press] => Off, [Off, :press] => On
42
41
 
43
42
  def button_name
44
43
  "Button"
@@ -4,20 +4,19 @@ class ARButton < ActiveRecord::Base
4
4
  class On < StatePattern::State
5
5
  def press
6
6
  transition_to(Off)
7
- "#{stateable.button_name} is off"
7
+ "#{stateful.button_name} is off"
8
8
  end
9
9
  end
10
10
 
11
11
  class Off < StatePattern::State
12
12
  def press
13
13
  transition_to(On)
14
- "#{stateable.button_name} is on"
14
+ "#{stateful.button_name} is on"
15
15
  end
16
16
  end
17
17
 
18
18
  include StatePattern::ActiveRecord
19
19
  set_initial_state Off
20
- valid_transitions [On, :press] => Off, [Off, :press] => On
21
20
 
22
21
  def button_name
23
22
  "The button"
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'rails'
2
3
  require 'active_record'
3
4
 
4
5
  {
@@ -13,7 +14,7 @@ require 'active_record'
13
14
  end
14
15
 
15
16
  #Nulldb expects Rails.root to be defined
16
- class Rails
17
+ module Rails
17
18
  def self.root
18
19
  File.dirname(__FILE__)
19
20
  end
@@ -4,7 +4,7 @@ module Family
4
4
  class James < StatePattern::State
5
5
  def name
6
6
  transition_to(Lynn)
7
- "James #{stateable.last_name}"
7
+ "James #{stateful.last_name}"
8
8
  end
9
9
 
10
10
  def james_method
@@ -14,18 +14,19 @@ module Family
14
14
  class Lynn < StatePattern::State
15
15
  def name
16
16
  transition_to(James)
17
- "Lynn #{stateable.last_name}"
17
+ "Lynn #{stateful.last_name}"
18
+ end
19
+
20
+ def james_method
18
21
  end
19
22
  end
20
23
 
21
24
  class Member
22
25
  include StatePattern
23
26
  set_initial_state Lynn
24
- valid_transitions [James, :name] => Lynn, [Lynn, :name] => James
25
27
 
26
- #notice this method is optional, it will be delegated automatically if removed
27
28
  def name
28
- delegate_to_state :name
29
+ super
29
30
  end
30
31
 
31
32
  def last_name
@@ -37,20 +38,20 @@ end
37
38
  Expectations do
38
39
  expect "Lynn Holbrook" do
39
40
  member = Family::Member.new
40
- member.name
41
+ member.name
41
42
  end
42
43
 
43
44
  expect "James Holbrook" do
44
45
  member = Family::Member.new
45
- member.name
46
- member.name
46
+ member.name
47
+ member.name
47
48
  end
48
49
 
49
50
  expect "Lynn Holbrook" do
50
51
  member = Family::Member.new
51
- member.name
52
- member.name
53
- member.name
52
+ member.name
53
+ member.name
54
+ member.name
54
55
  end
55
56
 
56
57
  expect true do
@@ -23,17 +23,6 @@ module TestClassCreationHelper
23
23
  created_consts << create_class(main_state_module_name) do
24
24
  include StatePattern
25
25
  set_initial_state Object.const_get(options[:initial_state]) if options.has_key?(:initial_state)
26
- if options.has_key?(:valid_transitions)
27
- valid_transitions_with_constants = {}
28
- options[:valid_transitions].each do |from_module_string_or_array, to_module_string|
29
- if from_module_string_or_array.respond_to?(:to_ary)
30
- valid_transitions_with_constants[[Object.const_get(from_module_string_or_array.first), from_module_string_or_array.last]] = Object.const_get(to_module_string)
31
- else
32
- valid_transitions_with_constants[Object.const_get(from_module_string_or_array)] = Object.const_get(to_module_string)
33
- end
34
- end
35
- valid_transitions valid_transitions_with_constants
36
- end
37
26
  end
38
27
 
39
28
  begin
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_pattern
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
- - 1
8
- - 3
7
+ - 2
9
8
  - 0
10
- version: 1.3.0
9
+ - 0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Daniel Cadenas
@@ -36,7 +36,6 @@ files:
36
36
  - Rakefile
37
37
  - rails/init.rb
38
38
  - ./lib/state_pattern/active_record.rb
39
- - ./lib/state_pattern/invalid_transition_exception.rb
40
39
  - ./lib/state_pattern/state.rb
41
40
  - ./lib/state_pattern.rb
42
41
  - ./examples/rails_2_3_8_button_example/app/controllers/application_controller.rb
@@ -91,6 +90,10 @@ files:
91
90
  - ./examples/rails_3_button_example/app/models/button/off.rb
92
91
  - ./examples/rails_3_button_example/app/models/button/on.rb
93
92
  - ./examples/rails_3_button_example/app/models/button.rb
93
+ - ./examples/rails_3_button_example/app/views/buttons/_form.html.erb
94
+ - ./examples/rails_3_button_example/app/views/buttons/edit.html.erb
95
+ - ./examples/rails_3_button_example/app/views/buttons/index.html.erb
96
+ - ./examples/rails_3_button_example/app/views/buttons/new.html.erb
94
97
  - ./examples/rails_3_button_example/app/views/buttons/show.html.erb
95
98
  - ./examples/rails_3_button_example/app/views/layouts/application.html.erb
96
99
  - ./examples/rails_3_button_example/config/application.rb
@@ -98,6 +101,8 @@ files:
98
101
  - ./examples/rails_3_button_example/config/database.yml
99
102
  - ./examples/rails_3_button_example/config/environment.rb
100
103
  - ./examples/rails_3_button_example/config/environments/development.rb
104
+ - ./examples/rails_3_button_example/config/environments/production.rb
105
+ - ./examples/rails_3_button_example/config/environments/test.rb
101
106
  - ./examples/rails_3_button_example/config/initializers/backtrace_silencers.rb
102
107
  - ./examples/rails_3_button_example/config/initializers/inflections.rb
103
108
  - ./examples/rails_3_button_example/config/initializers/mime_types.rb
@@ -114,22 +119,24 @@ files:
114
119
  - ./examples/rails_3_button_example/Gemfile.lock
115
120
  - ./examples/rails_3_button_example/log/development.log
116
121
  - ./examples/rails_3_button_example/public/javascripts/application.js
122
+ - ./examples/rails_3_button_example/public/javascripts/controls.js
123
+ - ./examples/rails_3_button_example/public/javascripts/dragdrop.js
124
+ - ./examples/rails_3_button_example/public/javascripts/effects.js
117
125
  - ./examples/rails_3_button_example/public/javascripts/prototype.js
118
126
  - ./examples/rails_3_button_example/public/javascripts/rails.js
127
+ - ./examples/rails_3_button_example/public/robots.txt
119
128
  - ./examples/rails_3_button_example/public/stylesheets/scaffold.css
120
129
  - ./examples/rails_3_button_example/Rakefile
121
130
  - ./examples/rails_3_button_example/script/rails
122
131
  - ./examples/semaphore.rb
123
132
  - ./test/arguments_of_event_delegation_test.rb
124
133
  - ./test/hook_test.rb
125
- - ./test/querying_test.rb
126
134
  - ./test/state_pattern/active_record/active_record_test.rb
127
135
  - ./test/state_pattern/active_record/schema.rb
128
136
  - ./test/state_pattern/active_record/test_helper.rb
129
137
  - ./test/state_pattern_test.rb
130
138
  - ./test/test_class_creation_helper.rb
131
139
  - ./test/test_helper.rb
132
- - ./test/transition_validations_test.rb
133
140
  has_rdoc: true
134
141
  homepage: http://github.com/dcadenas/state_pattern
135
142
  licenses: []
@@ -217,6 +224,10 @@ test_files:
217
224
  - ./examples/rails_3_button_example/app/models/button/off.rb
218
225
  - ./examples/rails_3_button_example/app/models/button/on.rb
219
226
  - ./examples/rails_3_button_example/app/models/button.rb
227
+ - ./examples/rails_3_button_example/app/views/buttons/_form.html.erb
228
+ - ./examples/rails_3_button_example/app/views/buttons/edit.html.erb
229
+ - ./examples/rails_3_button_example/app/views/buttons/index.html.erb
230
+ - ./examples/rails_3_button_example/app/views/buttons/new.html.erb
220
231
  - ./examples/rails_3_button_example/app/views/buttons/show.html.erb
221
232
  - ./examples/rails_3_button_example/app/views/layouts/application.html.erb
222
233
  - ./examples/rails_3_button_example/config/application.rb
@@ -224,6 +235,8 @@ test_files:
224
235
  - ./examples/rails_3_button_example/config/database.yml
225
236
  - ./examples/rails_3_button_example/config/environment.rb
226
237
  - ./examples/rails_3_button_example/config/environments/development.rb
238
+ - ./examples/rails_3_button_example/config/environments/production.rb
239
+ - ./examples/rails_3_button_example/config/environments/test.rb
227
240
  - ./examples/rails_3_button_example/config/initializers/backtrace_silencers.rb
228
241
  - ./examples/rails_3_button_example/config/initializers/inflections.rb
229
242
  - ./examples/rails_3_button_example/config/initializers/mime_types.rb
@@ -240,19 +253,21 @@ test_files:
240
253
  - ./examples/rails_3_button_example/Gemfile.lock
241
254
  - ./examples/rails_3_button_example/log/development.log
242
255
  - ./examples/rails_3_button_example/public/javascripts/application.js
256
+ - ./examples/rails_3_button_example/public/javascripts/controls.js
257
+ - ./examples/rails_3_button_example/public/javascripts/dragdrop.js
258
+ - ./examples/rails_3_button_example/public/javascripts/effects.js
243
259
  - ./examples/rails_3_button_example/public/javascripts/prototype.js
244
260
  - ./examples/rails_3_button_example/public/javascripts/rails.js
261
+ - ./examples/rails_3_button_example/public/robots.txt
245
262
  - ./examples/rails_3_button_example/public/stylesheets/scaffold.css
246
263
  - ./examples/rails_3_button_example/Rakefile
247
264
  - ./examples/rails_3_button_example/script/rails
248
265
  - ./examples/semaphore.rb
249
266
  - ./test/arguments_of_event_delegation_test.rb
250
267
  - ./test/hook_test.rb
251
- - ./test/querying_test.rb
252
268
  - ./test/state_pattern/active_record/active_record_test.rb
253
269
  - ./test/state_pattern/active_record/schema.rb
254
270
  - ./test/state_pattern/active_record/test_helper.rb
255
271
  - ./test/state_pattern_test.rb
256
272
  - ./test/test_class_creation_helper.rb
257
273
  - ./test/test_helper.rb
258
- - ./test/transition_validations_test.rb