state_machines 0.5.0 → 0.20.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 (466) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.txt +1 -1
  3. data/README.md +99 -16
  4. data/lib/state_machines/branch.rb +88 -82
  5. data/lib/state_machines/callback.rb +24 -21
  6. data/lib/state_machines/core.rb +3 -2
  7. data/lib/state_machines/core_ext/class/state_machine.rb +2 -0
  8. data/lib/state_machines/core_ext.rb +2 -0
  9. data/lib/state_machines/error.rb +2 -0
  10. data/lib/state_machines/eval_helpers.rb +51 -22
  11. data/lib/state_machines/event.rb +53 -35
  12. data/lib/state_machines/event_collection.rb +28 -25
  13. data/lib/state_machines/extensions.rb +3 -1
  14. data/lib/state_machines/helper_module.rb +3 -1
  15. data/lib/state_machines/integrations/base.rb +2 -0
  16. data/lib/state_machines/integrations.rb +10 -8
  17. data/lib/state_machines/machine/class_methods.rb +79 -0
  18. data/lib/state_machines/machine.rb +386 -429
  19. data/lib/state_machines/machine_collection.rb +16 -11
  20. data/lib/state_machines/macro_methods.rb +102 -100
  21. data/lib/state_machines/matcher.rb +26 -23
  22. data/lib/state_machines/matcher_helpers.rb +13 -11
  23. data/lib/state_machines/node_collection.rb +20 -14
  24. data/lib/state_machines/options_validator.rb +72 -0
  25. data/lib/state_machines/path.rb +61 -56
  26. data/lib/state_machines/path_collection.rb +40 -36
  27. data/lib/state_machines/state.rb +72 -43
  28. data/lib/state_machines/state_collection.rb +22 -19
  29. data/lib/state_machines/state_context.rb +38 -36
  30. data/lib/state_machines/stdio_renderer.rb +74 -0
  31. data/lib/state_machines/test_helper.rb +305 -0
  32. data/lib/state_machines/transition.rb +182 -178
  33. data/lib/state_machines/transition_collection.rb +175 -169
  34. data/lib/state_machines/version.rb +3 -1
  35. data/lib/state_machines.rb +4 -1
  36. metadata +12 -440
  37. data/.gitignore +0 -21
  38. data/.rspec +0 -3
  39. data/.ruby-gemset +0 -1
  40. data/.ruby-version +0 -1
  41. data/.travis.yml +0 -16
  42. data/Changelog.md +0 -22
  43. data/Contributors.md +0 -39
  44. data/Gemfile +0 -8
  45. data/Rakefile +0 -12
  46. data/Testing.md +0 -0
  47. data/lib/state_machines/assertions.rb +0 -40
  48. data/state_machines.gemspec +0 -22
  49. data/test/files/integrations/event_on_failure_integration.rb +0 -10
  50. data/test/files/integrations/vehicle.rb +0 -7
  51. data/test/files/models/auto_shop.rb +0 -31
  52. data/test/files/models/car.rb +0 -21
  53. data/test/files/models/driver.rb +0 -13
  54. data/test/files/models/model_base.rb +0 -6
  55. data/test/files/models/motorcycle.rb +0 -16
  56. data/test/files/models/traffic_light.rb +0 -47
  57. data/test/files/models/vehicle.rb +0 -127
  58. data/test/files/node.rb +0 -5
  59. data/test/files/switch.rb +0 -15
  60. data/test/functional/auto_shop_available_test.rb +0 -20
  61. data/test/functional/auto_shop_busy_test.rb +0 -25
  62. data/test/functional/car_backing_up_test.rb +0 -45
  63. data/test/functional/car_test.rb +0 -49
  64. data/test/functional/driver_default_nonstandard_test.rb +0 -13
  65. data/test/functional/motorcycle_test.rb +0 -52
  66. data/test/functional/traffic_light_caution_test.rb +0 -17
  67. data/test/functional/traffic_light_proceed_test.rb +0 -17
  68. data/test/functional/traffic_light_stop_test.rb +0 -26
  69. data/test/functional/vehicle_first_gear_test.rb +0 -42
  70. data/test/functional/vehicle_idling_test.rb +0 -59
  71. data/test/functional/vehicle_locked_test.rb +0 -29
  72. data/test/functional/vehicle_parked_test.rb +0 -53
  73. data/test/functional/vehicle_repaired_test.rb +0 -20
  74. data/test/functional/vehicle_second_gear_test.rb +0 -42
  75. data/test/functional/vehicle_stalled_test.rb +0 -65
  76. data/test/functional/vehicle_test.rb +0 -20
  77. data/test/functional/vehicle_third_gear_test.rb +0 -42
  78. data/test/functional/vehicle_unsaved_test.rb +0 -181
  79. data/test/functional/vehicle_with_event_attributes_test.rb +0 -30
  80. data/test/functional/vehicle_with_parallel_events_test.rb +0 -36
  81. data/test/test_helper.rb +0 -15
  82. data/test/unit/assertions/assert_exclusive_keys_test.rb +0 -22
  83. data/test/unit/assertions/assert_valid_key_test.rb +0 -12
  84. data/test/unit/branch/branch_test.rb +0 -28
  85. data/test/unit/branch/branch_with_conflicting_conditionals_test.rb +0 -27
  86. data/test/unit/branch/branch_with_conflicting_from_requirements_test.rb +0 -8
  87. data/test/unit/branch/branch_with_conflicting_on_requirements_test.rb +0 -8
  88. data/test/unit/branch/branch_with_conflicting_to_requirements_test.rb +0 -8
  89. data/test/unit/branch/branch_with_different_requirements_test.rb +0 -41
  90. data/test/unit/branch/branch_with_except_from_matcher_requirement_test.rb +0 -8
  91. data/test/unit/branch/branch_with_except_from_requirement_test.rb +0 -36
  92. data/test/unit/branch/branch_with_except_on_matcher_requirement_test.rb +0 -8
  93. data/test/unit/branch/branch_with_except_on_requirement_test.rb +0 -36
  94. data/test/unit/branch/branch_with_except_to_matcher_requirement_test.rb +0 -8
  95. data/test/unit/branch/branch_with_except_to_requirement_test.rb +0 -36
  96. data/test/unit/branch/branch_with_from_matcher_requirement_test.rb +0 -20
  97. data/test/unit/branch/branch_with_from_requirement_test.rb +0 -45
  98. data/test/unit/branch/branch_with_if_conditional_test.rb +0 -27
  99. data/test/unit/branch/branch_with_implicit_and_explicit_requirements_test.rb +0 -23
  100. data/test/unit/branch/branch_with_implicit_from_requirement_matcher_test.rb +0 -20
  101. data/test/unit/branch/branch_with_implicit_requirement_test.rb +0 -20
  102. data/test/unit/branch/branch_with_implicit_to_requirement_matcher_test.rb +0 -16
  103. data/test/unit/branch/branch_with_multiple_except_from_requirements_test.rb +0 -20
  104. data/test/unit/branch/branch_with_multiple_except_on_requirements_test.rb +0 -16
  105. data/test/unit/branch/branch_with_multiple_except_to_requirements_test.rb +0 -20
  106. data/test/unit/branch/branch_with_multiple_from_requirements_test.rb +0 -16
  107. data/test/unit/branch/branch_with_multiple_if_conditionals_test.rb +0 -20
  108. data/test/unit/branch/branch_with_multiple_implicit_requirements_test.rb +0 -53
  109. data/test/unit/branch/branch_with_multiple_to_requirements_test.rb +0 -20
  110. data/test/unit/branch/branch_with_multiple_unless_conditionals_test.rb +0 -20
  111. data/test/unit/branch/branch_with_nil_requirements_test.rb +0 -28
  112. data/test/unit/branch/branch_with_no_requirements_test.rb +0 -36
  113. data/test/unit/branch/branch_with_on_matcher_requirement_test.rb +0 -16
  114. data/test/unit/branch/branch_with_on_requirement_test.rb +0 -45
  115. data/test/unit/branch/branch_with_to_matcher_requirement_test.rb +0 -20
  116. data/test/unit/branch/branch_with_to_requirement_test.rb +0 -45
  117. data/test/unit/branch/branch_with_unless_conditional_test.rb +0 -27
  118. data/test/unit/branch/branch_without_guards_test.rb +0 -27
  119. data/test/unit/callback/callback_by_default_test.rb +0 -25
  120. data/test/unit/callback/callback_test.rb +0 -53
  121. data/test/unit/callback/callback_with_application_bound_object_test.rb +0 -23
  122. data/test/unit/callback/callback_with_application_terminator_test.rb +0 -24
  123. data/test/unit/callback/callback_with_arguments_test.rb +0 -14
  124. data/test/unit/callback/callback_with_around_type_and_arguments_test.rb +0 -25
  125. data/test/unit/callback/callback_with_around_type_and_block_test.rb +0 -44
  126. data/test/unit/callback/callback_with_around_type_and_bound_method_test.rb +0 -23
  127. data/test/unit/callback/callback_with_around_type_and_multiple_methods_test.rb +0 -93
  128. data/test/unit/callback/callback_with_around_type_and_terminator_test.rb +0 -17
  129. data/test/unit/callback/callback_with_block_test.rb +0 -20
  130. data/test/unit/callback/callback_with_bound_method_and_arguments_test.rb +0 -28
  131. data/test/unit/callback/callback_with_bound_method_test.rb +0 -35
  132. data/test/unit/callback/callback_with_do_method_test.rb +0 -18
  133. data/test/unit/callback/callback_with_explicit_requirements_test.rb +0 -32
  134. data/test/unit/callback/callback_with_if_condition_test.rb +0 -17
  135. data/test/unit/callback/callback_with_implicit_requirements_test.rb +0 -32
  136. data/test/unit/callback/callback_with_method_argument_test.rb +0 -18
  137. data/test/unit/callback/callback_with_mixed_methods_test.rb +0 -31
  138. data/test/unit/callback/callback_with_multiple_bound_methods_test.rb +0 -21
  139. data/test/unit/callback/callback_with_multiple_do_methods_test.rb +0 -29
  140. data/test/unit/callback/callback_with_multiple_method_arguments_test.rb +0 -29
  141. data/test/unit/callback/callback_with_terminator_test.rb +0 -22
  142. data/test/unit/callback/callback_with_unbound_method_test.rb +0 -14
  143. data/test/unit/callback/callback_with_unless_condition_test.rb +0 -17
  144. data/test/unit/callback/callback_without_arguments_test.rb +0 -14
  145. data/test/unit/callback/callback_without_terminator_test.rb +0 -12
  146. data/test/unit/error/error_by_default_test.rb +0 -21
  147. data/test/unit/error/error_with_message_test.rb +0 -23
  148. data/test/unit/eval_helper/eval_helpers_base_test.rb +0 -8
  149. data/test/unit/eval_helper/eval_helpers_proc_block_and_explicit_arguments_test.rb +0 -14
  150. data/test/unit/eval_helper/eval_helpers_proc_block_and_implicit_arguments_test.rb +0 -14
  151. data/test/unit/eval_helper/eval_helpers_proc_test.rb +0 -13
  152. data/test/unit/eval_helper/eval_helpers_proc_with_arguments_test.rb +0 -13
  153. data/test/unit/eval_helper/eval_helpers_proc_with_block_test.rb +0 -13
  154. data/test/unit/eval_helper/eval_helpers_proc_with_block_without_arguments_test.rb +0 -18
  155. data/test/unit/eval_helper/eval_helpers_proc_with_block_without_object_test.rb +0 -14
  156. data/test/unit/eval_helper/eval_helpers_proc_without_arguments_test.rb +0 -19
  157. data/test/unit/eval_helper/eval_helpers_string_test.rb +0 -25
  158. data/test/unit/eval_helper/eval_helpers_string_with_block_test.rb +0 -12
  159. data/test/unit/eval_helper/eval_helpers_symbol_method_missing_test.rb +0 -20
  160. data/test/unit/eval_helper/eval_helpers_symbol_private_test.rb +0 -17
  161. data/test/unit/eval_helper/eval_helpers_symbol_protected_test.rb +0 -17
  162. data/test/unit/eval_helper/eval_helpers_symbol_tainted_method_test.rb +0 -18
  163. data/test/unit/eval_helper/eval_helpers_symbol_test.rb +0 -16
  164. data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_and_block_test.rb +0 -16
  165. data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_test.rb +0 -16
  166. data/test/unit/eval_helper/eval_helpers_symbol_with_block_test.rb +0 -16
  167. data/test/unit/eval_helper/eval_helpers_test.rb +0 -13
  168. data/test/unit/event/event_after_being_copied_test.rb +0 -17
  169. data/test/unit/event/event_by_default_test.rb +0 -60
  170. data/test/unit/event/event_context_test.rb +0 -16
  171. data/test/unit/event/event_on_failure_test.rb +0 -44
  172. data/test/unit/event/event_test.rb +0 -34
  173. data/test/unit/event/event_transitions_test.rb +0 -62
  174. data/test/unit/event/event_with_conflicting_helpers_after_definition_test.rb +0 -79
  175. data/test/unit/event/event_with_conflicting_helpers_before_definition_test.rb +0 -58
  176. data/test/unit/event/event_with_conflicting_machine_test.rb +0 -48
  177. data/test/unit/event/event_with_dynamic_human_name_test.rb +0 -26
  178. data/test/unit/event/event_with_human_name_test.rb +0 -13
  179. data/test/unit/event/event_with_invalid_current_state_test.rb +0 -30
  180. data/test/unit/event/event_with_machine_action_test.rb +0 -33
  181. data/test/unit/event/event_with_marshalling_test.rb +0 -47
  182. data/test/unit/event/event_with_matching_disabled_transitions_test.rb +0 -115
  183. data/test/unit/event/event_with_matching_enabled_transitions_test.rb +0 -75
  184. data/test/unit/event/event_with_multiple_transitions_test.rb +0 -61
  185. data/test/unit/event/event_with_namespace_test.rb +0 -34
  186. data/test/unit/event/event_with_transition_with_blacklisted_to_state_test.rb +0 -60
  187. data/test/unit/event/event_with_transition_with_loopback_state_test.rb +0 -36
  188. data/test/unit/event/event_with_transition_with_nil_to_state_test.rb +0 -36
  189. data/test/unit/event/event_with_transition_with_whitelisted_to_state_test.rb +0 -51
  190. data/test/unit/event/event_with_transition_without_to_state_test.rb +0 -36
  191. data/test/unit/event/event_with_transitions_test.rb +0 -32
  192. data/test/unit/event/event_without_matching_transitions_test.rb +0 -41
  193. data/test/unit/event/event_without_transitions_test.rb +0 -28
  194. data/test/unit/event/invalid_event_test.rb +0 -20
  195. data/test/unit/event_collection/event_collection_attribute_with_machine_action_test.rb +0 -62
  196. data/test/unit/event_collection/event_collection_attribute_with_namespaced_machine_test.rb +0 -36
  197. data/test/unit/event_collection/event_collection_by_default_test.rb +0 -26
  198. data/test/unit/event_collection/event_collection_test.rb +0 -39
  199. data/test/unit/event_collection/event_collection_with_custom_machine_attribute_test.rb +0 -31
  200. data/test/unit/event_collection/event_collection_with_events_with_transitions_test.rb +0 -76
  201. data/test/unit/event_collection/event_collection_with_multiple_events_test.rb +0 -27
  202. data/test/unit/event_collection/event_collection_with_validations_test.rb +0 -74
  203. data/test/unit/event_collection/event_collection_without_machine_action_test.rb +0 -18
  204. data/test/unit/event_collection/event_string_collection_test.rb +0 -31
  205. data/test/unit/helper_module_test.rb +0 -17
  206. data/test/unit/integrations/integration_finder_test.rb +0 -16
  207. data/test/unit/integrations/integration_matcher_test.rb +0 -29
  208. data/test/unit/invalid_transition/invalid_parallel_transition_test.rb +0 -18
  209. data/test/unit/invalid_transition/invalid_transition_test.rb +0 -47
  210. data/test/unit/invalid_transition/invalid_transition_with_integration_test.rb +0 -45
  211. data/test/unit/invalid_transition/invalid_transition_with_namespace_test.rb +0 -32
  212. data/test/unit/machine/machine_after_being_copied_test.rb +0 -62
  213. data/test/unit/machine/machine_after_changing_initial_state.rb +0 -28
  214. data/test/unit/machine/machine_after_changing_owner_class_test.rb +0 -31
  215. data/test/unit/machine/machine_by_default_test.rb +0 -160
  216. data/test/unit/machine/machine_finder_custom_options_test.rb +0 -17
  217. data/test/unit/machine/machine_finder_with_existing_machine_on_superclass_test.rb +0 -85
  218. data/test/unit/machine/machine_finder_with_existing_on_same_class_test.rb +0 -23
  219. data/test/unit/machine/machine_finder_without_existing_machine_test.rb +0 -25
  220. data/test/unit/machine/machine_persistence_test.rb +0 -52
  221. data/test/unit/machine/machine_state_initialization_test.rb +0 -56
  222. data/test/unit/machine/machine_test.rb +0 -30
  223. data/test/unit/machine/machine_with_action_already_overridden_test.rb +0 -23
  224. data/test/unit/machine/machine_with_action_defined_in_class_test.rb +0 -37
  225. data/test/unit/machine/machine_with_action_defined_in_included_module_test.rb +0 -46
  226. data/test/unit/machine/machine_with_action_defined_in_superclass_test.rb +0 -43
  227. data/test/unit/machine/machine_with_action_undefined_test.rb +0 -33
  228. data/test/unit/machine/machine_with_cached_state_test.rb +0 -20
  229. data/test/unit/machine/machine_with_class_helpers_test.rb +0 -179
  230. data/test/unit/machine/machine_with_conflicting_helpers_after_definition_test.rb +0 -244
  231. data/test/unit/machine/machine_with_conflicting_helpers_before_definition_test.rb +0 -175
  232. data/test/unit/machine/machine_with_custom_action_test.rb +0 -11
  233. data/test/unit/machine/machine_with_custom_attribute_test.rb +0 -103
  234. data/test/unit/machine/machine_with_custom_initialize_test.rb +0 -24
  235. data/test/unit/machine/machine_with_custom_integration_test.rb +0 -72
  236. data/test/unit/machine/machine_with_custom_invalidation_test.rb +0 -39
  237. data/test/unit/machine/machine_with_custom_name_test.rb +0 -57
  238. data/test/unit/machine/machine_with_custom_plural_test.rb +0 -52
  239. data/test/unit/machine/machine_with_dynamic_initial_state_test.rb +0 -65
  240. data/test/unit/machine/machine_with_event_matchers_test.rb +0 -41
  241. data/test/unit/machine/machine_with_events_test.rb +0 -52
  242. data/test/unit/machine/machine_with_events_with_custom_human_names_test.rb +0 -18
  243. data/test/unit/machine/machine_with_events_with_transitions_test.rb +0 -37
  244. data/test/unit/machine/machine_with_existing_event_test.rb +0 -17
  245. data/test/unit/machine/machine_with_existing_machines_on_owner_class_test.rb +0 -20
  246. data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_class_test.rb +0 -71
  247. data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_subclass_test.rb +0 -31
  248. data/test/unit/machine/machine_with_existing_state_test.rb +0 -27
  249. data/test/unit/machine/machine_with_failure_callbacks_test.rb +0 -48
  250. data/test/unit/machine/machine_with_helpers_test.rb +0 -14
  251. data/test/unit/machine/machine_with_initial_state_with_value_and_owner_default.rb +0 -25
  252. data/test/unit/machine/machine_with_initialize_and_super_test.rb +0 -17
  253. data/test/unit/machine/machine_with_initialize_arguments_and_block_test.rb +0 -31
  254. data/test/unit/machine/machine_with_initialize_without_super_test.rb +0 -17
  255. data/test/unit/machine/machine_with_instance_helpers_test.rb +0 -179
  256. data/test/unit/machine/machine_with_integration_test.rb +0 -72
  257. data/test/unit/machine/machine_with_multiple_events_test.rb +0 -32
  258. data/test/unit/machine/machine_with_namespace_test.rb +0 -48
  259. data/test/unit/machine/machine_with_nil_action_test.rb +0 -27
  260. data/test/unit/machine/machine_with_other_states.rb +0 -22
  261. data/test/unit/machine/machine_with_owner_subclass_test.rb +0 -18
  262. data/test/unit/machine/machine_with_paths_test.rb +0 -25
  263. data/test/unit/machine/machine_with_private_action_test.rb +0 -43
  264. data/test/unit/machine/machine_with_state_matchers_test.rb +0 -41
  265. data/test/unit/machine/machine_with_state_with_matchers_test.rb +0 -19
  266. data/test/unit/machine/machine_with_states_test.rb +0 -55
  267. data/test/unit/machine/machine_with_states_with_behaviors_test.rb +0 -23
  268. data/test/unit/machine/machine_with_states_with_custom_human_names_test.rb +0 -18
  269. data/test/unit/machine/machine_with_states_with_custom_values_test.rb +0 -21
  270. data/test/unit/machine/machine_with_states_with_runtime_dependencies_test.rb +0 -19
  271. data/test/unit/machine/machine_with_static_initial_state_test.rb +0 -49
  272. data/test/unit/machine/machine_with_superclass_conflicting_helpers_after_definition_test.rb +0 -36
  273. data/test/unit/machine/machine_with_transition_callbacks_test.rb +0 -144
  274. data/test/unit/machine/machine_with_transitions_test.rb +0 -87
  275. data/test/unit/machine/machine_without_initialization_test.rb +0 -31
  276. data/test/unit/machine/machine_without_initialize_test.rb +0 -14
  277. data/test/unit/machine/machine_without_integration_test.rb +0 -31
  278. data/test/unit/machine_collection/machine_collection_by_default_test.rb +0 -11
  279. data/test/unit/machine_collection/machine_collection_fire_test.rb +0 -80
  280. data/test/unit/machine_collection/machine_collection_fire_with_transactions_test.rb +0 -54
  281. data/test/unit/machine_collection/machine_collection_fire_with_validations_test.rb +0 -76
  282. data/test/unit/machine_collection/machine_collection_state_initialization_test.rb +0 -111
  283. data/test/unit/machine_collection/machine_collection_transitions_with_blank_events_test.rb +0 -25
  284. data/test/unit/machine_collection/machine_collection_transitions_with_custom_options_test.rb +0 -20
  285. data/test/unit/machine_collection/machine_collection_transitions_with_different_actions_test.rb +0 -26
  286. data/test/unit/machine_collection/machine_collection_transitions_with_exisiting_transitions_test.rb +0 -25
  287. data/test/unit/machine_collection/machine_collection_transitions_with_invalid_events_test.rb +0 -25
  288. data/test/unit/machine_collection/machine_collection_transitions_with_same_actions_test.rb +0 -31
  289. data/test/unit/machine_collection/machine_collection_transitions_with_transition_test.rb +0 -26
  290. data/test/unit/machine_collection/machine_collection_transitions_without_events_test.rb +0 -25
  291. data/test/unit/machine_collection/machine_collection_transitions_without_transition_test.rb +0 -27
  292. data/test/unit/matcher/all_matcher_test.rb +0 -29
  293. data/test/unit/matcher/blacklist_matcher_test.rb +0 -30
  294. data/test/unit/matcher/loopback_matcher_test.rb +0 -27
  295. data/test/unit/matcher/matcher_by_default_test.rb +0 -15
  296. data/test/unit/matcher/matcher_with_multiple_values_test.rb +0 -15
  297. data/test/unit/matcher/matcher_with_value_test.rb +0 -15
  298. data/test/unit/matcher/whitelist_matcher_test.rb +0 -30
  299. data/test/unit/matcher_helpers/matcher_helpers_all_test.rb +0 -14
  300. data/test/unit/matcher_helpers/matcher_helpers_any_test.rb +0 -14
  301. data/test/unit/matcher_helpers/matcher_helpers_same_test.rb +0 -13
  302. data/test/unit/node_collection/node_collection_after_being_copied_test.rb +0 -46
  303. data/test/unit/node_collection/node_collection_after_update_test.rb +0 -36
  304. data/test/unit/node_collection/node_collection_by_default_test.rb +0 -22
  305. data/test/unit/node_collection/node_collection_test.rb +0 -23
  306. data/test/unit/node_collection/node_collection_with_indices_test.rb +0 -42
  307. data/test/unit/node_collection/node_collection_with_matcher_contexts_test.rb +0 -25
  308. data/test/unit/node_collection/node_collection_with_nodes_test.rb +0 -46
  309. data/test/unit/node_collection/node_collection_with_numeric_index_test.rb +0 -24
  310. data/test/unit/node_collection/node_collection_with_postdefined_contexts_test.rb +0 -22
  311. data/test/unit/node_collection/node_collection_with_predefined_contexts_test.rb +0 -23
  312. data/test/unit/node_collection/node_collection_with_string_index_test.rb +0 -20
  313. data/test/unit/node_collection/node_collection_with_symbol_index_test.rb +0 -20
  314. data/test/unit/node_collection/node_collection_without_indices_test.rb +0 -30
  315. data/test/unit/path/path_by_default_test.rb +0 -54
  316. data/test/unit/path/path_test.rb +0 -14
  317. data/test/unit/path/path_with_available_transitions_after_reaching_target_test.rb +0 -40
  318. data/test/unit/path/path_with_available_transitions_test.rb +0 -54
  319. data/test/unit/path/path_with_deep_target_reached_test.rb +0 -50
  320. data/test/unit/path/path_with_deep_target_test.rb +0 -40
  321. data/test/unit/path/path_with_duplicates_test.rb +0 -32
  322. data/test/unit/path/path_with_encountered_transitions_test.rb +0 -34
  323. data/test/unit/path/path_with_guarded_transitions_test.rb +0 -42
  324. data/test/unit/path/path_with_reached_target_test.rb +0 -35
  325. data/test/unit/path/path_with_transitions_test.rb +0 -54
  326. data/test/unit/path/path_with_unreached_target_test.rb +0 -31
  327. data/test/unit/path/path_without_transitions_test.rb +0 -24
  328. data/test/unit/path_collection/path_collection_by_default_test.rb +0 -46
  329. data/test/unit/path_collection/path_collection_test.rb +0 -24
  330. data/test/unit/path_collection/path_collection_with_deep_paths_test.rb +0 -43
  331. data/test/unit/path_collection/path_collection_with_duplicate_nodes_test.rb +0 -31
  332. data/test/unit/path_collection/path_collection_with_from_state_test.rb +0 -27
  333. data/test/unit/path_collection/path_collection_with_paths_test.rb +0 -47
  334. data/test/unit/path_collection/path_collection_with_to_state_test.rb +0 -29
  335. data/test/unit/path_collection/path_with_guarded_paths_test.rb +0 -25
  336. data/test/unit/state/state_after_being_copied_test.rb +0 -19
  337. data/test/unit/state/state_by_default_test.rb +0 -41
  338. data/test/unit/state/state_final_test.rb +0 -28
  339. data/test/unit/state/state_initial_test.rb +0 -13
  340. data/test/unit/state/state_not_final_test.rb +0 -32
  341. data/test/unit/state/state_not_initial_test.rb +0 -13
  342. data/test/unit/state/state_test.rb +0 -44
  343. data/test/unit/state/state_with_cached_lambda_value_test.rb +0 -29
  344. data/test/unit/state/state_with_conflicting_helpers_after_definition_test.rb +0 -38
  345. data/test/unit/state/state_with_conflicting_helpers_before_definition_test.rb +0 -29
  346. data/test/unit/state/state_with_conflicting_machine_name_test.rb +0 -20
  347. data/test/unit/state/state_with_conflicting_machine_test.rb +0 -37
  348. data/test/unit/state/state_with_context_test.rb +0 -60
  349. data/test/unit/state/state_with_dynamic_human_name_test.rb +0 -25
  350. data/test/unit/state/state_with_existing_context_method_test.rb +0 -24
  351. data/test/unit/state/state_with_human_name_test.rb +0 -13
  352. data/test/unit/state/state_with_integer_value_test.rb +0 -32
  353. data/test/unit/state/state_with_invalid_method_call_test.rb +0 -21
  354. data/test/unit/state/state_with_lambda_value_test.rb +0 -37
  355. data/test/unit/state/state_with_matcher_test.rb +0 -18
  356. data/test/unit/state/state_with_multiple_contexts_test.rb +0 -57
  357. data/test/unit/state/state_with_name_test.rb +0 -43
  358. data/test/unit/state/state_with_namespace_test.rb +0 -22
  359. data/test/unit/state/state_with_nil_value_test.rb +0 -35
  360. data/test/unit/state/state_with_redefined_context_method_test.rb +0 -45
  361. data/test/unit/state/state_with_symbolic_value_test.rb +0 -32
  362. data/test/unit/state/state_with_valid_inherited_method_call_for_current_state_test.rb +0 -40
  363. data/test/unit/state/state_with_valid_method_call_for_current_state_test.rb +0 -33
  364. data/test/unit/state/state_with_valid_method_call_for_different_state_test.rb +0 -41
  365. data/test/unit/state/state_without_cached_lambda_value_test.rb +0 -25
  366. data/test/unit/state/state_without_name_test.rb +0 -39
  367. data/test/unit/state_collection/state_collection_by_default_test.rb +0 -21
  368. data/test/unit/state_collection/state_collection_string_test.rb +0 -35
  369. data/test/unit/state_collection/state_collection_test.rb +0 -74
  370. data/test/unit/state_collection/state_collection_with_custom_state_values_test.rb +0 -29
  371. data/test/unit/state_collection/state_collection_with_event_transitions_test.rb +0 -39
  372. data/test/unit/state_collection/state_collection_with_initial_state_test.rb +0 -40
  373. data/test/unit/state_collection/state_collection_with_namespace_test.rb +0 -21
  374. data/test/unit/state_collection/state_collection_with_state_behaviors_test.rb +0 -40
  375. data/test/unit/state_collection/state_collection_with_state_matchers_test.rb +0 -29
  376. data/test/unit/state_collection/state_collection_with_transition_callbacks_test.rb +0 -40
  377. data/test/unit/state_context/state_context_proxy_test.rb +0 -26
  378. data/test/unit/state_context/state_context_proxy_with_if_and_unless_conditions_test.rb +0 -42
  379. data/test/unit/state_context/state_context_proxy_with_if_condition_test.rb +0 -64
  380. data/test/unit/state_context/state_context_proxy_with_multiple_if_conditions_test.rb +0 -32
  381. data/test/unit/state_context/state_context_proxy_with_multiple_unless_conditions_test.rb +0 -32
  382. data/test/unit/state_context/state_context_proxy_with_unless_condition_test.rb +0 -64
  383. data/test/unit/state_context/state_context_proxy_without_conditions_test.rb +0 -31
  384. data/test/unit/state_context/state_context_test.rb +0 -28
  385. data/test/unit/state_context/state_context_transition_test.rb +0 -104
  386. data/test/unit/state_context/state_context_with_matching_transition_test.rb +0 -27
  387. data/test/unit/state_machine/state_machine_by_default_test.rb +0 -12
  388. data/test/unit/state_machine/state_machine_test.rb +0 -20
  389. data/test/unit/transition/transition_after_being_performed_test.rb +0 -48
  390. data/test/unit/transition/transition_after_being_persisted_test.rb +0 -46
  391. data/test/unit/transition/transition_after_being_rolled_back_test.rb +0 -35
  392. data/test/unit/transition/transition_equality_test.rb +0 -52
  393. data/test/unit/transition/transition_loopback_test.rb +0 -18
  394. data/test/unit/transition/transition_test.rb +0 -96
  395. data/test/unit/transition/transition_transient_test.rb +0 -20
  396. data/test/unit/transition/transition_with_action_test.rb +0 -27
  397. data/test/unit/transition/transition_with_after_callbacks_skipped_test.rb +0 -127
  398. data/test/unit/transition/transition_with_after_callbacks_test.rb +0 -93
  399. data/test/unit/transition/transition_with_around_callbacks_test.rb +0 -141
  400. data/test/unit/transition/transition_with_before_callbacks_skipped_test.rb +0 -30
  401. data/test/unit/transition/transition_with_before_callbacks_test.rb +0 -104
  402. data/test/unit/transition/transition_with_custom_machine_attribute_test.rb +0 -28
  403. data/test/unit/transition/transition_with_different_states_test.rb +0 -18
  404. data/test/unit/transition/transition_with_dynamic_to_value_test.rb +0 -19
  405. data/test/unit/transition/transition_with_failure_callbacks_test.rb +0 -84
  406. data/test/unit/transition/transition_with_invalid_nodes_test.rb +0 -29
  407. data/test/unit/transition/transition_with_mixed_callbacks_test.rb +0 -105
  408. data/test/unit/transition/transition_with_multiple_after_callbacks_test.rb +0 -40
  409. data/test/unit/transition/transition_with_multiple_around_callbacks_test.rb +0 -114
  410. data/test/unit/transition/transition_with_multiple_before_callbacks_test.rb +0 -40
  411. data/test/unit/transition/transition_with_multiple_failure_callbacks_test.rb +0 -40
  412. data/test/unit/transition/transition_with_namespace_test.rb +0 -47
  413. data/test/unit/transition/transition_with_perform_arguments_test.rb +0 -35
  414. data/test/unit/transition/transition_with_transactions_test.rb +0 -42
  415. data/test/unit/transition/transition_without_callbacks_test.rb +0 -33
  416. data/test/unit/transition/transition_without_reading_state_test.rb +0 -22
  417. data/test/unit/transition/transition_without_running_action_test.rb +0 -47
  418. data/test/unit/transition_collection/attribute_transition_collection_by_default_test.rb +0 -23
  419. data/test/unit/transition_collection/attribute_transition_collection_marshalling_test.rb +0 -64
  420. data/test/unit/transition_collection/attribute_transition_collection_with_action_error_test.rb +0 -44
  421. data/test/unit/transition_collection/attribute_transition_collection_with_action_failed_test.rb +0 -44
  422. data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_error_test.rb +0 -32
  423. data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_halt_test.rb +0 -33
  424. data/test/unit/transition_collection/attribute_transition_collection_with_around_after_yield_callback_error_test.rb +0 -32
  425. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_error_test.rb +0 -32
  426. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_halt_test.rb +0 -33
  427. data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_before_yield_halt_test.rb +0 -33
  428. data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_error_test.rb +0 -32
  429. data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_halt_test.rb +0 -33
  430. data/test/unit/transition_collection/attribute_transition_collection_with_callbacks_test.rb +0 -68
  431. data/test/unit/transition_collection/attribute_transition_collection_with_event_transitions_test.rb +0 -41
  432. data/test/unit/transition_collection/attribute_transition_collection_with_events_test.rb +0 -44
  433. data/test/unit/transition_collection/attribute_transition_collection_with_skipped_after_callbacks_test.rb +0 -42
  434. data/test/unit/transition_collection/transition_collection_by_default_test.rb +0 -23
  435. data/test/unit/transition_collection/transition_collection_empty_with_block_test.rb +0 -23
  436. data/test/unit/transition_collection/transition_collection_empty_without_block_test.rb +0 -12
  437. data/test/unit/transition_collection/transition_collection_invalid_test.rb +0 -21
  438. data/test/unit/transition_collection/transition_collection_partial_invalid_test.rb +0 -69
  439. data/test/unit/transition_collection/transition_collection_test.rb +0 -26
  440. data/test/unit/transition_collection/transition_collection_valid_test.rb +0 -57
  441. data/test/unit/transition_collection/transition_collection_with_action_error_test.rb +0 -66
  442. data/test/unit/transition_collection/transition_collection_with_action_failed_test.rb +0 -60
  443. data/test/unit/transition_collection/transition_collection_with_action_hook_and_block_test.rb +0 -17
  444. data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_action_test.rb +0 -17
  445. data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_after_callbacks_test.rb +0 -37
  446. data/test/unit/transition_collection/transition_collection_with_action_hook_base_test.rb +0 -34
  447. data/test/unit/transition_collection/transition_collection_with_action_hook_error_test.rb +0 -29
  448. data/test/unit/transition_collection/transition_collection_with_action_hook_invalid_test.rb +0 -17
  449. data/test/unit/transition_collection/transition_collection_with_action_hook_multiple_test.rb +0 -79
  450. data/test/unit/transition_collection/transition_collection_with_action_hook_test.rb +0 -45
  451. data/test/unit/transition_collection/transition_collection_with_action_hook_with_different_actions_test.rb +0 -48
  452. data/test/unit/transition_collection/transition_collection_with_action_hook_with_nil_action_test.rb +0 -42
  453. data/test/unit/transition_collection/transition_collection_with_after_callback_halt_test.rb +0 -47
  454. data/test/unit/transition_collection/transition_collection_with_before_callback_halt_test.rb +0 -51
  455. data/test/unit/transition_collection/transition_collection_with_block_test.rb +0 -46
  456. data/test/unit/transition_collection/transition_collection_with_callbacks_test.rb +0 -135
  457. data/test/unit/transition_collection/transition_collection_with_different_actions_test.rb +0 -189
  458. data/test/unit/transition_collection/transition_collection_with_duplicate_actions_test.rb +0 -48
  459. data/test/unit/transition_collection/transition_collection_with_empty_actions_test.rb +0 -41
  460. data/test/unit/transition_collection/transition_collection_with_mixed_actions_test.rb +0 -41
  461. data/test/unit/transition_collection/transition_collection_with_skipped_actions_and_block_test.rb +0 -34
  462. data/test/unit/transition_collection/transition_collection_with_skipped_actions_test.rb +0 -69
  463. data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_and_around_callbacks_test.rb +0 -53
  464. data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_test.rb +0 -34
  465. data/test/unit/transition_collection/transition_collection_with_transactions_test.rb +0 -65
  466. data/test/unit/transition_collection/transition_collection_without_transactions_test.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: '029961fc61666a778298a5b6e5b5b31802b8710f'
4
- data.tar.gz: d9e00ff04cbffbaf522e82b40e76aeb9c9ab3564
2
+ SHA256:
3
+ metadata.gz: 5aa5d105c78cb53f15f42e8662dd7f8e0d0d5f8807b88dcbd8b4201f13718384
4
+ data.tar.gz: d761cedbe052c5c8829626e0875f54dce064f7156162119b4a040594b439068c
5
5
  SHA512:
6
- metadata.gz: 52f6b57620f17c661585a1bccf2340d46be80366f2a7de609c41033ff46024cc62fc17814279267b26de65974612f149c0a057b47f2396e45f842c249742c9cd
7
- data.tar.gz: b8bbe1923532edffd936139272782d6053b0ab8f1b338eaf61f805fbbc2a3b1c284bd523c35a375fc40fecb6f4948cb4aabcfc72c0fda5ded46959557a20b1cc
6
+ metadata.gz: 37398c9ca5f2de7413dfb7a8a467984d0fc4d47f8367ea0747fec6d9c1eaca5a7c3439f37988c02dd8ce27622a9a9e54cf5cc0b2d84404f00f92a862c168bb23
7
+ data.tar.gz: 159022534eb3c308bc2f2c8e960f111053631d3e10adafc9ae8156c95a26165f48690c682229a577bdfecf918b335ebe5b6d57e82e095c924585ad8d11b9d1ee
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2006-2012 Aaron Pfeifer
2
- Copyright (c) 2014-2015 Abdelkader Boudih
2
+ Copyright (c) 2014-2023 Abdelkader Boudih
3
3
 
4
4
  MIT License
5
5
 
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- [![Build Status](https://travis-ci.org/state-machines/state_machines.svg?branch=master)](https://travis-ci.org/state-machines/state_machines)
2
- [![Code Climate](https://codeclimate.com/github/state-machines/state_machines.svg)](https://codeclimate.com/github/state-machines/state_machines)
1
+ ![Build Status](https://github.com/state-machines/state_machines/actions/workflows/ruby.yml/badge.svg)
3
2
  # State Machines
4
3
 
5
4
  State Machines adds support for creating state machines for attributes on any Ruby class.
@@ -237,6 +236,10 @@ vehicle.state_paths # => [[#<StateMachines
237
236
  vehicle.state_paths.to_states # => [:parked, :idling, :first_gear, :stalled, :second_gear, :third_gear]
238
237
  vehicle.state_paths.events # => [:park, :ignite, :shift_up, :idle, :crash, :repair, :shift_down]
239
238
 
239
+ # Possible states can be analyzed for a class
240
+ Vehicle.state_machine.states.to_a # [#<StateMachines::State name=:parked value="parked" initial=true>, #<StateMachines::State name=:idling value="idling" initial=false>, ...]
241
+ Vehicle.state_machines[:state].states.to_a # [#<StateMachines::State name=:parked value="parked" initial=true>, #<StateMachines::State name=:idling value="idling" initial=false>, ...]
242
+
240
243
  # Find all paths that start and end on certain states
241
244
  vehicle.state_paths(:from => :parked, :to => :first_gear) # => [[
242
245
  # #<StateMachines:Transition attribute=:state event=:ignite from="parked" ...>,
@@ -251,6 +254,71 @@ vehicle.state_name # => :parked
251
254
  # vehicle.state = :parked
252
255
  ```
253
256
 
257
+ ## Testing
258
+
259
+ State Machines provides a `TestHelper` module with assertion methods to make testing state machines easier and more expressive.
260
+
261
+ ### Setup
262
+
263
+ Include the test helper in your test class:
264
+
265
+ ```ruby
266
+ # For Minitest
267
+ class VehicleTest < Minitest::Test
268
+ include StateMachines::TestHelper
269
+
270
+ def test_initial_state
271
+ vehicle = Vehicle.new
272
+ assert_state vehicle, :state, :parked
273
+ end
274
+ end
275
+
276
+ # For RSpec
277
+ RSpec.describe Vehicle do
278
+ include StateMachines::TestHelper
279
+
280
+ it "starts in parked state" do
281
+ vehicle = Vehicle.new
282
+ assert_state vehicle, :state, :parked
283
+ end
284
+ end
285
+ ```
286
+
287
+ ### Available Assertions
288
+
289
+ The TestHelper provides both basic assertions and comprehensive state machine-specific assertions with `sm_` prefixes:
290
+
291
+ #### Basic Assertions
292
+
293
+ ```ruby
294
+ vehicle = Vehicle.new
295
+ assert_state vehicle, :state, :parked
296
+ assert_can_transition vehicle, :ignite
297
+ assert_cannot_transition vehicle, :shift_up
298
+ assert_transition vehicle, :ignite, :state, :idling
299
+ ```
300
+
301
+ #### Extended State Machine Assertions
302
+
303
+ ```ruby
304
+ machine = Vehicle.state_machine(:state)
305
+ vehicle = Vehicle.new
306
+
307
+ # State configuration
308
+ assert_sm_states_list machine, [:parked, :idling, :stalled]
309
+ assert_sm_initial_state machine, :parked
310
+
311
+ # Event behavior
312
+ assert_sm_event_triggers vehicle, :ignite
313
+ refute_sm_event_triggers vehicle, :shift_up
314
+ assert_sm_event_raises_error vehicle, :invalid_event, StateMachines::InvalidTransition
315
+
316
+ # Persistence (with ActiveRecord integration)
317
+ assert_sm_state_persisted record, expected: :active
318
+ ```
319
+
320
+ The test helper works with both Minitest and RSpec, automatically detecting your testing framework.
321
+
254
322
  ## Additional Topics
255
323
 
256
324
  ### Explicit vs. Implicit Event Transitions
@@ -424,7 +492,7 @@ easily migrate from a different library, you can do so as shown below:
424
492
  ```ruby
425
493
  class Vehicle
426
494
  state_machine initial: :parked do
427
- ...
495
+ # ...
428
496
 
429
497
  state :parked do
430
498
  transition to: :idling, :on => [:ignite, :shift_up], if: :seatbelt_on?
@@ -460,12 +528,11 @@ example below:
460
528
  ```ruby
461
529
  class Vehicle
462
530
  state_machine initial: :parked do
463
- ...
531
+ # ...
464
532
 
465
533
  transition parked: :idling, :on => [:ignite, :shift_up]
466
534
  transition first_gear: :second_gear, second_gear: :third_gear, on: :shift_up
467
535
  transition [:idling, :first_gear] => :parked, on: :park
468
- transition [:idling, :first_gear] => :parked, on: :park
469
536
  transition all - [:parked, :stalled]: :stalled, unless: :auto_shop_busy?
470
537
  end
471
538
  end
@@ -493,12 +560,31 @@ class Vehicle
493
560
  transition [:idling, :first_gear] => :parked
494
561
  end
495
562
 
496
- ...
563
+ # ...
497
564
  end
498
565
  end
499
566
  ```
500
567
 
501
- However, there may be cases where the definition of a state machine is **dynamic**.
568
+ #### Draw state machines
569
+
570
+ State machines includes a default STDIORenderer for debugging state machines without external dependencies.
571
+ This renderer can be used to visualize the state machine in the console.
572
+
573
+ To use the renderer, simply call the `draw` method on the state machine:
574
+
575
+ ```ruby
576
+ Vehicle.state_machine.draw # Outputs the state machine diagram to the console
577
+ ```
578
+
579
+ You can customize the output by passing in options to the `draw` method, such as the output stream:
580
+
581
+ ```ruby
582
+ Vehicle.state_machine.draw(io: $stderr) # Outputs the state machine diagram to stderr
583
+ ```
584
+
585
+ #### Dynamic definitions
586
+
587
+ There may be cases where the definition of a state machine is **dynamic**.
502
588
  This means that you don't know the possible states or events for a machine until
503
589
  runtime. For example, you may allow users in your application to manage the
504
590
  state machine of a project or task in your system. This means that the list of
@@ -563,7 +649,7 @@ end
563
649
  vehicle = Vehicle.new # => #<Vehicle:0xb708412c @state="parked" ...>
564
650
  vehicle.state # => "parked"
565
651
  vehicle.machine.ignite # => true
566
- vehicle.machine.state # => "idling
652
+ vehicle.machine.state # => "idling"
567
653
  vehicle.state # => "idling"
568
654
  vehicle.machine.state_transitions # => [#<StateMachines:Transition ...>]
569
655
  vehicle.machine.definition.states.keys # => :first_gear, :second_gear, :parked, :idling
@@ -577,22 +663,19 @@ transitions.
577
663
 
578
664
  Ruby versions officially supported and tested:
579
665
 
580
- * Ruby (MRI) 2.0.0+
581
- * JRuby
582
- * Rubinius
666
+ * Ruby (MRI) 3.0.0+
583
667
 
584
668
  For graphing state machine:
585
669
 
586
- * [state_machines-graphviz](http://github.com/state-machines/state_machines-graphviz)
670
+ * [state_machines-graphviz](https://github.com/state-machines/state_machines-graphviz)
587
671
 
588
672
  For documenting state machines:
589
673
 
590
- * [state_machines-yard](http://github.com/state-machines/state_machines-yard)
591
-
674
+ * [state_machines-yard](https://github.com/state-machines/state_machines-yard)
592
675
 
593
- ## TODO
676
+ For RSpec testing, use the custom RSpec matchers:
594
677
 
595
- * Add matchers/assertions for rspec and minitest
678
+ * [state_machines-rspec](https://github.com/state-machines/state_machines-rspec)
596
679
 
597
680
  ## Contributing
598
681
 
@@ -1,3 +1,7 @@
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
@@ -6,68 +10,68 @@ module StateMachines
6
10
  class Branch
7
11
 
8
12
  include EvalHelpers
9
-
13
+
10
14
  # The condition that must be met on an object
11
15
  attr_reader :if_condition
12
-
16
+
13
17
  # The condition that must *not* be met on an object
14
18
  attr_reader :unless_condition
15
-
19
+
16
20
  # The requirement for verifying the event being matched
17
21
  attr_reader :event_requirement
18
-
22
+
19
23
  # One or more requirements for verifying the states being matched. All
20
24
  # requirements contain a mapping of {:from => matcher, :to => matcher}.
21
25
  attr_reader :state_requirements
22
-
26
+
23
27
  # A list of all of the states known to this branch. This will pull states
24
28
  # from the following options (in the same order):
25
29
  # * +from+ / +except_from+
26
30
  # * +to+ / +except_to+
27
31
  attr_reader :known_states
28
-
32
+
29
33
  # Creates a new branch
30
34
  def initialize(options = {}) #:nodoc:
31
35
  # Build conditionals
32
36
  @if_condition = options.delete(:if)
33
37
  @unless_condition = options.delete(:unless)
34
-
38
+
35
39
  # Build event requirement
36
40
  @event_requirement = build_matcher(options, :on, :except_on)
37
-
41
+
38
42
  if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on]).empty?
39
43
  # Explicit from/to requirements specified
40
- @state_requirements = [{:from => build_matcher(options, :from, :except_from), :to => build_matcher(options, :to, :except_to)}]
44
+ @state_requirements = [{from: build_matcher(options, :from, :except_from), to: build_matcher(options, :to, :except_to)}]
41
45
  else
42
46
  # Separate out the event requirement
43
47
  options.delete(:on)
44
48
  options.delete(:except_on)
45
-
49
+
46
50
  # Implicit from/to requirements specified
47
51
  @state_requirements = options.collect do |from, to|
48
52
  from = WhitelistMatcher.new(from) unless from.is_a?(Matcher)
49
53
  to = WhitelistMatcher.new(to) unless to.is_a?(Matcher)
50
- {:from => from, :to => to}
54
+ {from: from, to: to}
51
55
  end
52
56
  end
53
-
57
+
54
58
  # Track known states. The order that requirements are iterated is based
55
59
  # on the priority in which tracked states should be added.
56
60
  @known_states = []
57
61
  @state_requirements.each do |state_requirement|
58
- [:from, :to].each {|option| @known_states |= state_requirement[option].values}
62
+ [:from, :to].each { |option| @known_states |= state_requirement[option].values }
59
63
  end
60
64
  end
61
-
65
+
62
66
  # Determines whether the given object / query matches the requirements
63
67
  # configured for this branch. In addition to matching the event, from state,
64
68
  # and to state, this will also check whether the configured :if/:unless
65
69
  # conditions pass on the given object.
66
- #
70
+ #
67
71
  # == Examples
68
- #
72
+ #
69
73
  # branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
70
- #
74
+ #
71
75
  # # Successful
72
76
  # branch.matches?(object, :on => :ignite) # => true
73
77
  # branch.matches?(object, :from => nil) # => true
@@ -75,7 +79,7 @@ module StateMachines
75
79
  # branch.matches?(object, :to => :idling) # => true
76
80
  # branch.matches?(object, :from => :parked, :to => :idling) # => true
77
81
  # branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
78
- #
82
+ #
79
83
  # # Unsuccessful
80
84
  # branch.matches?(object, :on => :park) # => false
81
85
  # branch.matches?(object, :from => :idling) # => false
@@ -85,16 +89,16 @@ module StateMachines
85
89
  def matches?(object, query = {})
86
90
  !match(object, query).nil?
87
91
  end
88
-
92
+
89
93
  # Attempts to match the given object / query against the set of requirements
90
94
  # configured for this branch. In addition to matching the event, from state,
91
95
  # and to state, this will also check whether the configured :if/:unless
92
96
  # conditions pass on the given object.
93
- #
97
+ #
94
98
  # If a match is found, then the event/state requirements that the query
95
99
  # passed successfully will be returned. Otherwise, nil is returned if there
96
100
  # was no match.
97
- #
101
+ #
98
102
  # Query options:
99
103
  # * <tt>:from</tt> - One or more states being transitioned from. If none
100
104
  # are specified, then this will always match.
@@ -104,80 +108,82 @@ module StateMachines
104
108
  # are specified, then this will always match.
105
109
  # * <tt>:guard</tt> - Whether to guard matches with the if/unless
106
110
  # conditionals defined for this branch. Default is true.
107
- #
111
+ #
108
112
  # == Examples
109
- #
113
+ #
110
114
  # branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
111
- #
115
+ #
112
116
  # branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
113
117
  # branch.match(object, :on => :park) # => nil
114
118
  def match(object, query = {})
115
- query.assert_valid_keys(:from, :to, :on, :guard)
116
-
119
+ StateMachines::OptionsValidator.assert_valid_keys!(query, :from, :to, :on, :guard)
120
+
117
121
  if (match = match_query(query)) && matches_conditions?(object, query)
118
122
  match
119
123
  end
120
124
  end
121
125
 
122
- def draw(graph, event, valid_states)
123
- fail NotImplementedError
126
+ def draw(graph, event, valid_states, io = $stdout)
127
+ machine.renderer.draw_branch(self, graph, event, valid_states, io)
124
128
  end
125
-
126
- 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
143
- 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
154
- end
155
-
156
- # Verifies that the event requirement matches the given query
157
- def match_event(query)
158
- matches_requirement?(query, :on, event_requirement)
159
- 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])}
166
- end
129
+
130
+ protected
131
+
132
+ # Builds a matcher strategy to use for the given options. If neither a
133
+ # whitelist nor a blacklist option is specified, then an AllMatcher is
134
+ # built.
135
+ def build_matcher(options, whitelist_option, blacklist_option)
136
+ StateMachines::OptionsValidator.assert_exclusive_keys!(options, whitelist_option, blacklist_option)
137
+
138
+ if options.include?(whitelist_option)
139
+ value = options[whitelist_option]
140
+ value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
141
+ elsif options.include?(blacklist_option)
142
+ value = options[blacklist_option]
143
+ raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
144
+
145
+ BlacklistMatcher.new(value)
146
+ else
147
+ AllMatcher.instance
167
148
  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)
149
+ end
150
+
151
+ # Verifies that all configured requirements (event and state) match the
152
+ # given query. If a match is found, then a hash containing the
153
+ # event/state requirements that passed will be returned; otherwise, nil.
154
+ def match_query(query)
155
+ query ||= {}
156
+
157
+ if match_event(query) && (state_requirement = match_states(query))
158
+ state_requirement.merge(on: event_requirement)
173
159
  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)}
160
+ end
161
+
162
+ # Verifies that the event requirement matches the given query
163
+ def match_event(query)
164
+ matches_requirement?(query, :on, event_requirement)
165
+ end
166
+
167
+ # Verifies that the state requirements match the given query. If a
168
+ # matching requirement is found, then it is returned.
169
+ def match_states(query)
170
+ state_requirements.detect do |state_requirement|
171
+ [:from, :to].all? { |option| matches_requirement?(query, option, state_requirement[option]) }
181
172
  end
173
+ end
174
+
175
+ # Verifies that an option in the given query matches the values required
176
+ # for that option
177
+ def matches_requirement?(query, option, requirement)
178
+ !query.include?(option) || requirement.matches?(query[option], query)
179
+ end
180
+
181
+ # Verifies that the conditionals for this branch evaluate to true for the
182
+ # given object
183
+ def matches_conditions?(object, query)
184
+ query[:guard] == false ||
185
+ Array(if_condition).all? { |condition| evaluate_method(object, condition) } &&
186
+ !Array(unless_condition).any? { |condition| evaluate_method(object, condition) }
187
+ end
182
188
  end
183
189
  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,7 +119,7 @@ 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)
@@ -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,7 +153,7 @@ 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
159
  def call(object, context = {}, *args, &block)
@@ -163,7 +165,8 @@ module StateMachines
163
165
  end
164
166
  end
165
167
 
166
- private
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
@@ -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'
@@ -40,4 +41,4 @@ require 'state_machines/path_collection'
40
41
  require 'state_machines/machine'
41
42
  require 'state_machines/machine_collection'
42
43
 
43
- require 'state_machines/macro_methods'
44
+ 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,3 +1,5 @@
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