state_pattern 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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