state_machines 0.5.0 → 0.50.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 (486) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.txt +1 -1
  3. data/README.md +443 -22
  4. data/lib/state_machines/async_mode/async_event_extensions.rb +49 -0
  5. data/lib/state_machines/async_mode/async_events.rb +282 -0
  6. data/lib/state_machines/async_mode/async_machine.rb +60 -0
  7. data/lib/state_machines/async_mode/async_transition_collection.rb +141 -0
  8. data/lib/state_machines/async_mode/thread_safe_state.rb +47 -0
  9. data/lib/state_machines/async_mode.rb +64 -0
  10. data/lib/state_machines/branch.rb +146 -86
  11. data/lib/state_machines/callback.rb +35 -32
  12. data/lib/state_machines/core.rb +3 -3
  13. data/lib/state_machines/core_ext/class/state_machine.rb +2 -0
  14. data/lib/state_machines/core_ext.rb +2 -0
  15. data/lib/state_machines/error.rb +7 -4
  16. data/lib/state_machines/eval_helpers.rb +197 -39
  17. data/lib/state_machines/event.rb +77 -58
  18. data/lib/state_machines/event_collection.rb +49 -39
  19. data/lib/state_machines/extensions.rb +6 -4
  20. data/lib/state_machines/helper_module.rb +4 -2
  21. data/lib/state_machines/integrations/base.rb +3 -1
  22. data/lib/state_machines/integrations.rb +19 -20
  23. data/lib/state_machines/machine/action_hooks.rb +53 -0
  24. data/lib/state_machines/machine/async_extensions.rb +88 -0
  25. data/lib/state_machines/machine/callbacks.rb +59 -0
  26. data/lib/state_machines/machine/class_methods.rb +97 -0
  27. data/lib/state_machines/machine/configuration.rb +134 -0
  28. data/lib/state_machines/machine/event_methods.rb +59 -0
  29. data/lib/state_machines/machine/helper_generators.rb +125 -0
  30. data/lib/state_machines/machine/integration.rb +70 -0
  31. data/lib/state_machines/machine/parsing.rb +77 -0
  32. data/lib/state_machines/machine/rendering.rb +17 -0
  33. data/lib/state_machines/machine/scoping.rb +44 -0
  34. data/lib/state_machines/machine/state_methods.rb +101 -0
  35. data/lib/state_machines/machine/utilities.rb +85 -0
  36. data/lib/state_machines/machine/validation.rb +39 -0
  37. data/lib/state_machines/machine.rb +425 -1011
  38. data/lib/state_machines/machine_collection.rb +28 -19
  39. data/lib/state_machines/macro_methods.rb +104 -102
  40. data/lib/state_machines/matcher.rb +31 -28
  41. data/lib/state_machines/matcher_helpers.rb +14 -12
  42. data/lib/state_machines/node_collection.rb +36 -29
  43. data/lib/state_machines/options_validator.rb +72 -0
  44. data/lib/state_machines/path.rb +60 -57
  45. data/lib/state_machines/path_collection.rb +39 -36
  46. data/lib/state_machines/state.rb +84 -47
  47. data/lib/state_machines/state_collection.rb +22 -19
  48. data/lib/state_machines/state_context.rb +40 -39
  49. data/lib/state_machines/stdio_renderer.rb +74 -0
  50. data/lib/state_machines/syntax_validator.rb +57 -0
  51. data/lib/state_machines/test_helper.rb +896 -0
  52. data/lib/state_machines/transition.rb +215 -199
  53. data/lib/state_machines/transition_collection.rb +187 -170
  54. data/lib/state_machines/version.rb +3 -1
  55. data/lib/state_machines.rb +4 -1
  56. metadata +39 -446
  57. data/.gitignore +0 -21
  58. data/.rspec +0 -3
  59. data/.ruby-gemset +0 -1
  60. data/.ruby-version +0 -1
  61. data/.travis.yml +0 -16
  62. data/Changelog.md +0 -22
  63. data/Contributors.md +0 -39
  64. data/Gemfile +0 -8
  65. data/Rakefile +0 -12
  66. data/Testing.md +0 -0
  67. data/lib/state_machines/assertions.rb +0 -40
  68. data/state_machines.gemspec +0 -22
  69. data/test/files/integrations/event_on_failure_integration.rb +0 -10
  70. data/test/files/integrations/vehicle.rb +0 -7
  71. data/test/files/models/auto_shop.rb +0 -31
  72. data/test/files/models/car.rb +0 -21
  73. data/test/files/models/driver.rb +0 -13
  74. data/test/files/models/model_base.rb +0 -6
  75. data/test/files/models/motorcycle.rb +0 -16
  76. data/test/files/models/traffic_light.rb +0 -47
  77. data/test/files/models/vehicle.rb +0 -127
  78. data/test/files/node.rb +0 -5
  79. data/test/files/switch.rb +0 -15
  80. data/test/functional/auto_shop_available_test.rb +0 -20
  81. data/test/functional/auto_shop_busy_test.rb +0 -25
  82. data/test/functional/car_backing_up_test.rb +0 -45
  83. data/test/functional/car_test.rb +0 -49
  84. data/test/functional/driver_default_nonstandard_test.rb +0 -13
  85. data/test/functional/motorcycle_test.rb +0 -52
  86. data/test/functional/traffic_light_caution_test.rb +0 -17
  87. data/test/functional/traffic_light_proceed_test.rb +0 -17
  88. data/test/functional/traffic_light_stop_test.rb +0 -26
  89. data/test/functional/vehicle_first_gear_test.rb +0 -42
  90. data/test/functional/vehicle_idling_test.rb +0 -59
  91. data/test/functional/vehicle_locked_test.rb +0 -29
  92. data/test/functional/vehicle_parked_test.rb +0 -53
  93. data/test/functional/vehicle_repaired_test.rb +0 -20
  94. data/test/functional/vehicle_second_gear_test.rb +0 -42
  95. data/test/functional/vehicle_stalled_test.rb +0 -65
  96. data/test/functional/vehicle_test.rb +0 -20
  97. data/test/functional/vehicle_third_gear_test.rb +0 -42
  98. data/test/functional/vehicle_unsaved_test.rb +0 -181
  99. data/test/functional/vehicle_with_event_attributes_test.rb +0 -30
  100. data/test/functional/vehicle_with_parallel_events_test.rb +0 -36
  101. data/test/test_helper.rb +0 -15
  102. data/test/unit/assertions/assert_exclusive_keys_test.rb +0 -22
  103. data/test/unit/assertions/assert_valid_key_test.rb +0 -12
  104. data/test/unit/branch/branch_test.rb +0 -28
  105. data/test/unit/branch/branch_with_conflicting_conditionals_test.rb +0 -27
  106. data/test/unit/branch/branch_with_conflicting_from_requirements_test.rb +0 -8
  107. data/test/unit/branch/branch_with_conflicting_on_requirements_test.rb +0 -8
  108. data/test/unit/branch/branch_with_conflicting_to_requirements_test.rb +0 -8
  109. data/test/unit/branch/branch_with_different_requirements_test.rb +0 -41
  110. data/test/unit/branch/branch_with_except_from_matcher_requirement_test.rb +0 -8
  111. data/test/unit/branch/branch_with_except_from_requirement_test.rb +0 -36
  112. data/test/unit/branch/branch_with_except_on_matcher_requirement_test.rb +0 -8
  113. data/test/unit/branch/branch_with_except_on_requirement_test.rb +0 -36
  114. data/test/unit/branch/branch_with_except_to_matcher_requirement_test.rb +0 -8
  115. data/test/unit/branch/branch_with_except_to_requirement_test.rb +0 -36
  116. data/test/unit/branch/branch_with_from_matcher_requirement_test.rb +0 -20
  117. data/test/unit/branch/branch_with_from_requirement_test.rb +0 -45
  118. data/test/unit/branch/branch_with_if_conditional_test.rb +0 -27
  119. data/test/unit/branch/branch_with_implicit_and_explicit_requirements_test.rb +0 -23
  120. data/test/unit/branch/branch_with_implicit_from_requirement_matcher_test.rb +0 -20
  121. data/test/unit/branch/branch_with_implicit_requirement_test.rb +0 -20
  122. data/test/unit/branch/branch_with_implicit_to_requirement_matcher_test.rb +0 -16
  123. data/test/unit/branch/branch_with_multiple_except_from_requirements_test.rb +0 -20
  124. data/test/unit/branch/branch_with_multiple_except_on_requirements_test.rb +0 -16
  125. data/test/unit/branch/branch_with_multiple_except_to_requirements_test.rb +0 -20
  126. data/test/unit/branch/branch_with_multiple_from_requirements_test.rb +0 -16
  127. data/test/unit/branch/branch_with_multiple_if_conditionals_test.rb +0 -20
  128. data/test/unit/branch/branch_with_multiple_implicit_requirements_test.rb +0 -53
  129. data/test/unit/branch/branch_with_multiple_to_requirements_test.rb +0 -20
  130. data/test/unit/branch/branch_with_multiple_unless_conditionals_test.rb +0 -20
  131. data/test/unit/branch/branch_with_nil_requirements_test.rb +0 -28
  132. data/test/unit/branch/branch_with_no_requirements_test.rb +0 -36
  133. data/test/unit/branch/branch_with_on_matcher_requirement_test.rb +0 -16
  134. data/test/unit/branch/branch_with_on_requirement_test.rb +0 -45
  135. data/test/unit/branch/branch_with_to_matcher_requirement_test.rb +0 -20
  136. data/test/unit/branch/branch_with_to_requirement_test.rb +0 -45
  137. data/test/unit/branch/branch_with_unless_conditional_test.rb +0 -27
  138. data/test/unit/branch/branch_without_guards_test.rb +0 -27
  139. data/test/unit/callback/callback_by_default_test.rb +0 -25
  140. data/test/unit/callback/callback_test.rb +0 -53
  141. data/test/unit/callback/callback_with_application_bound_object_test.rb +0 -23
  142. data/test/unit/callback/callback_with_application_terminator_test.rb +0 -24
  143. data/test/unit/callback/callback_with_arguments_test.rb +0 -14
  144. data/test/unit/callback/callback_with_around_type_and_arguments_test.rb +0 -25
  145. data/test/unit/callback/callback_with_around_type_and_block_test.rb +0 -44
  146. data/test/unit/callback/callback_with_around_type_and_bound_method_test.rb +0 -23
  147. data/test/unit/callback/callback_with_around_type_and_multiple_methods_test.rb +0 -93
  148. data/test/unit/callback/callback_with_around_type_and_terminator_test.rb +0 -17
  149. data/test/unit/callback/callback_with_block_test.rb +0 -20
  150. data/test/unit/callback/callback_with_bound_method_and_arguments_test.rb +0 -28
  151. data/test/unit/callback/callback_with_bound_method_test.rb +0 -35
  152. data/test/unit/callback/callback_with_do_method_test.rb +0 -18
  153. data/test/unit/callback/callback_with_explicit_requirements_test.rb +0 -32
  154. data/test/unit/callback/callback_with_if_condition_test.rb +0 -17
  155. data/test/unit/callback/callback_with_implicit_requirements_test.rb +0 -32
  156. data/test/unit/callback/callback_with_method_argument_test.rb +0 -18
  157. data/test/unit/callback/callback_with_mixed_methods_test.rb +0 -31
  158. data/test/unit/callback/callback_with_multiple_bound_methods_test.rb +0 -21
  159. data/test/unit/callback/callback_with_multiple_do_methods_test.rb +0 -29
  160. data/test/unit/callback/callback_with_multiple_method_arguments_test.rb +0 -29
  161. data/test/unit/callback/callback_with_terminator_test.rb +0 -22
  162. data/test/unit/callback/callback_with_unbound_method_test.rb +0 -14
  163. data/test/unit/callback/callback_with_unless_condition_test.rb +0 -17
  164. data/test/unit/callback/callback_without_arguments_test.rb +0 -14
  165. data/test/unit/callback/callback_without_terminator_test.rb +0 -12
  166. data/test/unit/error/error_by_default_test.rb +0 -21
  167. data/test/unit/error/error_with_message_test.rb +0 -23
  168. data/test/unit/eval_helper/eval_helpers_base_test.rb +0 -8
  169. data/test/unit/eval_helper/eval_helpers_proc_block_and_explicit_arguments_test.rb +0 -14
  170. data/test/unit/eval_helper/eval_helpers_proc_block_and_implicit_arguments_test.rb +0 -14
  171. data/test/unit/eval_helper/eval_helpers_proc_test.rb +0 -13
  172. data/test/unit/eval_helper/eval_helpers_proc_with_arguments_test.rb +0 -13
  173. data/test/unit/eval_helper/eval_helpers_proc_with_block_test.rb +0 -13
  174. data/test/unit/eval_helper/eval_helpers_proc_with_block_without_arguments_test.rb +0 -18
  175. data/test/unit/eval_helper/eval_helpers_proc_with_block_without_object_test.rb +0 -14
  176. data/test/unit/eval_helper/eval_helpers_proc_without_arguments_test.rb +0 -19
  177. data/test/unit/eval_helper/eval_helpers_string_test.rb +0 -25
  178. data/test/unit/eval_helper/eval_helpers_string_with_block_test.rb +0 -12
  179. data/test/unit/eval_helper/eval_helpers_symbol_method_missing_test.rb +0 -20
  180. data/test/unit/eval_helper/eval_helpers_symbol_private_test.rb +0 -17
  181. data/test/unit/eval_helper/eval_helpers_symbol_protected_test.rb +0 -17
  182. data/test/unit/eval_helper/eval_helpers_symbol_tainted_method_test.rb +0 -18
  183. data/test/unit/eval_helper/eval_helpers_symbol_test.rb +0 -16
  184. data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_and_block_test.rb +0 -16
  185. data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_test.rb +0 -16
  186. data/test/unit/eval_helper/eval_helpers_symbol_with_block_test.rb +0 -16
  187. data/test/unit/eval_helper/eval_helpers_test.rb +0 -13
  188. data/test/unit/event/event_after_being_copied_test.rb +0 -17
  189. data/test/unit/event/event_by_default_test.rb +0 -60
  190. data/test/unit/event/event_context_test.rb +0 -16
  191. data/test/unit/event/event_on_failure_test.rb +0 -44
  192. data/test/unit/event/event_test.rb +0 -34
  193. data/test/unit/event/event_transitions_test.rb +0 -62
  194. data/test/unit/event/event_with_conflicting_helpers_after_definition_test.rb +0 -79
  195. data/test/unit/event/event_with_conflicting_helpers_before_definition_test.rb +0 -58
  196. data/test/unit/event/event_with_conflicting_machine_test.rb +0 -48
  197. data/test/unit/event/event_with_dynamic_human_name_test.rb +0 -26
  198. data/test/unit/event/event_with_human_name_test.rb +0 -13
  199. data/test/unit/event/event_with_invalid_current_state_test.rb +0 -30
  200. data/test/unit/event/event_with_machine_action_test.rb +0 -33
  201. data/test/unit/event/event_with_marshalling_test.rb +0 -47
  202. data/test/unit/event/event_with_matching_disabled_transitions_test.rb +0 -115
  203. data/test/unit/event/event_with_matching_enabled_transitions_test.rb +0 -75
  204. data/test/unit/event/event_with_multiple_transitions_test.rb +0 -61
  205. data/test/unit/event/event_with_namespace_test.rb +0 -34
  206. data/test/unit/event/event_with_transition_with_blacklisted_to_state_test.rb +0 -60
  207. data/test/unit/event/event_with_transition_with_loopback_state_test.rb +0 -36
  208. data/test/unit/event/event_with_transition_with_nil_to_state_test.rb +0 -36
  209. data/test/unit/event/event_with_transition_with_whitelisted_to_state_test.rb +0 -51
  210. data/test/unit/event/event_with_transition_without_to_state_test.rb +0 -36
  211. data/test/unit/event/event_with_transitions_test.rb +0 -32
  212. data/test/unit/event/event_without_matching_transitions_test.rb +0 -41
  213. data/test/unit/event/event_without_transitions_test.rb +0 -28
  214. data/test/unit/event/invalid_event_test.rb +0 -20
  215. data/test/unit/event_collection/event_collection_attribute_with_machine_action_test.rb +0 -62
  216. data/test/unit/event_collection/event_collection_attribute_with_namespaced_machine_test.rb +0 -36
  217. data/test/unit/event_collection/event_collection_by_default_test.rb +0 -26
  218. data/test/unit/event_collection/event_collection_test.rb +0 -39
  219. data/test/unit/event_collection/event_collection_with_custom_machine_attribute_test.rb +0 -31
  220. data/test/unit/event_collection/event_collection_with_events_with_transitions_test.rb +0 -76
  221. data/test/unit/event_collection/event_collection_with_multiple_events_test.rb +0 -27
  222. data/test/unit/event_collection/event_collection_with_validations_test.rb +0 -74
  223. data/test/unit/event_collection/event_collection_without_machine_action_test.rb +0 -18
  224. data/test/unit/event_collection/event_string_collection_test.rb +0 -31
  225. data/test/unit/helper_module_test.rb +0 -17
  226. data/test/unit/integrations/integration_finder_test.rb +0 -16
  227. data/test/unit/integrations/integration_matcher_test.rb +0 -29
  228. data/test/unit/invalid_transition/invalid_parallel_transition_test.rb +0 -18
  229. data/test/unit/invalid_transition/invalid_transition_test.rb +0 -47
  230. data/test/unit/invalid_transition/invalid_transition_with_integration_test.rb +0 -45
  231. data/test/unit/invalid_transition/invalid_transition_with_namespace_test.rb +0 -32
  232. data/test/unit/machine/machine_after_being_copied_test.rb +0 -62
  233. data/test/unit/machine/machine_after_changing_initial_state.rb +0 -28
  234. data/test/unit/machine/machine_after_changing_owner_class_test.rb +0 -31
  235. data/test/unit/machine/machine_by_default_test.rb +0 -160
  236. data/test/unit/machine/machine_finder_custom_options_test.rb +0 -17
  237. data/test/unit/machine/machine_finder_with_existing_machine_on_superclass_test.rb +0 -85
  238. data/test/unit/machine/machine_finder_with_existing_on_same_class_test.rb +0 -23
  239. data/test/unit/machine/machine_finder_without_existing_machine_test.rb +0 -25
  240. data/test/unit/machine/machine_persistence_test.rb +0 -52
  241. data/test/unit/machine/machine_state_initialization_test.rb +0 -56
  242. data/test/unit/machine/machine_test.rb +0 -30
  243. data/test/unit/machine/machine_with_action_already_overridden_test.rb +0 -23
  244. data/test/unit/machine/machine_with_action_defined_in_class_test.rb +0 -37
  245. data/test/unit/machine/machine_with_action_defined_in_included_module_test.rb +0 -46
  246. data/test/unit/machine/machine_with_action_defined_in_superclass_test.rb +0 -43
  247. data/test/unit/machine/machine_with_action_undefined_test.rb +0 -33
  248. data/test/unit/machine/machine_with_cached_state_test.rb +0 -20
  249. data/test/unit/machine/machine_with_class_helpers_test.rb +0 -179
  250. data/test/unit/machine/machine_with_conflicting_helpers_after_definition_test.rb +0 -244
  251. data/test/unit/machine/machine_with_conflicting_helpers_before_definition_test.rb +0 -175
  252. data/test/unit/machine/machine_with_custom_action_test.rb +0 -11
  253. data/test/unit/machine/machine_with_custom_attribute_test.rb +0 -103
  254. data/test/unit/machine/machine_with_custom_initialize_test.rb +0 -24
  255. data/test/unit/machine/machine_with_custom_integration_test.rb +0 -72
  256. data/test/unit/machine/machine_with_custom_invalidation_test.rb +0 -39
  257. data/test/unit/machine/machine_with_custom_name_test.rb +0 -57
  258. data/test/unit/machine/machine_with_custom_plural_test.rb +0 -52
  259. data/test/unit/machine/machine_with_dynamic_initial_state_test.rb +0 -65
  260. data/test/unit/machine/machine_with_event_matchers_test.rb +0 -41
  261. data/test/unit/machine/machine_with_events_test.rb +0 -52
  262. data/test/unit/machine/machine_with_events_with_custom_human_names_test.rb +0 -18
  263. data/test/unit/machine/machine_with_events_with_transitions_test.rb +0 -37
  264. data/test/unit/machine/machine_with_existing_event_test.rb +0 -17
  265. data/test/unit/machine/machine_with_existing_machines_on_owner_class_test.rb +0 -20
  266. data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_class_test.rb +0 -71
  267. data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_subclass_test.rb +0 -31
  268. data/test/unit/machine/machine_with_existing_state_test.rb +0 -27
  269. data/test/unit/machine/machine_with_failure_callbacks_test.rb +0 -48
  270. data/test/unit/machine/machine_with_helpers_test.rb +0 -14
  271. data/test/unit/machine/machine_with_initial_state_with_value_and_owner_default.rb +0 -25
  272. data/test/unit/machine/machine_with_initialize_and_super_test.rb +0 -17
  273. data/test/unit/machine/machine_with_initialize_arguments_and_block_test.rb +0 -31
  274. data/test/unit/machine/machine_with_initialize_without_super_test.rb +0 -17
  275. data/test/unit/machine/machine_with_instance_helpers_test.rb +0 -179
  276. data/test/unit/machine/machine_with_integration_test.rb +0 -72
  277. data/test/unit/machine/machine_with_multiple_events_test.rb +0 -32
  278. data/test/unit/machine/machine_with_namespace_test.rb +0 -48
  279. data/test/unit/machine/machine_with_nil_action_test.rb +0 -27
  280. data/test/unit/machine/machine_with_other_states.rb +0 -22
  281. data/test/unit/machine/machine_with_owner_subclass_test.rb +0 -18
  282. data/test/unit/machine/machine_with_paths_test.rb +0 -25
  283. data/test/unit/machine/machine_with_private_action_test.rb +0 -43
  284. data/test/unit/machine/machine_with_state_matchers_test.rb +0 -41
  285. data/test/unit/machine/machine_with_state_with_matchers_test.rb +0 -19
  286. data/test/unit/machine/machine_with_states_test.rb +0 -55
  287. data/test/unit/machine/machine_with_states_with_behaviors_test.rb +0 -23
  288. data/test/unit/machine/machine_with_states_with_custom_human_names_test.rb +0 -18
  289. data/test/unit/machine/machine_with_states_with_custom_values_test.rb +0 -21
  290. data/test/unit/machine/machine_with_states_with_runtime_dependencies_test.rb +0 -19
  291. data/test/unit/machine/machine_with_static_initial_state_test.rb +0 -49
  292. data/test/unit/machine/machine_with_superclass_conflicting_helpers_after_definition_test.rb +0 -36
  293. data/test/unit/machine/machine_with_transition_callbacks_test.rb +0 -144
  294. data/test/unit/machine/machine_with_transitions_test.rb +0 -87
  295. data/test/unit/machine/machine_without_initialization_test.rb +0 -31
  296. data/test/unit/machine/machine_without_initialize_test.rb +0 -14
  297. data/test/unit/machine/machine_without_integration_test.rb +0 -31
  298. data/test/unit/machine_collection/machine_collection_by_default_test.rb +0 -11
  299. data/test/unit/machine_collection/machine_collection_fire_test.rb +0 -80
  300. data/test/unit/machine_collection/machine_collection_fire_with_transactions_test.rb +0 -54
  301. data/test/unit/machine_collection/machine_collection_fire_with_validations_test.rb +0 -76
  302. data/test/unit/machine_collection/machine_collection_state_initialization_test.rb +0 -111
  303. data/test/unit/machine_collection/machine_collection_transitions_with_blank_events_test.rb +0 -25
  304. data/test/unit/machine_collection/machine_collection_transitions_with_custom_options_test.rb +0 -20
  305. data/test/unit/machine_collection/machine_collection_transitions_with_different_actions_test.rb +0 -26
  306. data/test/unit/machine_collection/machine_collection_transitions_with_exisiting_transitions_test.rb +0 -25
  307. data/test/unit/machine_collection/machine_collection_transitions_with_invalid_events_test.rb +0 -25
  308. data/test/unit/machine_collection/machine_collection_transitions_with_same_actions_test.rb +0 -31
  309. data/test/unit/machine_collection/machine_collection_transitions_with_transition_test.rb +0 -26
  310. data/test/unit/machine_collection/machine_collection_transitions_without_events_test.rb +0 -25
  311. data/test/unit/machine_collection/machine_collection_transitions_without_transition_test.rb +0 -27
  312. data/test/unit/matcher/all_matcher_test.rb +0 -29
  313. data/test/unit/matcher/blacklist_matcher_test.rb +0 -30
  314. data/test/unit/matcher/loopback_matcher_test.rb +0 -27
  315. data/test/unit/matcher/matcher_by_default_test.rb +0 -15
  316. data/test/unit/matcher/matcher_with_multiple_values_test.rb +0 -15
  317. data/test/unit/matcher/matcher_with_value_test.rb +0 -15
  318. data/test/unit/matcher/whitelist_matcher_test.rb +0 -30
  319. data/test/unit/matcher_helpers/matcher_helpers_all_test.rb +0 -14
  320. data/test/unit/matcher_helpers/matcher_helpers_any_test.rb +0 -14
  321. data/test/unit/matcher_helpers/matcher_helpers_same_test.rb +0 -13
  322. data/test/unit/node_collection/node_collection_after_being_copied_test.rb +0 -46
  323. data/test/unit/node_collection/node_collection_after_update_test.rb +0 -36
  324. data/test/unit/node_collection/node_collection_by_default_test.rb +0 -22
  325. data/test/unit/node_collection/node_collection_test.rb +0 -23
  326. data/test/unit/node_collection/node_collection_with_indices_test.rb +0 -42
  327. data/test/unit/node_collection/node_collection_with_matcher_contexts_test.rb +0 -25
  328. data/test/unit/node_collection/node_collection_with_nodes_test.rb +0 -46
  329. data/test/unit/node_collection/node_collection_with_numeric_index_test.rb +0 -24
  330. data/test/unit/node_collection/node_collection_with_postdefined_contexts_test.rb +0 -22
  331. data/test/unit/node_collection/node_collection_with_predefined_contexts_test.rb +0 -23
  332. data/test/unit/node_collection/node_collection_with_string_index_test.rb +0 -20
  333. data/test/unit/node_collection/node_collection_with_symbol_index_test.rb +0 -20
  334. data/test/unit/node_collection/node_collection_without_indices_test.rb +0 -30
  335. data/test/unit/path/path_by_default_test.rb +0 -54
  336. data/test/unit/path/path_test.rb +0 -14
  337. data/test/unit/path/path_with_available_transitions_after_reaching_target_test.rb +0 -40
  338. data/test/unit/path/path_with_available_transitions_test.rb +0 -54
  339. data/test/unit/path/path_with_deep_target_reached_test.rb +0 -50
  340. data/test/unit/path/path_with_deep_target_test.rb +0 -40
  341. data/test/unit/path/path_with_duplicates_test.rb +0 -32
  342. data/test/unit/path/path_with_encountered_transitions_test.rb +0 -34
  343. data/test/unit/path/path_with_guarded_transitions_test.rb +0 -42
  344. data/test/unit/path/path_with_reached_target_test.rb +0 -35
  345. data/test/unit/path/path_with_transitions_test.rb +0 -54
  346. data/test/unit/path/path_with_unreached_target_test.rb +0 -31
  347. data/test/unit/path/path_without_transitions_test.rb +0 -24
  348. data/test/unit/path_collection/path_collection_by_default_test.rb +0 -46
  349. data/test/unit/path_collection/path_collection_test.rb +0 -24
  350. data/test/unit/path_collection/path_collection_with_deep_paths_test.rb +0 -43
  351. data/test/unit/path_collection/path_collection_with_duplicate_nodes_test.rb +0 -31
  352. data/test/unit/path_collection/path_collection_with_from_state_test.rb +0 -27
  353. data/test/unit/path_collection/path_collection_with_paths_test.rb +0 -47
  354. data/test/unit/path_collection/path_collection_with_to_state_test.rb +0 -29
  355. data/test/unit/path_collection/path_with_guarded_paths_test.rb +0 -25
  356. data/test/unit/state/state_after_being_copied_test.rb +0 -19
  357. data/test/unit/state/state_by_default_test.rb +0 -41
  358. data/test/unit/state/state_final_test.rb +0 -28
  359. data/test/unit/state/state_initial_test.rb +0 -13
  360. data/test/unit/state/state_not_final_test.rb +0 -32
  361. data/test/unit/state/state_not_initial_test.rb +0 -13
  362. data/test/unit/state/state_test.rb +0 -44
  363. data/test/unit/state/state_with_cached_lambda_value_test.rb +0 -29
  364. data/test/unit/state/state_with_conflicting_helpers_after_definition_test.rb +0 -38
  365. data/test/unit/state/state_with_conflicting_helpers_before_definition_test.rb +0 -29
  366. data/test/unit/state/state_with_conflicting_machine_name_test.rb +0 -20
  367. data/test/unit/state/state_with_conflicting_machine_test.rb +0 -37
  368. data/test/unit/state/state_with_context_test.rb +0 -60
  369. data/test/unit/state/state_with_dynamic_human_name_test.rb +0 -25
  370. data/test/unit/state/state_with_existing_context_method_test.rb +0 -24
  371. data/test/unit/state/state_with_human_name_test.rb +0 -13
  372. data/test/unit/state/state_with_integer_value_test.rb +0 -32
  373. data/test/unit/state/state_with_invalid_method_call_test.rb +0 -21
  374. data/test/unit/state/state_with_lambda_value_test.rb +0 -37
  375. data/test/unit/state/state_with_matcher_test.rb +0 -18
  376. data/test/unit/state/state_with_multiple_contexts_test.rb +0 -57
  377. data/test/unit/state/state_with_name_test.rb +0 -43
  378. data/test/unit/state/state_with_namespace_test.rb +0 -22
  379. data/test/unit/state/state_with_nil_value_test.rb +0 -35
  380. data/test/unit/state/state_with_redefined_context_method_test.rb +0 -45
  381. data/test/unit/state/state_with_symbolic_value_test.rb +0 -32
  382. data/test/unit/state/state_with_valid_inherited_method_call_for_current_state_test.rb +0 -40
  383. data/test/unit/state/state_with_valid_method_call_for_current_state_test.rb +0 -33
  384. data/test/unit/state/state_with_valid_method_call_for_different_state_test.rb +0 -41
  385. data/test/unit/state/state_without_cached_lambda_value_test.rb +0 -25
  386. data/test/unit/state/state_without_name_test.rb +0 -39
  387. data/test/unit/state_collection/state_collection_by_default_test.rb +0 -21
  388. data/test/unit/state_collection/state_collection_string_test.rb +0 -35
  389. data/test/unit/state_collection/state_collection_test.rb +0 -74
  390. data/test/unit/state_collection/state_collection_with_custom_state_values_test.rb +0 -29
  391. data/test/unit/state_collection/state_collection_with_event_transitions_test.rb +0 -39
  392. data/test/unit/state_collection/state_collection_with_initial_state_test.rb +0 -40
  393. data/test/unit/state_collection/state_collection_with_namespace_test.rb +0 -21
  394. data/test/unit/state_collection/state_collection_with_state_behaviors_test.rb +0 -40
  395. data/test/unit/state_collection/state_collection_with_state_matchers_test.rb +0 -29
  396. data/test/unit/state_collection/state_collection_with_transition_callbacks_test.rb +0 -40
  397. data/test/unit/state_context/state_context_proxy_test.rb +0 -26
  398. data/test/unit/state_context/state_context_proxy_with_if_and_unless_conditions_test.rb +0 -42
  399. data/test/unit/state_context/state_context_proxy_with_if_condition_test.rb +0 -64
  400. data/test/unit/state_context/state_context_proxy_with_multiple_if_conditions_test.rb +0 -32
  401. data/test/unit/state_context/state_context_proxy_with_multiple_unless_conditions_test.rb +0 -32
  402. data/test/unit/state_context/state_context_proxy_with_unless_condition_test.rb +0 -64
  403. data/test/unit/state_context/state_context_proxy_without_conditions_test.rb +0 -31
  404. data/test/unit/state_context/state_context_test.rb +0 -28
  405. data/test/unit/state_context/state_context_transition_test.rb +0 -104
  406. data/test/unit/state_context/state_context_with_matching_transition_test.rb +0 -27
  407. data/test/unit/state_machine/state_machine_by_default_test.rb +0 -12
  408. data/test/unit/state_machine/state_machine_test.rb +0 -20
  409. data/test/unit/transition/transition_after_being_performed_test.rb +0 -48
  410. data/test/unit/transition/transition_after_being_persisted_test.rb +0 -46
  411. data/test/unit/transition/transition_after_being_rolled_back_test.rb +0 -35
  412. data/test/unit/transition/transition_equality_test.rb +0 -52
  413. data/test/unit/transition/transition_loopback_test.rb +0 -18
  414. data/test/unit/transition/transition_test.rb +0 -96
  415. data/test/unit/transition/transition_transient_test.rb +0 -20
  416. data/test/unit/transition/transition_with_action_test.rb +0 -27
  417. data/test/unit/transition/transition_with_after_callbacks_skipped_test.rb +0 -127
  418. data/test/unit/transition/transition_with_after_callbacks_test.rb +0 -93
  419. data/test/unit/transition/transition_with_around_callbacks_test.rb +0 -141
  420. data/test/unit/transition/transition_with_before_callbacks_skipped_test.rb +0 -30
  421. data/test/unit/transition/transition_with_before_callbacks_test.rb +0 -104
  422. data/test/unit/transition/transition_with_custom_machine_attribute_test.rb +0 -28
  423. data/test/unit/transition/transition_with_different_states_test.rb +0 -18
  424. data/test/unit/transition/transition_with_dynamic_to_value_test.rb +0 -19
  425. data/test/unit/transition/transition_with_failure_callbacks_test.rb +0 -84
  426. data/test/unit/transition/transition_with_invalid_nodes_test.rb +0 -29
  427. data/test/unit/transition/transition_with_mixed_callbacks_test.rb +0 -105
  428. data/test/unit/transition/transition_with_multiple_after_callbacks_test.rb +0 -40
  429. data/test/unit/transition/transition_with_multiple_around_callbacks_test.rb +0 -114
  430. data/test/unit/transition/transition_with_multiple_before_callbacks_test.rb +0 -40
  431. data/test/unit/transition/transition_with_multiple_failure_callbacks_test.rb +0 -40
  432. data/test/unit/transition/transition_with_namespace_test.rb +0 -47
  433. data/test/unit/transition/transition_with_perform_arguments_test.rb +0 -35
  434. data/test/unit/transition/transition_with_transactions_test.rb +0 -42
  435. data/test/unit/transition/transition_without_callbacks_test.rb +0 -33
  436. data/test/unit/transition/transition_without_reading_state_test.rb +0 -22
  437. data/test/unit/transition/transition_without_running_action_test.rb +0 -47
  438. data/test/unit/transition_collection/attribute_transition_collection_by_default_test.rb +0 -23
  439. data/test/unit/transition_collection/attribute_transition_collection_marshalling_test.rb +0 -64
  440. data/test/unit/transition_collection/attribute_transition_collection_with_action_error_test.rb +0 -44
  441. data/test/unit/transition_collection/attribute_transition_collection_with_action_failed_test.rb +0 -44
  442. data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_error_test.rb +0 -32
  443. data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_halt_test.rb +0 -33
  444. data/test/unit/transition_collection/attribute_transition_collection_with_around_after_yield_callback_error_test.rb +0 -32
  445. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_error_test.rb +0 -32
  446. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_halt_test.rb +0 -33
  447. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_before_yield_halt_test.rb +0 -33
  448. data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_error_test.rb +0 -32
  449. data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_halt_test.rb +0 -33
  450. data/test/unit/transition_collection/attribute_transition_collection_with_callbacks_test.rb +0 -68
  451. data/test/unit/transition_collection/attribute_transition_collection_with_event_transitions_test.rb +0 -41
  452. data/test/unit/transition_collection/attribute_transition_collection_with_events_test.rb +0 -44
  453. data/test/unit/transition_collection/attribute_transition_collection_with_skipped_after_callbacks_test.rb +0 -42
  454. data/test/unit/transition_collection/transition_collection_by_default_test.rb +0 -23
  455. data/test/unit/transition_collection/transition_collection_empty_with_block_test.rb +0 -23
  456. data/test/unit/transition_collection/transition_collection_empty_without_block_test.rb +0 -12
  457. data/test/unit/transition_collection/transition_collection_invalid_test.rb +0 -21
  458. data/test/unit/transition_collection/transition_collection_partial_invalid_test.rb +0 -69
  459. data/test/unit/transition_collection/transition_collection_test.rb +0 -26
  460. data/test/unit/transition_collection/transition_collection_valid_test.rb +0 -57
  461. data/test/unit/transition_collection/transition_collection_with_action_error_test.rb +0 -66
  462. data/test/unit/transition_collection/transition_collection_with_action_failed_test.rb +0 -60
  463. data/test/unit/transition_collection/transition_collection_with_action_hook_and_block_test.rb +0 -17
  464. data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_action_test.rb +0 -17
  465. data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_after_callbacks_test.rb +0 -37
  466. data/test/unit/transition_collection/transition_collection_with_action_hook_base_test.rb +0 -34
  467. data/test/unit/transition_collection/transition_collection_with_action_hook_error_test.rb +0 -29
  468. data/test/unit/transition_collection/transition_collection_with_action_hook_invalid_test.rb +0 -17
  469. data/test/unit/transition_collection/transition_collection_with_action_hook_multiple_test.rb +0 -79
  470. data/test/unit/transition_collection/transition_collection_with_action_hook_test.rb +0 -45
  471. data/test/unit/transition_collection/transition_collection_with_action_hook_with_different_actions_test.rb +0 -48
  472. data/test/unit/transition_collection/transition_collection_with_action_hook_with_nil_action_test.rb +0 -42
  473. data/test/unit/transition_collection/transition_collection_with_after_callback_halt_test.rb +0 -47
  474. data/test/unit/transition_collection/transition_collection_with_before_callback_halt_test.rb +0 -51
  475. data/test/unit/transition_collection/transition_collection_with_block_test.rb +0 -46
  476. data/test/unit/transition_collection/transition_collection_with_callbacks_test.rb +0 -135
  477. data/test/unit/transition_collection/transition_collection_with_different_actions_test.rb +0 -189
  478. data/test/unit/transition_collection/transition_collection_with_duplicate_actions_test.rb +0 -48
  479. data/test/unit/transition_collection/transition_collection_with_empty_actions_test.rb +0 -41
  480. data/test/unit/transition_collection/transition_collection_with_mixed_actions_test.rb +0 -41
  481. data/test/unit/transition_collection/transition_collection_with_skipped_actions_and_block_test.rb +0 -34
  482. data/test/unit/transition_collection/transition_collection_with_skipped_actions_test.rb +0 -69
  483. data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_and_around_callbacks_test.rb +0 -53
  484. data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_test.rb +0 -34
  485. data/test/unit/transition_collection/transition_collection_with_transactions_test.rb +0 -65
  486. data/test/unit/transition_collection/transition_collection_without_transactions_test.rb +0 -29
@@ -1,73 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'options_validator'
4
+
1
5
  module StateMachines
2
6
  # Represents a set of requirements that must be met in order for a transition
3
7
  # or callback to occur. Branches verify that the event, from state, and to
4
8
  # state of the transition match, in addition to if/unless conditionals for
5
9
  # an object's state.
6
10
  class Branch
7
-
8
11
  include EvalHelpers
9
-
12
+
10
13
  # The condition that must be met on an object
11
14
  attr_reader :if_condition
12
-
15
+
13
16
  # The condition that must *not* be met on an object
14
17
  attr_reader :unless_condition
15
-
18
+
16
19
  # The requirement for verifying the event being matched
17
20
  attr_reader :event_requirement
18
-
21
+
19
22
  # One or more requirements for verifying the states being matched. All
20
23
  # requirements contain a mapping of {:from => matcher, :to => matcher}.
21
24
  attr_reader :state_requirements
22
-
25
+
23
26
  # A list of all of the states known to this branch. This will pull states
24
27
  # from the following options (in the same order):
25
28
  # * +from+ / +except_from+
26
29
  # * +to+ / +except_to+
27
30
  attr_reader :known_states
28
-
31
+
29
32
  # Creates a new branch
30
- def initialize(options = {}) #:nodoc:
33
+ def initialize(options = {}) # :nodoc:
31
34
  # Build conditionals
32
35
  @if_condition = options.delete(:if)
33
36
  @unless_condition = options.delete(:unless)
34
-
37
+ @if_state_condition = options.delete(:if_state)
38
+ @unless_state_condition = options.delete(:unless_state)
39
+ @if_all_states_condition = options.delete(:if_all_states)
40
+ @unless_all_states_condition = options.delete(:unless_all_states)
41
+ @if_any_state_condition = options.delete(:if_any_state)
42
+ @unless_any_state_condition = options.delete(:unless_any_state)
43
+
35
44
  # Build event requirement
36
45
  @event_requirement = build_matcher(options, :on, :except_on)
37
-
38
- if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on]).empty?
46
+
47
+ if (options.keys - %i[from to on except_from except_to except_on]).empty?
39
48
  # Explicit from/to requirements specified
40
- @state_requirements = [{:from => build_matcher(options, :from, :except_from), :to => build_matcher(options, :to, :except_to)}]
49
+ @state_requirements = [{ from: build_matcher(options, :from, :except_from), to: build_matcher(options, :to, :except_to) }]
41
50
  else
42
51
  # Separate out the event requirement
43
52
  options.delete(:on)
44
53
  options.delete(:except_on)
45
-
54
+
46
55
  # Implicit from/to requirements specified
47
56
  @state_requirements = options.collect do |from, to|
48
57
  from = WhitelistMatcher.new(from) unless from.is_a?(Matcher)
49
58
  to = WhitelistMatcher.new(to) unless to.is_a?(Matcher)
50
- {:from => from, :to => to}
59
+ { from: from, to: to }
51
60
  end
52
61
  end
53
-
62
+
54
63
  # Track known states. The order that requirements are iterated is based
55
64
  # on the priority in which tracked states should be added.
56
65
  @known_states = []
57
66
  @state_requirements.each do |state_requirement|
58
- [:from, :to].each {|option| @known_states |= state_requirement[option].values}
67
+ %i[from to].each { |option| @known_states |= state_requirement[option].values }
59
68
  end
60
69
  end
61
-
70
+
62
71
  # Determines whether the given object / query matches the requirements
63
72
  # configured for this branch. In addition to matching the event, from state,
64
73
  # and to state, this will also check whether the configured :if/:unless
65
74
  # conditions pass on the given object.
66
- #
75
+ #
67
76
  # == Examples
68
- #
77
+ #
69
78
  # branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
70
- #
79
+ #
71
80
  # # Successful
72
81
  # branch.matches?(object, :on => :ignite) # => true
73
82
  # branch.matches?(object, :from => nil) # => true
@@ -75,7 +84,7 @@ module StateMachines
75
84
  # branch.matches?(object, :to => :idling) # => true
76
85
  # branch.matches?(object, :from => :parked, :to => :idling) # => true
77
86
  # branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
78
- #
87
+ #
79
88
  # # Unsuccessful
80
89
  # branch.matches?(object, :on => :park) # => false
81
90
  # branch.matches?(object, :from => :idling) # => false
@@ -85,16 +94,16 @@ module StateMachines
85
94
  def matches?(object, query = {})
86
95
  !match(object, query).nil?
87
96
  end
88
-
97
+
89
98
  # Attempts to match the given object / query against the set of requirements
90
99
  # configured for this branch. In addition to matching the event, from state,
91
100
  # and to state, this will also check whether the configured :if/:unless
92
101
  # conditions pass on the given object.
93
- #
102
+ #
94
103
  # If a match is found, then the event/state requirements that the query
95
104
  # passed successfully will be returned. Otherwise, nil is returned if there
96
105
  # was no match.
97
- #
106
+ #
98
107
  # Query options:
99
108
  # * <tt>:from</tt> - One or more states being transitioned from. If none
100
109
  # are specified, then this will always match.
@@ -104,80 +113,131 @@ module StateMachines
104
113
  # are specified, then this will always match.
105
114
  # * <tt>:guard</tt> - Whether to guard matches with the if/unless
106
115
  # conditionals defined for this branch. Default is true.
107
- #
116
+ #
117
+ # Event arguments are passed to guard conditions if they accept multiple parameters.
118
+ #
108
119
  # == Examples
109
- #
120
+ #
110
121
  # branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
111
- #
122
+ #
112
123
  # branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
113
124
  # branch.match(object, :on => :park) # => nil
114
- def match(object, query = {})
115
- query.assert_valid_keys(:from, :to, :on, :guard)
116
-
117
- if (match = match_query(query)) && matches_conditions?(object, query)
118
- match
119
- end
125
+ def match(object, query = {}, event_args = [])
126
+ StateMachines::OptionsValidator.assert_valid_keys!(query, :from, :to, :on, :guard)
127
+
128
+ return unless (match = match_query(query)) && matches_conditions?(object, query, event_args)
129
+
130
+ match
120
131
  end
121
132
 
122
- def draw(graph, event, valid_states)
123
- fail NotImplementedError
133
+ def draw(graph, event, valid_states, io = $stdout)
134
+ machine.renderer.draw_branch(self, graph, event, valid_states, io)
124
135
  end
125
-
136
+
126
137
  protected
127
- # Builds a matcher strategy to use for the given options. If neither a
128
- # whitelist nor a blacklist option is specified, then an AllMatcher is
129
- # built.
130
- def build_matcher(options, whitelist_option, blacklist_option)
131
- options.assert_exclusive_keys(whitelist_option, blacklist_option)
132
-
133
- if options.include?(whitelist_option)
134
- value = options[whitelist_option]
135
- value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
136
- elsif options.include?(blacklist_option)
137
- value = options[blacklist_option]
138
- raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
139
- BlacklistMatcher.new(value)
140
- else
141
- AllMatcher.instance
142
- end
138
+
139
+ # Builds a matcher strategy to use for the given options. If neither a
140
+ # whitelist nor a blacklist option is specified, then an AllMatcher is
141
+ # built.
142
+ def build_matcher(options, whitelist_option, blacklist_option)
143
+ StateMachines::OptionsValidator.assert_exclusive_keys!(options, whitelist_option, blacklist_option)
144
+
145
+ if options.include?(whitelist_option)
146
+ value = options[whitelist_option]
147
+ value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
148
+ elsif options.include?(blacklist_option)
149
+ value = options[blacklist_option]
150
+ raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
151
+
152
+ BlacklistMatcher.new(value)
153
+ else
154
+ AllMatcher.instance
143
155
  end
144
-
145
- # Verifies that all configured requirements (event and state) match the
146
- # given query. If a match is found, then a hash containing the
147
- # event/state requirements that passed will be returned; otherwise, nil.
148
- def match_query(query)
149
- query ||= {}
150
-
151
- if match_event(query) && (state_requirement = match_states(query))
152
- state_requirement.merge(:on => event_requirement)
153
- end
156
+ end
157
+
158
+ # Verifies that all configured requirements (event and state) match the
159
+ # given query. If a match is found, then a hash containing the
160
+ # event/state requirements that passed will be returned; otherwise, nil.
161
+ def match_query(query)
162
+ query ||= {}
163
+
164
+ if match_event(query) && (state_requirement = match_states(query))
165
+ state_requirement.merge(on: event_requirement)
154
166
  end
155
-
156
- # Verifies that the event requirement matches the given query
157
- def match_event(query)
158
- matches_requirement?(query, :on, event_requirement)
167
+ end
168
+
169
+ # Verifies that the event requirement matches the given query
170
+ def match_event(query)
171
+ matches_requirement?(query, :on, event_requirement)
172
+ end
173
+
174
+ # Verifies that the state requirements match the given query. If a
175
+ # matching requirement is found, then it is returned.
176
+ def match_states(query)
177
+ state_requirements.detect do |state_requirement|
178
+ %i[from to].all? { |option| matches_requirement?(query, option, state_requirement[option]) }
159
179
  end
160
-
161
- # Verifies that the state requirements match the given query. If a
162
- # matching requirement is found, then it is returned.
163
- def match_states(query)
164
- state_requirements.detect do |state_requirement|
165
- [:from, :to].all? {|option| matches_requirement?(query, option, state_requirement[option])}
180
+ end
181
+
182
+ # Verifies that an option in the given query matches the values required
183
+ # for that option
184
+ def matches_requirement?(query, option, requirement)
185
+ !query.include?(option) || requirement.matches?(query[option], query)
186
+ end
187
+
188
+ # Verifies that the conditionals for this branch evaluate to true for the
189
+ # given object. Event arguments are passed to guards that accept multiple parameters.
190
+ def matches_conditions?(object, query, event_args = [])
191
+ return true if query[:guard] == false
192
+
193
+ # Evaluate original if/unless conditions
194
+ if_passes = !if_condition || Array(if_condition).all? { |condition| evaluate_method_with_event_args(object, condition, event_args) }
195
+ unless_passes = !unless_condition || Array(unless_condition).none? { |condition| evaluate_method_with_event_args(object, condition, event_args) }
196
+
197
+ return false unless if_passes && unless_passes
198
+
199
+ # Consolidate all state guards
200
+ state_guards = {
201
+ if_state: @if_state_condition,
202
+ unless_state: @unless_state_condition,
203
+ if_all_states: @if_all_states_condition,
204
+ unless_all_states: @unless_all_states_condition,
205
+ if_any_state: @if_any_state_condition,
206
+ unless_any_state: @unless_any_state_condition
207
+ }.compact
208
+
209
+ return true if state_guards.empty?
210
+
211
+ validate_and_check_state_guards(object, state_guards)
212
+ end
213
+
214
+ private
215
+
216
+ def validate_and_check_state_guards(object, guards)
217
+ guards.all? do |guard_type, conditions|
218
+ case guard_type
219
+ when :if_state, :if_all_states
220
+ conditions.all? { |machine, state| check_state(object, machine, state) }
221
+ when :unless_state
222
+ conditions.none? { |machine, state| check_state(object, machine, state) }
223
+ when :if_any_state
224
+ conditions.any? { |machine, state| check_state(object, machine, state) }
225
+ when :unless_all_states
226
+ !conditions.all? { |machine, state| check_state(object, machine, state) }
227
+ when :unless_any_state
228
+ conditions.none? { |machine, state| check_state(object, machine, state) }
166
229
  end
167
230
  end
168
-
169
- # Verifies that an option in the given query matches the values required
170
- # for that option
171
- def matches_requirement?(query, option, requirement)
172
- !query.include?(option) || requirement.matches?(query[option], query)
173
- end
174
-
175
- # Verifies that the conditionals for this branch evaluate to true for the
176
- # given object
177
- def matches_conditions?(object, query)
178
- query[:guard] == false ||
179
- Array(if_condition).all? {|condition| evaluate_method(object, condition)} &&
180
- !Array(unless_condition).any? {|condition| evaluate_method(object, condition)}
181
- end
231
+ end
232
+
233
+ def check_state(object, machine_name, state_name)
234
+ machine = object.class.state_machines[machine_name]
235
+ raise ArgumentError, "State machine '#{machine_name}' is not defined for #{object.class.name}" unless machine
236
+
237
+ state = machine.states[state_name]
238
+ raise ArgumentError, "State '#{state_name}' is not defined in state machine '#{machine_name}'" unless state
239
+
240
+ state.matches?(object.send(machine_name))
241
+ end
182
242
  end
183
243
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'state_machines/branch'
2
4
  require 'state_machines/eval_helpers'
3
5
 
@@ -16,38 +18,38 @@ module StateMachines
16
18
  # the callback. This can be configured on an application-wide basis by
17
19
  # setting this configuration to +true+ or +false+. The default value
18
20
  # is +false+.
19
- #
21
+ #
20
22
  # *Note* that the DataMapper and Sequel integrations automatically
21
23
  # configure this value on a per-callback basis, so it does not have to
22
24
  # be enabled application-wide.
23
- #
25
+ #
24
26
  # == Examples
25
- #
27
+ #
26
28
  # When not bound to the object:
27
- #
29
+ #
28
30
  # class Vehicle
29
31
  # state_machine do
30
32
  # before_transition do |vehicle|
31
33
  # vehicle.set_alarm
32
34
  # end
33
35
  # end
34
- #
36
+ #
35
37
  # def set_alarm
36
38
  # ...
37
39
  # end
38
40
  # end
39
- #
41
+ #
40
42
  # When bound to the object:
41
- #
43
+ #
42
44
  # StateMachines::Callback.bind_to_object = true
43
- #
45
+ #
44
46
  # class Vehicle
45
47
  # state_machine do
46
48
  # before_transition do
47
49
  # self.set_alarm
48
50
  # end
49
51
  # end
50
- #
52
+ #
51
53
  # def set_alarm
52
54
  # ...
53
55
  # end
@@ -57,7 +59,7 @@ module StateMachines
57
59
  # The application-wide terminator to use for callbacks when not
58
60
  # explicitly defined. Terminators determine whether to cancel a
59
61
  # callback chain based on the return value of the callback.
60
- #
62
+ #
61
63
  # See StateMachines::Callback#terminator for more information.
62
64
  attr_accessor :terminator
63
65
  end
@@ -75,11 +77,11 @@ module StateMachines
75
77
  # chain never cancels based on the return value (i.e. there is no implicit
76
78
  # terminator). Certain integrations, such as ActiveRecord and Sequel,
77
79
  # change this default value.
78
- #
80
+ #
79
81
  # == Examples
80
- #
82
+ #
81
83
  # Canceling the callback chain without a terminator:
82
- #
84
+ #
83
85
  # class Vehicle
84
86
  # state_machine do
85
87
  # before_transition do |vehicle|
@@ -87,9 +89,9 @@ module StateMachines
87
89
  # end
88
90
  # end
89
91
  # end
90
- #
92
+ #
91
93
  # Canceling the callback chain with a terminator value of +false+:
92
- #
94
+ #
93
95
  # class Vehicle
94
96
  # state_machine do
95
97
  # before_transition do |vehicle|
@@ -102,13 +104,13 @@ module StateMachines
102
104
  # The branch that determines whether or not this callback can be invoked
103
105
  # based on the context of the transition. The event, from state, and
104
106
  # to state must all match in order for the branch to pass.
105
- #
107
+ #
106
108
  # See StateMachines::Branch for more information.
107
109
  attr_reader :branch
108
110
 
109
111
  # Creates a new callback that can get called based on the configured
110
112
  # options.
111
- #
113
+ #
112
114
  # In addition to the possible configuration options for branches, the
113
115
  # following options can be configured:
114
116
  # * <tt>:bind_to_object</tt> - Whether to bind the callback to the object involved.
@@ -117,12 +119,12 @@ module StateMachines
117
119
  # * <tt>:terminator</tt> - A block/proc that determines what callback
118
120
  # results should cause the callback chain to halt (if not using the
119
121
  # default <tt>throw :halt</tt> technique).
120
- #
122
+ #
121
123
  # More information about how those options affect the behavior of the
122
124
  # callback can be found in their attribute definitions.
123
125
  def initialize(type, *args, &block)
124
126
  @type = type
125
- raise ArgumentError, 'Type must be :before, :after, :around, or :failure' unless [:before, :after, :around, :failure].include?(type)
127
+ raise ArgumentError, 'Type must be :before, :after, :around, or :failure' unless %i[before after around failure].include?(type)
126
128
 
127
129
  options = args.last.is_a?(Hash) ? args.pop : {}
128
130
  @methods = args
@@ -130,7 +132,7 @@ module StateMachines
130
132
  @methods << block if block_given?
131
133
  raise ArgumentError, 'Method(s) for callback must be specified' unless @methods.any?
132
134
 
133
- options = {:bind_to_object => self.class.bind_to_object, :terminator => self.class.terminator}.merge(options)
135
+ options = { bind_to_object: self.class.bind_to_object, terminator: self.class.terminator }.merge(options)
134
136
 
135
137
  # Proxy lambda blocks so that they're bound to the object
136
138
  bind_to_object = options.delete(:bind_to_object)
@@ -151,12 +153,12 @@ module StateMachines
151
153
  # Runs the callback as long as the transition context matches the branch
152
154
  # requirements configured for this callback. If a block is provided, it
153
155
  # will be called when the last method has run.
154
- #
156
+ #
155
157
  # If a terminator has been configured and it matches the result from the
156
158
  # evaluated method, then the callback chain should be halted.
157
- def call(object, context = {}, *args, &block)
159
+ def call(object, context = {}, *, &)
158
160
  if @branch.matches?(object, context)
159
- run_methods(object, context, 0, *args, &block)
161
+ run_methods(object, context, 0, *, &)
160
162
  true
161
163
  else
162
164
  false
@@ -164,6 +166,7 @@ module StateMachines
164
166
  end
165
167
 
166
168
  private
169
+
167
170
  # Runs all of the methods configured for this callback.
168
171
  #
169
172
  # When running +around+ callbacks, this will evaluate each method and
@@ -174,9 +177,10 @@ module StateMachines
174
177
  # order. The callback will only halt if the resulting value from the
175
178
  # method passes the terminator.
176
179
  def run_methods(object, context = {}, index = 0, *args, &block)
177
- if type == :around
180
+ case type
181
+ when :around
178
182
  current_method = @methods[index]
179
- if current_method
183
+ if current_method
180
184
  yielded = false
181
185
  evaluate_method(object, current_method, *args) do
182
186
  yielded = true
@@ -184,13 +188,13 @@ module StateMachines
184
188
  end
185
189
 
186
190
  throw :halt unless yielded
187
- else
188
- yield if block_given?
191
+ elsif block_given?
192
+ yield
189
193
  end
190
194
  else
191
195
  @methods.each do |method|
192
196
  result = evaluate_method(object, method, *args)
193
- throw :halt if @terminator && @terminator.call(result)
197
+ throw :halt if @terminator&.call(result)
194
198
  end
195
199
  end
196
200
  end
@@ -203,13 +207,12 @@ module StateMachines
203
207
  arity += 1 if arity >= 0 # Make sure the object gets passed
204
208
  arity += 1 if arity == 1 && type == :around # Make sure the block gets passed
205
209
 
206
- method = lambda { |object, *args| object.instance_exec(*args, &block) }
207
-
210
+ method = ->(object, *args) { object.instance_exec(*args, &block) }
208
211
 
209
212
  # Proxy arity to the original block
210
213
  (
211
- class << method;
212
- self;
214
+ class << method
215
+ self
213
216
  end).class_eval do
214
217
  define_method(:arity) { arity }
215
218
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Load all of the core implementation required to use state_machine. This
2
4
  # includes:
3
5
  # * StateMachines::MacroMethods which adds the state_machine DSL to your class
4
6
  # * A set of initializers for setting state_machine defaults based on the current
5
7
  # running environment (such as within Rails)
6
- require 'state_machines/assertions'
7
8
  require 'state_machines/error'
8
9
 
9
10
  require 'state_machines/extensions'
@@ -23,7 +24,6 @@ require 'state_machines/transition_collection'
23
24
  require 'state_machines/branch'
24
25
 
25
26
  require 'state_machines/helper_module'
26
- require 'state_machines/state'
27
27
  require 'state_machines/callback'
28
28
  require 'state_machines/node_collection'
29
29
 
@@ -40,4 +40,4 @@ require 'state_machines/path_collection'
40
40
  require 'state_machines/machine'
41
41
  require 'state_machines/machine_collection'
42
42
 
43
- require 'state_machines/macro_methods'
43
+ require 'state_machines/macro_methods'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Class.class_eval do
2
4
  include StateMachines::MacroMethods
3
5
  end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Loads all of the extensions to be made to Ruby core classes
2
4
  require 'state_machines/core_ext/class/state_machine'
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module StateMachines
2
4
  # An error occurred during a state machine invocation
3
5
  class Error < StandardError
4
6
  # The object that failed
5
7
  attr_reader :object
6
8
 
7
- def initialize(object, message = nil) #:nodoc:
9
+ def initialize(object, message = nil) # :nodoc:
8
10
  @object = object
9
11
 
10
12
  super(message)
@@ -47,12 +49,13 @@ module StateMachines
47
49
  # The event that was attempted to be run
48
50
  attr_reader :event
49
51
 
50
- def initialize(object, event_name) #:nodoc:
52
+ def initialize(object, event_name) # :nodoc:
51
53
  @event = event_name
52
54
 
53
55
  super(object, "#{event.inspect} is an unknown state machine event")
54
56
  end
55
57
  end
58
+
56
59
  # An invalid transition was attempted
57
60
  class InvalidTransition < Error
58
61
  # The machine attempting to be transitioned
@@ -61,7 +64,7 @@ module StateMachines
61
64
  # The current state value for the machine
62
65
  attr_reader :from
63
66
 
64
- def initialize(object, machine, event) #:nodoc:
67
+ def initialize(object, machine, event) # :nodoc:
65
68
  @machine = machine
66
69
  @from_state = machine.states.match!(object)
67
70
  @from = machine.read(object, :state)
@@ -99,7 +102,7 @@ module StateMachines
99
102
  # The set of events that failed the transition(s)
100
103
  attr_reader :events
101
104
 
102
- def initialize(object, events) #:nodoc:
105
+ def initialize(object, events) # :nodoc:
103
106
  @events = events
104
107
 
105
108
  super(object, "Cannot run events in parallel: #{events * ', '}")