state_machine_updated_for_ruby_3_2 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +72 -0
  4. data/.yardopts +5 -0
  5. data/Appraisals +491 -0
  6. data/CHANGELOG.md +506 -0
  7. data/Dockerfile +13 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE +20 -0
  10. data/README.md +1244 -0
  11. data/Rakefile +41 -0
  12. data/examples/AutoShop_state.png +0 -0
  13. data/examples/Car_state.png +0 -0
  14. data/examples/Gemfile +5 -0
  15. data/examples/Gemfile.lock +14 -0
  16. data/examples/TrafficLight_state.png +0 -0
  17. data/examples/Vehicle_state.png +0 -0
  18. data/examples/auto_shop.rb +13 -0
  19. data/examples/car.rb +21 -0
  20. data/examples/doc/AutoShop.html +2856 -0
  21. data/examples/doc/AutoShop_state.png +0 -0
  22. data/examples/doc/Car.html +919 -0
  23. data/examples/doc/Car_state.png +0 -0
  24. data/examples/doc/TrafficLight.html +2230 -0
  25. data/examples/doc/TrafficLight_state.png +0 -0
  26. data/examples/doc/Vehicle.html +7921 -0
  27. data/examples/doc/Vehicle_state.png +0 -0
  28. data/examples/doc/_index.html +136 -0
  29. data/examples/doc/class_list.html +47 -0
  30. data/examples/doc/css/common.css +1 -0
  31. data/examples/doc/css/full_list.css +55 -0
  32. data/examples/doc/css/style.css +322 -0
  33. data/examples/doc/file_list.html +46 -0
  34. data/examples/doc/frames.html +13 -0
  35. data/examples/doc/index.html +136 -0
  36. data/examples/doc/js/app.js +205 -0
  37. data/examples/doc/js/full_list.js +173 -0
  38. data/examples/doc/js/jquery.js +16 -0
  39. data/examples/doc/method_list.html +734 -0
  40. data/examples/doc/top-level-namespace.html +105 -0
  41. data/examples/merb-rest/controller.rb +51 -0
  42. data/examples/merb-rest/model.rb +28 -0
  43. data/examples/merb-rest/view_edit.html.erb +24 -0
  44. data/examples/merb-rest/view_index.html.erb +23 -0
  45. data/examples/merb-rest/view_new.html.erb +13 -0
  46. data/examples/merb-rest/view_show.html.erb +17 -0
  47. data/examples/rails-rest/controller.rb +43 -0
  48. data/examples/rails-rest/migration.rb +7 -0
  49. data/examples/rails-rest/model.rb +23 -0
  50. data/examples/rails-rest/view__form.html.erb +34 -0
  51. data/examples/rails-rest/view_edit.html.erb +6 -0
  52. data/examples/rails-rest/view_index.html.erb +25 -0
  53. data/examples/rails-rest/view_new.html.erb +5 -0
  54. data/examples/rails-rest/view_show.html.erb +19 -0
  55. data/examples/traffic_light.rb +9 -0
  56. data/examples/vehicle.rb +33 -0
  57. data/gemfiles/active_model_3.0.0.gemfile +7 -0
  58. data/gemfiles/active_model_3.0.0.gemfile.lock +35 -0
  59. data/gemfiles/active_model_3.0.5.gemfile +7 -0
  60. data/gemfiles/active_model_3.0.5.gemfile.lock +35 -0
  61. data/gemfiles/active_model_3.1.1.gemfile +7 -0
  62. data/gemfiles/active_model_3.1.1.gemfile.lock +36 -0
  63. data/gemfiles/active_model_3.2.1.gemfile +7 -0
  64. data/gemfiles/active_model_3.2.12.gemfile +7 -0
  65. data/gemfiles/active_model_3.2.12.gemfile.lock +36 -0
  66. data/gemfiles/active_model_3.2.13.rc1.gemfile +7 -0
  67. data/gemfiles/active_model_3.2.13.rc1.gemfile.lock +36 -0
  68. data/gemfiles/active_model_4.0.0.gemfile +9 -0
  69. data/gemfiles/active_model_4.0.0.gemfile.lock +78 -0
  70. data/gemfiles/active_record_2.0.0.gemfile +9 -0
  71. data/gemfiles/active_record_2.0.0.gemfile.lock +39 -0
  72. data/gemfiles/active_record_2.0.5.gemfile +9 -0
  73. data/gemfiles/active_record_2.0.5.gemfile.lock +39 -0
  74. data/gemfiles/active_record_2.1.0.gemfile +9 -0
  75. data/gemfiles/active_record_2.1.0.gemfile.lock +39 -0
  76. data/gemfiles/active_record_2.1.2.gemfile +9 -0
  77. data/gemfiles/active_record_2.1.2.gemfile.lock +39 -0
  78. data/gemfiles/active_record_2.2.3.gemfile +9 -0
  79. data/gemfiles/active_record_2.2.3.gemfile.lock +39 -0
  80. data/gemfiles/active_record_2.3.12.gemfile +9 -0
  81. data/gemfiles/active_record_2.3.12.gemfile.lock +39 -0
  82. data/gemfiles/active_record_2.3.5.gemfile +9 -0
  83. data/gemfiles/active_record_2.3.5.gemfile.lock +39 -0
  84. data/gemfiles/active_record_3.0.0.gemfile +9 -0
  85. data/gemfiles/active_record_3.0.0.gemfile.lock +51 -0
  86. data/gemfiles/active_record_3.0.5.gemfile +9 -0
  87. data/gemfiles/active_record_3.0.5.gemfile.lock +50 -0
  88. data/gemfiles/active_record_3.1.1.gemfile +9 -0
  89. data/gemfiles/active_record_3.1.1.gemfile.lock +51 -0
  90. data/gemfiles/active_record_3.2.12.gemfile +9 -0
  91. data/gemfiles/active_record_3.2.12.gemfile.lock +51 -0
  92. data/gemfiles/active_record_3.2.13.rc1.gemfile +9 -0
  93. data/gemfiles/active_record_3.2.13.rc1.gemfile.lock +51 -0
  94. data/gemfiles/active_record_4.0.0.gemfile +11 -0
  95. data/gemfiles/active_record_4.0.0.gemfile.lock +83 -0
  96. data/gemfiles/data_mapper_0.10.2.gemfile +13 -0
  97. data/gemfiles/data_mapper_0.10.2.gemfile.lock +56 -0
  98. data/gemfiles/data_mapper_0.9.11.gemfile +13 -0
  99. data/gemfiles/data_mapper_0.9.11.gemfile.lock +71 -0
  100. data/gemfiles/data_mapper_0.9.4.gemfile +12 -0
  101. data/gemfiles/data_mapper_0.9.4.gemfile.lock +70 -0
  102. data/gemfiles/data_mapper_0.9.7.gemfile +13 -0
  103. data/gemfiles/data_mapper_0.9.7.gemfile.lock +67 -0
  104. data/gemfiles/data_mapper_1.0.0.gemfile +12 -0
  105. data/gemfiles/data_mapper_1.0.0.gemfile.lock +63 -0
  106. data/gemfiles/data_mapper_1.0.1.gemfile +12 -0
  107. data/gemfiles/data_mapper_1.0.1.gemfile.lock +63 -0
  108. data/gemfiles/data_mapper_1.0.2.gemfile +12 -0
  109. data/gemfiles/data_mapper_1.0.2.gemfile.lock +63 -0
  110. data/gemfiles/data_mapper_1.1.0.gemfile +12 -0
  111. data/gemfiles/data_mapper_1.1.0.gemfile.lock +61 -0
  112. data/gemfiles/data_mapper_1.2.0.gemfile +12 -0
  113. data/gemfiles/data_mapper_1.2.0.gemfile.lock +61 -0
  114. data/gemfiles/default.gemfile +7 -0
  115. data/gemfiles/default.gemfile.lock +27 -0
  116. data/gemfiles/graphviz_0.9.17.gemfile +7 -0
  117. data/gemfiles/graphviz_0.9.17.gemfile.lock +29 -0
  118. data/gemfiles/graphviz_0.9.21.gemfile +7 -0
  119. data/gemfiles/graphviz_0.9.21.gemfile.lock +29 -0
  120. data/gemfiles/graphviz_1.0.0.gemfile +7 -0
  121. data/gemfiles/graphviz_1.0.0.gemfile.lock +29 -0
  122. data/gemfiles/graphviz_1.0.3.gemfile +7 -0
  123. data/gemfiles/graphviz_1.0.3.gemfile.lock +29 -0
  124. data/gemfiles/graphviz_1.0.8.gemfile +7 -0
  125. data/gemfiles/graphviz_1.0.8.gemfile.lock +29 -0
  126. data/gemfiles/mongo_mapper_0.10.0.gemfile +8 -0
  127. data/gemfiles/mongo_mapper_0.10.0.gemfile.lock +47 -0
  128. data/gemfiles/mongo_mapper_0.11.2.gemfile +9 -0
  129. data/gemfiles/mongo_mapper_0.11.2.gemfile.lock +48 -0
  130. data/gemfiles/mongo_mapper_0.12.0.gemfile +9 -0
  131. data/gemfiles/mongo_mapper_0.12.0.gemfile.lock +48 -0
  132. data/gemfiles/mongo_mapper_0.5.5.gemfile +8 -0
  133. data/gemfiles/mongo_mapper_0.5.5.gemfile.lock +36 -0
  134. data/gemfiles/mongo_mapper_0.5.8.gemfile +8 -0
  135. data/gemfiles/mongo_mapper_0.5.8.gemfile.lock +36 -0
  136. data/gemfiles/mongo_mapper_0.6.0.gemfile +8 -0
  137. data/gemfiles/mongo_mapper_0.6.0.gemfile.lock +36 -0
  138. data/gemfiles/mongo_mapper_0.6.10.gemfile +8 -0
  139. data/gemfiles/mongo_mapper_0.6.10.gemfile.lock +36 -0
  140. data/gemfiles/mongo_mapper_0.7.0.gemfile +8 -0
  141. data/gemfiles/mongo_mapper_0.7.0.gemfile.lock +36 -0
  142. data/gemfiles/mongo_mapper_0.7.5.gemfile +8 -0
  143. data/gemfiles/mongo_mapper_0.7.5.gemfile.lock +39 -0
  144. data/gemfiles/mongo_mapper_0.8.0.gemfile +10 -0
  145. data/gemfiles/mongo_mapper_0.8.0.gemfile.lock +43 -0
  146. data/gemfiles/mongo_mapper_0.8.3.gemfile +10 -0
  147. data/gemfiles/mongo_mapper_0.8.3.gemfile.lock +43 -0
  148. data/gemfiles/mongo_mapper_0.8.4.gemfile +8 -0
  149. data/gemfiles/mongo_mapper_0.8.4.gemfile.lock +42 -0
  150. data/gemfiles/mongo_mapper_0.8.6.gemfile +8 -0
  151. data/gemfiles/mongo_mapper_0.8.6.gemfile.lock +42 -0
  152. data/gemfiles/mongo_mapper_0.9.0.gemfile +7 -0
  153. data/gemfiles/mongo_mapper_0.9.0.gemfile.lock +45 -0
  154. data/gemfiles/mongoid_2.0.0.gemfile +9 -0
  155. data/gemfiles/mongoid_2.0.0.gemfile.lock +49 -0
  156. data/gemfiles/mongoid_2.1.4.gemfile +9 -0
  157. data/gemfiles/mongoid_2.1.4.gemfile.lock +47 -0
  158. data/gemfiles/mongoid_2.2.4.gemfile +9 -0
  159. data/gemfiles/mongoid_2.2.4.gemfile.lock +47 -0
  160. data/gemfiles/mongoid_2.3.3.gemfile +9 -0
  161. data/gemfiles/mongoid_2.3.3.gemfile.lock +47 -0
  162. data/gemfiles/mongoid_2.4.0.gemfile +9 -0
  163. data/gemfiles/mongoid_2.4.0.gemfile.lock +47 -0
  164. data/gemfiles/mongoid_2.4.10.gemfile +9 -0
  165. data/gemfiles/mongoid_2.4.10.gemfile.lock +47 -0
  166. data/gemfiles/mongoid_2.5.2.gemfile +9 -0
  167. data/gemfiles/mongoid_2.5.2.gemfile.lock +47 -0
  168. data/gemfiles/mongoid_2.6.0.gemfile +9 -0
  169. data/gemfiles/mongoid_2.6.0.gemfile.lock +47 -0
  170. data/gemfiles/mongoid_3.0.0.gemfile +8 -0
  171. data/gemfiles/mongoid_3.0.0.gemfile.lock +45 -0
  172. data/gemfiles/mongoid_3.0.22.gemfile +8 -0
  173. data/gemfiles/mongoid_3.0.22.gemfile.lock +45 -0
  174. data/gemfiles/mongoid_3.1.0.gemfile +8 -0
  175. data/gemfiles/mongoid_3.1.0.gemfile.lock +45 -0
  176. data/gemfiles/sequel_2.11.0.gemfile +9 -0
  177. data/gemfiles/sequel_2.11.0.gemfile.lock +33 -0
  178. data/gemfiles/sequel_2.12.0.gemfile +9 -0
  179. data/gemfiles/sequel_2.12.0.gemfile.lock +33 -0
  180. data/gemfiles/sequel_2.8.0.gemfile +9 -0
  181. data/gemfiles/sequel_2.8.0.gemfile.lock +33 -0
  182. data/gemfiles/sequel_3.0.0.gemfile +9 -0
  183. data/gemfiles/sequel_3.0.0.gemfile.lock +33 -0
  184. data/gemfiles/sequel_3.10.0.gemfile +9 -0
  185. data/gemfiles/sequel_3.10.0.gemfile.lock +33 -0
  186. data/gemfiles/sequel_3.13.0.gemfile +9 -0
  187. data/gemfiles/sequel_3.13.0.gemfile.lock +33 -0
  188. data/gemfiles/sequel_3.14.0.gemfile +9 -0
  189. data/gemfiles/sequel_3.14.0.gemfile.lock +33 -0
  190. data/gemfiles/sequel_3.23.0.gemfile +9 -0
  191. data/gemfiles/sequel_3.23.0.gemfile.lock +33 -0
  192. data/gemfiles/sequel_3.24.0.gemfile +9 -0
  193. data/gemfiles/sequel_3.24.0.gemfile.lock +33 -0
  194. data/gemfiles/sequel_3.29.0.gemfile +9 -0
  195. data/gemfiles/sequel_3.29.0.gemfile.lock +33 -0
  196. data/gemfiles/sequel_3.34.0.gemfile +9 -0
  197. data/gemfiles/sequel_3.34.0.gemfile.lock +33 -0
  198. data/gemfiles/sequel_3.35.0.gemfile +9 -0
  199. data/gemfiles/sequel_3.35.0.gemfile.lock +33 -0
  200. data/gemfiles/sequel_3.4.0.gemfile +9 -0
  201. data/gemfiles/sequel_3.4.0.gemfile.lock +33 -0
  202. data/gemfiles/sequel_3.44.0.gemfile +9 -0
  203. data/gemfiles/sequel_3.44.0.gemfile.lock +33 -0
  204. data/init.rb +1 -0
  205. data/lib/state_machine/assertions.rb +36 -0
  206. data/lib/state_machine/branch.rb +225 -0
  207. data/lib/state_machine/callback.rb +236 -0
  208. data/lib/state_machine/core.rb +12 -0
  209. data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
  210. data/lib/state_machine/core_ext.rb +2 -0
  211. data/lib/state_machine/error.rb +13 -0
  212. data/lib/state_machine/eval_helpers.rb +87 -0
  213. data/lib/state_machine/event.rb +257 -0
  214. data/lib/state_machine/event_collection.rb +141 -0
  215. data/lib/state_machine/extensions.rb +149 -0
  216. data/lib/state_machine/graph.rb +92 -0
  217. data/lib/state_machine/helper_module.rb +17 -0
  218. data/lib/state_machine/initializers/merb.rb +1 -0
  219. data/lib/state_machine/initializers/rails.rb +25 -0
  220. data/lib/state_machine/initializers.rb +4 -0
  221. data/lib/state_machine/integrations/active_model/locale.rb +11 -0
  222. data/lib/state_machine/integrations/active_model/observer.rb +33 -0
  223. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  224. data/lib/state_machine/integrations/active_model/versions.rb +31 -0
  225. data/lib/state_machine/integrations/active_model.rb +585 -0
  226. data/lib/state_machine/integrations/active_record/locale.rb +20 -0
  227. data/lib/state_machine/integrations/active_record/versions.rb +123 -0
  228. data/lib/state_machine/integrations/active_record.rb +548 -0
  229. data/lib/state_machine/integrations/base.rb +100 -0
  230. data/lib/state_machine/integrations/data_mapper/observer.rb +210 -0
  231. data/lib/state_machine/integrations/data_mapper/versions.rb +85 -0
  232. data/lib/state_machine/integrations/data_mapper.rb +511 -0
  233. data/lib/state_machine/integrations/mongo_mapper/locale.rb +4 -0
  234. data/lib/state_machine/integrations/mongo_mapper/versions.rb +89 -0
  235. data/lib/state_machine/integrations/mongo_mapper.rb +389 -0
  236. data/lib/state_machine/integrations/mongoid/locale.rb +4 -0
  237. data/lib/state_machine/integrations/mongoid/versions.rb +81 -0
  238. data/lib/state_machine/integrations/mongoid.rb +461 -0
  239. data/lib/state_machine/integrations/sequel/versions.rb +95 -0
  240. data/lib/state_machine/integrations/sequel.rb +486 -0
  241. data/lib/state_machine/integrations.rb +121 -0
  242. data/lib/state_machine/machine.rb +2292 -0
  243. data/lib/state_machine/machine_collection.rb +86 -0
  244. data/lib/state_machine/macro_methods.rb +522 -0
  245. data/lib/state_machine/matcher.rb +123 -0
  246. data/lib/state_machine/matcher_helpers.rb +54 -0
  247. data/lib/state_machine/node_collection.rb +222 -0
  248. data/lib/state_machine/path.rb +120 -0
  249. data/lib/state_machine/path_collection.rb +90 -0
  250. data/lib/state_machine/state.rb +297 -0
  251. data/lib/state_machine/state_collection.rb +112 -0
  252. data/lib/state_machine/state_context.rb +138 -0
  253. data/lib/state_machine/transition.rb +470 -0
  254. data/lib/state_machine/transition_collection.rb +245 -0
  255. data/lib/state_machine/version.rb +3 -0
  256. data/lib/state_machine/yard/handlers/base.rb +32 -0
  257. data/lib/state_machine/yard/handlers/event.rb +25 -0
  258. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  259. data/lib/state_machine/yard/handlers/state.rb +25 -0
  260. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  261. data/lib/state_machine/yard/handlers.rb +12 -0
  262. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  263. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  264. data/lib/state_machine/yard/templates.rb +3 -0
  265. data/lib/state_machine/yard.rb +8 -0
  266. data/lib/state_machine.rb +8 -0
  267. data/lib/tasks/state_machine.rake +1 -0
  268. data/lib/tasks/state_machine.rb +30 -0
  269. data/lib/yard-state_machine.rb +2 -0
  270. data/state_machine.gemspec +23 -0
  271. data/test/files/en.yml +17 -0
  272. data/test/files/switch.rb +15 -0
  273. data/test/functional/state_machine_test.rb +1066 -0
  274. data/test/test_helper.rb +7 -0
  275. data/test/unit/assertions_test.rb +40 -0
  276. data/test/unit/branch_test.rb +969 -0
  277. data/test/unit/callback_test.rb +704 -0
  278. data/test/unit/error_test.rb +43 -0
  279. data/test/unit/eval_helpers_test.rb +272 -0
  280. data/test/unit/event_collection_test.rb +398 -0
  281. data/test/unit/event_test.rb +1196 -0
  282. data/test/unit/graph_test.rb +98 -0
  283. data/test/unit/helper_module_test.rb +17 -0
  284. data/test/unit/integrations/active_model_test.rb +1245 -0
  285. data/test/unit/integrations/active_record_test.rb +2551 -0
  286. data/test/unit/integrations/base_test.rb +104 -0
  287. data/test/unit/integrations/data_mapper_test.rb +2194 -0
  288. data/test/unit/integrations/mongo_mapper_test.rb +2026 -0
  289. data/test/unit/integrations/mongoid_test.rb +2309 -0
  290. data/test/unit/integrations/sequel_test.rb +1896 -0
  291. data/test/unit/integrations_test.rb +83 -0
  292. data/test/unit/invalid_event_test.rb +20 -0
  293. data/test/unit/invalid_parallel_transition_test.rb +18 -0
  294. data/test/unit/invalid_transition_test.rb +115 -0
  295. data/test/unit/machine_collection_test.rb +603 -0
  296. data/test/unit/machine_test.rb +3407 -0
  297. data/test/unit/matcher_helpers_test.rb +37 -0
  298. data/test/unit/matcher_test.rb +155 -0
  299. data/test/unit/node_collection_test.rb +362 -0
  300. data/test/unit/path_collection_test.rb +266 -0
  301. data/test/unit/path_test.rb +485 -0
  302. data/test/unit/state_collection_test.rb +352 -0
  303. data/test/unit/state_context_test.rb +441 -0
  304. data/test/unit/state_machine_test.rb +31 -0
  305. data/test/unit/state_test.rb +1101 -0
  306. data/test/unit/transition_collection_test.rb +2168 -0
  307. data/test/unit/transition_test.rb +1558 -0
  308. metadata +450 -0
@@ -0,0 +1,100 @@
1
+ module StateMachine
2
+ module Integrations
3
+ # Provides a set of base helpers for managing individual integrations
4
+ module Base
5
+ module ClassMethods
6
+ # The default options to use for state machines using this integration
7
+ attr_reader :defaults
8
+
9
+ # The name of the integration
10
+ def integration_name
11
+ @integration_name ||= begin
12
+ name = self.name.split('::').last
13
+ name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
14
+ name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
15
+ name.downcase!
16
+ name.to_sym
17
+ end
18
+ end
19
+
20
+ # Whether this integration is available for the current library. This
21
+ # is only true if the ORM that the integration is for is currently
22
+ # defined.
23
+ def available?
24
+ matching_ancestors.any? && Object.const_defined?(matching_ancestors[0].split('::')[0])
25
+ end
26
+
27
+ # The list of ancestor names that cause this integration to matched.
28
+ def matching_ancestors
29
+ []
30
+ end
31
+
32
+ # Whether the integration should be used for the given class.
33
+ def matches?(klass)
34
+ matches_ancestors?(klass.ancestors.map {|ancestor| ancestor.name})
35
+ end
36
+
37
+ # Whether the integration should be used for the given list of ancestors.
38
+ def matches_ancestors?(ancestors)
39
+ (ancestors & matching_ancestors).any?
40
+ end
41
+
42
+ # Tracks the various version overrides for an integration
43
+ def versions
44
+ @versions ||= []
45
+ end
46
+
47
+ # Creates a new version override for an integration. When this
48
+ # integration is activated, each version that is marked as active will
49
+ # also extend the integration.
50
+ #
51
+ # == Example
52
+ #
53
+ # module StateMachine
54
+ # module Integrations
55
+ # module ORMLibrary
56
+ # version '0.2.x - 0.3.x' do
57
+ # def self.active?
58
+ # ::ORMLibrary::VERSION >= '0.2.0' && ::ORMLibrary::VERSION < '0.4.0'
59
+ # end
60
+ #
61
+ # def invalidate(object, attribute, message, values = [])
62
+ # # Override here...
63
+ # end
64
+ # end
65
+ # end
66
+ # end
67
+ # end
68
+ #
69
+ # In the above example, a version override is defined for the ORMLibrary
70
+ # integration when the version is between 0.2.x and 0.3.x.
71
+ def version(name, &block)
72
+ versions << mod = Module.new(&block)
73
+ mod
74
+ end
75
+
76
+ # The path to the locale file containing translations for this
77
+ # integration. This file will only exist for integrations that actually
78
+ # support i18n.
79
+ def locale_path
80
+ path = "#{File.dirname(__FILE__)}/#{integration_name}/locale.rb"
81
+ path if File.exist?(path)
82
+ end
83
+
84
+ # Extends the given object with any version overrides that are currently
85
+ # active
86
+ def extended(base)
87
+ versions.each do |version|
88
+ base.extend(version) if version.active?
89
+ end
90
+ end
91
+ end
92
+
93
+ extend ClassMethods
94
+
95
+ def self.included(base) #:nodoc:
96
+ base.class_eval { extend ClassMethods }
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,210 @@
1
+ module StateMachine
2
+ module Integrations #:nodoc:
3
+ module DataMapper
4
+ # Adds support for creating before/after/around/failure transition
5
+ # callbacks within a DataMapper observer. These callbacks behave very
6
+ # similar to hooks during save/update/destroy/etc., but with the following
7
+ # modifications:
8
+ # * Each callback can define a set of transition requirements that must be
9
+ # met in order for the callback to get invoked.
10
+ # * An additional transition parameter is available that provides
11
+ # contextual information about the event (see StateMachine::Transition
12
+ # for more information)
13
+ #
14
+ # To define a single observer for multiple state machines:
15
+ #
16
+ # class StateMachineObserver
17
+ # include DataMapper::Observer
18
+ #
19
+ # observe Vehicle, Switch, Project
20
+ #
21
+ # after_transition do |transition|
22
+ # Audit.log(self, transition)
23
+ # end
24
+ # end
25
+ #
26
+ # == Requirements
27
+ #
28
+ # To use this feature of the DataMapper integration, the dm-observer library
29
+ # must be available. This can be installed either directly or indirectly
30
+ # through dm-more. When loading DataMapper, be sure to load the dm-observer
31
+ # library as well like so:
32
+ #
33
+ # require 'rubygems'
34
+ # require 'dm-core'
35
+ # require 'dm-observer'
36
+ #
37
+ # If dm-observer is not available, then this feature will be skipped.
38
+ module Observer
39
+ include MatcherHelpers
40
+
41
+ # Creates a callback that will be invoked *before* a transition is
42
+ # performed, so long as the given configuration options match the
43
+ # transition. Each part of the transition (event, to state, from state)
44
+ # must match in order for the callback to get invoked.
45
+ #
46
+ # See StateMachine::Machine#before_transition for more
47
+ # information about the various configuration options available.
48
+ #
49
+ # == Examples
50
+ #
51
+ # class Vehicle
52
+ # include DataMapper::Resource
53
+ #
54
+ # property :id, Serial
55
+ # property :state, :String
56
+ #
57
+ # state_machine :initial => :parked do
58
+ # event :ignite do
59
+ # transition :parked => :idling
60
+ # end
61
+ # end
62
+ # end
63
+ #
64
+ # class VehicleObserver
65
+ # include DataMapper::Observer
66
+ #
67
+ # observe Vehicle
68
+ #
69
+ # before :save do
70
+ # # log message
71
+ # end
72
+ #
73
+ # # Target all state machines
74
+ # before_transition :parked => :idling, :on => :ignite do
75
+ # # put on seatbelt
76
+ # end
77
+ #
78
+ # # Target a specific state machine
79
+ # before_transition :state, any => :idling do
80
+ # # put on seatbelt
81
+ # end
82
+ #
83
+ # # Target all state machines without requirements
84
+ # before_transition do |transition|
85
+ # # log message
86
+ # end
87
+ # end
88
+ #
89
+ # *Note* that in each of the above +before_transition+ callbacks, the
90
+ # callback is executed within the context of the object (i.e. the
91
+ # Vehicle instance being transition). This means that +self+ refers
92
+ # to the vehicle record within each callback block.
93
+ def before_transition(*args, &block)
94
+ add_transition_callback(:before_transition, *args, &block)
95
+ end
96
+
97
+ # Creates a callback that will be invoked *after* a transition is
98
+ # performed so long as the given configuration options match the
99
+ # transition.
100
+ #
101
+ # See +before_transition+ for a description of the possible configurations
102
+ # for defining callbacks.
103
+ def after_transition(*args, &block)
104
+ add_transition_callback(:after_transition, *args, &block)
105
+ end
106
+
107
+ # Creates a callback that will be invoked *around* a transition so long
108
+ # as the given requirements match the transition.
109
+ #
110
+ # == Examples
111
+ #
112
+ # class Vehicle
113
+ # include DataMapper::Resource
114
+ #
115
+ # property :id, Serial
116
+ # property :state, :String
117
+ #
118
+ # state_machine :initial => :parked do
119
+ # event :ignite do
120
+ # transition :parked => :idling
121
+ # end
122
+ # end
123
+ # end
124
+ #
125
+ # class VehicleObserver
126
+ # include DataMapper::Observer
127
+ #
128
+ # observe Vehicle
129
+ #
130
+ # around_transition do |transition, block|
131
+ # # track start time
132
+ # block.call
133
+ # # track end time
134
+ # end
135
+ # end
136
+ #
137
+ # See +before_transition+ for a description of the possible configurations
138
+ # for defining callbacks.
139
+ def around_transition(*args, &block)
140
+ add_transition_callback(:around_transition, *args, &block)
141
+ end
142
+
143
+ # Creates a callback that will be invoked *after* a transition failures to
144
+ # be performed so long as the given requirements match the transition.
145
+ #
146
+ # == Example
147
+ #
148
+ # class Vehicle
149
+ # include DataMapper::Resource
150
+ #
151
+ # property :id, Serial
152
+ # property :state, :String
153
+ #
154
+ # state_machine :initial => :parked do
155
+ # event :ignite do
156
+ # transition :parked => :idling
157
+ # end
158
+ # end
159
+ # end
160
+ #
161
+ # class VehicleObserver
162
+ # after_transition_failure do |transition|
163
+ # # log failure
164
+ # end
165
+ #
166
+ # after_transition_failure :on => :ignite do
167
+ # # log failure
168
+ # end
169
+ # end
170
+ #
171
+ # See +before_transition+ for a description of the possible configurations
172
+ # for defining callbacks. *Note* however that you cannot define the state
173
+ # requirements in these callbacks. You may only define event requirements.
174
+ def after_transition_failure(*args, &block)
175
+ add_transition_callback(:after_failure, *args, &block)
176
+ end
177
+
178
+ private
179
+ # Adds the transition callback to a specific machine or all of the
180
+ # state machines for each observed class.
181
+ def add_transition_callback(type, *args, &block)
182
+ if args.any? && !args.first.is_a?(Hash)
183
+ # Specific machine(s) being targeted
184
+ names = args
185
+ args = args.last.is_a?(Hash) ? [args.pop] : []
186
+ else
187
+ # Target all state machines
188
+ names = nil
189
+ end
190
+
191
+ # Add the transition callback to each class being observed
192
+ observing.each do |klass|
193
+ state_machines =
194
+ if names
195
+ names.map {|name| klass.state_machines.fetch(name)}
196
+ else
197
+ klass.state_machines.values
198
+ end
199
+
200
+ state_machines.each {|machine| machine.send(type, *args, &block)}
201
+ end if observing
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
208
+ DataMapper::Observer::ClassMethods.class_eval do
209
+ include StateMachine::Integrations::DataMapper::Observer
210
+ end
@@ -0,0 +1,85 @@
1
+ module StateMachine
2
+ module Integrations #:nodoc:
3
+ module DataMapper
4
+ version '0.9.x - 0.10.x' do
5
+ def self.active?
6
+ ::DataMapper::VERSION =~ /^0\.\d\./ || ::DataMapper::VERSION =~ /^0\.10\./
7
+ end
8
+
9
+ def pluralize(word)
10
+ ::Extlib::Inflection.pluralize(word.to_s)
11
+ end
12
+ end
13
+
14
+ version '0.9.x' do
15
+ def self.active?
16
+ ::DataMapper::VERSION =~ /^0\.9\./
17
+ end
18
+
19
+ def define_action_helpers
20
+ if action_hook == :save
21
+ define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
22
+ def save(*)
23
+ self.class.state_machines.transitions(self, :save).perform { super }
24
+ end
25
+ end_eval
26
+
27
+ define_validation_hook
28
+ else
29
+ super
30
+ end
31
+ end
32
+ end
33
+
34
+ version '0.9.4 - 0.9.6' do
35
+ def self.active?
36
+ ::DataMapper::VERSION =~ /^0\.9\.[4-6]/
37
+ end
38
+
39
+ # 0.9.4 - 0.9.6 fails to run after callbacks when validations are
40
+ # enabled because of the way dm-validations integrates
41
+ def define_action_helpers?
42
+ super if action != :save || !supports_validations?
43
+ end
44
+ end
45
+
46
+ version '0.10.x' do
47
+ def self.active?
48
+ ::DataMapper::VERSION =~ /^0\.10\./
49
+ end
50
+
51
+ def define_action_helpers
52
+ if action_hook == :save
53
+ define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
54
+ def save(*)
55
+ self.class.state_machines.transitions(self, :save).perform { super }
56
+ end
57
+
58
+ def save!(*)
59
+ self.class.state_machines.transitions(self, :save).perform { super }
60
+ end
61
+
62
+ def save_self(*)
63
+ self.class.state_machines.transitions(self, :save).perform { super }
64
+ end
65
+ end_eval
66
+
67
+ define_validation_hook
68
+ else
69
+ super
70
+ end
71
+ end
72
+ end
73
+
74
+ version '1.0.0' do
75
+ def self.active?
76
+ ::DataMapper::VERSION == '1.0.0'
77
+ end
78
+
79
+ def pluralize(word)
80
+ (defined?(::ActiveSupport::Inflector) ? ::ActiveSupport::Inflector : ::Extlib::Inflection).pluralize(word.to_s)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end