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,2004 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
-
3
- class MachineByDefaultTest < Test::Unit::TestCase
4
- def setup
5
- @klass = Class.new
6
- @machine = StateMachine::Machine.new(@klass)
7
- @object = @klass.new
8
- end
9
-
10
- def test_should_have_an_owner_class
11
- assert_equal @klass, @machine.owner_class
12
- end
13
-
14
- def test_should_have_a_name
15
- assert_equal :state, @machine.name
16
- end
17
-
18
- def test_should_have_an_attribute
19
- assert_equal :state, @machine.attribute
20
- end
21
-
22
- def test_should_prefix_custom_attributes_with_attribute
23
- assert_equal :state_event, @machine.attribute(:event)
24
- end
25
-
26
- def test_should_have_an_initial_state
27
- assert_not_nil @machine.initial_state(@object)
28
- end
29
-
30
- def test_should_have_a_nil_initial_state
31
- assert_nil @machine.initial_state(@object).value
32
- end
33
-
34
- def test_should_not_have_any_events
35
- assert !@machine.events.any?
36
- end
37
-
38
- def test_should_not_have_any_before_callbacks
39
- assert @machine.callbacks[:before].empty?
40
- end
41
-
42
- def test_should_not_have_any_after_callbacks
43
- assert @machine.callbacks[:after].empty?
44
- end
45
-
46
- def test_should_not_have_an_action
47
- assert_nil @machine.action
48
- end
49
-
50
- def test_should_use_tranactions
51
- assert_equal true, @machine.use_transactions
52
- end
53
-
54
- def test_should_not_have_a_namespace
55
- assert_nil @machine.namespace
56
- end
57
-
58
- def test_should_have_a_nil_state
59
- assert_equal [nil], @machine.states.keys
60
- end
61
-
62
- def test_should_set_initial_on_nil_state
63
- assert @machine.state(nil).initial
64
- end
65
-
66
- def test_should_generate_default_messages
67
- assert_equal 'is invalid', @machine.generate_message(:invalid)
68
- assert_equal 'cannot transition when parked', @machine.generate_message(:invalid_event, [[:state, :parked]])
69
- assert_equal 'cannot transition via "park"', @machine.generate_message(:invalid_transition, [[:event, :park]])
70
- end
71
-
72
- def test_should_not_be_extended_by_the_active_record_integration
73
- assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::ActiveRecord)
74
- end
75
-
76
- def test_should_not_be_extended_by_the_datamapper_integration
77
- assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::DataMapper)
78
- end
79
-
80
- def test_should_not_be_extended_by_the_sequel_integration
81
- assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::Sequel)
82
- end
83
-
84
- def test_should_define_a_reader_attribute_for_the_attribute
85
- assert @object.respond_to?(:state)
86
- end
87
-
88
- def test_should_define_a_writer_attribute_for_the_attribute
89
- assert @object.respond_to?(:state=)
90
- end
91
-
92
- def test_should_define_a_predicate_for_the_attribute
93
- assert @object.respond_to?(:state?)
94
- end
95
-
96
- def test_should_define_a_name_reader_for_the_attribute
97
- assert @object.respond_to?(:state_name)
98
- end
99
-
100
- def test_should_define_an_event_reader_for_the_attribute
101
- assert @object.respond_to?(:state_events)
102
- end
103
-
104
- def test_should_define_a_transition_reader_for_the_attribute
105
- assert @object.respond_to?(:state_transitions)
106
- end
107
-
108
- def test_should_not_define_an_event_attribute_reader
109
- assert !@object.respond_to?(:state_event)
110
- end
111
-
112
- def test_should_not_define_an_event_attribute_writer
113
- assert !@object.respond_to?(:state_event=)
114
- end
115
-
116
- def test_should_not_define_an_event_transition_attribute_reader
117
- assert !@object.respond_to?(:state_event_transition)
118
- end
119
-
120
- def test_should_not_define_an_event_transition_attribute_writer
121
- assert !@object.respond_to?(:state_event_transition=)
122
- end
123
-
124
- def test_should_not_define_singular_with_scope
125
- assert !@klass.respond_to?(:with_state)
126
- end
127
-
128
- def test_should_not_define_singular_without_scope
129
- assert !@klass.respond_to?(:without_state)
130
- end
131
-
132
- def test_should_not_define_plural_with_scope
133
- assert !@klass.respond_to?(:with_states)
134
- end
135
-
136
- def test_should_not_define_plural_without_scope
137
- assert !@klass.respond_to?(:without_states)
138
- end
139
-
140
- def test_should_extend_owner_class_with_class_methods
141
- assert (class << @klass; ancestors; end).include?(StateMachine::ClassMethods)
142
- end
143
-
144
- def test_should_include_instance_methods_in_owner_class
145
- assert @klass.included_modules.include?(StateMachine::InstanceMethods)
146
- end
147
-
148
- def test_should_define_state_machines_reader
149
- expected = {:state => @machine}
150
- assert_equal expected, @klass.state_machines
151
- end
152
- end
153
-
154
- class MachineWithCustomNameTest < Test::Unit::TestCase
155
- def setup
156
- @klass = Class.new
157
- @machine = StateMachine::Machine.new(@klass, :status)
158
- @object = @klass.new
159
- end
160
-
161
- def test_should_use_custom_name
162
- assert_equal :status, @machine.name
163
- end
164
-
165
- def test_should_use_custom_name_for_attribute
166
- assert_equal :status, @machine.attribute
167
- end
168
-
169
- def test_should_prefix_custom_attributes_with_custom_name
170
- assert_equal :status_event, @machine.attribute(:event)
171
- end
172
-
173
- def test_should_define_a_reader_attribute_for_the_attribute
174
- assert @object.respond_to?(:status)
175
- end
176
-
177
- def test_should_define_a_writer_attribute_for_the_attribute
178
- assert @object.respond_to?(:status=)
179
- end
180
-
181
- def test_should_define_a_predicate_for_the_attribute
182
- assert @object.respond_to?(:status?)
183
- end
184
-
185
- def test_should_define_a_name_reader_for_the_attribute
186
- assert @object.respond_to?(:status_name)
187
- end
188
-
189
- def test_should_define_an_event_reader_for_the_attribute
190
- assert @object.respond_to?(:status_events)
191
- end
192
-
193
- def test_should_define_a_transition_reader_for_the_attribute
194
- assert @object.respond_to?(:status_transitions)
195
- end
196
- end
197
-
198
- class MachineWithStaticInitialStateTest < Test::Unit::TestCase
199
- def setup
200
- @klass = Class.new do
201
- def initialize(attributes = {})
202
- attributes.each {|attr, value| send("#{attr}=", value)}
203
- super()
204
- end
205
- end
206
-
207
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
208
- end
209
-
210
- def test_should_not_have_dynamic_initial_state
211
- assert !@machine.dynamic_initial_state?
212
- end
213
-
214
- def test_should_have_an_initial_state
215
- object = @klass.new
216
- assert_equal 'parked', @machine.initial_state(object).value
217
- end
218
-
219
- def test_should_set_initial_on_state_object
220
- assert @machine.state(:parked).initial
221
- end
222
-
223
- def test_should_set_initial_state_if_existing_is_nil
224
- object = @klass.new(:state => nil)
225
- assert_equal 'parked', object.state
226
- end
227
-
228
- def test_should_set_initial_state_if_existing_is_empty
229
- object = @klass.new(:state => '')
230
- assert_equal 'parked', object.state
231
- end
232
-
233
- def test_should_not_set_initial_state_if_existing_is_not_empty
234
- object = @klass.new(:state => 'idling')
235
- assert_equal 'idling', object.state
236
- end
237
-
238
- def test_should_set_initial_state_prior_to_initialization
239
- base = Class.new do
240
- attr_accessor :state_on_init
241
-
242
- def initialize
243
- self.state_on_init = state
244
- end
245
- end
246
- klass = Class.new(base)
247
- machine = StateMachine::Machine.new(klass, :initial => :parked)
248
-
249
- assert_equal 'parked', klass.new.state_on_init
250
- end
251
-
252
- def test_should_be_included_in_known_states
253
- assert_equal [:parked], @machine.states.keys
254
- end
255
- end
256
-
257
- class MachineWithDynamicInitialStateTest < Test::Unit::TestCase
258
- def setup
259
- @klass = Class.new do
260
- attr_accessor :initial_state
261
- end
262
- @machine = StateMachine::Machine.new(@klass, :initial => lambda {|object| object.initial_state || :default})
263
- @machine.state :parked, :idling, :default
264
- @object = @klass.new
265
- end
266
-
267
- def test_should_have_dynamic_initial_state
268
- assert @machine.dynamic_initial_state?
269
- end
270
-
271
- def test_should_use_the_record_for_determining_the_initial_state
272
- @object.initial_state = :parked
273
- assert_equal :parked, @machine.initial_state(@object).name
274
-
275
- @object.initial_state = :idling
276
- assert_equal :idling, @machine.initial_state(@object).name
277
- end
278
-
279
- def test_should_set_initial_state_on_created_object
280
- assert_equal 'default', @object.state
281
- end
282
-
283
- def test_should_set_initial_state_after_initialization
284
- base = Class.new do
285
- attr_accessor :state_on_init
286
-
287
- def initialize
288
- self.state_on_init = state
289
- end
290
- end
291
- klass = Class.new(base)
292
- machine = StateMachine::Machine.new(klass, :initial => lambda {|object| :parked})
293
- machine.state :parked
294
-
295
- assert_nil klass.new.state_on_init
296
- end
297
-
298
- def test_should_not_be_included_in_known_states
299
- assert_equal [:parked, :idling, :default], @machine.states.map {|state| state.name}
300
- end
301
- end
302
-
303
- class MachineWithCustomActionTest < Test::Unit::TestCase
304
- def setup
305
- @machine = StateMachine::Machine.new(Class.new, :action => :save)
306
- end
307
-
308
- def test_should_use_the_custom_action
309
- assert_equal :save, @machine.action
310
- end
311
- end
312
-
313
- class MachineWithNilActionTest < Test::Unit::TestCase
314
- def setup
315
- integration = Module.new do
316
- class << self; attr_reader :defaults; end
317
- @defaults = {:action => :save}
318
- end
319
- StateMachine::Integrations.const_set('Custom', integration)
320
- @machine = StateMachine::Machine.new(Class.new, :action => nil, :integration => :custom)
321
- end
322
-
323
- def test_should_have_a_nil_action
324
- assert_nil @machine.action
325
- end
326
-
327
- def teardown
328
- StateMachine::Integrations.send(:remove_const, 'Custom')
329
- end
330
- end
331
-
332
- class MachineWithoutIntegrationTest < Test::Unit::TestCase
333
- def setup
334
- @klass = Class.new
335
- @machine = StateMachine::Machine.new(@klass)
336
- @object = @klass.new
337
- end
338
-
339
- def test_transaction_should_yield
340
- @yielded = false
341
- @machine.within_transaction(@object) do
342
- @yielded = true
343
- end
344
-
345
- assert @yielded
346
- end
347
-
348
- def test_invalidation_should_do_nothing
349
- assert_nil @machine.invalidate(@object, :state, :invalid_transition, [[:event, :park]])
350
- end
351
-
352
- def test_reset_should_do_nothing
353
- assert_nil @machine.reset(@object)
354
- end
355
- end
356
-
357
- class MachineWithCustomIntegrationTest < Test::Unit::TestCase
358
- def setup
359
- StateMachine::Integrations.const_set('Custom', Module.new)
360
- @machine = StateMachine::Machine.new(Class.new, :integration => :custom)
361
- end
362
-
363
- def test_should_be_extended_by_the_integration
364
- assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom)
365
- end
366
-
367
- def teardown
368
- StateMachine::Integrations.send(:remove_const, 'Custom')
369
- end
370
- end
371
-
372
- class MachineWithIntegrationTest < Test::Unit::TestCase
373
- def setup
374
- StateMachine::Integrations.const_set('Custom', Module.new do
375
- class << self; attr_reader :defaults; end
376
- @defaults = {:action => :save, :use_transactions => false}
377
-
378
- attr_reader :initialized, :with_scopes, :without_scopes, :ran_transaction
379
-
380
- def after_initialize
381
- @initialized = true
382
- end
383
-
384
- def create_with_scope(name)
385
- (@with_scopes ||= []) << name
386
- lambda {}
387
- end
388
-
389
- def create_without_scope(name)
390
- (@without_scopes ||= []) << name
391
- lambda {}
392
- end
393
-
394
- def transaction(object)
395
- @ran_transaction = true
396
- yield
397
- end
398
- end)
399
-
400
- @machine = StateMachine::Machine.new(Class.new, :integration => :custom)
401
- end
402
-
403
- def test_should_call_after_initialize_hook
404
- assert @machine.initialized
405
- end
406
-
407
- def test_should_use_the_default_action
408
- assert_equal :save, @machine.action
409
- end
410
-
411
- def test_should_use_the_custom_action_if_specified
412
- machine = StateMachine::Machine.new(Class.new, :integration => :custom, :action => :save!)
413
- assert_equal :save!, machine.action
414
- end
415
-
416
- def test_should_use_the_default_use_transactions
417
- assert_equal false, @machine.use_transactions
418
- end
419
-
420
- def test_should_use_the_custom_use_transactions_if_specified
421
- machine = StateMachine::Machine.new(Class.new, :integration => :custom, :use_transactions => true)
422
- assert_equal true, machine.use_transactions
423
- end
424
-
425
- def test_should_define_a_singular_and_plural_with_scope
426
- assert_equal %w(with_state with_states), @machine.with_scopes
427
- end
428
-
429
- def test_should_define_a_singular_and_plural_without_scope
430
- assert_equal %w(without_state without_states), @machine.without_scopes
431
- end
432
-
433
- def teardown
434
- StateMachine::Integrations.send(:remove_const, 'Custom')
435
- end
436
- end
437
-
438
- class MachineWithActionTest < Test::Unit::TestCase
439
- def setup
440
- @klass = Class.new do
441
- def save
442
- end
443
- end
444
-
445
- @machine = StateMachine::Machine.new(@klass, :action => :save)
446
- @object = @klass.new
447
- end
448
-
449
- def test_should_define_an_event_attribute_reader
450
- assert @object.respond_to?(:state_event)
451
- end
452
-
453
- def test_should_define_an_event_attribute_writer
454
- assert @object.respond_to?(:state_event=)
455
- end
456
-
457
- def test_should_define_an_event_transition_attribute_reader
458
- assert @object.respond_to?(:state_event_transition)
459
- end
460
-
461
- def test_should_define_an_event_transition_attribute_writer
462
- assert @object.respond_to?(:state_event_transition=)
463
- end
464
- end
465
-
466
- class MachineWithActionUndefinedTest < Test::Unit::TestCase
467
- def setup
468
- @klass = Class.new
469
- @machine = StateMachine::Machine.new(@klass, :action => :save)
470
- @object = @klass.new
471
- end
472
-
473
- def test_should_define_an_event_attribute_reader
474
- assert @object.respond_to?(:state_event)
475
- end
476
-
477
- def test_should_define_an_event_attribute_writer
478
- assert @object.respond_to?(:state_event=)
479
- end
480
-
481
- def test_should_define_an_event_transition_attribute_reader
482
- assert @object.respond_to?(:state_event_transition)
483
- end
484
-
485
- def test_should_define_an_event_transition_attribute_writer
486
- assert @object.respond_to?(:state_event_transition=)
487
- end
488
-
489
- def test_should_not_define_action
490
- assert !@object.respond_to?(:save)
491
- end
492
- end
493
-
494
- class MachineWithCustomPluralTest < Test::Unit::TestCase
495
- def setup
496
- @integration = Module.new do
497
- class << self; attr_accessor :with_scopes, :without_scopes; end
498
- @with_scopes = []
499
- @without_scopes = []
500
-
501
- def create_with_scope(name)
502
- StateMachine::Integrations::Custom.with_scopes << name
503
- lambda {}
504
- end
505
-
506
- def create_without_scope(name)
507
- StateMachine::Integrations::Custom.without_scopes << name
508
- lambda {}
509
- end
510
- end
511
-
512
- StateMachine::Integrations.const_set('Custom', @integration)
513
- @machine = StateMachine::Machine.new(Class.new, :integration => :custom, :plural => 'staties')
514
- end
515
-
516
- def test_should_define_a_singular_and_plural_with_scope
517
- assert_equal %w(with_state with_staties), @integration.with_scopes
518
- end
519
-
520
- def test_should_define_a_singular_and_plural_without_scope
521
- assert_equal %w(without_state without_staties), @integration.without_scopes
522
- end
523
-
524
- def teardown
525
- StateMachine::Integrations.send(:remove_const, 'Custom')
526
- end
527
- end
528
-
529
- class MachineWithCustomInvalidationTest < Test::Unit::TestCase
530
- def setup
531
- @integration = Module.new do
532
- def invalidate(object, attribute, message, values = [])
533
- object.error = generate_message(message, values)
534
- end
535
- end
536
- StateMachine::Integrations.const_set('Custom', @integration)
537
-
538
- @klass = Class.new do
539
- attr_accessor :error
540
- end
541
-
542
- @machine = StateMachine::Machine.new(@klass, :integration => :custom, :messages => {:invalid_transition => 'cannot %s'})
543
- @machine.state :parked
544
-
545
- @object = @klass.new
546
- @object.state = 'parked'
547
- end
548
-
549
- def test_generate_custom_message
550
- assert_equal 'cannot park', @machine.generate_message(:invalid_transition, [[:event, :park]])
551
- end
552
-
553
- def test_use_custom_message
554
- @machine.invalidate(@object, :state, :invalid_transition, [[:event, :park]])
555
- assert_equal 'cannot park', @object.error
556
- end
557
-
558
- def teardown
559
- StateMachine::Integrations.send(:remove_const, 'Custom')
560
- end
561
- end
562
-
563
- class MachineTest < Test::Unit::TestCase
564
- def test_should_raise_exception_if_invalid_option_specified
565
- assert_raise(ArgumentError) {StateMachine::Machine.new(Class.new, :invalid => true)}
566
- end
567
-
568
- def test_should_not_raise_exception_if_custom_messages_specified
569
- assert_nothing_raised {StateMachine::Machine.new(Class.new, :messages => {:invalid_transition => 'custom'})}
570
- end
571
-
572
- def test_should_evaluate_a_block_during_initialization
573
- called = true
574
- StateMachine::Machine.new(Class.new) do
575
- called = respond_to?(:event)
576
- end
577
-
578
- assert called
579
- end
580
-
581
- def test_should_provide_matcher_helpers_during_initialization
582
- matchers = []
583
-
584
- StateMachine::Machine.new(Class.new) do
585
- matchers = [all, any, same]
586
- end
587
-
588
- assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers
589
- end
590
- end
591
-
592
- class MachineAfterBeingCopiedTest < Test::Unit::TestCase
593
- def setup
594
- @machine = StateMachine::Machine.new(Class.new, :state, :initial => :parked)
595
- @machine.event(:ignite) {}
596
- @machine.before_transition(lambda {})
597
- @machine.after_transition(lambda {})
598
-
599
- @copied_machine = @machine.clone
600
- end
601
-
602
- def test_should_not_have_the_same_collection_of_states
603
- assert_not_same @copied_machine.states, @machine.states
604
- end
605
-
606
- def test_should_copy_each_state
607
- assert_not_same @copied_machine.states[:parked], @machine.states[:parked]
608
- end
609
-
610
- def test_should_update_machine_for_each_state
611
- assert_equal @copied_machine, @copied_machine.states[:parked].machine
612
- end
613
-
614
- def test_should_not_update_machine_for_original_state
615
- assert_equal @machine, @machine.states[:parked].machine
616
- end
617
-
618
- def test_should_not_have_the_same_collection_of_events
619
- assert_not_same @copied_machine.events, @machine.events
620
- end
621
-
622
- def test_should_copy_each_event
623
- assert_not_same @copied_machine.events[:ignite], @machine.events[:ignite]
624
- end
625
-
626
- def test_should_update_machine_for_each_event
627
- assert_equal @copied_machine, @copied_machine.events[:ignite].machine
628
- end
629
-
630
- def test_should_not_update_machine_for_original_event
631
- assert_equal @machine, @machine.events[:ignite].machine
632
- end
633
-
634
- def test_should_not_have_the_same_callbacks
635
- assert_not_same @copied_machine.callbacks, @machine.callbacks
636
- end
637
-
638
- def test_should_not_have_the_same_before_callbacks
639
- assert_not_same @copied_machine.callbacks[:before], @machine.callbacks[:before]
640
- end
641
-
642
- def test_should_not_have_the_same_after_callbacks
643
- assert_not_same @copied_machine.callbacks[:after], @machine.callbacks[:after]
644
- end
645
- end
646
-
647
- class MachineAfterChangingOwnerClassTest < Test::Unit::TestCase
648
- def setup
649
- @original_class = Class.new
650
- @machine = StateMachine::Machine.new(@original_class)
651
-
652
- @new_class = Class.new(@original_class)
653
- @new_machine = @machine.clone
654
- @new_machine.owner_class = @new_class
655
-
656
- @object = @new_class.new
657
- end
658
-
659
- def test_should_update_owner_class
660
- assert_equal @new_class, @new_machine.owner_class
661
- end
662
-
663
- def test_should_not_change_original_owner_class
664
- assert_equal @original_class, @machine.owner_class
665
- end
666
-
667
- def test_should_change_the_associated_machine_in_the_new_class
668
- assert_equal @new_machine, @new_class.state_machines[:state]
669
- end
670
-
671
- def test_should_not_change_the_associated_machine_in_the_original_class
672
- assert_equal @machine, @original_class.state_machines[:state]
673
- end
674
- end
675
-
676
- class MachineAfterChangingInitialState < Test::Unit::TestCase
677
- def setup
678
- @klass = Class.new
679
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
680
- @machine.initial_state = :idling
681
-
682
- @object = @klass.new
683
- end
684
-
685
- def test_should_change_the_initial_state
686
- assert_equal :idling, @machine.initial_state(@object).name
687
- end
688
-
689
- def test_should_include_in_known_states
690
- assert_equal [:parked, :idling], @machine.states.map {|state| state.name}
691
- end
692
-
693
- def test_should_reset_original_initial_state
694
- assert !@machine.state(:parked).initial
695
- end
696
-
697
- def test_should_set_new_state_to_initial
698
- assert @machine.state(:idling).initial
699
- end
700
- end
701
-
702
- class MachineWithInstanceHelpersTest < Test::Unit::TestCase
703
- def setup
704
- @klass = Class.new
705
- @machine = StateMachine::Machine.new(@klass)
706
- @object = @klass.new
707
- end
708
-
709
- def test_should_not_redefine_existing_public_methods
710
- @klass.class_eval do
711
- def state
712
- 'parked'
713
- end
714
- end
715
-
716
- @machine.define_instance_method(:state) {}
717
- assert_equal 'parked', @object.state
718
- end
719
-
720
- def test_should_not_redefine_existing_protected_methods
721
- @klass.class_eval do
722
- protected
723
- def state
724
- 'parked'
725
- end
726
- end
727
-
728
- @machine.define_instance_method(:state) {}
729
- assert_equal 'parked', @object.send(:state)
730
- end
731
-
732
- def test_should_not_redefine_existing_private_methods
733
- @klass.class_eval do
734
- private
735
- def state
736
- 'parked'
737
- end
738
- end
739
-
740
- @machine.define_instance_method(:state) {}
741
- assert_equal 'parked', @object.send(:state)
742
- end
743
-
744
- def test_should_define_nonexistent_methods
745
- @machine.define_instance_method(:state) {'parked'}
746
- assert_equal 'parked', @object.state
747
- end
748
- end
749
-
750
- class MachineWithClassHelpersTest < Test::Unit::TestCase
751
- def setup
752
- @klass = Class.new
753
- @machine = StateMachine::Machine.new(@klass)
754
- end
755
-
756
- def test_should_not_redefine_existing_public_methods
757
- class << @klass
758
- def states
759
- []
760
- end
761
- end
762
-
763
- @machine.define_class_method(:states) {}
764
- assert_equal [], @klass.states
765
- end
766
-
767
- def test_should_not_redefine_existing_protected_methods
768
- class << @klass
769
- protected
770
- def states
771
- []
772
- end
773
- end
774
-
775
- @machine.define_class_method(:states) {}
776
- assert_equal [], @klass.send(:states)
777
- end
778
-
779
- def test_should_not_redefine_existing_private_methods
780
- class << @klass
781
- private
782
- def states
783
- []
784
- end
785
- end
786
-
787
- @machine.define_class_method(:states) {}
788
- assert_equal [], @klass.send(:states)
789
- end
790
-
791
- def test_should_define_nonexistent_methods
792
- @machine.define_class_method(:states) {[]}
793
- assert_equal [], @klass.states
794
- end
795
- end
796
-
797
- class MachineWithConflictingHelpersTest < Test::Unit::TestCase
798
- def setup
799
- @klass = Class.new do
800
- def self.with_state
801
- :with_state
802
- end
803
-
804
- def self.with_states
805
- :with_states
806
- end
807
-
808
- def self.without_state
809
- :without_state
810
- end
811
-
812
- def self.without_states
813
- :without_states
814
- end
815
-
816
- attr_accessor :status
817
-
818
- def state
819
- 'parked'
820
- end
821
-
822
- def state=(value)
823
- self.status = value
824
- end
825
-
826
- def state?
827
- true
828
- end
829
-
830
- def state_name
831
- :parked
832
- end
833
-
834
- def state_events
835
- [:ignite]
836
- end
837
-
838
- def state_transitions
839
- [{:parked => :idling}]
840
- end
841
- end
842
-
843
- StateMachine::Integrations.const_set('Custom', Module.new do
844
- def create_with_scope(name)
845
- lambda {|klass, values| []}
846
- end
847
-
848
- def create_without_scope(name)
849
- lambda {|klass, values| []}
850
- end
851
- end)
852
-
853
- @machine = StateMachine::Machine.new(@klass, :integration => :custom)
854
- @machine.state :parked, :idling
855
- @object = @klass.new
856
- end
857
-
858
- def test_should_not_redefine_singular_with_scope
859
- assert_equal :with_state, @klass.with_state
860
- end
861
-
862
- def test_should_not_redefine_plural_with_scope
863
- assert_equal :with_states, @klass.with_states
864
- end
865
-
866
- def test_should_not_redefine_singular_without_scope
867
- assert_equal :without_state, @klass.without_state
868
- end
869
-
870
- def test_should_not_redefine_plural_without_scope
871
- assert_equal :without_states, @klass.without_states
872
- end
873
-
874
- def test_should_not_redefine_attribute_writer
875
- assert_equal 'parked', @object.state
876
- end
877
-
878
- def test_should_not_redefine_attribute_writer
879
- @object.state = 'parked'
880
- assert_equal 'parked', @object.status
881
- end
882
-
883
- def test_should_not_define_attribute_predicate
884
- assert @object.state?
885
- end
886
-
887
- def test_should_not_redefine_attribute_name_reader
888
- assert_equal :parked, @object.state_name
889
- end
890
-
891
- def test_should_not_redefine_attribute_events_reader
892
- assert_equal [:ignite], @object.state_events
893
- end
894
-
895
- def test_should_not_redefine_attribute_transitions_reader
896
- assert_equal [{:parked => :idling}], @object.state_transitions
897
- end
898
-
899
- def test_should_allow_super_chaining
900
- @klass.class_eval do
901
- def self.with_state(*states)
902
- super == []
903
- end
904
-
905
- def self.with_states(*states)
906
- super == []
907
- end
908
-
909
- def self.without_state(*states)
910
- super == []
911
- end
912
-
913
- def self.without_states(*states)
914
- super == []
915
- end
916
-
917
- attr_accessor :status
918
-
919
- def state
920
- super || 'parked'
921
- end
922
-
923
- def state=(value)
924
- super
925
- self.status = value
926
- end
927
-
928
- def state?(state)
929
- super ? 1 : 0
930
- end
931
-
932
- def state_name
933
- super == :parked ? 1 : 0
934
- end
935
-
936
- def state_events
937
- super == []
938
- end
939
-
940
- def state_transitions
941
- super == []
942
- end
943
- end
944
-
945
- assert_equal true, @klass.with_state
946
- assert_equal true, @klass.with_states
947
- assert_equal true, @klass.without_state
948
- assert_equal true, @klass.without_states
949
-
950
- assert_equal 'parked', @object.state
951
- @object.state = 'idling'
952
- assert_equal 'idling', @object.status
953
- assert_equal 0, @object.state?(:parked)
954
- assert_equal 0, @object.state_name
955
- assert_equal true, @object.state_events
956
- assert_equal true, @object.state_transitions
957
- end
958
-
959
- def teardown
960
- StateMachine::Integrations.send(:remove_const, 'Custom')
961
- end
962
- end
963
-
964
- class MachineWithoutInitializeTest < Test::Unit::TestCase
965
- def setup
966
- @klass = Class.new
967
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
968
- @object = @klass.new
969
- end
970
-
971
- def test_should_initialize_state
972
- assert_equal 'parked', @object.state
973
- end
974
- end
975
-
976
- class MachineWithInitializeWithoutSuperTest < Test::Unit::TestCase
977
- def setup
978
- @klass = Class.new do
979
- def initialize
980
- end
981
- end
982
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
983
- @object = @klass.new
984
- end
985
-
986
- def test_should_not_initialize_state
987
- assert_nil @object.state
988
- end
989
- end
990
-
991
- class MachineWithInitializeAndSuperTest < Test::Unit::TestCase
992
- def setup
993
- @klass = Class.new do
994
- def initialize
995
- super()
996
- end
997
- end
998
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
999
- @object = @klass.new
1000
- end
1001
-
1002
- def test_should_initialize_state
1003
- assert_equal 'parked', @object.state
1004
- end
1005
- end
1006
-
1007
- class MachineWithInitializeArgumentsAndBlockTest < Test::Unit::TestCase
1008
- def setup
1009
- @superclass = Class.new do
1010
- attr_reader :args
1011
- attr_reader :block_given
1012
-
1013
- def initialize(*args)
1014
- @args = args
1015
- @block_given = block_given?
1016
- end
1017
- end
1018
- @klass = Class.new(@superclass)
1019
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1020
- @object = @klass.new(1, 2, 3) {}
1021
- end
1022
-
1023
- def test_should_initialize_state
1024
- assert_equal 'parked', @object.state
1025
- end
1026
-
1027
- def test_should_preserve_arguments
1028
- assert_equal [1, 2, 3], @object.args
1029
- end
1030
-
1031
- def test_should_preserve_block
1032
- assert @object.block_given
1033
- end
1034
- end
1035
-
1036
- class MachineWithCustomInitializeTest < Test::Unit::TestCase
1037
- def setup
1038
- @klass = Class.new do
1039
- def initialize
1040
- initialize_state_machines
1041
- end
1042
- end
1043
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1044
- @object = @klass.new
1045
- end
1046
-
1047
- def test_should_initialize_state
1048
- assert_equal 'parked', @object.state
1049
- end
1050
- end
1051
-
1052
- class MachinePersistenceTest < Test::Unit::TestCase
1053
- def setup
1054
- @klass = Class.new do
1055
- attr_accessor :state_event
1056
- end
1057
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1058
- @object = @klass.new
1059
- end
1060
-
1061
- def test_should_allow_reading_state
1062
- assert_equal 'parked', @machine.read(@object, :state)
1063
- end
1064
-
1065
- def test_should_allow_reading_custom_attributes
1066
- assert_nil @machine.read(@object, :event)
1067
-
1068
- @object.state_event = 'ignite'
1069
- assert_equal 'ignite', @machine.read(@object, :event)
1070
- end
1071
-
1072
- def test_should_allow_reading_custom_instance_variables
1073
- @klass.class_eval do
1074
- attr_writer :state_value
1075
- end
1076
-
1077
- @object.state_value = 1
1078
- assert_raise(NoMethodError) { @machine.read(@object, :value) }
1079
- assert_equal 1, @machine.read(@object, :value, true)
1080
- end
1081
-
1082
- def test_should_allow_writing_state
1083
- @machine.write(@object, :state, 'idling')
1084
- assert_equal 'idling', @object.state
1085
- end
1086
-
1087
- def test_should_allow_writing_custom_attributes
1088
- @machine.write(@object, :event, 'ignite')
1089
- assert_equal 'ignite', @object.state_event
1090
- end
1091
- end
1092
-
1093
-
1094
- class MachineWithStatesTest < Test::Unit::TestCase
1095
- def setup
1096
- @klass = Class.new
1097
- @machine = StateMachine::Machine.new(@klass)
1098
- @parked, @idling = @machine.state :parked, :idling
1099
-
1100
- @object = @klass.new
1101
- end
1102
-
1103
- def test_should_have_states
1104
- assert_equal [nil, :parked, :idling], @machine.states.map {|state| state.name}
1105
- end
1106
-
1107
- def test_should_allow_state_lookup_by_name
1108
- assert_equal @parked, @machine.states[:parked]
1109
- end
1110
-
1111
- def test_should_allow_state_lookup_by_value
1112
- assert_equal @parked, @machine.states['parked', :value]
1113
- end
1114
-
1115
- def test_should_use_stringified_name_for_value
1116
- assert_equal 'parked', @parked.value
1117
- end
1118
-
1119
- def test_should_not_use_custom_matcher
1120
- assert_nil @parked.matcher
1121
- end
1122
-
1123
- def test_should_raise_exception_if_invalid_option_specified
1124
- exception = assert_raise(ArgumentError) {@machine.state(:first_gear, :invalid => true)}
1125
- assert_equal 'Invalid key(s): invalid', exception.message
1126
- end
1127
- end
1128
-
1129
- class MachineWithStatesWithCustomValuesTest < Test::Unit::TestCase
1130
- def setup
1131
- @klass = Class.new
1132
- @machine = StateMachine::Machine.new(@klass)
1133
- @state = @machine.state :parked, :value => 1
1134
-
1135
- @object = @klass.new
1136
- @object.state = 1
1137
- end
1138
-
1139
- def test_should_use_custom_value
1140
- assert_equal 1, @state.value
1141
- end
1142
-
1143
- def test_should_allow_lookup_by_custom_value
1144
- assert_equal @state, @machine.states[1, :value]
1145
- end
1146
- end
1147
-
1148
- class MachineWithStatesWithRuntimeDependenciesTest < Test::Unit::TestCase
1149
- def setup
1150
- @klass = Class.new
1151
- @machine = StateMachine::Machine.new(@klass)
1152
- @machine.state :parked
1153
- end
1154
-
1155
- def test_should_not_evaluate_value_during_definition
1156
- assert_nothing_raised { @machine.state :parked, :value => lambda {raise ArgumentError} }
1157
- end
1158
-
1159
- def test_should_not_evaluate_if_not_initial_state
1160
- @machine.state :parked, :value => lambda {raise ArgumentError}
1161
- assert_nothing_raised { @klass.new }
1162
- end
1163
- end
1164
-
1165
- class MachineWithStateWithMatchersTest < Test::Unit::TestCase
1166
- def setup
1167
- @klass = Class.new
1168
- @machine = StateMachine::Machine.new(@klass)
1169
- @state = @machine.state :parked, :if => lambda {|value| !value.nil?}
1170
-
1171
- @object = @klass.new
1172
- @object.state = 1
1173
- end
1174
-
1175
- def test_should_use_custom_matcher
1176
- assert_not_nil @state.matcher
1177
- assert @state.matches?(1)
1178
- assert !@state.matches?(nil)
1179
- end
1180
- end
1181
-
1182
- class MachineWithCachedStateTest < Test::Unit::TestCase
1183
- def setup
1184
- @klass = Class.new
1185
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1186
- @state = @machine.state :parked, :value => lambda {Object.new}, :cache => true
1187
-
1188
- @object = @klass.new
1189
- end
1190
-
1191
- def test_should_use_evaluated_value
1192
- assert_instance_of Object, @object.state
1193
- end
1194
-
1195
- def test_use_same_value_across_multiple_objects
1196
- assert_equal @object.state, @klass.new.state
1197
- end
1198
- end
1199
-
1200
- class MachineWithStatesWithBehaviorsTest < Test::Unit::TestCase
1201
- def setup
1202
- @klass = Class.new
1203
- @machine = StateMachine::Machine.new(@klass)
1204
-
1205
- @parked, @idling = @machine.state :parked, :idling do
1206
- def speed
1207
- 0
1208
- end
1209
- end
1210
- end
1211
-
1212
- def test_should_define_behaviors_for_each_state
1213
- assert_not_nil @parked.methods[:speed]
1214
- assert_not_nil @idling.methods[:speed]
1215
- end
1216
-
1217
- def test_should_define_different_behaviors_for_each_state
1218
- assert_not_equal @parked.methods[:speed], @idling.methods[:speed]
1219
- end
1220
- end
1221
-
1222
- class MachineWithExistingStateTest < Test::Unit::TestCase
1223
- def setup
1224
- @klass = Class.new
1225
- @machine = StateMachine::Machine.new(@klass)
1226
- @state = @machine.state :parked
1227
- @same_state = @machine.state :parked, :value => 1
1228
- end
1229
-
1230
- def test_should_not_create_a_new_state
1231
- assert_same @state, @same_state
1232
- end
1233
-
1234
- def test_should_update_attributes
1235
- assert_equal 1, @state.value
1236
- end
1237
-
1238
- def test_should_no_longer_be_able_to_look_up_state_by_original_value
1239
- assert_nil @machine.states['parked', :value]
1240
- end
1241
-
1242
- def test_should_be_able_to_look_up_state_by_new_value
1243
- assert_equal @state, @machine.states[1, :value]
1244
- end
1245
- end
1246
-
1247
- class MachineWithOtherStates < Test::Unit::TestCase
1248
- def setup
1249
- @klass = Class.new
1250
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1251
- @parked, @idling = @machine.other_states(:parked, :idling)
1252
- end
1253
-
1254
- def test_should_include_other_states_in_known_states
1255
- assert_equal [@parked, @idling], @machine.states.to_a
1256
- end
1257
-
1258
- def test_should_use_default_value
1259
- assert_equal 'idling', @idling.value
1260
- end
1261
-
1262
- def test_should_not_create_matcher
1263
- assert_nil @idling.matcher
1264
- end
1265
- end
1266
-
1267
- class MachineWithEventsTest < Test::Unit::TestCase
1268
- def setup
1269
- @klass = Class.new
1270
- @machine = StateMachine::Machine.new(@klass)
1271
- end
1272
-
1273
- def test_should_return_the_created_event
1274
- assert_instance_of StateMachine::Event, @machine.event(:ignite)
1275
- end
1276
-
1277
- def test_should_create_event_with_given_name
1278
- event = @machine.event(:ignite) {}
1279
- assert_equal :ignite, event.name
1280
- end
1281
-
1282
- def test_should_evaluate_block_within_event_context
1283
- responded = false
1284
- @machine.event :ignite do
1285
- responded = respond_to?(:transition)
1286
- end
1287
-
1288
- assert responded
1289
- end
1290
-
1291
- def test_should_be_aliased_as_on
1292
- event = @machine.on(:ignite) {}
1293
- assert_equal :ignite, event.name
1294
- end
1295
-
1296
- def test_should_have_events
1297
- event = @machine.event(:ignite)
1298
- assert_equal [event], @machine.events.to_a
1299
- end
1300
- end
1301
-
1302
- class MachineWithExistingEventTest < Test::Unit::TestCase
1303
- def setup
1304
- @machine = StateMachine::Machine.new(Class.new)
1305
- @event = @machine.event(:ignite)
1306
- @same_event = @machine.event(:ignite)
1307
- end
1308
-
1309
- def test_should_not_create_new_event
1310
- assert_same @event, @same_event
1311
- end
1312
-
1313
- def test_should_allow_accessing_event_without_block
1314
- assert_equal @event, @machine.event(:ignite)
1315
- end
1316
- end
1317
-
1318
- class MachineWithEventsWithTransitionsTest < Test::Unit::TestCase
1319
- def setup
1320
- @klass = Class.new
1321
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1322
- @event = @machine.event(:ignite) do
1323
- transition :parked => :idling
1324
- transition :stalled => :idling
1325
- end
1326
- end
1327
-
1328
- def test_should_have_events
1329
- assert_equal [@event], @machine.events.to_a
1330
- end
1331
-
1332
- def test_should_track_states_defined_in_event_transitions
1333
- assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name}
1334
- end
1335
-
1336
- def test_should_not_duplicate_states_defined_in_multiple_event_transitions
1337
- @machine.event :park do
1338
- transition :idling => :parked
1339
- end
1340
-
1341
- assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name}
1342
- end
1343
-
1344
- def test_should_track_state_from_new_events
1345
- @machine.event :shift_up do
1346
- transition :idling => :first_gear
1347
- end
1348
-
1349
- assert_equal [:parked, :idling, :stalled, :first_gear], @machine.states.map {|state| state.name}
1350
- end
1351
- end
1352
-
1353
- class MachineWithMultipleEventsTest < Test::Unit::TestCase
1354
- def setup
1355
- @klass = Class.new
1356
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1357
- @park, @shift_down = @machine.event(:park, :shift_down) do
1358
- transition :first_gear => :parked
1359
- end
1360
- end
1361
-
1362
- def test_should_have_events
1363
- assert_equal [@park, @shift_down], @machine.events.to_a
1364
- end
1365
-
1366
- def test_should_define_transitions_for_each_event
1367
- [@park, @shift_down].each {|event| assert_equal 1, event.guards.size}
1368
- end
1369
-
1370
- def test_should_transition_the_same_for_each_event
1371
- object = @klass.new
1372
- object.state = 'first_gear'
1373
- object.park
1374
- assert_equal 'parked', object.state
1375
-
1376
- object = @klass.new
1377
- object.state = 'first_gear'
1378
- object.shift_down
1379
- assert_equal 'parked', object.state
1380
- end
1381
- end
1382
-
1383
- class MachineWithTransitionCallbacksTest < Test::Unit::TestCase
1384
- def setup
1385
- @klass = Class.new do
1386
- attr_accessor :callbacks
1387
- end
1388
-
1389
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1390
- @event = @machine.event :ignite do
1391
- transition :parked => :idling
1392
- end
1393
-
1394
- @object = @klass.new
1395
- @object.callbacks = []
1396
- end
1397
-
1398
- def test_should_not_raise_exception_if_implicit_option_specified
1399
- assert_nothing_raised {@machine.before_transition :invalid => :valid, :do => lambda {}}
1400
- end
1401
-
1402
- def test_should_raise_exception_if_method_not_specified
1403
- exception = assert_raise(ArgumentError) {@machine.before_transition :to => :idling}
1404
- assert_equal 'Method(s) for callback must be specified', exception.message
1405
- end
1406
-
1407
- def test_should_invoke_callbacks_during_transition
1408
- @machine.before_transition lambda {|object| object.callbacks << 'before'}
1409
- @machine.after_transition lambda {|object| object.callbacks << 'after'}
1410
-
1411
- @event.fire(@object)
1412
- assert_equal %w(before after), @object.callbacks
1413
- end
1414
-
1415
- def test_should_allow_multiple_callbacks
1416
- @machine.before_transition lambda {|object| object.callbacks << 'before1'}, lambda {|object| object.callbacks << 'before2'}
1417
- @machine.after_transition lambda {|object| object.callbacks << 'after1'}, lambda {|object| object.callbacks << 'after2'}
1418
-
1419
- @event.fire(@object)
1420
- assert_equal %w(before1 before2 after1 after2), @object.callbacks
1421
- end
1422
-
1423
- def test_should_allow_multiple_callbacks_with_requirements
1424
- @machine.before_transition lambda {|object| object.callbacks << 'before_parked1'}, lambda {|object| object.callbacks << 'before_parked2'}, :from => :parked
1425
- @machine.before_transition lambda {|object| object.callbacks << 'before_idling1'}, lambda {|object| object.callbacks << 'before_idling2'}, :from => :idling
1426
- @machine.after_transition lambda {|object| object.callbacks << 'after_parked1'}, lambda {|object| object.callbacks << 'after_parked2'}, :from => :parked
1427
- @machine.after_transition lambda {|object| object.callbacks << 'after_idling1'}, lambda {|object| object.callbacks << 'after_idling2'}, :from => :idling
1428
-
1429
- @event.fire(@object)
1430
- assert_equal %w(before_parked1 before_parked2 after_parked1 after_parked2), @object.callbacks
1431
- end
1432
-
1433
- def test_should_support_from_requirement
1434
- @machine.before_transition :from => :parked, :do => lambda {|object| object.callbacks << :parked}
1435
- @machine.before_transition :from => :idling, :do => lambda {|object| object.callbacks << :idling}
1436
-
1437
- @event.fire(@object)
1438
- assert_equal [:parked], @object.callbacks
1439
- end
1440
-
1441
- def test_should_support_except_from_requirement
1442
- @machine.before_transition :except_from => :parked, :do => lambda {|object| object.callbacks << :parked}
1443
- @machine.before_transition :except_from => :idling, :do => lambda {|object| object.callbacks << :idling}
1444
-
1445
- @event.fire(@object)
1446
- assert_equal [:idling], @object.callbacks
1447
- end
1448
-
1449
- def test_should_support_to_requirement
1450
- @machine.before_transition :to => :parked, :do => lambda {|object| object.callbacks << :parked}
1451
- @machine.before_transition :to => :idling, :do => lambda {|object| object.callbacks << :idling}
1452
-
1453
- @event.fire(@object)
1454
- assert_equal [:idling], @object.callbacks
1455
- end
1456
-
1457
- def test_should_support_except_to_requirement
1458
- @machine.before_transition :except_to => :parked, :do => lambda {|object| object.callbacks << :parked}
1459
- @machine.before_transition :except_to => :idling, :do => lambda {|object| object.callbacks << :idling}
1460
-
1461
- @event.fire(@object)
1462
- assert_equal [:parked], @object.callbacks
1463
- end
1464
-
1465
- def test_should_support_on_requirement
1466
- @machine.before_transition :on => :park, :do => lambda {|object| object.callbacks << :park}
1467
- @machine.before_transition :on => :ignite, :do => lambda {|object| object.callbacks << :ignite}
1468
-
1469
- @event.fire(@object)
1470
- assert_equal [:ignite], @object.callbacks
1471
- end
1472
-
1473
- def test_should_support_except_on_requirement
1474
- @machine.before_transition :except_on => :park, :do => lambda {|object| object.callbacks << :park}
1475
- @machine.before_transition :except_on => :ignite, :do => lambda {|object| object.callbacks << :ignite}
1476
-
1477
- @event.fire(@object)
1478
- assert_equal [:park], @object.callbacks
1479
- end
1480
-
1481
- def test_should_support_implicit_requirement
1482
- @machine.before_transition :parked => :idling, :do => lambda {|object| object.callbacks << :parked}
1483
- @machine.before_transition :idling => :parked, :do => lambda {|object| object.callbacks << :idling}
1484
-
1485
- @event.fire(@object)
1486
- assert_equal [:parked], @object.callbacks
1487
- end
1488
-
1489
- def test_should_track_states_defined_in_transition_callbacks
1490
- @machine.before_transition :parked => :idling, :do => lambda {}
1491
- @machine.after_transition :first_gear => :second_gear, :do => lambda {}
1492
-
1493
- assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name}
1494
- end
1495
-
1496
- def test_should_not_duplicate_states_defined_in_multiple_event_transitions
1497
- @machine.before_transition :parked => :idling, :do => lambda {}
1498
- @machine.after_transition :first_gear => :second_gear, :do => lambda {}
1499
- @machine.after_transition :parked => :idling, :do => lambda {}
1500
-
1501
- assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name}
1502
- end
1503
-
1504
- def test_should_define_predicates_for_each_state
1505
- [:parked?, :idling?].each {|predicate| assert @object.respond_to?(predicate)}
1506
- end
1507
- end
1508
-
1509
- class MachineWithOwnerSubclassTest < Test::Unit::TestCase
1510
- def setup
1511
- @klass = Class.new
1512
- @machine = StateMachine::Machine.new(@klass)
1513
- @subclass = Class.new(@klass)
1514
- end
1515
-
1516
- def test_should_have_a_different_collection_of_state_machines
1517
- assert_not_same @klass.state_machines, @subclass.state_machines
1518
- end
1519
-
1520
- def test_should_have_the_same_attribute_associated_state_machines
1521
- assert_equal @klass.state_machines, @subclass.state_machines
1522
- end
1523
- end
1524
-
1525
- class MachineWithExistingMachinesOnOwnerClassTest < Test::Unit::TestCase
1526
- def setup
1527
- @klass = Class.new
1528
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1529
- @second_machine = StateMachine::Machine.new(@klass, :status, :initial => :idling)
1530
- @object = @klass.new
1531
- end
1532
-
1533
- def test_should_track_each_state_machine
1534
- expected = {:state => @machine, :status => @second_machine}
1535
- assert_equal expected, @klass.state_machines
1536
- end
1537
-
1538
- def test_should_initialize_state_for_both_machines
1539
- assert_equal 'parked', @object.state
1540
- assert_equal 'idling', @object.status
1541
- end
1542
- end
1543
-
1544
- class MachineWithExistingMachinesWithSameAttributesOnOwnerClassTest < Test::Unit::TestCase
1545
- def setup
1546
- @klass = Class.new
1547
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1548
- @second_machine = StateMachine::Machine.new(@klass, :public_state, :attribute => :state)
1549
- @object = @klass.new
1550
- end
1551
-
1552
- def test_should_track_each_state_machine
1553
- expected = {:state => @machine, :public_state => @second_machine}
1554
- assert_equal expected, @klass.state_machines
1555
- end
1556
-
1557
- def test_should_initialize_based_on_first_available_initial_state
1558
- assert_equal 'parked', @object.state
1559
- end
1560
-
1561
- def test_should_allow_transitions_on_both_machines
1562
- @machine.event :ignite do
1563
- transition :parked => :idling
1564
- end
1565
-
1566
- @second_machine.event :park do
1567
- transition :idling => :parked
1568
- end
1569
-
1570
- @object.ignite
1571
- assert_equal 'idling', @object.state
1572
-
1573
- @object.park
1574
- assert_equal 'parked', @object.state
1575
- end
1576
- end
1577
-
1578
- class MachineWithNamespaceTest < Test::Unit::TestCase
1579
- def setup
1580
- @klass = Class.new
1581
- @machine = StateMachine::Machine.new(@klass, :namespace => 'alarm', :initial => :active) do
1582
- event :enable do
1583
- transition :off => :active
1584
- end
1585
-
1586
- event :disable do
1587
- transition :active => :off
1588
- end
1589
- end
1590
- @object = @klass.new
1591
- end
1592
-
1593
- def test_should_namespace_state_predicates
1594
- [:alarm_active?, :alarm_off?].each do |name|
1595
- assert @object.respond_to?(name)
1596
- end
1597
- end
1598
-
1599
- def test_should_namespace_event_checks
1600
- [:can_enable_alarm?, :can_disable_alarm?].each do |name|
1601
- assert @object.respond_to?(name)
1602
- end
1603
- end
1604
-
1605
- def test_should_namespace_event_transition_readers
1606
- [:enable_alarm_transition, :disable_alarm_transition].each do |name|
1607
- assert @object.respond_to?(name)
1608
- end
1609
- end
1610
-
1611
- def test_should_namespace_events
1612
- [:enable_alarm, :disable_alarm].each do |name|
1613
- assert @object.respond_to?(name)
1614
- end
1615
- end
1616
-
1617
- def test_should_namespace_bang_events
1618
- [:enable_alarm!, :disable_alarm!].each do |name|
1619
- assert @object.respond_to?(name)
1620
- end
1621
- end
1622
- end
1623
-
1624
- class MachineWithCustomAttributeTest < Test::Unit::TestCase
1625
- def setup
1626
- StateMachine::Integrations.const_set('Custom', Module.new do
1627
- class << self; attr_reader :defaults; end
1628
- @defaults = {:action => :save, :use_transactions => false}
1629
-
1630
- def create_with_scope(name)
1631
- lambda {}
1632
- end
1633
-
1634
- def create_without_scope(name)
1635
- lambda {}
1636
- end
1637
- end)
1638
-
1639
- @klass = Class.new
1640
- @machine = StateMachine::Machine.new(@klass, :state, :attribute => :state_id, :initial => :active, :integration => :custom) do
1641
- event :ignite do
1642
- transition :parked => :idling
1643
- end
1644
- end
1645
- @object = @klass.new
1646
- end
1647
-
1648
- def test_should_define_a_reader_attribute_for_the_attribute
1649
- assert @object.respond_to?(:state_id)
1650
- end
1651
-
1652
- def test_should_define_a_writer_attribute_for_the_attribute
1653
- assert @object.respond_to?(:state_id=)
1654
- end
1655
-
1656
- def test_should_define_a_predicate_for_the_attribute
1657
- assert @object.respond_to?(:state?)
1658
- end
1659
-
1660
- def test_should_define_a_name_reader_for_the_attribute
1661
- assert @object.respond_to?(:state_name)
1662
- end
1663
-
1664
- def test_should_define_an_event_reader_for_the_attribute
1665
- assert @object.respond_to?(:state_events)
1666
- end
1667
-
1668
- def test_should_define_a_transition_reader_for_the_attribute
1669
- assert @object.respond_to?(:state_transitions)
1670
- end
1671
-
1672
- def test_should_define_singular_with_scope
1673
- assert @klass.respond_to?(:with_state)
1674
- end
1675
-
1676
- def test_should_define_singular_without_scope
1677
- assert @klass.respond_to?(:without_state)
1678
- end
1679
-
1680
- def test_should_define_plural_with_scope
1681
- assert @klass.respond_to?(:with_states)
1682
- end
1683
-
1684
- def test_should_define_plural_without_scope
1685
- assert @klass.respond_to?(:without_states)
1686
- end
1687
-
1688
- def test_should_define_state_machines_reader
1689
- expected = {:state => @machine}
1690
- assert_equal expected, @klass.state_machines
1691
- end
1692
-
1693
- def teardown
1694
- StateMachine::Integrations.send(:remove_const, 'Custom')
1695
- end
1696
- end
1697
-
1698
- class MachineFinderWithoutExistingMachineTest < Test::Unit::TestCase
1699
- def setup
1700
- @klass = Class.new
1701
- @machine = StateMachine::Machine.find_or_create(@klass)
1702
- end
1703
-
1704
- def test_should_accept_a_block
1705
- called = false
1706
- StateMachine::Machine.find_or_create(Class.new) do
1707
- called = respond_to?(:event)
1708
- end
1709
-
1710
- assert called
1711
- end
1712
-
1713
- def test_should_create_a_new_machine
1714
- assert_not_nil @machine
1715
- end
1716
-
1717
- def test_should_use_default_state
1718
- assert_equal :state, @machine.attribute
1719
- end
1720
- end
1721
-
1722
- class MachineFinderWithExistingOnSameClassTest < Test::Unit::TestCase
1723
- def setup
1724
- @klass = Class.new
1725
- @existing_machine = StateMachine::Machine.new(@klass)
1726
- @machine = StateMachine::Machine.find_or_create(@klass)
1727
- end
1728
-
1729
- def test_should_accept_a_block
1730
- called = false
1731
- StateMachine::Machine.find_or_create(@klass) do
1732
- called = respond_to?(:event)
1733
- end
1734
-
1735
- assert called
1736
- end
1737
-
1738
- def test_should_not_create_a_new_machine
1739
- assert_same @machine, @existing_machine
1740
- end
1741
- end
1742
-
1743
- class MachineFinderWithExistingMachineOnSuperclassTest < Test::Unit::TestCase
1744
- def setup
1745
- integration = Module.new do
1746
- def self.matches?(klass)
1747
- false
1748
- end
1749
- end
1750
- StateMachine::Integrations.const_set('Custom', integration)
1751
-
1752
- @base_class = Class.new
1753
- @base_machine = StateMachine::Machine.new(@base_class, :status, :action => :save, :integration => :custom)
1754
- @base_machine.event(:ignite) {}
1755
- @base_machine.before_transition(lambda {})
1756
- @base_machine.after_transition(lambda {})
1757
-
1758
- @klass = Class.new(@base_class)
1759
- @machine = StateMachine::Machine.find_or_create(@klass, :status) {}
1760
- end
1761
-
1762
- def test_should_accept_a_block
1763
- called = false
1764
- StateMachine::Machine.find_or_create(Class.new(@base_class)) do
1765
- called = respond_to?(:event)
1766
- end
1767
-
1768
- assert called
1769
- end
1770
-
1771
- def test_should_not_create_a_new_machine_if_no_block_or_options
1772
- machine = StateMachine::Machine.find_or_create(Class.new(@base_class), :status)
1773
-
1774
- assert_same machine, @base_machine
1775
- end
1776
-
1777
- def test_should_create_a_new_machine_if_given_options
1778
- machine = StateMachine::Machine.find_or_create(@klass, :status, :initial => :parked)
1779
-
1780
- assert_not_nil machine
1781
- assert_not_same machine, @base_machine
1782
- end
1783
-
1784
- def test_should_create_a_new_machine_if_given_block
1785
- assert_not_nil @machine
1786
- assert_not_same @machine, @base_machine
1787
- end
1788
-
1789
- def test_should_copy_the_base_attribute
1790
- assert_equal :status, @machine.attribute
1791
- end
1792
-
1793
- def test_should_copy_the_base_configuration
1794
- assert_equal :save, @machine.action
1795
- end
1796
-
1797
- def test_should_copy_events
1798
- # Can't assert equal arrays since their machines change
1799
- assert_equal 1, @machine.events.length
1800
- end
1801
-
1802
- def test_should_copy_before_callbacks
1803
- assert_equal @base_machine.callbacks[:before], @machine.callbacks[:before]
1804
- end
1805
-
1806
- def test_should_copy_after_transitions
1807
- assert_equal @base_machine.callbacks[:after], @machine.callbacks[:after]
1808
- end
1809
-
1810
- def test_should_use_the_same_integration
1811
- assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom)
1812
- end
1813
-
1814
- def teardown
1815
- StateMachine::Integrations.send(:remove_const, 'Custom')
1816
- end
1817
- end
1818
-
1819
- class MachineFinderCustomOptionsTest < Test::Unit::TestCase
1820
- def setup
1821
- @klass = Class.new
1822
- @machine = StateMachine::Machine.find_or_create(@klass, :status, :initial => :parked)
1823
- @object = @klass.new
1824
- end
1825
-
1826
- def test_should_use_custom_attribute
1827
- assert_equal :status, @machine.attribute
1828
- end
1829
-
1830
- def test_should_set_custom_initial_state
1831
- assert_equal :parked, @machine.initial_state(@object).name
1832
- end
1833
- end
1834
-
1835
- begin
1836
- # Load library
1837
- require 'rubygems'
1838
- require 'graphviz'
1839
-
1840
- class MachineDrawingTest < Test::Unit::TestCase
1841
- def setup
1842
- @klass = Class.new do
1843
- def self.name; 'Vehicle'; end
1844
- end
1845
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1846
- @machine.event :ignite do
1847
- transition :parked => :idling
1848
- end
1849
- end
1850
-
1851
- def test_should_raise_exception_if_invalid_option_specified
1852
- assert_raise(ArgumentError) {@machine.draw(:invalid => true)}
1853
- end
1854
-
1855
- def test_should_save_file_with_class_name_by_default
1856
- graph = @machine.draw(:output => false)
1857
- assert_equal './Vehicle_state.png', graph.instance_variable_get('@filename')
1858
- end
1859
-
1860
- def test_should_allow_base_name_to_be_customized
1861
- graph = @machine.draw(:name => 'machine', :output => false)
1862
- assert_equal './machine.png', graph.instance_variable_get('@filename')
1863
- end
1864
-
1865
- def test_should_allow_format_to_be_customized
1866
- graph = @machine.draw(:format => 'jpg', :output => false)
1867
- assert_equal './Vehicle_state.jpg', graph.instance_variable_get('@filename')
1868
- assert_equal 'jpg', graph.instance_variable_get('@format')
1869
- end
1870
-
1871
- def test_should_allow_path_to_be_customized
1872
- graph = @machine.draw(:path => "#{File.dirname(__FILE__)}/", :output => false)
1873
- assert_equal "#{File.dirname(__FILE__)}/Vehicle_state.png", graph.instance_variable_get('@filename')
1874
- end
1875
-
1876
- def test_should_allow_orientation_to_be_landscape
1877
- graph = @machine.draw(:orientation => 'landscape', :output => false)
1878
- assert_equal 'LR', graph['rankdir']
1879
- end
1880
-
1881
- def test_should_allow_orientation_to_be_portrait
1882
- graph = @machine.draw(:orientation => 'portrait', :output => false)
1883
- assert_equal 'TB', graph['rankdir']
1884
- end
1885
- end
1886
-
1887
- class MachineDrawingWithIntegerStatesTest < Test::Unit::TestCase
1888
- def setup
1889
- @klass = Class.new do
1890
- def self.name; 'Vehicle'; end
1891
- end
1892
- @machine = StateMachine::Machine.new(@klass, :state_id, :initial => :parked)
1893
- @machine.event :ignite do
1894
- transition :parked => :idling
1895
- end
1896
- @machine.state :parked, :value => 1
1897
- @machine.state :idling, :value => 2
1898
- @graph = @machine.draw
1899
- end
1900
-
1901
- def test_should_draw_all_states
1902
- assert_equal 3, @graph.node_count
1903
- end
1904
-
1905
- def test_should_draw_all_events
1906
- assert_equal 2, @graph.edge_count
1907
- end
1908
-
1909
- def test_should_draw_machine
1910
- assert File.exist?('./Vehicle_state_id.png')
1911
- ensure
1912
- FileUtils.rm('./Vehicle_state_id.png')
1913
- end
1914
- end
1915
-
1916
- class MachineDrawingWithNilStatesTest < Test::Unit::TestCase
1917
- def setup
1918
- @klass = Class.new do
1919
- def self.name; 'Vehicle'; end
1920
- end
1921
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1922
- @machine.event :ignite do
1923
- transition :parked => :idling
1924
- end
1925
- @machine.state :parked, :value => nil
1926
- @graph = @machine.draw
1927
- end
1928
-
1929
- def test_should_draw_all_states
1930
- assert_equal 3, @graph.node_count
1931
- end
1932
-
1933
- def test_should_draw_all_events
1934
- assert_equal 2, @graph.edge_count
1935
- end
1936
-
1937
- def test_should_draw_machine
1938
- assert File.exist?('./Vehicle_state.png')
1939
- ensure
1940
- FileUtils.rm('./Vehicle_state.png')
1941
- end
1942
- end
1943
-
1944
- class MachineDrawingWithDynamicStatesTest < Test::Unit::TestCase
1945
- def setup
1946
- @klass = Class.new do
1947
- def self.name; 'Vehicle'; end
1948
- end
1949
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1950
- @machine.event :activate do
1951
- transition :parked => :idling
1952
- end
1953
- @machine.state :idling, :value => lambda {Time.now}
1954
- @graph = @machine.draw
1955
- end
1956
-
1957
- def test_should_draw_all_states
1958
- assert_equal 3, @graph.node_count
1959
- end
1960
-
1961
- def test_should_draw_all_events
1962
- assert_equal 2, @graph.edge_count
1963
- end
1964
-
1965
- def test_should_draw_machine
1966
- assert File.exist?('./Vehicle_state.png')
1967
- ensure
1968
- FileUtils.rm('./Vehicle_state.png')
1969
- end
1970
- end
1971
-
1972
- class MachineClassDrawingTest < Test::Unit::TestCase
1973
- def setup
1974
- @klass = Class.new do
1975
- def self.name; 'Vehicle'; end
1976
- end
1977
- @machine = StateMachine::Machine.new(@klass)
1978
- @machine.event :ignite do
1979
- transition :parked => :idling
1980
- end
1981
- end
1982
-
1983
- def test_should_raise_exception_if_no_class_names_specified
1984
- exception = assert_raise(ArgumentError) {StateMachine::Machine.draw(nil)}
1985
- assert_equal 'At least one class must be specified', exception.message
1986
- end
1987
-
1988
- def test_should_load_files
1989
- StateMachine::Machine.draw('Switch', :file => "#{File.dirname(__FILE__)}/../classes/switch.rb")
1990
- assert defined?(::Switch)
1991
- ensure
1992
- FileUtils.rm('./Switch_state.png')
1993
- end
1994
-
1995
- def test_should_allow_path_and_format_to_be_customized
1996
- StateMachine::Machine.draw('Switch', :file => "#{File.dirname(__FILE__)}/../classes/switch.rb", :path => "#{File.dirname(__FILE__)}/", :format => 'jpg')
1997
- assert File.exist?("#{File.dirname(__FILE__)}/Switch_state.jpg")
1998
- ensure
1999
- FileUtils.rm("#{File.dirname(__FILE__)}/Switch_state.jpg")
2000
- end
2001
- end
2002
- rescue LoadError
2003
- $stderr.puts 'Skipping GraphViz StateMachine::Machine tests. `gem install ruby-graphviz` and try again.'
2004
- end