branston 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. data/README.rdoc +1 -1
  2. data/lib/branston/Gemfile +25 -0
  3. data/lib/branston/Gemfile.lock +76 -0
  4. data/lib/branston/app/controllers/application_controller.rb +1 -1
  5. data/lib/branston/app/controllers/outcomes_controller.rb +2 -0
  6. data/lib/branston/app/controllers/stories_controller.rb +82 -86
  7. data/lib/branston/app/controllers/users_controller.rb +69 -11
  8. data/lib/branston/app/helpers/iterations_helper.rb +13 -13
  9. data/lib/branston/app/models/iteration.rb +3 -1
  10. data/lib/branston/app/models/release.rb +0 -1
  11. data/lib/branston/app/models/story.rb +30 -28
  12. data/lib/branston/app/models/user.rb +46 -1
  13. data/lib/branston/app/views/layouts/_header.html.erb +8 -3
  14. data/lib/branston/app/views/layouts/user_roles.html.erb +5 -5
  15. data/lib/branston/app/views/sessions/new.html.erb +8 -14
  16. data/lib/branston/app/views/users/_admin_controls.html.erb +14 -0
  17. data/lib/branston/app/views/users/_form.html.erb +27 -0
  18. data/lib/branston/app/views/users/edit.html.erb +9 -0
  19. data/lib/branston/app/views/users/index.html.erb +14 -0
  20. data/lib/branston/app/views/users/new.html.erb +3 -22
  21. data/lib/branston/config/boot.rb +20 -0
  22. data/lib/branston/config/environment.rb +2 -7
  23. data/lib/branston/config/environments/test.rb +0 -8
  24. data/lib/branston/config/preinitializer.rb +21 -0
  25. data/lib/branston/config/routes.rb +15 -10
  26. data/lib/branston/db/development.sqlite3 +0 -0
  27. data/lib/branston/db/development_structure.sql +21 -8
  28. data/lib/branston/db/migrate/20100723161424_add_state_to_user.rb +12 -0
  29. data/lib/branston/db/migrate/20100726150322_add_activation_fields_to_user.rb +12 -0
  30. data/lib/branston/db/migrate/20100729125551_set_default_user_state_to_pending.rb +10 -0
  31. data/lib/branston/db/migrate/20100812133837_add_is_admin_property_to_user.rb +10 -0
  32. data/lib/branston/db/migrate/20100812140532_set_default_user_state_to_active.rb +10 -0
  33. data/lib/branston/db/migrate/20100812143455_add_default_admin_user.rb +17 -0
  34. data/lib/branston/db/migrate/20110408162438_remove_is_admin_property_and_add_role_instead.rb +12 -0
  35. data/lib/branston/db/pristine.sqlite3 +0 -0
  36. data/lib/branston/db/schema.rb +6 -8
  37. data/lib/branston/db/test.sqlite3 +0 -0
  38. data/lib/branston/log/development.log +1181 -433
  39. data/lib/branston/log/test.log +145306 -52026
  40. data/lib/branston/test/blueprints.rb +22 -28
  41. data/lib/branston/test/functional/iterations_controller_test.rb +149 -113
  42. data/lib/branston/test/functional/outcomes_controller_test.rb +94 -60
  43. data/lib/branston/test/functional/preconditions_controller_test.rb +101 -67
  44. data/lib/branston/test/functional/releases_controller_test.rb +85 -49
  45. data/lib/branston/test/functional/scenarios_controller_test.rb +104 -70
  46. data/lib/branston/test/functional/stories_controller_test.rb +41 -12
  47. data/lib/branston/test/functional/users_controller_test.rb +364 -43
  48. data/lib/branston/test/unit/iteration_test.rb +37 -6
  49. data/lib/branston/test/unit/outcome_test.rb +2 -2
  50. data/lib/branston/test/unit/participation_test.rb +2 -2
  51. data/lib/branston/test/unit/precondition_test.rb +3 -3
  52. data/lib/branston/test/unit/release_test.rb +4 -0
  53. data/lib/branston/test/unit/scenario_test.rb +4 -4
  54. data/lib/branston/test/unit/story_test.rb +62 -40
  55. data/lib/branston/test/unit/user_test.rb +195 -5
  56. metadata +136 -156
  57. data/lib/branston/app/controllers/user_roles_controller.rb +0 -105
  58. data/lib/branston/app/helpers/user_roles_helper.rb +0 -2
  59. data/lib/branston/app/models/user_role.rb +0 -21
  60. data/lib/branston/app/views/layouts/outcomes.html.erb +0 -17
  61. data/lib/branston/app/views/layouts/preconditions.html.erb +0 -17
  62. data/lib/branston/app/views/layouts/releases.html.erb +0 -17
  63. data/lib/branston/app/views/user_roles/edit.html.erb +0 -16
  64. data/lib/branston/app/views/user_roles/index.html.erb +0 -20
  65. data/lib/branston/app/views/user_roles/new.html.erb +0 -15
  66. data/lib/branston/app/views/user_roles/show.html.erb +0 -8
  67. data/lib/branston/coverage/app-controllers-application_controller_rb.html +0 -231
  68. data/lib/branston/coverage/app-controllers-iterations_controller_rb.html +0 -801
  69. data/lib/branston/coverage/app-controllers-outcomes_controller_rb.html +0 -759
  70. data/lib/branston/coverage/app-controllers-preconditions_controller_rb.html +0 -783
  71. data/lib/branston/coverage/app-controllers-releases_controller_rb.html +0 -705
  72. data/lib/branston/coverage/app-controllers-scenarios_controller_rb.html +0 -777
  73. data/lib/branston/coverage/app-controllers-sessions_controller_rb.html +0 -411
  74. data/lib/branston/coverage/app-controllers-stories_controller_rb.html +0 -1071
  75. data/lib/branston/coverage/app-controllers-user_roles_controller_rb.html +0 -693
  76. data/lib/branston/coverage/app-controllers-users_controller_rb.html +0 -315
  77. data/lib/branston/coverage/app-helpers-application_helper_rb.html +0 -327
  78. data/lib/branston/coverage/app-helpers-iterations_helper_rb.html +0 -363
  79. data/lib/branston/coverage/app-helpers-outcomes_helper_rb.html +0 -75
  80. data/lib/branston/coverage/app-helpers-preconditions_helper_rb.html +0 -75
  81. data/lib/branston/coverage/app-helpers-releases_helper_rb.html +0 -75
  82. data/lib/branston/coverage/app-helpers-sessions_helper_rb.html +0 -75
  83. data/lib/branston/coverage/app-helpers-stories_helper_rb.html +0 -75
  84. data/lib/branston/coverage/app-helpers-user_roles_helper_rb.html +0 -75
  85. data/lib/branston/coverage/app-models-iteration_rb.html +0 -321
  86. data/lib/branston/coverage/app-models-outcome_rb.html +0 -243
  87. data/lib/branston/coverage/app-models-participation_rb.html +0 -189
  88. data/lib/branston/coverage/app-models-precondition_rb.html +0 -243
  89. data/lib/branston/coverage/app-models-release_rb.html +0 -195
  90. data/lib/branston/coverage/app-models-scenario_rb.html +0 -231
  91. data/lib/branston/coverage/app-models-story_rb.html +0 -621
  92. data/lib/branston/coverage/app-models-user_rb.html +0 -513
  93. data/lib/branston/coverage/app-models-user_role_rb.html +0 -189
  94. data/lib/branston/coverage/index.html +0 -570
  95. data/lib/branston/coverage/jquery-1.3.2.min.js +0 -19
  96. data/lib/branston/coverage/jquery.tablesorter.min.js +0 -15
  97. data/lib/branston/coverage/lib-client_rb.html +0 -537
  98. data/lib/branston/coverage/lib-faker_extras_rb.html +0 -207
  99. data/lib/branston/coverage/lib-story_generator_rb.html +0 -873
  100. data/lib/branston/coverage/print.css +0 -12
  101. data/lib/branston/coverage/rcov.js +0 -42
  102. data/lib/branston/coverage/screen.css +0 -270
  103. data/lib/branston/db/migrate/20091127131037_create_user_roles.rb +0 -13
  104. data/lib/branston/db/migrate/20091127172950_add_story_id_to_user_role.rb +0 -10
  105. data/lib/branston/test/functional/user_roles_controller_test.rb +0 -71
  106. data/lib/branston/test/unit/helpers/user_roles_helper_test.rb +0 -4
  107. data/lib/branston/test/unit/user_role_test.rb +0 -9
  108. data/lib/branston/tmp/performance/BrowsingTest#test_homepage_process_time_flat.txt +0 -8
  109. data/lib/branston/tmp/performance/BrowsingTest#test_homepage_process_time_graph.html +0 -6718
  110. data/lib/branston/tmp/performance/BrowsingTest#test_homepage_process_time_tree.txt +0 -9942
  111. data/lib/branston/vendor/plugins/state_machine/CHANGELOG.rdoc +0 -298
  112. data/lib/branston/vendor/plugins/state_machine/LICENSE +0 -20
  113. data/lib/branston/vendor/plugins/state_machine/README.rdoc +0 -466
  114. data/lib/branston/vendor/plugins/state_machine/Rakefile +0 -98
  115. data/lib/branston/vendor/plugins/state_machine/examples/AutoShop_state.png +0 -0
  116. data/lib/branston/vendor/plugins/state_machine/examples/Car_state.png +0 -0
  117. data/lib/branston/vendor/plugins/state_machine/examples/TrafficLight_state.png +0 -0
  118. data/lib/branston/vendor/plugins/state_machine/examples/Vehicle_state.png +0 -0
  119. data/lib/branston/vendor/plugins/state_machine/examples/auto_shop.rb +0 -11
  120. data/lib/branston/vendor/plugins/state_machine/examples/car.rb +0 -19
  121. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/controller.rb +0 -51
  122. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/model.rb +0 -28
  123. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/view_edit.html.erb +0 -24
  124. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/view_index.html.erb +0 -23
  125. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/view_new.html.erb +0 -13
  126. data/lib/branston/vendor/plugins/state_machine/examples/merb-rest/view_show.html.erb +0 -17
  127. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/controller.rb +0 -43
  128. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/migration.rb +0 -11
  129. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/model.rb +0 -23
  130. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/view_edit.html.erb +0 -25
  131. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/view_index.html.erb +0 -23
  132. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/view_new.html.erb +0 -14
  133. data/lib/branston/vendor/plugins/state_machine/examples/rails-rest/view_show.html.erb +0 -17
  134. data/lib/branston/vendor/plugins/state_machine/examples/traffic_light.rb +0 -7
  135. data/lib/branston/vendor/plugins/state_machine/examples/vehicle.rb +0 -31
  136. data/lib/branston/vendor/plugins/state_machine/init.rb +0 -1
  137. data/lib/branston/vendor/plugins/state_machine/lib/state_machine.rb +0 -388
  138. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/assertions.rb +0 -36
  139. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/callback.rb +0 -189
  140. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/condition_proxy.rb +0 -94
  141. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/eval_helpers.rb +0 -67
  142. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/event.rb +0 -252
  143. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/event_collection.rb +0 -122
  144. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/extensions.rb +0 -149
  145. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/guard.rb +0 -230
  146. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations.rb +0 -68
  147. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/active_record.rb +0 -492
  148. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/active_record/locale.rb +0 -11
  149. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/active_record/observer.rb +0 -41
  150. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/data_mapper.rb +0 -351
  151. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/data_mapper/observer.rb +0 -139
  152. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/integrations/sequel.rb +0 -322
  153. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/machine.rb +0 -1467
  154. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/machine_collection.rb +0 -155
  155. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/matcher.rb +0 -123
  156. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/matcher_helpers.rb +0 -54
  157. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/node_collection.rb +0 -152
  158. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/state.rb +0 -249
  159. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/state_collection.rb +0 -112
  160. data/lib/branston/vendor/plugins/state_machine/lib/state_machine/transition.rb +0 -394
  161. data/lib/branston/vendor/plugins/state_machine/state_machine.gemspec +0 -30
  162. data/lib/branston/vendor/plugins/state_machine/tasks/state_machine.rake +0 -1
  163. data/lib/branston/vendor/plugins/state_machine/tasks/state_machine.rb +0 -30
  164. data/lib/branston/vendor/plugins/state_machine/test/classes/switch.rb +0 -11
  165. data/lib/branston/vendor/plugins/state_machine/test/functional/state_machine_test.rb +0 -941
  166. data/lib/branston/vendor/plugins/state_machine/test/test_helper.rb +0 -4
  167. data/lib/branston/vendor/plugins/state_machine/test/unit/assertions_test.rb +0 -40
  168. data/lib/branston/vendor/plugins/state_machine/test/unit/callback_test.rb +0 -455
  169. data/lib/branston/vendor/plugins/state_machine/test/unit/condition_proxy_test.rb +0 -328
  170. data/lib/branston/vendor/plugins/state_machine/test/unit/eval_helpers_test.rb +0 -120
  171. data/lib/branston/vendor/plugins/state_machine/test/unit/event_collection_test.rb +0 -326
  172. data/lib/branston/vendor/plugins/state_machine/test/unit/event_test.rb +0 -743
  173. data/lib/branston/vendor/plugins/state_machine/test/unit/guard_test.rb +0 -908
  174. data/lib/branston/vendor/plugins/state_machine/test/unit/integrations/active_record_test.rb +0 -1367
  175. data/lib/branston/vendor/plugins/state_machine/test/unit/integrations/data_mapper_test.rb +0 -962
  176. data/lib/branston/vendor/plugins/state_machine/test/unit/integrations/sequel_test.rb +0 -859
  177. data/lib/branston/vendor/plugins/state_machine/test/unit/integrations_test.rb +0 -42
  178. data/lib/branston/vendor/plugins/state_machine/test/unit/invalid_event_test.rb +0 -7
  179. data/lib/branston/vendor/plugins/state_machine/test/unit/invalid_transition_test.rb +0 -7
  180. data/lib/branston/vendor/plugins/state_machine/test/unit/machine_collection_test.rb +0 -938
  181. data/lib/branston/vendor/plugins/state_machine/test/unit/machine_test.rb +0 -2004
  182. data/lib/branston/vendor/plugins/state_machine/test/unit/matcher_helpers_test.rb +0 -37
  183. data/lib/branston/vendor/plugins/state_machine/test/unit/matcher_test.rb +0 -155
  184. data/lib/branston/vendor/plugins/state_machine/test/unit/node_collection_test.rb +0 -207
  185. data/lib/branston/vendor/plugins/state_machine/test/unit/state_collection_test.rb +0 -280
  186. data/lib/branston/vendor/plugins/state_machine/test/unit/state_machine_test.rb +0 -31
  187. data/lib/branston/vendor/plugins/state_machine/test/unit/state_test.rb +0 -795
  188. data/lib/branston/vendor/plugins/state_machine/test/unit/transition_test.rb +0 -1212
@@ -1,1367 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
-
3
- begin
4
- # Load library
5
- require 'rubygems'
6
-
7
- gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.0.0'
8
- require 'active_record'
9
-
10
- FIXTURES_ROOT = File.dirname(__FILE__) + '/../../fixtures/'
11
-
12
- # Load TestCase helpers
13
- require 'active_support/test_case'
14
- require 'active_record/fixtures'
15
-
16
- require 'active_record/version'
17
- if ActiveRecord::VERSION::STRING >= '2.1.0'
18
- require 'active_record/test_case'
19
- else
20
- class ActiveRecord::TestCase < ActiveSupport::TestCase
21
- self.fixture_path = FIXTURES_ROOT
22
- self.use_instantiated_fixtures = false
23
- self.use_transactional_fixtures = true
24
- end
25
- end
26
-
27
- # Establish database connection
28
- ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'})
29
- ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/../../active_record.log")
30
-
31
- # Add model/observer creation helpers
32
- ActiveRecord::TestCase.class_eval do
33
- # Creates a new ActiveRecord model (and the associated table)
34
- def new_model(create_table = true, &block)
35
- model = Class.new(ActiveRecord::Base) do
36
- connection.create_table(:foo, :force => true) {|t| t.string(:state)} if create_table
37
- set_table_name('foo')
38
-
39
- def self.name; 'ActiveRecordTest::Foo'; end
40
- end
41
- model.class_eval(&block) if block_given?
42
- model
43
- end
44
-
45
- # Creates a new ActiveRecord observer
46
- def new_observer(model, &block)
47
- observer = Class.new(ActiveRecord::Observer) do
48
- attr_accessor :notifications
49
-
50
- def initialize
51
- super
52
- @notifications = []
53
- end
54
- end
55
- observer.observe(model)
56
- observer.class_eval(&block) if block_given?
57
- observer
58
- end
59
- end
60
-
61
- module ActiveRecordTest
62
- class IntegrationTest < ActiveRecord::TestCase
63
- def test_should_match_if_class_inherits_from_active_record
64
- assert StateMachine::Integrations::ActiveRecord.matches?(new_model)
65
- end
66
-
67
- def test_should_not_match_if_class_does_not_inherit_from_active_record
68
- assert !StateMachine::Integrations::ActiveRecord.matches?(Class.new)
69
- end
70
- end
71
-
72
- class MachineByDefaultTest < ActiveRecord::TestCase
73
- def setup
74
- @model = new_model
75
- @machine = StateMachine::Machine.new(@model)
76
- end
77
-
78
- def test_should_use_save_as_action
79
- assert_equal :save, @machine.action
80
- end
81
-
82
- def test_should_use_transactions
83
- assert_equal true, @machine.use_transactions
84
- end
85
-
86
- def test_should_create_notifier_before_callback
87
- assert_equal 1, @machine.callbacks[:before].size
88
- end
89
-
90
- def test_should_create_notifier_after_callback
91
- assert_equal 1, @machine.callbacks[:after].size
92
- end
93
- end
94
-
95
- class MachineTest < ActiveRecord::TestCase
96
- def setup
97
- @model = new_model
98
- @machine = StateMachine::Machine.new(@model)
99
- @machine.state :parked, :first_gear
100
- @machine.state :idling, :value => lambda {'idling'}
101
- end
102
-
103
- def test_should_rollback_transaction_if_false
104
- @machine.within_transaction(@model.new) do
105
- @model.create
106
- false
107
- end
108
-
109
- assert_equal 0, @model.count
110
- end
111
-
112
- def test_should_not_rollback_transaction_if_true
113
- @machine.within_transaction(@model.new) do
114
- @model.create
115
- true
116
- end
117
-
118
- assert_equal 1, @model.count
119
- end
120
-
121
- def test_should_invalidate_using_errors
122
- I18n.backend = I18n::Backend::Simple.new if Object.const_defined?(:I18n)
123
-
124
- record = @model.new
125
- record.state = 'parked'
126
-
127
- @machine.invalidate(record, :state, :invalid_transition, [[:event, :park]])
128
-
129
- assert_equal ['State cannot transition via "park"'], record.errors.full_messages
130
- end
131
-
132
- def test_should_auto_prefix_custom_attributes_on_invalidation
133
- record = @model.new
134
- @machine.invalidate(record, :event, :invalid)
135
-
136
- assert_equal ['State event is invalid'], record.errors.full_messages
137
- end
138
-
139
- def test_should_clear_errors_on_reset
140
- record = @model.new
141
- record.state = 'parked'
142
- record.errors.add(:state, 'is invalid')
143
-
144
- @machine.reset(record)
145
- assert_equal [], record.errors.full_messages
146
- end
147
-
148
- def test_should_not_override_the_column_reader
149
- record = @model.new
150
- record[:state] = 'parked'
151
- assert_equal 'parked', record.state
152
- end
153
-
154
- def test_should_not_override_the_column_writer
155
- record = @model.new
156
- record.state = 'parked'
157
- assert_equal 'parked', record[:state]
158
- end
159
- end
160
-
161
- class MachineWithoutDatabaseTest < ActiveRecord::TestCase
162
- def setup
163
- @model = new_model(false) do
164
- # Simulate the database not being available entirely
165
- def self.connection
166
- raise ActiveRecord::ConnectionNotEstablished
167
- end
168
- end
169
- end
170
-
171
- def test_should_allow_machine_creation
172
- assert_nothing_raised { StateMachine::Machine.new(@model) }
173
- end
174
- end
175
-
176
- class MachineUnmigratedTest < ActiveRecord::TestCase
177
- def setup
178
- @model = new_model(false)
179
-
180
- # Drop the table so that it definitely doesn't exist
181
- @model.connection.drop_table(:foo) if @model.table_exists?
182
- end
183
-
184
- def test_should_allow_machine_creation
185
- assert_nothing_raised { StateMachine::Machine.new(@model) }
186
- end
187
- end
188
-
189
- class MachineWithStaticInitialStateTest < ActiveRecord::TestCase
190
- def setup
191
- @model = new_model do
192
- attr_accessor :value
193
- end
194
- @machine = StateMachine::Machine.new(@model, :initial => :parked)
195
- end
196
-
197
- def test_should_set_initial_state_on_created_object
198
- record = @model.new
199
- assert_equal 'parked', record.state
200
- end
201
-
202
- def test_should_set_initial_state_with_nil_attributes
203
- record = @model.new(nil)
204
- assert_equal 'parked', record.state
205
- end
206
-
207
- def test_should_still_set_attributes
208
- record = @model.new(:value => 1)
209
- assert_equal 1, record.value
210
- end
211
-
212
- def test_should_still_allow_initialize_blocks
213
- block_args = nil
214
- record = @model.new do |*args|
215
- block_args = args
216
- end
217
-
218
- assert_equal [record], block_args
219
- end
220
-
221
- def test_should_set_attributes_prior_to_after_initialize_hook
222
- state = nil
223
- @model.class_eval do
224
- define_method(:after_initialize) do
225
- state = self.state
226
- end
227
- end
228
- @model.new
229
- assert_equal 'parked', state
230
- end
231
-
232
- def test_should_set_initial_state_before_setting_attributes
233
- @model.class_eval do
234
- attr_accessor :state_during_setter
235
-
236
- define_method(:value=) do |value|
237
- self.state_during_setter = state
238
- end
239
- end
240
-
241
- record = @model.new(:value => 1)
242
- assert_equal 'parked', record.state_during_setter
243
- end
244
-
245
- def test_should_not_set_initial_state_after_already_initialized
246
- record = @model.new(:value => 1)
247
- assert_equal 'parked', record.state
248
-
249
- record.state = 'idling'
250
- record.attributes = {}
251
- assert_equal 'idling', record.state
252
- end
253
- end
254
-
255
- class MachineWithDynamicInitialStateTest < ActiveRecord::TestCase
256
- def setup
257
- @model = new_model do
258
- attr_accessor :value
259
- end
260
- @machine = StateMachine::Machine.new(@model, :initial => lambda {|object| :parked})
261
- @machine.state :parked
262
- end
263
-
264
- def test_should_set_initial_state_on_created_object
265
- record = @model.new
266
- assert_equal 'parked', record.state
267
- end
268
-
269
- def test_should_still_set_attributes
270
- record = @model.new(:value => 1)
271
- assert_equal 1, record.value
272
- end
273
-
274
- def test_should_still_allow_initialize_blocks
275
- block_args = nil
276
- record = @model.new do |*args|
277
- block_args = args
278
- end
279
-
280
- assert_equal [record], block_args
281
- end
282
-
283
- def test_should_set_attributes_prior_to_after_initialize_hook
284
- state = nil
285
- @model.class_eval do
286
- define_method(:after_initialize) do
287
- state = self.state
288
- end
289
- end
290
- @model.new
291
- assert_equal 'parked', state
292
- end
293
-
294
- def test_should_set_initial_state_after_setting_attributes
295
- @model.class_eval do
296
- attr_accessor :state_during_setter
297
-
298
- define_method(:value=) do |value|
299
- self.state_during_setter = state || 'nil'
300
- end
301
- end
302
-
303
- record = @model.new(:value => 1)
304
- assert_equal 'nil', record.state_during_setter
305
- end
306
-
307
- def test_should_not_set_initial_state_after_already_initialized
308
- record = @model.new(:value => 1)
309
- assert_equal 'parked', record.state
310
-
311
- record.state = 'idling'
312
- record.attributes = {}
313
- assert_equal 'idling', record.state
314
- end
315
- end
316
-
317
- class MachineWithColumnDefaultTest < ActiveRecord::TestCase
318
- def setup
319
- @model = new_model do
320
- connection.add_column :foo, :status, :string, :default => 'idling'
321
- end
322
- @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
323
- @record = @model.new
324
- end
325
-
326
- def test_should_use_machine_default
327
- assert_equal 'parked', @record.status
328
- end
329
- end
330
-
331
- class MachineWithConflictingPredicateTest < ActiveRecord::TestCase
332
- def setup
333
- @model = new_model do
334
- def state?(*args)
335
- true
336
- end
337
- end
338
-
339
- @machine = StateMachine::Machine.new(@model)
340
- @record = @model.new
341
- end
342
-
343
- def test_should_not_define_attribute_predicate
344
- assert @record.state?
345
- end
346
- end
347
-
348
- class MachineWithColumnStateAttributeTest < ActiveRecord::TestCase
349
- def setup
350
- @model = new_model
351
- @machine = StateMachine::Machine.new(@model, :initial => :parked)
352
- @machine.other_states(:idling)
353
-
354
- @record = @model.new
355
- end
356
-
357
- def test_should_have_an_attribute_predicate
358
- assert @record.respond_to?(:state?)
359
- end
360
-
361
- def test_should_test_for_existence_on_predicate_without_parameters
362
- assert @record.state?
363
-
364
- @record.state = nil
365
- assert !@record.state?
366
- end
367
-
368
- def test_should_return_false_for_predicate_if_does_not_match_current_value
369
- assert !@record.state?(:idling)
370
- end
371
-
372
- def test_should_return_true_for_predicate_if_matches_current_value
373
- assert @record.state?(:parked)
374
- end
375
-
376
- def test_should_raise_exception_for_predicate_if_invalid_state_specified
377
- assert_raise(IndexError) { @record.state?(:invalid) }
378
- end
379
- end
380
-
381
- class MachineWithNonColumnStateAttributeUndefinedTest < ActiveRecord::TestCase
382
- def setup
383
- @model = new_model do
384
- def initialize
385
- # Skip attribute initialization
386
- @initialized_state_machines = true
387
- super
388
- end
389
- end
390
-
391
- @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
392
- @machine.other_states(:idling)
393
- @record = @model.new
394
- end
395
-
396
- def test_should_not_define_a_reader_attribute_for_the_attribute
397
- assert !@record.respond_to?(:status)
398
- end
399
-
400
- def test_should_not_define_a_writer_attribute_for_the_attribute
401
- assert !@record.respond_to?(:status=)
402
- end
403
-
404
- def test_should_define_an_attribute_predicate
405
- assert @record.respond_to?(:status?)
406
- end
407
-
408
- def test_should_raise_exception_on_predicate_without_parameters
409
- old_verbose, $VERBOSE = $VERBOSE, nil
410
- assert_raise(NoMethodError) { @record.status? }
411
- ensure
412
- $VERBOSE = old_verbose
413
- end
414
- end
415
-
416
- class MachineWithNonColumnStateAttributeDefinedTest < ActiveRecord::TestCase
417
- def setup
418
- @model = new_model do
419
- attr_accessor :status
420
- end
421
-
422
- @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
423
- @machine.other_states(:idling)
424
- @record = @model.new
425
- end
426
-
427
- def test_should_return_false_for_predicate_if_does_not_match_current_value
428
- assert !@record.status?(:idling)
429
- end
430
-
431
- def test_should_return_true_for_predicate_if_matches_current_value
432
- assert @record.status?(:parked)
433
- end
434
-
435
- def test_should_raise_exception_for_predicate_if_invalid_state_specified
436
- assert_raise(IndexError) { @record.status?(:invalid) }
437
- end
438
-
439
- def test_should_set_initial_state_on_created_object
440
- assert_equal 'parked', @record.status
441
- end
442
- end
443
-
444
- class MachineWithCustomAttributeTest < ActiveRecord::TestCase
445
- def setup
446
- @model = new_model do
447
- alias_attribute :vehicle_status, :state
448
- end
449
-
450
- @machine = StateMachine::Machine.new(@model, :status, :attribute => :vehicle_status)
451
- @machine.state :parked
452
-
453
- @record = @model.new
454
- end
455
-
456
- def test_should_add_validation_errors_to_custom_attribute
457
- @record.vehicle_status = 'invalid'
458
-
459
- assert !@record.valid?
460
- assert_equal ['Vehicle status is invalid'], @record.errors.full_messages
461
-
462
- @record.vehicle_status = 'parked'
463
- assert @record.valid?
464
- end
465
-
466
- def test_should_check_custom_attribute_for_predicate
467
- @record.vehicle_status = nil
468
- assert !@record.status?(:parked)
469
-
470
- @record.vehicle_status = 'parked'
471
- assert @record.status?(:parked)
472
- end
473
- end
474
-
475
- class MachineWithInitializedStateTest < ActiveRecord::TestCase
476
- def setup
477
- @model = new_model
478
- @machine = StateMachine::Machine.new(@model, :initial => :parked)
479
- @machine.state nil, :idling
480
- end
481
-
482
- def test_should_allow_nil_initial_state_when_static
483
- record = @model.new(:state => nil)
484
- assert_nil record.state
485
- end
486
-
487
- def test_should_allow_nil_initial_state_when_dynamic
488
- @machine.initial_state = lambda {:parked}
489
- record = @model.new(:state => nil)
490
- assert_nil record.state
491
- end
492
-
493
- def test_should_allow_different_initial_state_when_static
494
- record = @model.new(:state => 'idling')
495
- assert_equal 'idling', record.state
496
- end
497
-
498
- def test_should_allow_different_initial_state_when_dynamic
499
- @machine.initial_state = lambda {:parked}
500
- record = @model.new(:state => 'idling')
501
- assert_equal 'idling', record.state
502
- end
503
-
504
- def test_should_use_default_state_if_protected
505
- @model.class_eval do
506
- attr_protected :state
507
- end
508
-
509
- record = @model.new(:state => 'idling')
510
- assert_equal 'parked', record.state
511
- end
512
- end
513
-
514
- class MachineWithCallbacksTest < ActiveRecord::TestCase
515
- def setup
516
- @model = new_model
517
- @machine = StateMachine::Machine.new(@model, :initial => :parked)
518
- @machine.other_states :idling
519
- @machine.event :ignite
520
-
521
- @record = @model.new(:state => 'parked')
522
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
523
- end
524
-
525
- def test_should_run_before_callbacks
526
- called = false
527
- @machine.before_transition(lambda {called = true})
528
-
529
- @transition.perform
530
- assert called
531
- end
532
-
533
- def test_should_pass_record_to_before_callbacks_with_one_argument
534
- record = nil
535
- @machine.before_transition(lambda {|arg| record = arg})
536
-
537
- @transition.perform
538
- assert_equal @record, record
539
- end
540
-
541
- def test_should_pass_record_and_transition_to_before_callbacks_with_multiple_arguments
542
- callback_args = nil
543
- @machine.before_transition(lambda {|*args| callback_args = args})
544
-
545
- @transition.perform
546
- assert_equal [@record, @transition], callback_args
547
- end
548
-
549
- def test_should_run_before_callbacks_outside_the_context_of_the_record
550
- context = nil
551
- @machine.before_transition(lambda {context = self})
552
-
553
- @transition.perform
554
- assert_equal self, context
555
- end
556
-
557
- def test_should_run_after_callbacks
558
- called = false
559
- @machine.after_transition(lambda {called = true})
560
-
561
- @transition.perform
562
- assert called
563
- end
564
-
565
- def test_should_pass_record_to_after_callbacks_with_one_argument
566
- record = nil
567
- @machine.after_transition(lambda {|arg| record = arg})
568
-
569
- @transition.perform
570
- assert_equal @record, record
571
- end
572
-
573
- def test_should_pass_record_and_transition_to_after_callbacks_with_multiple_arguments
574
- callback_args = nil
575
- @machine.after_transition(lambda {|*args| callback_args = args})
576
-
577
- @transition.perform
578
- assert_equal [@record, @transition], callback_args
579
- end
580
-
581
- def test_should_run_after_callbacks_outside_the_context_of_the_record
582
- context = nil
583
- @machine.after_transition(lambda {context = self})
584
-
585
- @transition.perform
586
- assert_equal self, context
587
- end
588
-
589
- def test_should_include_transition_states_in_known_states
590
- @machine.before_transition :to => :first_gear, :do => lambda {}
591
-
592
- assert_equal [:parked, :idling, :first_gear], @machine.states.map {|state| state.name}
593
- end
594
-
595
- def test_should_allow_symbolic_callbacks
596
- callback_args = nil
597
-
598
- klass = class << @record; self; end
599
- klass.send(:define_method, :after_ignite) do |*args|
600
- callback_args = args
601
- end
602
-
603
- @machine.before_transition(:after_ignite)
604
-
605
- @transition.perform
606
- assert_equal [@transition], callback_args
607
- end
608
-
609
- def test_should_allow_string_callbacks
610
- class << @record
611
- attr_reader :callback_result
612
- end
613
-
614
- @machine.before_transition('@callback_result = [1, 2, 3]')
615
- @transition.perform
616
-
617
- assert_equal [1, 2, 3], @record.callback_result
618
- end
619
- end
620
-
621
- class MachineWithFailedBeforeCallbacksTest < ActiveRecord::TestCase
622
- def setup
623
- @before_count = 0
624
- @after_count = 0
625
-
626
- @model = new_model
627
- @machine = StateMachine::Machine.new(@model)
628
- @machine.state :parked, :idling
629
- @machine.event :ignite
630
- @machine.before_transition(lambda {@before_count += 1; false})
631
- @machine.before_transition(lambda {@before_count += 1})
632
- @machine.after_transition(lambda {@after_count += 1})
633
-
634
- @record = @model.new(:state => 'parked')
635
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
636
- @result = @transition.perform
637
- end
638
-
639
- def test_should_not_be_successful
640
- assert !@result
641
- end
642
-
643
- def test_should_not_change_current_state
644
- assert_equal 'parked', @record.state
645
- end
646
-
647
- def test_should_not_run_action
648
- assert @record.new_record?
649
- end
650
-
651
- def test_should_not_run_further_before_callbacks
652
- assert_equal 1, @before_count
653
- end
654
-
655
- def test_should_not_run_after_callbacks
656
- assert_equal 0, @after_count
657
- end
658
- end
659
-
660
- class MachineWithFailedActionTest < ActiveRecord::TestCase
661
- def setup
662
- @model = new_model do
663
- validates_inclusion_of :state, :in => %w(first_gear)
664
- end
665
-
666
- @machine = StateMachine::Machine.new(@model)
667
- @machine.state :parked, :idling
668
- @machine.event :ignite
669
-
670
- @before_transition_called = false
671
- @after_transition_called = false
672
- @after_transition_with_failures_called = false
673
- @machine.before_transition(lambda {@before_transition_called = true})
674
- @machine.after_transition(lambda {@after_transition_called = true})
675
- @machine.after_transition(lambda {@after_transition_with_failures_called = true}, :include_failures => true)
676
-
677
- @record = @model.new(:state => 'parked')
678
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
679
- @result = @transition.perform
680
- end
681
-
682
- def test_should_not_be_successful
683
- assert !@result
684
- end
685
-
686
- def test_should_not_change_current_state
687
- assert_equal 'parked', @record.state
688
- end
689
-
690
- def test_should_not_save_record
691
- assert @record.new_record?
692
- end
693
-
694
- def test_should_run_before_callback
695
- assert @before_transition_called
696
- end
697
-
698
- def test_should_not_run_after_callback_if_not_including_failures
699
- assert !@after_transition_called
700
- end
701
-
702
- def test_should_run_after_callback_if_including_failures
703
- assert @after_transition_with_failures_called
704
- end
705
- end
706
-
707
- class MachineWithValidationsTest < ActiveRecord::TestCase
708
- def setup
709
- @model = new_model
710
- @machine = StateMachine::Machine.new(@model)
711
- @machine.state :parked
712
-
713
- @record = @model.new
714
- end
715
-
716
- def test_should_be_valid_if_state_is_known
717
- @record.state = 'parked'
718
-
719
- assert @record.valid?
720
- end
721
-
722
- def test_should_not_be_valid_if_state_is_unknown
723
- @record.state = 'invalid'
724
-
725
- assert !@record.valid?
726
- assert_equal ['State is invalid'], @record.errors.full_messages
727
- end
728
- end
729
-
730
- class MachineWithStateDrivenValidationsTest < ActiveRecord::TestCase
731
- def setup
732
- @model = new_model do
733
- attr_accessor :seatbelt
734
- end
735
-
736
- @machine = StateMachine::Machine.new(@model)
737
- @machine.state :first_gear, :second_gear do
738
- validates_presence_of :seatbelt
739
- end
740
- @machine.other_states :parked
741
- end
742
-
743
- def test_should_be_valid_if_validation_fails_outside_state_scope
744
- record = @model.new(:state => 'parked', :seatbelt => nil)
745
- assert record.valid?
746
- end
747
-
748
- def test_should_be_invalid_if_validation_fails_within_state_scope
749
- record = @model.new(:state => 'first_gear', :seatbelt => nil)
750
- assert !record.valid?
751
- end
752
-
753
- def test_should_be_valid_if_validation_succeeds_within_state_scope
754
- record = @model.new(:state => 'second_gear', :seatbelt => true)
755
- assert record.valid?
756
- end
757
- end
758
-
759
- class MachineWithFailedAfterCallbacksTest < ActiveRecord::TestCase
760
- def setup
761
- @after_count = 0
762
-
763
- @model = new_model
764
- @machine = StateMachine::Machine.new(@model)
765
- @machine.state :parked, :idling
766
- @machine.event :ignite
767
- @machine.after_transition(lambda {@after_count += 1; false})
768
- @machine.after_transition(lambda {@after_count += 1})
769
-
770
- @record = @model.new(:state => 'parked')
771
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
772
- @result = @transition.perform
773
- end
774
-
775
- def test_should_be_successful
776
- assert @result
777
- end
778
-
779
- def test_should_change_current_state
780
- assert_equal 'idling', @record.state
781
- end
782
-
783
- def test_should_save_record
784
- assert !@record.new_record?
785
- end
786
-
787
- def test_should_not_run_further_after_callbacks
788
- assert_equal 1, @after_count
789
- end
790
- end
791
-
792
- class MachineWithEventAttributesOnValidationTest < ActiveRecord::TestCase
793
- def setup
794
- @model = new_model
795
- @machine = StateMachine::Machine.new(@model)
796
- @machine.event :ignite do
797
- transition :parked => :idling
798
- end
799
-
800
- @record = @model.new
801
- @record.state = 'parked'
802
- @record.state_event = 'ignite'
803
- end
804
-
805
- def test_should_fail_if_event_is_invalid
806
- @record.state_event = 'invalid'
807
- assert !@record.valid?
808
- assert_equal ['State event is invalid'], @record.errors.full_messages
809
- end
810
-
811
- def test_should_fail_if_event_has_no_transition
812
- @record.state = 'idling'
813
- assert !@record.valid?
814
- assert_equal ['State event cannot transition when idling'], @record.errors.full_messages
815
- end
816
-
817
- def test_should_be_successful_if_event_has_transition
818
- assert @record.valid?
819
- end
820
-
821
- def test_should_run_before_callbacks
822
- ran_callback = false
823
- @machine.before_transition { ran_callback = true }
824
-
825
- @record.valid?
826
- assert ran_callback
827
- end
828
-
829
- def test_should_persist_new_state
830
- @record.valid?
831
- assert_equal 'idling', @record.state
832
- end
833
-
834
- def test_should_not_run_after_callbacks
835
- ran_callback = false
836
- @machine.after_transition { ran_callback = true }
837
-
838
- @record.valid?
839
- assert !ran_callback
840
- end
841
-
842
- def test_should_not_run_after_callbacks_with_failures_disabled_if_validation_fails
843
- @model.class_eval do
844
- attr_accessor :seatbelt
845
- validates_presence_of :seatbelt
846
- end
847
-
848
- ran_callback = false
849
- @machine.after_transition { ran_callback = true }
850
-
851
- @record.valid?
852
- assert !ran_callback
853
- end
854
-
855
- def test_should_run_after_callbacks_with_failures_enabled_if_validation_fails
856
- @model.class_eval do
857
- attr_accessor :seatbelt
858
- validates_presence_of :seatbelt
859
- end
860
-
861
- ran_callback = false
862
- @machine.after_transition(:include_failures => true) { ran_callback = true }
863
-
864
- @record.valid?
865
- assert ran_callback
866
- end
867
- end
868
-
869
- class MachineWithEventAttributesOnSaveBangTest < ActiveRecord::TestCase
870
- def setup
871
- @model = new_model
872
- @machine = StateMachine::Machine.new(@model)
873
- @machine.event :ignite do
874
- transition :parked => :idling
875
- end
876
-
877
- @record = @model.new
878
- @record.state = 'parked'
879
- @record.state_event = 'ignite'
880
- end
881
-
882
- def test_should_fail_if_event_is_invalid
883
- @record.state_event = 'invalid'
884
- assert_raise(ActiveRecord::RecordInvalid) { @record.save! }
885
- end
886
-
887
- def test_should_fail_if_event_has_no_transition
888
- @record.state = 'idling'
889
- assert_raise(ActiveRecord::RecordInvalid) { @record.save! }
890
- end
891
-
892
- def test_should_be_successful_if_event_has_transition
893
- assert_equal true, @record.save!
894
- end
895
-
896
- def test_should_run_before_callbacks
897
- ran_callback = false
898
- @machine.before_transition { ran_callback = true }
899
-
900
- @record.save!
901
- assert ran_callback
902
- end
903
-
904
- def test_should_run_before_callbacks_once
905
- before_count = 0
906
- @machine.before_transition { before_count += 1 }
907
-
908
- @record.save!
909
- assert_equal 1, before_count
910
- end
911
-
912
- def test_should_persist_new_state
913
- @record.save!
914
- assert_equal 'idling', @record.state
915
- end
916
-
917
- def test_should_run_after_callbacks
918
- ran_callback = false
919
- @machine.after_transition { ran_callback = true }
920
-
921
- @record.save!
922
- assert ran_callback
923
- end
924
-
925
- def test_should_not_run_after_callbacks_with_failures_disabled_if_fails
926
- @model.before_create {|record| false}
927
-
928
- ran_callback = false
929
- @machine.after_transition { ran_callback = true }
930
-
931
- begin; @record.save!; rescue; end
932
- assert !ran_callback
933
- end
934
-
935
- def test_should_run_after_callbacks_with_failures_enabled_if_fails
936
- @model.before_create {|record| false}
937
-
938
- ran_callback = false
939
- @machine.after_transition(:include_failures => true) { ran_callback = true }
940
-
941
- begin; @record.save!; rescue; end
942
- assert ran_callback
943
- end
944
- end
945
-
946
- class MachineWithEventAttributesOnCustomActionTest < ActiveRecord::TestCase
947
- def setup
948
- @superclass = new_model do
949
- def persist
950
- create_or_update
951
- end
952
- end
953
- @model = Class.new(@superclass)
954
- @machine = StateMachine::Machine.new(@model, :action => :persist)
955
- @machine.event :ignite do
956
- transition :parked => :idling
957
- end
958
-
959
- @record = @model.new
960
- @record.state = 'parked'
961
- @record.state_event = 'ignite'
962
- end
963
-
964
- def test_should_not_transition_on_valid?
965
- @record.valid?
966
- assert_equal 'parked', @record.state
967
- end
968
-
969
- def test_should_not_transition_on_save
970
- @record.save
971
- assert_equal 'parked', @record.state
972
- end
973
-
974
- def test_should_not_transition_on_save!
975
- @record.save!
976
- assert_equal 'parked', @record.state
977
- end
978
-
979
- def test_should_transition_on_custom_action
980
- @record.persist
981
- assert_equal 'idling', @record.state
982
- end
983
- end
984
-
985
- class MachineWithObserversTest < ActiveRecord::TestCase
986
- def setup
987
- @model = new_model
988
- @machine = StateMachine::Machine.new(@model)
989
- @machine.state :parked, :idling
990
- @machine.event :ignite
991
- @record = @model.new(:state => 'parked')
992
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
993
- end
994
-
995
- def test_should_call_all_transition_callback_permutations
996
- callbacks = [
997
- :before_ignite_from_parked_to_idling,
998
- :before_ignite_from_parked,
999
- :before_ignite_to_idling,
1000
- :before_ignite,
1001
- :before_transition_state_from_parked_to_idling,
1002
- :before_transition_state_from_parked,
1003
- :before_transition_state_to_idling,
1004
- :before_transition_state,
1005
- :before_transition
1006
- ]
1007
-
1008
- notified = false
1009
- observer = new_observer(@model) do
1010
- callbacks.each do |callback|
1011
- define_method(callback) do |*args|
1012
- notifications << callback
1013
- end
1014
- end
1015
- end
1016
-
1017
- instance = observer.instance
1018
-
1019
- @transition.perform
1020
- assert_equal callbacks, instance.notifications
1021
- end
1022
-
1023
- def test_should_pass_record_and_transition_to_before_callbacks
1024
- observer = new_observer(@model) do
1025
- def before_transition(*args)
1026
- notifications << args
1027
- end
1028
- end
1029
- instance = observer.instance
1030
-
1031
- @transition.perform
1032
- assert_equal [[@record, @transition]], instance.notifications
1033
- end
1034
-
1035
- def test_should_pass_record_and_transition_to_after_callbacks
1036
- observer = new_observer(@model) do
1037
- def after_transition(*args)
1038
- notifications << args
1039
- end
1040
- end
1041
- instance = observer.instance
1042
-
1043
- @transition.perform
1044
- assert_equal [[@record, @transition]], instance.notifications
1045
- end
1046
-
1047
- def test_should_call_methods_outside_the_context_of_the_record
1048
- observer = new_observer(@model) do
1049
- def before_ignite(*args)
1050
- notifications << self
1051
- end
1052
- end
1053
- instance = observer.instance
1054
-
1055
- @transition.perform
1056
- assert_equal [instance], instance.notifications
1057
- end
1058
- end
1059
-
1060
- class MachineWithNamespacedObserversTest < ActiveRecord::TestCase
1061
- def setup
1062
- @model = new_model
1063
- @machine = StateMachine::Machine.new(@model, :state, :namespace => 'alarm')
1064
- @machine.state :active, :off
1065
- @machine.event :enable
1066
- @record = @model.new(:state => 'off')
1067
- @transition = StateMachine::Transition.new(@record, @machine, :enable, :off, :active)
1068
- end
1069
-
1070
- def test_should_call_namespaced_before_event_method
1071
- observer = new_observer(@model) do
1072
- def before_enable_alarm(*args)
1073
- notifications << args
1074
- end
1075
- end
1076
- instance = observer.instance
1077
-
1078
- @transition.perform
1079
- assert_equal [[@record, @transition]], instance.notifications
1080
- end
1081
-
1082
- def test_should_call_namespaced_after_event_method
1083
- observer = new_observer(@model) do
1084
- def after_enable_alarm(*args)
1085
- notifications << args
1086
- end
1087
- end
1088
- instance = observer.instance
1089
-
1090
- @transition.perform
1091
- assert_equal [[@record, @transition]], instance.notifications
1092
- end
1093
- end
1094
-
1095
- class MachineWithMixedCallbacksTest < ActiveRecord::TestCase
1096
- def setup
1097
- @model = new_model
1098
- @machine = StateMachine::Machine.new(@model)
1099
- @machine.state :parked, :idling
1100
- @machine.event :ignite
1101
- @record = @model.new(:state => 'parked')
1102
- @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
1103
-
1104
- @notifications = []
1105
-
1106
- # Create callbacks
1107
- @machine.before_transition(lambda {@notifications << :callback_before_transition})
1108
- @machine.after_transition(lambda {@notifications << :callback_after_transition})
1109
-
1110
- # Create observer callbacks
1111
- observer = new_observer(@model) do
1112
- def before_ignite(*args)
1113
- notifications << :observer_before_ignite
1114
- end
1115
-
1116
- def before_transition(*args)
1117
- notifications << :observer_before_transition
1118
- end
1119
-
1120
- def after_ignite(*args)
1121
- notifications << :observer_after_ignite
1122
- end
1123
-
1124
- def after_transition(*args)
1125
- notifications << :observer_after_transition
1126
- end
1127
- end
1128
- instance = observer.instance
1129
- instance.notifications = @notifications
1130
-
1131
- @transition.perform
1132
- end
1133
-
1134
- def test_should_invoke_callbacks_in_specific_order
1135
- expected = [
1136
- :callback_before_transition,
1137
- :observer_before_ignite,
1138
- :observer_before_transition,
1139
- :callback_after_transition,
1140
- :observer_after_ignite,
1141
- :observer_after_transition
1142
- ]
1143
-
1144
- assert_equal expected, @notifications
1145
- end
1146
- end
1147
-
1148
- if ActiveRecord.const_defined?(:Dirty) || ActiveRecord::AttributeMethods.const_defined?(:Dirty)
1149
- class MachineWithLoopbackTest < ActiveRecord::TestCase
1150
- def setup
1151
- changed_attrs = nil
1152
-
1153
- @model = new_model do
1154
- connection.add_column :foo, :updated_at, :datetime
1155
-
1156
- define_method(:before_update) do
1157
- changed_attrs = changed_attributes.dup
1158
- end
1159
- end
1160
-
1161
- @machine = StateMachine::Machine.new(@model, :initial => :parked)
1162
- @machine.event :park
1163
-
1164
- @record = @model.create(:updated_at => Time.now - 1)
1165
- @timestamp = @record.updated_at
1166
-
1167
- @transition = StateMachine::Transition.new(@record, @machine, :park, :parked, :parked)
1168
- @transition.perform
1169
-
1170
- @changed_attrs = changed_attrs
1171
- end
1172
-
1173
- def test_should_include_state_in_changed_attributes
1174
- @changed_attrs.delete('updated_at')
1175
-
1176
- expected = {'state' => 'parked'}
1177
- assert_equal expected, @changed_attrs
1178
- end
1179
-
1180
- def test_should_update_record
1181
- assert_not_equal @timestamp, @record.updated_at
1182
- end
1183
- end
1184
- end
1185
-
1186
- if ActiveRecord.const_defined?(:NamedScope)
1187
- class MachineWithScopesTest < ActiveRecord::TestCase
1188
- def setup
1189
- @model = new_model
1190
- @machine = StateMachine::Machine.new(@model)
1191
- @machine.state :parked, :first_gear
1192
- @machine.state :idling, :value => lambda {'idling'}
1193
- end
1194
-
1195
- def test_should_create_singular_with_scope
1196
- assert @model.respond_to?(:with_state)
1197
- end
1198
-
1199
- def test_should_only_include_records_with_state_in_singular_with_scope
1200
- parked = @model.create :state => 'parked'
1201
- idling = @model.create :state => 'idling'
1202
-
1203
- assert_equal [parked], @model.with_state(:parked)
1204
- end
1205
-
1206
- def test_should_create_plural_with_scope
1207
- assert @model.respond_to?(:with_states)
1208
- end
1209
-
1210
- def test_should_only_include_records_with_states_in_plural_with_scope
1211
- parked = @model.create :state => 'parked'
1212
- idling = @model.create :state => 'idling'
1213
-
1214
- assert_equal [parked, idling], @model.with_states(:parked, :idling)
1215
- end
1216
-
1217
- def test_should_create_singular_without_scope
1218
- assert @model.respond_to?(:without_state)
1219
- end
1220
-
1221
- def test_should_only_include_records_without_state_in_singular_without_scope
1222
- parked = @model.create :state => 'parked'
1223
- idling = @model.create :state => 'idling'
1224
-
1225
- assert_equal [parked], @model.without_state(:idling)
1226
- end
1227
-
1228
- def test_should_create_plural_without_scope
1229
- assert @model.respond_to?(:without_states)
1230
- end
1231
-
1232
- def test_should_only_include_records_without_states_in_plural_without_scope
1233
- parked = @model.create :state => 'parked'
1234
- idling = @model.create :state => 'idling'
1235
- first_gear = @model.create :state => 'first_gear'
1236
-
1237
- assert_equal [parked, idling], @model.without_states(:first_gear)
1238
- end
1239
-
1240
- def test_should_allow_chaining_scopes
1241
- parked = @model.create :state => 'parked'
1242
- idling = @model.create :state => 'idling'
1243
-
1244
- assert_equal [idling], @model.without_state(:parked).with_state(:idling)
1245
- end
1246
- end
1247
-
1248
- class MachineWithScopesAndOwnerSubclassTest < ActiveRecord::TestCase
1249
- def setup
1250
- @model = new_model
1251
- @machine = StateMachine::Machine.new(@model, :state)
1252
-
1253
- @subclass = Class.new(@model)
1254
- @subclass_machine = @subclass.state_machine(:state) {}
1255
- @subclass_machine.state :parked, :idling, :first_gear
1256
- end
1257
-
1258
- def test_should_only_include_records_with_subclass_states_in_with_scope
1259
- parked = @subclass.create :state => 'parked'
1260
- idling = @subclass.create :state => 'idling'
1261
-
1262
- assert_equal [parked, idling], @subclass.with_states(:parked, :idling)
1263
- end
1264
-
1265
- def test_should_only_include_records_without_subclass_states_in_without_scope
1266
- parked = @subclass.create :state => 'parked'
1267
- idling = @subclass.create :state => 'idling'
1268
- first_gear = @subclass.create :state => 'first_gear'
1269
-
1270
- assert_equal [parked, idling], @subclass.without_states(:first_gear)
1271
- end
1272
- end
1273
-
1274
- class MachineWithComplexPluralizationScopesTest < ActiveRecord::TestCase
1275
- def setup
1276
- @model = new_model
1277
- @machine = StateMachine::Machine.new(@model, :status)
1278
- end
1279
-
1280
- def test_should_create_singular_with_scope
1281
- assert @model.respond_to?(:with_status)
1282
- end
1283
-
1284
- def test_should_create_plural_with_scope
1285
- assert @model.respond_to?(:with_statuses)
1286
- end
1287
- end
1288
- end
1289
-
1290
- if Object.const_defined?(:I18n)
1291
- class MachineWithInternationalizationTest < ActiveRecord::TestCase
1292
- def setup
1293
- I18n.backend = I18n::Backend::Simple.new
1294
-
1295
- # Initialize the backend
1296
- I18n.backend.translate(:en, 'activerecord.errors.messages.invalid_transition', :event => 'ignite', :value => 'idling')
1297
-
1298
- @model = new_model
1299
- end
1300
-
1301
- def test_should_invalidate_using_i18n_default
1302
- I18n.backend.store_translations(:en, {
1303
- :activerecord => {
1304
- :errors => {
1305
- :messages => {
1306
- :invalid_transition => 'cannot {{event}}'
1307
- }
1308
- }
1309
- }
1310
- })
1311
-
1312
- machine = StateMachine::Machine.new(@model)
1313
- machine.state :parked, :idling
1314
- event = StateMachine::Event.new(machine, :ignite)
1315
-
1316
- record = @model.new(:state => 'idling')
1317
-
1318
- machine.invalidate(record, :state, :invalid_transition, [[:event, :ignite]])
1319
- assert_equal ['State cannot ignite'], record.errors.full_messages
1320
- end
1321
-
1322
- def test_should_invalidate_using_customized_i18n_key_if_specified
1323
- I18n.backend.store_translations(:en, {
1324
- :activerecord => {
1325
- :errors => {
1326
- :messages => {
1327
- :bad_transition => 'cannot {{event}}'
1328
- }
1329
- }
1330
- }
1331
- })
1332
-
1333
- machine = StateMachine::Machine.new(@model, :messages => {:invalid_transition => :bad_transition})
1334
- machine.state :parked, :idling
1335
-
1336
- record = @model.new(:state => 'idling')
1337
-
1338
- machine.invalidate(record, :state, :invalid_transition, [[:event, :ignite]])
1339
- assert_equal ['State cannot ignite'], record.errors.full_messages
1340
- end
1341
-
1342
- def test_should_invalidate_using_customized_i18n_string_if_specified
1343
- machine = StateMachine::Machine.new(@model, :messages => {:invalid_transition => 'cannot {{event}}'})
1344
- machine.state :parked, :idling
1345
-
1346
- record = @model.new(:state => 'idling')
1347
-
1348
- machine.invalidate(record, :state, :invalid_transition, [[:event, :ignite]])
1349
- assert_equal ['State cannot ignite'], record.errors.full_messages
1350
- end
1351
-
1352
- def test_should_only_add_locale_once_in_load_path
1353
- assert_equal 1, I18n.load_path.select {|path| path =~ %r{state_machine/integrations/active_record/locale\.rb$}}.length
1354
-
1355
- # Create another ActiveRecord model that will triger the i18n feature
1356
- new_model
1357
-
1358
- assert_equal 1, I18n.load_path.select {|path| path =~ %r{state_machine/integrations/active_record/locale\.rb$}}.length
1359
- end
1360
- end
1361
- else
1362
- $stderr.puts 'Skipping ActiveRecord I18n tests. `gem install active_record` >= v2.2.0 and try again.'
1363
- end
1364
- end
1365
- rescue LoadError
1366
- $stderr.puts "Skipping ActiveRecord tests. `gem install activerecord#{" -v #{ENV['AR_VERSION']}" if ENV['AR_VERSION']}` and try again."
1367
- end