state_machine 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. data/.gitignore +7 -11
  2. data/.travis.yml +49 -7
  3. data/Appraisals +255 -87
  4. data/CHANGELOG.md +30 -0
  5. data/README.md +142 -21
  6. data/Rakefile +1 -11
  7. data/examples/Gemfile +5 -0
  8. data/examples/Gemfile.lock +14 -0
  9. data/examples/auto_shop.rb +2 -0
  10. data/examples/car.rb +2 -0
  11. data/examples/doc/AutoShop.html +2856 -0
  12. data/examples/doc/AutoShop_state.png +0 -0
  13. data/examples/doc/Car.html +919 -0
  14. data/examples/doc/Car_state.png +0 -0
  15. data/examples/doc/TrafficLight.html +2230 -0
  16. data/examples/doc/TrafficLight_state.png +0 -0
  17. data/examples/doc/Vehicle.html +7921 -0
  18. data/examples/doc/Vehicle_state.png +0 -0
  19. data/examples/doc/_index.html +136 -0
  20. data/examples/doc/class_list.html +47 -0
  21. data/examples/doc/css/common.css +1 -0
  22. data/examples/doc/css/full_list.css +55 -0
  23. data/examples/doc/css/style.css +322 -0
  24. data/examples/doc/file_list.html +46 -0
  25. data/examples/doc/frames.html +13 -0
  26. data/examples/doc/index.html +136 -0
  27. data/examples/doc/js/app.js +205 -0
  28. data/examples/doc/js/full_list.js +173 -0
  29. data/examples/doc/js/jquery.js +16 -0
  30. data/examples/doc/method_list.html +734 -0
  31. data/examples/doc/top-level-namespace.html +105 -0
  32. data/examples/rails-rest/migration.rb +1 -5
  33. data/examples/rails-rest/view__form.html.erb +34 -0
  34. data/examples/rails-rest/view_edit.html.erb +2 -21
  35. data/examples/rails-rest/view_index.html.erb +6 -4
  36. data/examples/rails-rest/view_new.html.erb +2 -11
  37. data/examples/rails-rest/view_show.html.erb +5 -3
  38. data/examples/traffic_light.rb +2 -0
  39. data/examples/vehicle.rb +2 -0
  40. data/gemfiles/active_model-3.0.0.gemfile.lock +9 -6
  41. data/gemfiles/active_model-3.0.5.gemfile.lock +10 -7
  42. data/gemfiles/active_model-3.1.1.gemfile.lock +12 -10
  43. data/gemfiles/{active_model-3.2.0.gemfile → active_model-3.2.1.gemfile} +1 -1
  44. data/gemfiles/{graphviz-0.9.0.gemfile → active_model-3.2.12.gemfile} +1 -1
  45. data/gemfiles/active_model-3.2.12.gemfile.lock +36 -0
  46. data/gemfiles/{active_record-3.2.0.gemfile → active_model-3.2.13.rc1.gemfile} +1 -2
  47. data/gemfiles/active_model-3.2.13.rc1.gemfile.lock +36 -0
  48. data/gemfiles/active_model-4.0.0.gemfile +9 -0
  49. data/gemfiles/active_model-4.0.0.gemfile.lock +78 -0
  50. data/gemfiles/active_record-2.0.0.gemfile +2 -1
  51. data/gemfiles/active_record-2.0.0.gemfile.lock +15 -6
  52. data/gemfiles/active_record-2.0.5.gemfile +2 -1
  53. data/gemfiles/active_record-2.0.5.gemfile.lock +15 -6
  54. data/gemfiles/active_record-2.1.0.gemfile +2 -1
  55. data/gemfiles/active_record-2.1.0.gemfile.lock +15 -6
  56. data/gemfiles/active_record-2.1.2.gemfile +2 -1
  57. data/gemfiles/active_record-2.1.2.gemfile.lock +15 -6
  58. data/gemfiles/active_record-2.2.3.gemfile +2 -1
  59. data/gemfiles/active_record-2.2.3.gemfile.lock +15 -6
  60. data/gemfiles/active_record-2.3.12.gemfile +2 -1
  61. data/gemfiles/active_record-2.3.12.gemfile.lock +15 -6
  62. data/gemfiles/active_record-2.3.5.gemfile +9 -0
  63. data/gemfiles/active_record-2.3.5.gemfile.lock +39 -0
  64. data/gemfiles/active_record-3.0.0.gemfile +2 -1
  65. data/gemfiles/active_record-3.0.0.gemfile.lock +18 -11
  66. data/gemfiles/active_record-3.0.5.gemfile +2 -1
  67. data/gemfiles/active_record-3.0.5.gemfile.lock +19 -12
  68. data/gemfiles/active_record-3.1.1.gemfile +2 -1
  69. data/gemfiles/active_record-3.1.1.gemfile.lock +22 -16
  70. data/gemfiles/active_record-3.2.12.gemfile +9 -0
  71. data/gemfiles/active_record-3.2.12.gemfile.lock +51 -0
  72. data/gemfiles/active_record-3.2.13.rc1.gemfile +9 -0
  73. data/gemfiles/active_record-3.2.13.rc1.gemfile.lock +51 -0
  74. data/gemfiles/active_record-4.0.0.gemfile +11 -0
  75. data/gemfiles/active_record-4.0.0.gemfile.lock +83 -0
  76. data/gemfiles/data_mapper-0.10.2.gemfile +1 -0
  77. data/gemfiles/data_mapper-0.10.2.gemfile.lock +13 -9
  78. data/gemfiles/data_mapper-0.9.11.gemfile +1 -0
  79. data/gemfiles/data_mapper-0.9.11.gemfile.lock +31 -7
  80. data/gemfiles/data_mapper-0.9.4.gemfile.lock +25 -14
  81. data/gemfiles/data_mapper-0.9.7.gemfile +1 -0
  82. data/gemfiles/data_mapper-0.9.7.gemfile.lock +27 -15
  83. data/gemfiles/data_mapper-1.0.0.gemfile.lock +20 -17
  84. data/gemfiles/data_mapper-1.0.1.gemfile.lock +20 -17
  85. data/gemfiles/data_mapper-1.0.2.gemfile.lock +20 -17
  86. data/gemfiles/data_mapper-1.1.0.gemfile.lock +19 -16
  87. data/gemfiles/data_mapper-1.2.0.gemfile.lock +19 -16
  88. data/gemfiles/default.gemfile.lock +8 -5
  89. data/gemfiles/graphviz-0.9.17.gemfile +7 -0
  90. data/gemfiles/graphviz-0.9.17.gemfile.lock +29 -0
  91. data/gemfiles/graphviz-0.9.21.gemfile.lock +7 -4
  92. data/gemfiles/graphviz-1.0.0.gemfile.lock +7 -4
  93. data/gemfiles/graphviz-1.0.3.gemfile +7 -0
  94. data/gemfiles/graphviz-1.0.3.gemfile.lock +29 -0
  95. data/gemfiles/graphviz-1.0.8.gemfile +7 -0
  96. data/gemfiles/graphviz-1.0.8.gemfile.lock +29 -0
  97. data/gemfiles/mongo_mapper-0.10.0.gemfile +1 -0
  98. data/gemfiles/mongo_mapper-0.10.0.gemfile.lock +14 -11
  99. data/gemfiles/mongo_mapper-0.11.1.gemfile +7 -0
  100. data/gemfiles/mongo_mapper-0.11.1.gemfile.lock +44 -0
  101. data/gemfiles/mongo_mapper-0.11.2.gemfile +9 -0
  102. data/gemfiles/mongo_mapper-0.11.2.gemfile.lock +48 -0
  103. data/gemfiles/mongo_mapper-0.12.0.gemfile +9 -0
  104. data/gemfiles/mongo_mapper-0.12.0.gemfile.lock +48 -0
  105. data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +7 -4
  106. data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +7 -4
  107. data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +7 -4
  108. data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +7 -4
  109. data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +7 -4
  110. data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +7 -4
  111. data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +7 -4
  112. data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +7 -4
  113. data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +7 -4
  114. data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +7 -4
  115. data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +7 -4
  116. data/gemfiles/mongoid-2.0.0.gemfile +2 -0
  117. data/gemfiles/mongoid-2.0.0.gemfile.lock +22 -18
  118. data/gemfiles/mongoid-2.1.4.gemfile +2 -0
  119. data/gemfiles/mongoid-2.1.4.gemfile.lock +21 -17
  120. data/gemfiles/mongoid-2.2.4.gemfile +2 -0
  121. data/gemfiles/mongoid-2.2.4.gemfile.lock +21 -17
  122. data/gemfiles/mongoid-2.3.3.gemfile +2 -0
  123. data/gemfiles/mongoid-2.3.3.gemfile.lock +21 -17
  124. data/gemfiles/mongoid-2.4.0.gemfile +9 -0
  125. data/gemfiles/mongoid-2.4.0.gemfile.lock +47 -0
  126. data/gemfiles/mongoid-2.4.10.gemfile +9 -0
  127. data/gemfiles/mongoid-2.4.10.gemfile.lock +47 -0
  128. data/gemfiles/mongoid-2.5.2.gemfile +9 -0
  129. data/gemfiles/mongoid-2.5.2.gemfile.lock +47 -0
  130. data/gemfiles/mongoid-2.6.0.gemfile +9 -0
  131. data/gemfiles/mongoid-2.6.0.gemfile.lock +47 -0
  132. data/gemfiles/mongoid-3.0.0.gemfile +8 -0
  133. data/gemfiles/mongoid-3.0.0.gemfile.lock +45 -0
  134. data/gemfiles/mongoid-3.0.22.gemfile +8 -0
  135. data/gemfiles/mongoid-3.0.22.gemfile.lock +45 -0
  136. data/gemfiles/mongoid-3.1.0.gemfile +8 -0
  137. data/gemfiles/mongoid-3.1.0.gemfile.lock +45 -0
  138. data/gemfiles/sequel-2.11.0.gemfile +2 -1
  139. data/gemfiles/sequel-2.11.0.gemfile.lock +11 -6
  140. data/gemfiles/sequel-2.12.0.gemfile +2 -1
  141. data/gemfiles/sequel-2.12.0.gemfile.lock +11 -6
  142. data/gemfiles/sequel-2.8.0.gemfile +2 -1
  143. data/gemfiles/sequel-2.8.0.gemfile.lock +11 -6
  144. data/gemfiles/sequel-3.0.0.gemfile +2 -1
  145. data/gemfiles/sequel-3.0.0.gemfile.lock +11 -6
  146. data/gemfiles/sequel-3.10.0.gemfile +9 -0
  147. data/gemfiles/sequel-3.10.0.gemfile.lock +33 -0
  148. data/gemfiles/sequel-3.13.0.gemfile +2 -1
  149. data/gemfiles/sequel-3.13.0.gemfile.lock +11 -6
  150. data/gemfiles/sequel-3.14.0.gemfile +2 -1
  151. data/gemfiles/sequel-3.14.0.gemfile.lock +11 -6
  152. data/gemfiles/sequel-3.23.0.gemfile +2 -1
  153. data/gemfiles/sequel-3.23.0.gemfile.lock +11 -6
  154. data/gemfiles/sequel-3.24.0.gemfile +2 -1
  155. data/gemfiles/sequel-3.24.0.gemfile.lock +11 -6
  156. data/gemfiles/sequel-3.29.0.gemfile +2 -1
  157. data/gemfiles/sequel-3.29.0.gemfile.lock +11 -6
  158. data/gemfiles/sequel-3.34.0.gemfile +9 -0
  159. data/gemfiles/sequel-3.34.0.gemfile.lock +33 -0
  160. data/gemfiles/sequel-3.35.0.gemfile +9 -0
  161. data/gemfiles/sequel-3.35.0.gemfile.lock +33 -0
  162. data/gemfiles/sequel-3.4.0.gemfile +9 -0
  163. data/gemfiles/sequel-3.4.0.gemfile.lock +33 -0
  164. data/gemfiles/sequel-3.44.0.gemfile +9 -0
  165. data/gemfiles/sequel-3.44.0.gemfile.lock +33 -0
  166. data/lib/state_machine.rb +6 -0
  167. data/lib/state_machine/branch.rb +9 -8
  168. data/lib/state_machine/callback.rb +2 -2
  169. data/lib/state_machine/core.rb +10 -0
  170. data/lib/state_machine/core_ext.rb +1 -0
  171. data/lib/state_machine/eval_helpers.rb +5 -3
  172. data/lib/state_machine/event.rb +17 -6
  173. data/lib/state_machine/graph.rb +92 -0
  174. data/lib/state_machine/integrations.rb +13 -1
  175. data/lib/state_machine/integrations/active_model.rb +14 -20
  176. data/lib/state_machine/integrations/active_model/observer.rb +3 -3
  177. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  178. data/lib/state_machine/integrations/active_record.rb +52 -25
  179. data/lib/state_machine/integrations/active_record/locale.rb +1 -1
  180. data/lib/state_machine/integrations/active_record/versions.rb +1 -17
  181. data/lib/state_machine/integrations/base.rb +15 -6
  182. data/lib/state_machine/integrations/data_mapper.rb +98 -35
  183. data/lib/state_machine/integrations/data_mapper/versions.rb +46 -8
  184. data/lib/state_machine/integrations/mongo_mapper.rb +39 -12
  185. data/lib/state_machine/integrations/mongo_mapper/locale.rb +1 -1
  186. data/lib/state_machine/integrations/mongo_mapper/versions.rb +3 -20
  187. data/lib/state_machine/integrations/mongoid.rb +52 -14
  188. data/lib/state_machine/integrations/mongoid/locale.rb +1 -1
  189. data/lib/state_machine/integrations/mongoid/versions.rb +52 -26
  190. data/lib/state_machine/integrations/sequel.rb +82 -33
  191. data/lib/state_machine/integrations/sequel/versions.rb +19 -44
  192. data/lib/state_machine/machine.rb +99 -59
  193. data/lib/state_machine/machine_collection.rb +1 -2
  194. data/lib/state_machine/macro_methods.rb +29 -0
  195. data/lib/state_machine/node_collection.rb +1 -1
  196. data/lib/state_machine/state.rb +18 -10
  197. data/lib/state_machine/state_context.rb +2 -2
  198. data/lib/state_machine/transition.rb +8 -1
  199. data/lib/state_machine/transition_collection.rb +2 -1
  200. data/lib/state_machine/version.rb +1 -1
  201. data/lib/state_machine/yard.rb +8 -0
  202. data/lib/state_machine/yard/handlers.rb +12 -0
  203. data/lib/state_machine/yard/handlers/base.rb +32 -0
  204. data/lib/state_machine/yard/handlers/event.rb +25 -0
  205. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  206. data/lib/state_machine/yard/handlers/state.rb +25 -0
  207. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  208. data/lib/state_machine/yard/templates.rb +3 -0
  209. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  210. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  211. data/lib/tasks/state_machine.rb +2 -1
  212. data/lib/yard-state_machine.rb +2 -0
  213. data/state_machine.gemspec +4 -3
  214. data/test/files/switch.rb +4 -0
  215. data/test/test_helper.rb +5 -0
  216. data/test/unit/branch_test.rb +117 -36
  217. data/test/unit/callback_test.rb +5 -2
  218. data/test/unit/eval_helpers_test.rb +49 -1
  219. data/test/unit/event_collection_test.rb +3 -1
  220. data/test/unit/event_test.rb +182 -12
  221. data/test/unit/graph_test.rb +98 -0
  222. data/test/unit/integrations/active_model_test.rb +82 -12
  223. data/test/unit/integrations/active_record_test.rb +393 -37
  224. data/test/unit/integrations/base_test.rb +7 -2
  225. data/test/unit/integrations/data_mapper_test.rb +326 -72
  226. data/test/unit/integrations/mongo_mapper_test.rb +338 -44
  227. data/test/unit/integrations/mongoid_test.rb +606 -98
  228. data/test/unit/integrations/sequel_test.rb +429 -102
  229. data/test/unit/integrations_test.rb +28 -6
  230. data/test/unit/machine_collection_test.rb +6 -2
  231. data/test/unit/machine_test.rb +134 -82
  232. data/test/unit/node_collection_test.rb +2 -2
  233. data/test/unit/path_test.rb +1 -1
  234. data/test/unit/state_test.rb +65 -21
  235. data/test/unit/transition_collection_test.rb +43 -23
  236. data/test/unit/transition_test.rb +8 -2
  237. metadata +303 -221
  238. data/gemfiles/active_model-3.2.0.gemfile.lock +0 -32
  239. data/gemfiles/active_record-3.2.0.gemfile.lock +0 -43
  240. data/gemfiles/graphviz-0.9.0.gemfile.lock +0 -26
@@ -0,0 +1,3 @@
1
+ require 'yard'
2
+
3
+ YARD::Templates::Engine.register_template_path File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
@@ -0,0 +1,30 @@
1
+ require 'tempfile'
2
+
3
+ # Define where state machine descriptions will be rendered
4
+ def init
5
+ super
6
+ sections.place(:state_machine_details).before(:children)
7
+ end
8
+
9
+ # Renders state machine details in the main content of the class's documentation
10
+ def state_machine_details
11
+ erb(:state_machines) if state_machines
12
+ end
13
+
14
+ # Gets a list of state machines prased for this class
15
+ def state_machines
16
+ @state_machines ||= begin
17
+ if state_machines = object['state_machines']
18
+ state_machines.each do |name, machine|
19
+ serializer.serialize(state_machine_image_path(machine), machine[:image]) if machine[:image]
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ # Generates the image path for the given machine's visualization
26
+ def state_machine_image_path(machine)
27
+ base_path = File.dirname(serializer.serialized_path(object))
28
+ image_name = "#{object.name}_#{machine[:name]}"
29
+ "#{File.join(base_path, image_name)}.png"
30
+ end
@@ -0,0 +1,12 @@
1
+ <h2>State Machines</h2>
2
+
3
+ This class contains <%= state_machines.count %> state machine(s).
4
+
5
+ <% state_machines.each do |name, machine| %>
6
+ <h3><%= h(machine[:name]) %></h3>
7
+ <p><%= h(machine[:description]) %></p>
8
+
9
+ <% if machine[:image] %>
10
+ <img alt="State machine diagram for <%= h(machine[:name]) %>" src="<%= url_for(state_machine_image_path(machine)) %>" />
11
+ <% end %>
12
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  namespace :state_machine do
2
- desc 'Draws state machines using GraphViz (options: CLASS=User,Vehicle; FILE=user.rb,vehicle.rb [not required in Rails / Merb]; FONT=Arial; FORMAT=png; ORIENTATION=portrait'
2
+ desc 'Draws state machines using GraphViz (options: CLASS=User,Vehicle; FILE=user.rb,vehicle.rb [not required in Rails / Merb]; FONT=Arial; FORMAT=png; ORIENTATION=portrait; HUMAN_NAMES=true'
3
3
  task :draw do
4
4
  # Build drawing options
5
5
  options = {}
@@ -8,6 +8,7 @@ namespace :state_machine do
8
8
  options[:format] = ENV['FORMAT'] if ENV['FORMAT']
9
9
  options[:font] = ENV['FONT'] if ENV['FONT']
10
10
  options[:orientation] = ENV['ORIENTATION'] if ENV['ORIENTATION']
11
+ options[:human_names] = ENV['HUMAN_NAMES'] == 'true' if ENV['HUMAN_NAMES']
11
12
 
12
13
  if defined?(Rails)
13
14
  puts "Files are automatically loaded in Rails; ignoring FILE option" if options.delete(:file)
@@ -0,0 +1,2 @@
1
+ require 'state_machine/core'
2
+ require 'state_machine/yard'
@@ -10,12 +10,13 @@ Gem::Specification.new do |s|
10
10
  s.description = "Adds support for creating state machines for attributes on any Ruby class"
11
11
  s.summary = "State machines for attributes"
12
12
  s.require_paths = ["lib"]
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- test/*`.split("\n")
13
+ ignores = File.read(".gitignore").split.map {|i| i.sub(/\/$/, "/*").sub(/^[^\/]/, "**/\\0")}
14
+ s.files = (Dir[".*"] + Dir["**/*"]).select {|f| File.file?(f) && !ignores.any? {|i| File.fnmatch(i, "/#{f}")}}
15
+ s.test_files = s.files.grep(/^test\//)
15
16
  s.rdoc_options = %w(--line-numbers --inline-source --title state_machine --main README.md)
16
17
  s.extra_rdoc_files = %w(README.md CHANGELOG.md LICENSE)
17
18
 
18
19
  s.add_development_dependency("rake")
19
- s.add_development_dependency("rcov")
20
+ s.add_development_dependency("simplecov")
20
21
  s.add_development_dependency("appraisal", "~> 0.4.0")
21
22
  end
@@ -1,4 +1,8 @@
1
1
  class Switch
2
+ def self.name
3
+ @name ||= "Switch_#{rand(1000000)}"
4
+ end
5
+
2
6
  state_machine do
3
7
  event :turn_on do
4
8
  transition all => :on
@@ -1,2 +1,7 @@
1
+ if ENV['COVERAGE']
2
+ require 'simplecov'
3
+ SimpleCov.start { add_filter '/test/' }
4
+ end
5
+
1
6
  require 'test/unit'
2
7
  require 'state_machine'
@@ -125,6 +125,25 @@ class BranchWithMultipleFromRequirementsTest < Test::Unit::TestCase
125
125
  end
126
126
  end
127
127
 
128
+ class BranchWithFromMatcherRequirementTest < Test::Unit::TestCase
129
+ def setup
130
+ @object = Object.new
131
+ @branch = StateMachine::Branch.new(:from => StateMachine::BlacklistMatcher.new([:idling, :parked]))
132
+ end
133
+
134
+ def test_should_match_if_included
135
+ assert @branch.matches?(@object, :from => :first_gear)
136
+ end
137
+
138
+ def test_should_not_match_if_not_included
139
+ assert !@branch.matches?(@object, :from => :idling)
140
+ end
141
+
142
+ def test_include_values_in_known_states
143
+ assert_equal [:idling, :parked], @branch.known_states
144
+ end
145
+ end
146
+
128
147
  class BranchWithToRequirementTest < Test::Unit::TestCase
129
148
  def setup
130
149
  @object = Object.new
@@ -188,6 +207,25 @@ class BranchWithMultipleToRequirementsTest < Test::Unit::TestCase
188
207
  end
189
208
  end
190
209
 
210
+ class BranchWithToMatcherRequirementTest < Test::Unit::TestCase
211
+ def setup
212
+ @object = Object.new
213
+ @branch = StateMachine::Branch.new(:to => StateMachine::BlacklistMatcher.new([:idling, :parked]))
214
+ end
215
+
216
+ def test_should_match_if_included
217
+ assert @branch.matches?(@object, :to => :first_gear)
218
+ end
219
+
220
+ def test_should_not_match_if_not_included
221
+ assert !@branch.matches?(@object, :to => :idling)
222
+ end
223
+
224
+ def test_include_values_in_known_states
225
+ assert_equal [:idling, :parked], @branch.known_states
226
+ end
227
+ end
228
+
191
229
  class BranchWithOnRequirementTest < Test::Unit::TestCase
192
230
  def setup
193
231
  @object = Object.new
@@ -247,6 +285,21 @@ class BranchWithMultipleOnRequirementsTest < Test::Unit::TestCase
247
285
  end
248
286
  end
249
287
 
288
+ class BranchWithOnMatcherRequirementTest < Test::Unit::TestCase
289
+ def setup
290
+ @object = Object.new
291
+ @branch = StateMachine::Branch.new(:on => StateMachine::BlacklistMatcher.new([:ignite, :park]))
292
+ end
293
+
294
+ def test_should_match_if_included
295
+ assert @branch.matches?(@object, :on => :shift_up)
296
+ end
297
+
298
+ def test_should_not_match_if_not_included
299
+ assert !@branch.matches?(@object, :on => :ignite)
300
+ end
301
+ end
302
+
250
303
  class BranchWithExceptFromRequirementTest < Test::Unit::TestCase
251
304
  def setup
252
305
  @object = Object.new
@@ -301,6 +354,13 @@ class BranchWithMultipleExceptFromRequirementsTest < Test::Unit::TestCase
301
354
  end
302
355
  end
303
356
 
357
+ class BranchWithExceptFromMatcherRequirementTest < Test::Unit::TestCase
358
+ def test_should_raise_an_exception
359
+ exception = assert_raise(ArgumentError) { StateMachine::Branch.new(:except_from => StateMachine::AllMatcher.instance) }
360
+ assert_equal ':except_from option cannot use matchers; use :from instead', exception.message
361
+ end
362
+ end
363
+
304
364
  class BranchWithExceptToRequirementTest < Test::Unit::TestCase
305
365
  def setup
306
366
  @object = Object.new
@@ -355,6 +415,13 @@ class BranchWithMultipleExceptToRequirementsTest < Test::Unit::TestCase
355
415
  end
356
416
  end
357
417
 
418
+ class BranchWithExceptToMatcherRequirementTest < Test::Unit::TestCase
419
+ def test_should_raise_an_exception
420
+ exception = assert_raise(ArgumentError) { StateMachine::Branch.new(:except_to => StateMachine::AllMatcher.instance) }
421
+ assert_equal ':except_to option cannot use matchers; use :to instead', exception.message
422
+ end
423
+ end
424
+
358
425
  class BranchWithExceptOnRequirementTest < Test::Unit::TestCase
359
426
  def setup
360
427
  @object = Object.new
@@ -390,6 +457,13 @@ class BranchWithExceptOnRequirementTest < Test::Unit::TestCase
390
457
  end
391
458
  end
392
459
 
460
+ class BranchWithExceptOnMatcherRequirementTest < Test::Unit::TestCase
461
+ def test_should_raise_an_exception
462
+ exception = assert_raise(ArgumentError) { StateMachine::Branch.new(:except_on => StateMachine::AllMatcher.instance) }
463
+ assert_equal ':except_on option cannot use matchers; use :on instead', exception.message
464
+ end
465
+ end
466
+
393
467
  class BranchWithMultipleExceptOnRequirementsTest < Test::Unit::TestCase
394
468
  def setup
395
469
  @object = Object.new
@@ -707,6 +781,10 @@ class BranchWithMultipleUnlessConditionalsTest < Test::Unit::TestCase
707
781
  end
708
782
 
709
783
  class BranchWithConflictingConditionalsTest < Test::Unit::TestCase
784
+ def setup
785
+ @object = Object.new
786
+ end
787
+
710
788
  def test_should_match_if_if_is_true_and_unless_is_false
711
789
  branch = StateMachine::Branch.new(:if => lambda {true}, :unless => lambda {false})
712
790
  assert branch.match(@object)
@@ -763,27 +841,28 @@ begin
763
841
  @machine = StateMachine::Machine.new(Class.new)
764
842
  states = [:parked, :idling]
765
843
 
766
- graph = GraphViz.new('G')
767
- states.each {|state| graph.add_node(state.to_s)}
844
+ @graph = StateMachine::Graph.new('test')
845
+ states.each {|state| @graph.add_nodes(state.to_s)}
768
846
 
769
847
  @branch = StateMachine::Branch.new(:from => :idling, :to => :parked)
770
- @edges = @branch.draw(graph, :park, states)
848
+ @branch.draw(@graph, :park, states)
849
+ @edge = @graph.get_edge_at_index(0)
771
850
  end
772
851
 
773
852
  def test_should_create_edges
774
- assert_equal 1, @edges.size
853
+ assert_equal 1, @graph.edge_count
775
854
  end
776
855
 
777
856
  def test_should_use_from_state_from_start_node
778
- assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne')
857
+ assert_equal 'idling', @edge.node_one(false)
779
858
  end
780
859
 
781
860
  def test_should_use_to_state_for_end_node
782
- assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo')
861
+ assert_equal 'parked', @edge.node_two(false)
783
862
  end
784
863
 
785
864
  def test_should_use_event_name_as_label
786
- assert_equal 'park', @edges.first['label'].to_s.gsub('"', '')
865
+ assert_equal 'park', @edge['label'].to_s.gsub('"', '')
787
866
  end
788
867
  end
789
868
 
@@ -792,18 +871,18 @@ begin
792
871
  @machine = StateMachine::Machine.new(Class.new)
793
872
  states = [:parked, :idling, :first_gear]
794
873
 
795
- graph = GraphViz.new('G')
796
- states.each {|state| graph.add_node(state.to_s)}
874
+ @graph = StateMachine::Graph.new('test')
875
+ states.each {|state| @graph.add_nodes(state.to_s)}
797
876
 
798
877
  @branch = StateMachine::Branch.new(:from => [:idling, :first_gear], :to => :parked)
799
- @edges = @branch.draw(graph, :park, states)
878
+ @branch.draw(@graph, :park, states)
800
879
  end
801
880
 
802
881
  def test_should_generate_edges_for_each_valid_from_state
803
882
  [:idling, :first_gear].each_with_index do |from_state, index|
804
- edge = @edges[index]
805
- assert_equal from_state.to_s, edge.instance_variable_get('@xNodeOne')
806
- assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
883
+ edge = @graph.get_edge_at_index(index)
884
+ assert_equal from_state.to_s, edge.node_one(false)
885
+ assert_equal 'parked', edge.node_two(false)
807
886
  end
808
887
  end
809
888
  end
@@ -813,18 +892,18 @@ begin
813
892
  @machine = StateMachine::Machine.new(Class.new)
814
893
  states = [:parked, :idling, :first_gear]
815
894
 
816
- graph = GraphViz.new('G')
817
- states.each {|state| graph.add_node(state.to_s)}
895
+ @graph = StateMachine::Graph.new('test')
896
+ states.each {|state| @graph.add_nodes(state.to_s)}
818
897
 
819
898
  @branch = StateMachine::Branch.new(:except_from => :parked, :to => :parked)
820
- @edges = @branch.draw(graph, :park, states)
899
+ @branch.draw(@graph, :park, states)
821
900
  end
822
901
 
823
902
  def test_should_generate_edges_for_each_valid_from_state
824
903
  %w(idling first_gear).each_with_index do |from_state, index|
825
- edge = @edges[index]
826
- assert_equal from_state, edge.instance_variable_get('@xNodeOne')
827
- assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
904
+ edge = @graph.get_edge_at_index(index)
905
+ assert_equal from_state, edge.node_one(false)
906
+ assert_equal 'parked', edge.node_two(false)
828
907
  end
829
908
  end
830
909
  end
@@ -834,18 +913,18 @@ begin
834
913
  @machine = StateMachine::Machine.new(Class.new)
835
914
  states = [:parked, :idling, :first_gear]
836
915
 
837
- graph = GraphViz.new('G')
838
- states.each {|state| graph.add_node(state.to_s)}
916
+ @graph = StateMachine::Graph.new('test')
917
+ states.each {|state| @graph.add_nodes(state.to_s)}
839
918
 
840
919
  @branch = StateMachine::Branch.new(:to => :parked)
841
- @edges = @branch.draw(graph, :park, states)
920
+ @branch.draw(@graph, :park, states)
842
921
  end
843
922
 
844
923
  def test_should_generate_edges_for_each_valid_from_state
845
924
  %w(parked idling first_gear).each_with_index do |from_state, index|
846
- edge = @edges[index]
847
- assert_equal from_state, edge.instance_variable_get('@xNodeOne')
848
- assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
925
+ edge = @graph.get_edge_at_index(index)
926
+ assert_equal from_state, edge.node_one(false)
927
+ assert_equal 'parked', edge.node_two(false)
849
928
  end
850
929
  end
851
930
  end
@@ -854,16 +933,17 @@ begin
854
933
  def setup
855
934
  @machine = StateMachine::Machine.new(Class.new)
856
935
 
857
- graph = GraphViz.new('G')
858
- graph.add_node('parked')
936
+ graph = StateMachine::Graph.new('test')
937
+ graph.add_nodes('parked')
859
938
 
860
939
  @branch = StateMachine::Branch.new(:from => :parked)
861
- @edges = @branch.draw(graph, :park, [:parked])
940
+ @branch.draw(graph, :park, [:parked])
941
+ @edge = graph.get_edge_at_index(0)
862
942
  end
863
943
 
864
944
  def test_should_create_loopback_edge
865
- assert_equal 'parked', @edges.first.instance_variable_get('@xNodeOne')
866
- assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo')
945
+ assert_equal 'parked', @edge.node_one(false)
946
+ assert_equal 'parked', @edge.node_two(false)
867
947
  end
868
948
  end
869
949
 
@@ -871,18 +951,19 @@ begin
871
951
  def setup
872
952
  @machine = StateMachine::Machine.new(Class.new)
873
953
 
874
- graph = GraphViz.new('G')
875
- graph.add_node('parked')
954
+ graph = StateMachine::Graph.new('test')
955
+ graph.add_nodes('parked')
876
956
 
877
957
  @branch = StateMachine::Branch.new(:from => :idling, :to => nil)
878
- @edges = @branch.draw(graph, :park, [nil, :idling])
958
+ @branch.draw(graph, :park, [nil, :idling])
959
+ @edge = graph.get_edge_at_index(0)
879
960
  end
880
961
 
881
962
  def test_should_generate_edges_for_each_valid_from_state
882
- assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne')
883
- assert_equal 'nil', @edges.first.instance_variable_get('@xNodeTwo')
963
+ assert_equal 'idling', @edge.node_one(false)
964
+ assert_equal 'nil', @edge.node_two(false)
884
965
  end
885
966
  end
886
967
  rescue LoadError
887
- $stderr.puts 'Skipping GraphViz StateMachine::Branch tests. `gem install ruby-graphviz` >= v0.9.0 and try again.'
968
+ $stderr.puts 'Skipping GraphViz StateMachine::Branch tests. `gem install ruby-graphviz` >= v0.9.17 and try again.'
888
969
  end unless ENV['TRAVIS']
@@ -485,7 +485,7 @@ end
485
485
 
486
486
  class CallbackWithApplicationTerminatorTest < Test::Unit::TestCase
487
487
  def setup
488
- @original_terminator = StateMachine::Callback.bind_to_object
488
+ @original_terminator = StateMachine::Callback.terminator
489
489
  StateMachine::Callback.terminator = lambda {|result| result == false}
490
490
 
491
491
  @object = Object.new
@@ -502,7 +502,7 @@ class CallbackWithApplicationTerminatorTest < Test::Unit::TestCase
502
502
  end
503
503
 
504
504
  def teardown
505
- StateMachine::Callback.bind_to_object = @original_bind_to_object
505
+ StateMachine::Callback.terminator = @original_terminator
506
506
  end
507
507
  end
508
508
 
@@ -597,6 +597,7 @@ class CallbackWithAroundTypeAndMultipleMethodsTest < Test::Unit::TestCase
597
597
 
598
598
  def test_should_halt_if_first_doesnt_yield
599
599
  class << @object
600
+ remove_method :run_1
600
601
  def run_1
601
602
  (@before_callbacks ||= []) << :run_1
602
603
  end
@@ -612,6 +613,7 @@ class CallbackWithAroundTypeAndMultipleMethodsTest < Test::Unit::TestCase
612
613
 
613
614
  def test_should_halt_if_last_doesnt_yield
614
615
  class << @object
616
+ remove_method :run_2
615
617
  def run_2
616
618
  (@before_callbacks ||= []) << :run_2
617
619
  end
@@ -624,6 +626,7 @@ class CallbackWithAroundTypeAndMultipleMethodsTest < Test::Unit::TestCase
624
626
 
625
627
  def test_should_not_evaluate_further_methods_if_after_halts
626
628
  class << @object
629
+ remove_method :run_2
627
630
  def run_2
628
631
  (@before_callbacks ||= []) << :run_2
629
632
  yield
@@ -14,7 +14,7 @@ class EvalHelpersTest < EvalHelpersBaseTest
14
14
 
15
15
  def test_should_raise_exception_if_method_is_not_symbol_string_or_proc
16
16
  exception = assert_raise(ArgumentError) { evaluate_method(@object, 1) }
17
- assert_match /Methods must/, exception.message
17
+ assert_match(/Methods must/, exception.message)
18
18
  end
19
19
  end
20
20
 
@@ -32,6 +32,36 @@ class EvalHelpersSymbolTest < EvalHelpersBaseTest
32
32
  end
33
33
  end
34
34
 
35
+ class EvalHelpersSymbolProtectedTest < EvalHelpersBaseTest
36
+ def setup
37
+ class << (@object = Object.new)
38
+ protected
39
+ def callback
40
+ true
41
+ end
42
+ end
43
+ end
44
+
45
+ def test_should_call_method_on_object_with_no_arguments
46
+ assert_equal true, evaluate_method(@object, :callback, 1, 2, 3)
47
+ end
48
+ end
49
+
50
+ class EvalHelpersSymbolPrivateTest < EvalHelpersBaseTest
51
+ def setup
52
+ class << (@object = Object.new)
53
+ private
54
+ def callback
55
+ true
56
+ end
57
+ end
58
+ end
59
+
60
+ def test_should_call_method_on_object_with_no_arguments
61
+ assert_equal true, evaluate_method(@object, :callback, 1, 2, 3)
62
+ end
63
+ end
64
+
35
65
  class EvalHelpersSymbolWithArgumentsTest < EvalHelpersBaseTest
36
66
  def setup
37
67
  class << (@object = Object.new)
@@ -90,6 +120,24 @@ class EvalHelpersSymbolTaintedMethodTest < EvalHelpersBaseTest
90
120
  end
91
121
  end
92
122
 
123
+ class EvalHelpersSymbolMethodMissingTest < EvalHelpersBaseTest
124
+ def setup
125
+ class << (@object = Object.new)
126
+ def method_missing(symbol, *args)
127
+ send("method_missing_#{symbol}", *args)
128
+ end
129
+
130
+ def method_missing_callback(*args)
131
+ args
132
+ end
133
+ end
134
+ end
135
+
136
+ def test_should_call_dynamic_method_with_all_arguments
137
+ assert_equal [1, 2, 3], evaluate_method(@object, :callback, 1, 2, 3)
138
+ end
139
+ end
140
+
93
141
  class EvalHelpersStringTest < EvalHelpersBaseTest
94
142
  def setup
95
143
  @object = Object.new