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.
- checksums.yaml +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +443 -22
- data/lib/state_machines/async_mode/async_event_extensions.rb +49 -0
- data/lib/state_machines/async_mode/async_events.rb +282 -0
- data/lib/state_machines/async_mode/async_machine.rb +60 -0
- data/lib/state_machines/async_mode/async_transition_collection.rb +141 -0
- data/lib/state_machines/async_mode/thread_safe_state.rb +47 -0
- data/lib/state_machines/async_mode.rb +64 -0
- data/lib/state_machines/branch.rb +146 -86
- data/lib/state_machines/callback.rb +35 -32
- data/lib/state_machines/core.rb +3 -3
- data/lib/state_machines/core_ext/class/state_machine.rb +2 -0
- data/lib/state_machines/core_ext.rb +2 -0
- data/lib/state_machines/error.rb +7 -4
- data/lib/state_machines/eval_helpers.rb +197 -39
- data/lib/state_machines/event.rb +77 -58
- data/lib/state_machines/event_collection.rb +49 -39
- data/lib/state_machines/extensions.rb +6 -4
- data/lib/state_machines/helper_module.rb +4 -2
- data/lib/state_machines/integrations/base.rb +3 -1
- data/lib/state_machines/integrations.rb +19 -20
- data/lib/state_machines/machine/action_hooks.rb +53 -0
- data/lib/state_machines/machine/async_extensions.rb +88 -0
- data/lib/state_machines/machine/callbacks.rb +59 -0
- data/lib/state_machines/machine/class_methods.rb +97 -0
- data/lib/state_machines/machine/configuration.rb +134 -0
- data/lib/state_machines/machine/event_methods.rb +59 -0
- data/lib/state_machines/machine/helper_generators.rb +125 -0
- data/lib/state_machines/machine/integration.rb +70 -0
- data/lib/state_machines/machine/parsing.rb +77 -0
- data/lib/state_machines/machine/rendering.rb +17 -0
- data/lib/state_machines/machine/scoping.rb +44 -0
- data/lib/state_machines/machine/state_methods.rb +101 -0
- data/lib/state_machines/machine/utilities.rb +85 -0
- data/lib/state_machines/machine/validation.rb +39 -0
- data/lib/state_machines/machine.rb +425 -1011
- data/lib/state_machines/machine_collection.rb +28 -19
- data/lib/state_machines/macro_methods.rb +104 -102
- data/lib/state_machines/matcher.rb +31 -28
- data/lib/state_machines/matcher_helpers.rb +14 -12
- data/lib/state_machines/node_collection.rb +36 -29
- data/lib/state_machines/options_validator.rb +72 -0
- data/lib/state_machines/path.rb +60 -57
- data/lib/state_machines/path_collection.rb +39 -36
- data/lib/state_machines/state.rb +84 -47
- data/lib/state_machines/state_collection.rb +22 -19
- data/lib/state_machines/state_context.rb +40 -39
- data/lib/state_machines/stdio_renderer.rb +74 -0
- data/lib/state_machines/syntax_validator.rb +57 -0
- data/lib/state_machines/test_helper.rb +896 -0
- data/lib/state_machines/transition.rb +215 -199
- data/lib/state_machines/transition_collection.rb +187 -170
- data/lib/state_machines/version.rb +3 -1
- data/lib/state_machines.rb +4 -1
- metadata +39 -446
- data/.gitignore +0 -21
- data/.rspec +0 -3
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -16
- data/Changelog.md +0 -22
- data/Contributors.md +0 -39
- data/Gemfile +0 -8
- data/Rakefile +0 -12
- data/Testing.md +0 -0
- data/lib/state_machines/assertions.rb +0 -40
- data/state_machines.gemspec +0 -22
- data/test/files/integrations/event_on_failure_integration.rb +0 -10
- data/test/files/integrations/vehicle.rb +0 -7
- data/test/files/models/auto_shop.rb +0 -31
- data/test/files/models/car.rb +0 -21
- data/test/files/models/driver.rb +0 -13
- data/test/files/models/model_base.rb +0 -6
- data/test/files/models/motorcycle.rb +0 -16
- data/test/files/models/traffic_light.rb +0 -47
- data/test/files/models/vehicle.rb +0 -127
- data/test/files/node.rb +0 -5
- data/test/files/switch.rb +0 -15
- data/test/functional/auto_shop_available_test.rb +0 -20
- data/test/functional/auto_shop_busy_test.rb +0 -25
- data/test/functional/car_backing_up_test.rb +0 -45
- data/test/functional/car_test.rb +0 -49
- data/test/functional/driver_default_nonstandard_test.rb +0 -13
- data/test/functional/motorcycle_test.rb +0 -52
- data/test/functional/traffic_light_caution_test.rb +0 -17
- data/test/functional/traffic_light_proceed_test.rb +0 -17
- data/test/functional/traffic_light_stop_test.rb +0 -26
- data/test/functional/vehicle_first_gear_test.rb +0 -42
- data/test/functional/vehicle_idling_test.rb +0 -59
- data/test/functional/vehicle_locked_test.rb +0 -29
- data/test/functional/vehicle_parked_test.rb +0 -53
- data/test/functional/vehicle_repaired_test.rb +0 -20
- data/test/functional/vehicle_second_gear_test.rb +0 -42
- data/test/functional/vehicle_stalled_test.rb +0 -65
- data/test/functional/vehicle_test.rb +0 -20
- data/test/functional/vehicle_third_gear_test.rb +0 -42
- data/test/functional/vehicle_unsaved_test.rb +0 -181
- data/test/functional/vehicle_with_event_attributes_test.rb +0 -30
- data/test/functional/vehicle_with_parallel_events_test.rb +0 -36
- data/test/test_helper.rb +0 -15
- data/test/unit/assertions/assert_exclusive_keys_test.rb +0 -22
- data/test/unit/assertions/assert_valid_key_test.rb +0 -12
- data/test/unit/branch/branch_test.rb +0 -28
- data/test/unit/branch/branch_with_conflicting_conditionals_test.rb +0 -27
- data/test/unit/branch/branch_with_conflicting_from_requirements_test.rb +0 -8
- data/test/unit/branch/branch_with_conflicting_on_requirements_test.rb +0 -8
- data/test/unit/branch/branch_with_conflicting_to_requirements_test.rb +0 -8
- data/test/unit/branch/branch_with_different_requirements_test.rb +0 -41
- data/test/unit/branch/branch_with_except_from_matcher_requirement_test.rb +0 -8
- data/test/unit/branch/branch_with_except_from_requirement_test.rb +0 -36
- data/test/unit/branch/branch_with_except_on_matcher_requirement_test.rb +0 -8
- data/test/unit/branch/branch_with_except_on_requirement_test.rb +0 -36
- data/test/unit/branch/branch_with_except_to_matcher_requirement_test.rb +0 -8
- data/test/unit/branch/branch_with_except_to_requirement_test.rb +0 -36
- data/test/unit/branch/branch_with_from_matcher_requirement_test.rb +0 -20
- data/test/unit/branch/branch_with_from_requirement_test.rb +0 -45
- data/test/unit/branch/branch_with_if_conditional_test.rb +0 -27
- data/test/unit/branch/branch_with_implicit_and_explicit_requirements_test.rb +0 -23
- data/test/unit/branch/branch_with_implicit_from_requirement_matcher_test.rb +0 -20
- data/test/unit/branch/branch_with_implicit_requirement_test.rb +0 -20
- data/test/unit/branch/branch_with_implicit_to_requirement_matcher_test.rb +0 -16
- data/test/unit/branch/branch_with_multiple_except_from_requirements_test.rb +0 -20
- data/test/unit/branch/branch_with_multiple_except_on_requirements_test.rb +0 -16
- data/test/unit/branch/branch_with_multiple_except_to_requirements_test.rb +0 -20
- data/test/unit/branch/branch_with_multiple_from_requirements_test.rb +0 -16
- data/test/unit/branch/branch_with_multiple_if_conditionals_test.rb +0 -20
- data/test/unit/branch/branch_with_multiple_implicit_requirements_test.rb +0 -53
- data/test/unit/branch/branch_with_multiple_to_requirements_test.rb +0 -20
- data/test/unit/branch/branch_with_multiple_unless_conditionals_test.rb +0 -20
- data/test/unit/branch/branch_with_nil_requirements_test.rb +0 -28
- data/test/unit/branch/branch_with_no_requirements_test.rb +0 -36
- data/test/unit/branch/branch_with_on_matcher_requirement_test.rb +0 -16
- data/test/unit/branch/branch_with_on_requirement_test.rb +0 -45
- data/test/unit/branch/branch_with_to_matcher_requirement_test.rb +0 -20
- data/test/unit/branch/branch_with_to_requirement_test.rb +0 -45
- data/test/unit/branch/branch_with_unless_conditional_test.rb +0 -27
- data/test/unit/branch/branch_without_guards_test.rb +0 -27
- data/test/unit/callback/callback_by_default_test.rb +0 -25
- data/test/unit/callback/callback_test.rb +0 -53
- data/test/unit/callback/callback_with_application_bound_object_test.rb +0 -23
- data/test/unit/callback/callback_with_application_terminator_test.rb +0 -24
- data/test/unit/callback/callback_with_arguments_test.rb +0 -14
- data/test/unit/callback/callback_with_around_type_and_arguments_test.rb +0 -25
- data/test/unit/callback/callback_with_around_type_and_block_test.rb +0 -44
- data/test/unit/callback/callback_with_around_type_and_bound_method_test.rb +0 -23
- data/test/unit/callback/callback_with_around_type_and_multiple_methods_test.rb +0 -93
- data/test/unit/callback/callback_with_around_type_and_terminator_test.rb +0 -17
- data/test/unit/callback/callback_with_block_test.rb +0 -20
- data/test/unit/callback/callback_with_bound_method_and_arguments_test.rb +0 -28
- data/test/unit/callback/callback_with_bound_method_test.rb +0 -35
- data/test/unit/callback/callback_with_do_method_test.rb +0 -18
- data/test/unit/callback/callback_with_explicit_requirements_test.rb +0 -32
- data/test/unit/callback/callback_with_if_condition_test.rb +0 -17
- data/test/unit/callback/callback_with_implicit_requirements_test.rb +0 -32
- data/test/unit/callback/callback_with_method_argument_test.rb +0 -18
- data/test/unit/callback/callback_with_mixed_methods_test.rb +0 -31
- data/test/unit/callback/callback_with_multiple_bound_methods_test.rb +0 -21
- data/test/unit/callback/callback_with_multiple_do_methods_test.rb +0 -29
- data/test/unit/callback/callback_with_multiple_method_arguments_test.rb +0 -29
- data/test/unit/callback/callback_with_terminator_test.rb +0 -22
- data/test/unit/callback/callback_with_unbound_method_test.rb +0 -14
- data/test/unit/callback/callback_with_unless_condition_test.rb +0 -17
- data/test/unit/callback/callback_without_arguments_test.rb +0 -14
- data/test/unit/callback/callback_without_terminator_test.rb +0 -12
- data/test/unit/error/error_by_default_test.rb +0 -21
- data/test/unit/error/error_with_message_test.rb +0 -23
- data/test/unit/eval_helper/eval_helpers_base_test.rb +0 -8
- data/test/unit/eval_helper/eval_helpers_proc_block_and_explicit_arguments_test.rb +0 -14
- data/test/unit/eval_helper/eval_helpers_proc_block_and_implicit_arguments_test.rb +0 -14
- data/test/unit/eval_helper/eval_helpers_proc_test.rb +0 -13
- data/test/unit/eval_helper/eval_helpers_proc_with_arguments_test.rb +0 -13
- data/test/unit/eval_helper/eval_helpers_proc_with_block_test.rb +0 -13
- data/test/unit/eval_helper/eval_helpers_proc_with_block_without_arguments_test.rb +0 -18
- data/test/unit/eval_helper/eval_helpers_proc_with_block_without_object_test.rb +0 -14
- data/test/unit/eval_helper/eval_helpers_proc_without_arguments_test.rb +0 -19
- data/test/unit/eval_helper/eval_helpers_string_test.rb +0 -25
- data/test/unit/eval_helper/eval_helpers_string_with_block_test.rb +0 -12
- data/test/unit/eval_helper/eval_helpers_symbol_method_missing_test.rb +0 -20
- data/test/unit/eval_helper/eval_helpers_symbol_private_test.rb +0 -17
- data/test/unit/eval_helper/eval_helpers_symbol_protected_test.rb +0 -17
- data/test/unit/eval_helper/eval_helpers_symbol_tainted_method_test.rb +0 -18
- data/test/unit/eval_helper/eval_helpers_symbol_test.rb +0 -16
- data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_and_block_test.rb +0 -16
- data/test/unit/eval_helper/eval_helpers_symbol_with_arguments_test.rb +0 -16
- data/test/unit/eval_helper/eval_helpers_symbol_with_block_test.rb +0 -16
- data/test/unit/eval_helper/eval_helpers_test.rb +0 -13
- data/test/unit/event/event_after_being_copied_test.rb +0 -17
- data/test/unit/event/event_by_default_test.rb +0 -60
- data/test/unit/event/event_context_test.rb +0 -16
- data/test/unit/event/event_on_failure_test.rb +0 -44
- data/test/unit/event/event_test.rb +0 -34
- data/test/unit/event/event_transitions_test.rb +0 -62
- data/test/unit/event/event_with_conflicting_helpers_after_definition_test.rb +0 -79
- data/test/unit/event/event_with_conflicting_helpers_before_definition_test.rb +0 -58
- data/test/unit/event/event_with_conflicting_machine_test.rb +0 -48
- data/test/unit/event/event_with_dynamic_human_name_test.rb +0 -26
- data/test/unit/event/event_with_human_name_test.rb +0 -13
- data/test/unit/event/event_with_invalid_current_state_test.rb +0 -30
- data/test/unit/event/event_with_machine_action_test.rb +0 -33
- data/test/unit/event/event_with_marshalling_test.rb +0 -47
- data/test/unit/event/event_with_matching_disabled_transitions_test.rb +0 -115
- data/test/unit/event/event_with_matching_enabled_transitions_test.rb +0 -75
- data/test/unit/event/event_with_multiple_transitions_test.rb +0 -61
- data/test/unit/event/event_with_namespace_test.rb +0 -34
- data/test/unit/event/event_with_transition_with_blacklisted_to_state_test.rb +0 -60
- data/test/unit/event/event_with_transition_with_loopback_state_test.rb +0 -36
- data/test/unit/event/event_with_transition_with_nil_to_state_test.rb +0 -36
- data/test/unit/event/event_with_transition_with_whitelisted_to_state_test.rb +0 -51
- data/test/unit/event/event_with_transition_without_to_state_test.rb +0 -36
- data/test/unit/event/event_with_transitions_test.rb +0 -32
- data/test/unit/event/event_without_matching_transitions_test.rb +0 -41
- data/test/unit/event/event_without_transitions_test.rb +0 -28
- data/test/unit/event/invalid_event_test.rb +0 -20
- data/test/unit/event_collection/event_collection_attribute_with_machine_action_test.rb +0 -62
- data/test/unit/event_collection/event_collection_attribute_with_namespaced_machine_test.rb +0 -36
- data/test/unit/event_collection/event_collection_by_default_test.rb +0 -26
- data/test/unit/event_collection/event_collection_test.rb +0 -39
- data/test/unit/event_collection/event_collection_with_custom_machine_attribute_test.rb +0 -31
- data/test/unit/event_collection/event_collection_with_events_with_transitions_test.rb +0 -76
- data/test/unit/event_collection/event_collection_with_multiple_events_test.rb +0 -27
- data/test/unit/event_collection/event_collection_with_validations_test.rb +0 -74
- data/test/unit/event_collection/event_collection_without_machine_action_test.rb +0 -18
- data/test/unit/event_collection/event_string_collection_test.rb +0 -31
- data/test/unit/helper_module_test.rb +0 -17
- data/test/unit/integrations/integration_finder_test.rb +0 -16
- data/test/unit/integrations/integration_matcher_test.rb +0 -29
- data/test/unit/invalid_transition/invalid_parallel_transition_test.rb +0 -18
- data/test/unit/invalid_transition/invalid_transition_test.rb +0 -47
- data/test/unit/invalid_transition/invalid_transition_with_integration_test.rb +0 -45
- data/test/unit/invalid_transition/invalid_transition_with_namespace_test.rb +0 -32
- data/test/unit/machine/machine_after_being_copied_test.rb +0 -62
- data/test/unit/machine/machine_after_changing_initial_state.rb +0 -28
- data/test/unit/machine/machine_after_changing_owner_class_test.rb +0 -31
- data/test/unit/machine/machine_by_default_test.rb +0 -160
- data/test/unit/machine/machine_finder_custom_options_test.rb +0 -17
- data/test/unit/machine/machine_finder_with_existing_machine_on_superclass_test.rb +0 -85
- data/test/unit/machine/machine_finder_with_existing_on_same_class_test.rb +0 -23
- data/test/unit/machine/machine_finder_without_existing_machine_test.rb +0 -25
- data/test/unit/machine/machine_persistence_test.rb +0 -52
- data/test/unit/machine/machine_state_initialization_test.rb +0 -56
- data/test/unit/machine/machine_test.rb +0 -30
- data/test/unit/machine/machine_with_action_already_overridden_test.rb +0 -23
- data/test/unit/machine/machine_with_action_defined_in_class_test.rb +0 -37
- data/test/unit/machine/machine_with_action_defined_in_included_module_test.rb +0 -46
- data/test/unit/machine/machine_with_action_defined_in_superclass_test.rb +0 -43
- data/test/unit/machine/machine_with_action_undefined_test.rb +0 -33
- data/test/unit/machine/machine_with_cached_state_test.rb +0 -20
- data/test/unit/machine/machine_with_class_helpers_test.rb +0 -179
- data/test/unit/machine/machine_with_conflicting_helpers_after_definition_test.rb +0 -244
- data/test/unit/machine/machine_with_conflicting_helpers_before_definition_test.rb +0 -175
- data/test/unit/machine/machine_with_custom_action_test.rb +0 -11
- data/test/unit/machine/machine_with_custom_attribute_test.rb +0 -103
- data/test/unit/machine/machine_with_custom_initialize_test.rb +0 -24
- data/test/unit/machine/machine_with_custom_integration_test.rb +0 -72
- data/test/unit/machine/machine_with_custom_invalidation_test.rb +0 -39
- data/test/unit/machine/machine_with_custom_name_test.rb +0 -57
- data/test/unit/machine/machine_with_custom_plural_test.rb +0 -52
- data/test/unit/machine/machine_with_dynamic_initial_state_test.rb +0 -65
- data/test/unit/machine/machine_with_event_matchers_test.rb +0 -41
- data/test/unit/machine/machine_with_events_test.rb +0 -52
- data/test/unit/machine/machine_with_events_with_custom_human_names_test.rb +0 -18
- data/test/unit/machine/machine_with_events_with_transitions_test.rb +0 -37
- data/test/unit/machine/machine_with_existing_event_test.rb +0 -17
- data/test/unit/machine/machine_with_existing_machines_on_owner_class_test.rb +0 -20
- data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_class_test.rb +0 -71
- data/test/unit/machine/machine_with_existing_machines_with_same_attributes_on_owner_subclass_test.rb +0 -31
- data/test/unit/machine/machine_with_existing_state_test.rb +0 -27
- data/test/unit/machine/machine_with_failure_callbacks_test.rb +0 -48
- data/test/unit/machine/machine_with_helpers_test.rb +0 -14
- data/test/unit/machine/machine_with_initial_state_with_value_and_owner_default.rb +0 -25
- data/test/unit/machine/machine_with_initialize_and_super_test.rb +0 -17
- data/test/unit/machine/machine_with_initialize_arguments_and_block_test.rb +0 -31
- data/test/unit/machine/machine_with_initialize_without_super_test.rb +0 -17
- data/test/unit/machine/machine_with_instance_helpers_test.rb +0 -179
- data/test/unit/machine/machine_with_integration_test.rb +0 -72
- data/test/unit/machine/machine_with_multiple_events_test.rb +0 -32
- data/test/unit/machine/machine_with_namespace_test.rb +0 -48
- data/test/unit/machine/machine_with_nil_action_test.rb +0 -27
- data/test/unit/machine/machine_with_other_states.rb +0 -22
- data/test/unit/machine/machine_with_owner_subclass_test.rb +0 -18
- data/test/unit/machine/machine_with_paths_test.rb +0 -25
- data/test/unit/machine/machine_with_private_action_test.rb +0 -43
- data/test/unit/machine/machine_with_state_matchers_test.rb +0 -41
- data/test/unit/machine/machine_with_state_with_matchers_test.rb +0 -19
- data/test/unit/machine/machine_with_states_test.rb +0 -55
- data/test/unit/machine/machine_with_states_with_behaviors_test.rb +0 -23
- data/test/unit/machine/machine_with_states_with_custom_human_names_test.rb +0 -18
- data/test/unit/machine/machine_with_states_with_custom_values_test.rb +0 -21
- data/test/unit/machine/machine_with_states_with_runtime_dependencies_test.rb +0 -19
- data/test/unit/machine/machine_with_static_initial_state_test.rb +0 -49
- data/test/unit/machine/machine_with_superclass_conflicting_helpers_after_definition_test.rb +0 -36
- data/test/unit/machine/machine_with_transition_callbacks_test.rb +0 -144
- data/test/unit/machine/machine_with_transitions_test.rb +0 -87
- data/test/unit/machine/machine_without_initialization_test.rb +0 -31
- data/test/unit/machine/machine_without_initialize_test.rb +0 -14
- data/test/unit/machine/machine_without_integration_test.rb +0 -31
- data/test/unit/machine_collection/machine_collection_by_default_test.rb +0 -11
- data/test/unit/machine_collection/machine_collection_fire_test.rb +0 -80
- data/test/unit/machine_collection/machine_collection_fire_with_transactions_test.rb +0 -54
- data/test/unit/machine_collection/machine_collection_fire_with_validations_test.rb +0 -76
- data/test/unit/machine_collection/machine_collection_state_initialization_test.rb +0 -111
- data/test/unit/machine_collection/machine_collection_transitions_with_blank_events_test.rb +0 -25
- data/test/unit/machine_collection/machine_collection_transitions_with_custom_options_test.rb +0 -20
- data/test/unit/machine_collection/machine_collection_transitions_with_different_actions_test.rb +0 -26
- data/test/unit/machine_collection/machine_collection_transitions_with_exisiting_transitions_test.rb +0 -25
- data/test/unit/machine_collection/machine_collection_transitions_with_invalid_events_test.rb +0 -25
- data/test/unit/machine_collection/machine_collection_transitions_with_same_actions_test.rb +0 -31
- data/test/unit/machine_collection/machine_collection_transitions_with_transition_test.rb +0 -26
- data/test/unit/machine_collection/machine_collection_transitions_without_events_test.rb +0 -25
- data/test/unit/machine_collection/machine_collection_transitions_without_transition_test.rb +0 -27
- data/test/unit/matcher/all_matcher_test.rb +0 -29
- data/test/unit/matcher/blacklist_matcher_test.rb +0 -30
- data/test/unit/matcher/loopback_matcher_test.rb +0 -27
- data/test/unit/matcher/matcher_by_default_test.rb +0 -15
- data/test/unit/matcher/matcher_with_multiple_values_test.rb +0 -15
- data/test/unit/matcher/matcher_with_value_test.rb +0 -15
- data/test/unit/matcher/whitelist_matcher_test.rb +0 -30
- data/test/unit/matcher_helpers/matcher_helpers_all_test.rb +0 -14
- data/test/unit/matcher_helpers/matcher_helpers_any_test.rb +0 -14
- data/test/unit/matcher_helpers/matcher_helpers_same_test.rb +0 -13
- data/test/unit/node_collection/node_collection_after_being_copied_test.rb +0 -46
- data/test/unit/node_collection/node_collection_after_update_test.rb +0 -36
- data/test/unit/node_collection/node_collection_by_default_test.rb +0 -22
- data/test/unit/node_collection/node_collection_test.rb +0 -23
- data/test/unit/node_collection/node_collection_with_indices_test.rb +0 -42
- data/test/unit/node_collection/node_collection_with_matcher_contexts_test.rb +0 -25
- data/test/unit/node_collection/node_collection_with_nodes_test.rb +0 -46
- data/test/unit/node_collection/node_collection_with_numeric_index_test.rb +0 -24
- data/test/unit/node_collection/node_collection_with_postdefined_contexts_test.rb +0 -22
- data/test/unit/node_collection/node_collection_with_predefined_contexts_test.rb +0 -23
- data/test/unit/node_collection/node_collection_with_string_index_test.rb +0 -20
- data/test/unit/node_collection/node_collection_with_symbol_index_test.rb +0 -20
- data/test/unit/node_collection/node_collection_without_indices_test.rb +0 -30
- data/test/unit/path/path_by_default_test.rb +0 -54
- data/test/unit/path/path_test.rb +0 -14
- data/test/unit/path/path_with_available_transitions_after_reaching_target_test.rb +0 -40
- data/test/unit/path/path_with_available_transitions_test.rb +0 -54
- data/test/unit/path/path_with_deep_target_reached_test.rb +0 -50
- data/test/unit/path/path_with_deep_target_test.rb +0 -40
- data/test/unit/path/path_with_duplicates_test.rb +0 -32
- data/test/unit/path/path_with_encountered_transitions_test.rb +0 -34
- data/test/unit/path/path_with_guarded_transitions_test.rb +0 -42
- data/test/unit/path/path_with_reached_target_test.rb +0 -35
- data/test/unit/path/path_with_transitions_test.rb +0 -54
- data/test/unit/path/path_with_unreached_target_test.rb +0 -31
- data/test/unit/path/path_without_transitions_test.rb +0 -24
- data/test/unit/path_collection/path_collection_by_default_test.rb +0 -46
- data/test/unit/path_collection/path_collection_test.rb +0 -24
- data/test/unit/path_collection/path_collection_with_deep_paths_test.rb +0 -43
- data/test/unit/path_collection/path_collection_with_duplicate_nodes_test.rb +0 -31
- data/test/unit/path_collection/path_collection_with_from_state_test.rb +0 -27
- data/test/unit/path_collection/path_collection_with_paths_test.rb +0 -47
- data/test/unit/path_collection/path_collection_with_to_state_test.rb +0 -29
- data/test/unit/path_collection/path_with_guarded_paths_test.rb +0 -25
- data/test/unit/state/state_after_being_copied_test.rb +0 -19
- data/test/unit/state/state_by_default_test.rb +0 -41
- data/test/unit/state/state_final_test.rb +0 -28
- data/test/unit/state/state_initial_test.rb +0 -13
- data/test/unit/state/state_not_final_test.rb +0 -32
- data/test/unit/state/state_not_initial_test.rb +0 -13
- data/test/unit/state/state_test.rb +0 -44
- data/test/unit/state/state_with_cached_lambda_value_test.rb +0 -29
- data/test/unit/state/state_with_conflicting_helpers_after_definition_test.rb +0 -38
- data/test/unit/state/state_with_conflicting_helpers_before_definition_test.rb +0 -29
- data/test/unit/state/state_with_conflicting_machine_name_test.rb +0 -20
- data/test/unit/state/state_with_conflicting_machine_test.rb +0 -37
- data/test/unit/state/state_with_context_test.rb +0 -60
- data/test/unit/state/state_with_dynamic_human_name_test.rb +0 -25
- data/test/unit/state/state_with_existing_context_method_test.rb +0 -24
- data/test/unit/state/state_with_human_name_test.rb +0 -13
- data/test/unit/state/state_with_integer_value_test.rb +0 -32
- data/test/unit/state/state_with_invalid_method_call_test.rb +0 -21
- data/test/unit/state/state_with_lambda_value_test.rb +0 -37
- data/test/unit/state/state_with_matcher_test.rb +0 -18
- data/test/unit/state/state_with_multiple_contexts_test.rb +0 -57
- data/test/unit/state/state_with_name_test.rb +0 -43
- data/test/unit/state/state_with_namespace_test.rb +0 -22
- data/test/unit/state/state_with_nil_value_test.rb +0 -35
- data/test/unit/state/state_with_redefined_context_method_test.rb +0 -45
- data/test/unit/state/state_with_symbolic_value_test.rb +0 -32
- data/test/unit/state/state_with_valid_inherited_method_call_for_current_state_test.rb +0 -40
- data/test/unit/state/state_with_valid_method_call_for_current_state_test.rb +0 -33
- data/test/unit/state/state_with_valid_method_call_for_different_state_test.rb +0 -41
- data/test/unit/state/state_without_cached_lambda_value_test.rb +0 -25
- data/test/unit/state/state_without_name_test.rb +0 -39
- data/test/unit/state_collection/state_collection_by_default_test.rb +0 -21
- data/test/unit/state_collection/state_collection_string_test.rb +0 -35
- data/test/unit/state_collection/state_collection_test.rb +0 -74
- data/test/unit/state_collection/state_collection_with_custom_state_values_test.rb +0 -29
- data/test/unit/state_collection/state_collection_with_event_transitions_test.rb +0 -39
- data/test/unit/state_collection/state_collection_with_initial_state_test.rb +0 -40
- data/test/unit/state_collection/state_collection_with_namespace_test.rb +0 -21
- data/test/unit/state_collection/state_collection_with_state_behaviors_test.rb +0 -40
- data/test/unit/state_collection/state_collection_with_state_matchers_test.rb +0 -29
- data/test/unit/state_collection/state_collection_with_transition_callbacks_test.rb +0 -40
- data/test/unit/state_context/state_context_proxy_test.rb +0 -26
- data/test/unit/state_context/state_context_proxy_with_if_and_unless_conditions_test.rb +0 -42
- data/test/unit/state_context/state_context_proxy_with_if_condition_test.rb +0 -64
- data/test/unit/state_context/state_context_proxy_with_multiple_if_conditions_test.rb +0 -32
- data/test/unit/state_context/state_context_proxy_with_multiple_unless_conditions_test.rb +0 -32
- data/test/unit/state_context/state_context_proxy_with_unless_condition_test.rb +0 -64
- data/test/unit/state_context/state_context_proxy_without_conditions_test.rb +0 -31
- data/test/unit/state_context/state_context_test.rb +0 -28
- data/test/unit/state_context/state_context_transition_test.rb +0 -104
- data/test/unit/state_context/state_context_with_matching_transition_test.rb +0 -27
- data/test/unit/state_machine/state_machine_by_default_test.rb +0 -12
- data/test/unit/state_machine/state_machine_test.rb +0 -20
- data/test/unit/transition/transition_after_being_performed_test.rb +0 -48
- data/test/unit/transition/transition_after_being_persisted_test.rb +0 -46
- data/test/unit/transition/transition_after_being_rolled_back_test.rb +0 -35
- data/test/unit/transition/transition_equality_test.rb +0 -52
- data/test/unit/transition/transition_loopback_test.rb +0 -18
- data/test/unit/transition/transition_test.rb +0 -96
- data/test/unit/transition/transition_transient_test.rb +0 -20
- data/test/unit/transition/transition_with_action_test.rb +0 -27
- data/test/unit/transition/transition_with_after_callbacks_skipped_test.rb +0 -127
- data/test/unit/transition/transition_with_after_callbacks_test.rb +0 -93
- data/test/unit/transition/transition_with_around_callbacks_test.rb +0 -141
- data/test/unit/transition/transition_with_before_callbacks_skipped_test.rb +0 -30
- data/test/unit/transition/transition_with_before_callbacks_test.rb +0 -104
- data/test/unit/transition/transition_with_custom_machine_attribute_test.rb +0 -28
- data/test/unit/transition/transition_with_different_states_test.rb +0 -18
- data/test/unit/transition/transition_with_dynamic_to_value_test.rb +0 -19
- data/test/unit/transition/transition_with_failure_callbacks_test.rb +0 -84
- data/test/unit/transition/transition_with_invalid_nodes_test.rb +0 -29
- data/test/unit/transition/transition_with_mixed_callbacks_test.rb +0 -105
- data/test/unit/transition/transition_with_multiple_after_callbacks_test.rb +0 -40
- data/test/unit/transition/transition_with_multiple_around_callbacks_test.rb +0 -114
- data/test/unit/transition/transition_with_multiple_before_callbacks_test.rb +0 -40
- data/test/unit/transition/transition_with_multiple_failure_callbacks_test.rb +0 -40
- data/test/unit/transition/transition_with_namespace_test.rb +0 -47
- data/test/unit/transition/transition_with_perform_arguments_test.rb +0 -35
- data/test/unit/transition/transition_with_transactions_test.rb +0 -42
- data/test/unit/transition/transition_without_callbacks_test.rb +0 -33
- data/test/unit/transition/transition_without_reading_state_test.rb +0 -22
- data/test/unit/transition/transition_without_running_action_test.rb +0 -47
- data/test/unit/transition_collection/attribute_transition_collection_by_default_test.rb +0 -23
- data/test/unit/transition_collection/attribute_transition_collection_marshalling_test.rb +0 -64
- data/test/unit/transition_collection/attribute_transition_collection_with_action_error_test.rb +0 -44
- data/test/unit/transition_collection/attribute_transition_collection_with_action_failed_test.rb +0 -44
- data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_error_test.rb +0 -32
- data/test/unit/transition_collection/attribute_transition_collection_with_after_callback_halt_test.rb +0 -33
- data/test/unit/transition_collection/attribute_transition_collection_with_around_after_yield_callback_error_test.rb +0 -32
- data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_error_test.rb +0 -32
- data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_after_yield_halt_test.rb +0 -33
- data/test/unit/transition_collection/attribute_transition_collection_with_around_callback_before_yield_halt_test.rb +0 -33
- data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_error_test.rb +0 -32
- data/test/unit/transition_collection/attribute_transition_collection_with_before_callback_halt_test.rb +0 -33
- data/test/unit/transition_collection/attribute_transition_collection_with_callbacks_test.rb +0 -68
- data/test/unit/transition_collection/attribute_transition_collection_with_event_transitions_test.rb +0 -41
- data/test/unit/transition_collection/attribute_transition_collection_with_events_test.rb +0 -44
- data/test/unit/transition_collection/attribute_transition_collection_with_skipped_after_callbacks_test.rb +0 -42
- data/test/unit/transition_collection/transition_collection_by_default_test.rb +0 -23
- data/test/unit/transition_collection/transition_collection_empty_with_block_test.rb +0 -23
- data/test/unit/transition_collection/transition_collection_empty_without_block_test.rb +0 -12
- data/test/unit/transition_collection/transition_collection_invalid_test.rb +0 -21
- data/test/unit/transition_collection/transition_collection_partial_invalid_test.rb +0 -69
- data/test/unit/transition_collection/transition_collection_test.rb +0 -26
- data/test/unit/transition_collection/transition_collection_valid_test.rb +0 -57
- data/test/unit/transition_collection/transition_collection_with_action_error_test.rb +0 -66
- data/test/unit/transition_collection/transition_collection_with_action_failed_test.rb +0 -60
- data/test/unit/transition_collection/transition_collection_with_action_hook_and_block_test.rb +0 -17
- data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_action_test.rb +0 -17
- data/test/unit/transition_collection/transition_collection_with_action_hook_and_skipped_after_callbacks_test.rb +0 -37
- data/test/unit/transition_collection/transition_collection_with_action_hook_base_test.rb +0 -34
- data/test/unit/transition_collection/transition_collection_with_action_hook_error_test.rb +0 -29
- data/test/unit/transition_collection/transition_collection_with_action_hook_invalid_test.rb +0 -17
- data/test/unit/transition_collection/transition_collection_with_action_hook_multiple_test.rb +0 -79
- data/test/unit/transition_collection/transition_collection_with_action_hook_test.rb +0 -45
- data/test/unit/transition_collection/transition_collection_with_action_hook_with_different_actions_test.rb +0 -48
- data/test/unit/transition_collection/transition_collection_with_action_hook_with_nil_action_test.rb +0 -42
- data/test/unit/transition_collection/transition_collection_with_after_callback_halt_test.rb +0 -47
- data/test/unit/transition_collection/transition_collection_with_before_callback_halt_test.rb +0 -51
- data/test/unit/transition_collection/transition_collection_with_block_test.rb +0 -46
- data/test/unit/transition_collection/transition_collection_with_callbacks_test.rb +0 -135
- data/test/unit/transition_collection/transition_collection_with_different_actions_test.rb +0 -189
- data/test/unit/transition_collection/transition_collection_with_duplicate_actions_test.rb +0 -48
- data/test/unit/transition_collection/transition_collection_with_empty_actions_test.rb +0 -41
- data/test/unit/transition_collection/transition_collection_with_mixed_actions_test.rb +0 -41
- data/test/unit/transition_collection/transition_collection_with_skipped_actions_and_block_test.rb +0 -34
- data/test/unit/transition_collection/transition_collection_with_skipped_actions_test.rb +0 -69
- data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_and_around_callbacks_test.rb +0 -53
- data/test/unit/transition_collection/transition_collection_with_skipped_after_callbacks_test.rb +0 -34
- data/test/unit/transition_collection/transition_collection_with_transactions_test.rb +0 -65
- data/test/unit/transition_collection/transition_collection_without_transactions_test.rb +0 -29
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# A transition represents a state change for a specific attribute.
|
3
|
-
#
|
5
|
+
#
|
4
6
|
# Transitions consist of:
|
5
7
|
# * An event
|
6
8
|
# * A starting state
|
@@ -8,201 +10,209 @@ module StateMachines
|
|
8
10
|
class Transition
|
9
11
|
# The object being transitioned
|
10
12
|
attr_reader :object
|
11
|
-
|
13
|
+
|
12
14
|
# The state machine for which this transition is defined
|
13
15
|
attr_reader :machine
|
14
|
-
|
16
|
+
|
15
17
|
# The original state value *before* the transition
|
16
18
|
attr_reader :from
|
17
|
-
|
19
|
+
|
18
20
|
# The new state value *after* the transition
|
19
21
|
attr_reader :to
|
20
|
-
|
22
|
+
|
21
23
|
# The arguments passed in to the event that triggered the transition
|
22
24
|
# (does not include the +run_action+ boolean argument if specified)
|
23
25
|
attr_accessor :args
|
24
|
-
|
26
|
+
|
25
27
|
# The result of invoking the action associated with the machine
|
26
28
|
attr_reader :result
|
27
|
-
|
29
|
+
|
28
30
|
# Whether the transition is only existing temporarily for the object
|
29
31
|
attr_writer :transient
|
30
|
-
|
32
|
+
|
31
33
|
# Determines whether the current ruby implementation supports pausing and
|
32
34
|
# resuming transitions
|
33
35
|
def self.pause_supported?
|
34
|
-
%w
|
36
|
+
%w[ruby maglev].include?(RUBY_ENGINE)
|
35
37
|
end
|
36
|
-
|
38
|
+
|
37
39
|
# Creates a new, specific transition
|
38
|
-
def initialize(object, machine, event, from_name, to_name, read_state = true)
|
40
|
+
def initialize(object, machine, event, from_name, to_name, read_state = true) # :nodoc:
|
39
41
|
@object = object
|
40
42
|
@machine = machine
|
41
43
|
@args = []
|
42
44
|
@transient = false
|
43
45
|
@resume_block = nil
|
44
|
-
|
46
|
+
|
45
47
|
@event = machine.events.fetch(event)
|
46
48
|
@from_state = machine.states.fetch(from_name)
|
47
49
|
@from = read_state ? machine.read(object, :state) : @from_state.value
|
48
50
|
@to_state = machine.states.fetch(to_name)
|
49
51
|
@to = @to_state.value
|
50
|
-
|
52
|
+
|
51
53
|
reset
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
# The attribute which this transition's machine is defined for
|
55
57
|
def attribute
|
56
58
|
machine.attribute
|
57
59
|
end
|
58
|
-
|
60
|
+
|
59
61
|
# The action that will be run when this transition is performed
|
60
62
|
def action
|
61
63
|
machine.action
|
62
64
|
end
|
63
|
-
|
65
|
+
|
64
66
|
# The event that triggered the transition
|
65
67
|
def event
|
66
68
|
@event.name
|
67
69
|
end
|
68
|
-
|
70
|
+
|
69
71
|
# The fully-qualified name of the event that triggered the transition
|
70
72
|
def qualified_event
|
71
73
|
@event.qualified_name
|
72
74
|
end
|
73
|
-
|
75
|
+
|
74
76
|
# The human-readable name of the event that triggered the transition
|
75
77
|
def human_event
|
76
78
|
@event.human_name(@object.class)
|
77
79
|
end
|
78
|
-
|
80
|
+
|
79
81
|
# The state name *before* the transition
|
80
82
|
def from_name
|
81
83
|
@from_state.name
|
82
84
|
end
|
83
|
-
|
85
|
+
|
84
86
|
# The fully-qualified state name *before* the transition
|
85
87
|
def qualified_from_name
|
86
88
|
@from_state.qualified_name
|
87
89
|
end
|
88
|
-
|
90
|
+
|
89
91
|
# The human-readable state name *before* the transition
|
90
92
|
def human_from_name
|
91
93
|
@from_state.human_name(@object.class)
|
92
94
|
end
|
93
|
-
|
95
|
+
|
94
96
|
# The new state name *after* the transition
|
95
97
|
def to_name
|
96
98
|
@to_state.name
|
97
99
|
end
|
98
|
-
|
100
|
+
|
99
101
|
# The new fully-qualified state name *after* the transition
|
100
102
|
def qualified_to_name
|
101
103
|
@to_state.qualified_name
|
102
104
|
end
|
103
|
-
|
105
|
+
|
104
106
|
# The new human-readable state name *after* the transition
|
105
107
|
def human_to_name
|
106
108
|
@to_state.human_name(@object.class)
|
107
109
|
end
|
108
|
-
|
110
|
+
|
109
111
|
# Does this transition represent a loopback (i.e. the from and to state
|
110
112
|
# are the same)
|
111
|
-
#
|
113
|
+
#
|
112
114
|
# == Example
|
113
|
-
#
|
115
|
+
#
|
114
116
|
# machine = StateMachine.new(Vehicle)
|
115
117
|
# StateMachines::Transition.new(Vehicle.new, machine, :park, :parked, :parked).loopback? # => true
|
116
118
|
# StateMachines::Transition.new(Vehicle.new, machine, :park, :idling, :parked).loopback? # => false
|
117
119
|
def loopback?
|
118
120
|
from_name == to_name
|
119
121
|
end
|
120
|
-
|
122
|
+
|
121
123
|
# Is this transition existing for a short period only? If this is set, it
|
122
124
|
# indicates that the transition (or the event backing it) should not be
|
123
125
|
# written to the object if it fails.
|
124
126
|
def transient?
|
125
127
|
@transient
|
126
128
|
end
|
127
|
-
|
129
|
+
|
128
130
|
# A hash of all the core attributes defined for this transition with their
|
129
131
|
# names as keys and values of the attributes as values.
|
130
|
-
#
|
132
|
+
#
|
131
133
|
# == Example
|
132
|
-
#
|
134
|
+
#
|
133
135
|
# machine = StateMachine.new(Vehicle)
|
134
136
|
# transition = StateMachines::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling)
|
135
137
|
# transition.attributes # => {:object => #<Vehicle:0xb7d60ea4>, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'}
|
136
138
|
def attributes
|
137
|
-
@attributes ||= {:
|
139
|
+
@attributes ||= { object: object, attribute: attribute, event: event, from: from, to: to }
|
138
140
|
end
|
139
|
-
|
141
|
+
|
140
142
|
# Runs the actual transition and any before/after callbacks associated
|
141
143
|
# with the transition. The action associated with the transition/machine
|
142
144
|
# can be skipped by passing in +false+.
|
143
|
-
#
|
145
|
+
#
|
144
146
|
# == Examples
|
145
|
-
#
|
147
|
+
#
|
146
148
|
# class Vehicle
|
147
149
|
# state_machine :action => :save do
|
148
150
|
# ...
|
149
151
|
# end
|
150
152
|
# end
|
151
|
-
#
|
153
|
+
#
|
152
154
|
# vehicle = Vehicle.new
|
153
155
|
# transition = StateMachines::Transition.new(vehicle, machine, :ignite, :parked, :idling)
|
154
|
-
# transition.perform
|
155
|
-
# transition.perform(false)
|
156
|
-
# transition.perform(
|
157
|
-
# transition.perform(Time.now
|
156
|
+
# transition.perform # => Runs the +save+ action after setting the state attribute
|
157
|
+
# transition.perform(false) # => Only sets the state attribute
|
158
|
+
# transition.perform(run_action: false) # => Only sets the state attribute
|
159
|
+
# transition.perform(Time.now) # => Passes in additional arguments and runs the +save+ action
|
160
|
+
# transition.perform(Time.now, false) # => Passes in additional arguments and only sets the state attribute
|
161
|
+
# transition.perform(Time.now, run_action: false) # => Passes in additional arguments and only sets the state attribute
|
158
162
|
def perform(*args)
|
159
|
-
run_action =
|
163
|
+
run_action = case args.last
|
164
|
+
in true | false
|
165
|
+
args.pop
|
166
|
+
in { run_action: }
|
167
|
+
args.last.delete(:run_action)
|
168
|
+
else
|
169
|
+
true
|
170
|
+
end
|
171
|
+
|
160
172
|
self.args = args
|
161
|
-
|
173
|
+
|
162
174
|
# Run the transition
|
163
|
-
!!TransitionCollection.new([self], {use_transactions: machine.use_transactions, actions: run_action}).perform
|
175
|
+
!!TransitionCollection.new([self], { use_transactions: machine.use_transactions, actions: run_action }).perform
|
164
176
|
end
|
165
|
-
|
177
|
+
|
166
178
|
# Runs a block within a transaction for the object being transitioned.
|
167
179
|
# By default, transactions are a no-op unless otherwise defined by the
|
168
180
|
# machine's integration.
|
169
|
-
def within_transaction
|
170
|
-
machine.within_transaction(object)
|
171
|
-
yield
|
172
|
-
end
|
181
|
+
def within_transaction(&)
|
182
|
+
machine.within_transaction(object, &)
|
173
183
|
end
|
174
|
-
|
184
|
+
|
175
185
|
# Runs the before / after callbacks for this transition. If a block is
|
176
186
|
# provided, then it will be executed between the before and after callbacks.
|
177
|
-
#
|
187
|
+
#
|
178
188
|
# Configuration options:
|
179
189
|
# * +before+ - Whether to run before callbacks.
|
180
190
|
# * +after+ - Whether to run after callbacks. If false, then any around
|
181
191
|
# callbacks will be paused until called again with +after+ enabled.
|
182
192
|
# Default is true.
|
183
|
-
#
|
193
|
+
#
|
184
194
|
# This will return true if all before callbacks gets executed. After
|
185
195
|
# callbacks will not have an effect on the result.
|
186
196
|
def run_callbacks(options = {}, &block)
|
187
|
-
options = {:
|
197
|
+
options = { before: true, after: true }.merge(options)
|
188
198
|
@success = false
|
189
|
-
|
199
|
+
|
190
200
|
halted = pausable { before(options[:after], &block) } if options[:before]
|
191
|
-
|
201
|
+
|
192
202
|
# After callbacks are only run if:
|
193
203
|
# * An around callback didn't halt after yielding
|
194
204
|
# * They're enabled or the run didn't succeed
|
195
205
|
after if !(@before_run && halted) && (options[:after] || !@success)
|
196
|
-
|
206
|
+
|
197
207
|
@before_run
|
198
208
|
end
|
199
|
-
|
209
|
+
|
200
210
|
# Transitions the current value of the state to that specified by the
|
201
211
|
# transition. Once the state is persisted, it cannot be persisted again
|
202
212
|
# until this transition is reset.
|
203
|
-
#
|
213
|
+
#
|
204
214
|
# == Example
|
205
|
-
#
|
215
|
+
#
|
206
216
|
# class Vehicle
|
207
217
|
# state_machine do
|
208
218
|
# event :ignite do
|
@@ -210,24 +220,24 @@ module StateMachines
|
|
210
220
|
# end
|
211
221
|
# end
|
212
222
|
# end
|
213
|
-
#
|
223
|
+
#
|
214
224
|
# vehicle = Vehicle.new
|
215
225
|
# transition = StateMachines::Transition.new(vehicle, Vehicle.state_machine, :ignite, :parked, :idling)
|
216
226
|
# transition.persist
|
217
|
-
#
|
227
|
+
#
|
218
228
|
# vehicle.state # => 'idling'
|
219
229
|
def persist
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
230
|
+
return if @persisted
|
231
|
+
|
232
|
+
machine.write(object, :state, to)
|
233
|
+
@persisted = true
|
224
234
|
end
|
225
|
-
|
235
|
+
|
226
236
|
# Rolls back changes made to the object's state via this transition. This
|
227
237
|
# will revert the state back to the +from+ value.
|
228
|
-
#
|
238
|
+
#
|
229
239
|
# == Example
|
230
|
-
#
|
240
|
+
#
|
231
241
|
# class Vehicle
|
232
242
|
# state_machine :initial => :parked do
|
233
243
|
# event :ignite do
|
@@ -235,15 +245,15 @@ module StateMachines
|
|
235
245
|
# end
|
236
246
|
# end
|
237
247
|
# end
|
238
|
-
#
|
248
|
+
#
|
239
249
|
# vehicle = Vehicle.new # => #<Vehicle:0xb7b7f568 @state="parked">
|
240
250
|
# transition = StateMachines::Transition.new(vehicle, Vehicle.state_machine, :ignite, :parked, :idling)
|
241
|
-
#
|
251
|
+
#
|
242
252
|
# # Persist the new state
|
243
253
|
# vehicle.state # => "parked"
|
244
254
|
# transition.persist
|
245
255
|
# vehicle.state # => "idling"
|
246
|
-
#
|
256
|
+
#
|
247
257
|
# # Roll back to the original state
|
248
258
|
# transition.rollback
|
249
259
|
# vehicle.state # => "parked"
|
@@ -251,164 +261,170 @@ module StateMachines
|
|
251
261
|
reset
|
252
262
|
machine.write(object, :state, from)
|
253
263
|
end
|
254
|
-
|
264
|
+
|
255
265
|
# Resets any tracking of which callbacks have already been run and whether
|
256
266
|
# the state has already been persisted
|
257
267
|
def reset
|
258
268
|
@before_run = @persisted = @after_run = false
|
259
269
|
@paused_block = nil
|
260
270
|
end
|
261
|
-
|
271
|
+
|
262
272
|
# Determines equality of transitions by testing whether the object, states,
|
263
273
|
# and event involved in the transition are equal
|
264
274
|
def ==(other)
|
265
275
|
other.instance_of?(self.class) &&
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
276
|
+
other.object == object &&
|
277
|
+
other.machine == machine &&
|
278
|
+
other.from_name == from_name &&
|
279
|
+
other.to_name == to_name &&
|
280
|
+
other.event == event
|
271
281
|
end
|
272
|
-
|
282
|
+
|
273
283
|
# Generates a nicely formatted description of this transitions's contents.
|
274
|
-
#
|
284
|
+
#
|
275
285
|
# For example,
|
276
|
-
#
|
286
|
+
#
|
277
287
|
# transition = StateMachines::Transition.new(object, machine, :ignite, :parked, :idling)
|
278
288
|
# transition # => #<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>
|
279
289
|
def inspect
|
280
|
-
"#<#{self.class} #{%w
|
290
|
+
"#<#{self.class} #{%w[attribute event from from_name to to_name].map { |attr| "#{attr}=#{send(attr).inspect}" } * ' '}>"
|
281
291
|
end
|
282
|
-
|
292
|
+
|
283
293
|
private
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
if @resume_block
|
298
|
-
@resume_block.call(halted, error)
|
299
|
-
else
|
300
|
-
halted
|
294
|
+
|
295
|
+
# Runs a block that may get paused. If the block doesn't pause, then
|
296
|
+
# execution will continue as normal. If the block gets paused, then it
|
297
|
+
# will take care of switching the execution context when it's resumed.
|
298
|
+
#
|
299
|
+
# This will return true if the given block halts for a reason other than
|
300
|
+
# getting paused.
|
301
|
+
def pausable
|
302
|
+
begin
|
303
|
+
halted = !catch(:halt) do
|
304
|
+
yield
|
305
|
+
true
|
301
306
|
end
|
307
|
+
rescue StandardError => e
|
308
|
+
raise unless @resume_block
|
302
309
|
end
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
raise ArgumentError, 'around_transition callbacks cannot be called in multiple execution contexts in java implementations of Ruby. Use before/after_transitions instead.' unless self.class.pause_supported?
|
309
|
-
|
310
|
-
unless @resume_block
|
311
|
-
require 'continuation' unless defined?(callcc)
|
312
|
-
callcc do |block|
|
313
|
-
@paused_block = block
|
314
|
-
throw :halt, true
|
315
|
-
end
|
316
|
-
end
|
310
|
+
|
311
|
+
if @resume_block
|
312
|
+
@resume_block.call(halted, e)
|
313
|
+
else
|
314
|
+
halted
|
317
315
|
end
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
316
|
+
end
|
317
|
+
|
318
|
+
# Pauses the current callback execution. This should only occur within
|
319
|
+
# around callbacks when the remainder of the callback will be executed at
|
320
|
+
# a later point in time.
|
321
|
+
def pause
|
322
|
+
raise ArgumentError, 'around_transition callbacks cannot be called in multiple execution contexts in java implementations of Ruby. Use before/after_transitions instead.' unless self.class.pause_supported?
|
323
|
+
|
324
|
+
return if @resume_block
|
325
|
+
|
326
|
+
require 'continuation' unless defined?(callcc)
|
327
|
+
callcc do |block|
|
328
|
+
@paused_block = block
|
329
|
+
throw :halt, true
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# Resumes the execution of a previously paused callback execution. Once
|
334
|
+
# the paused callbacks complete, the current execution will continue.
|
335
|
+
def resume
|
336
|
+
if @paused_block
|
337
|
+
halted, error = callcc do |block|
|
338
|
+
@resume_block = block
|
339
|
+
@paused_block.call
|
334
340
|
end
|
341
|
+
|
342
|
+
@resume_block = @paused_block = nil
|
343
|
+
|
344
|
+
raise error if error
|
345
|
+
|
346
|
+
!halted
|
347
|
+
else
|
348
|
+
true
|
335
349
|
end
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
350
|
+
end
|
351
|
+
|
352
|
+
# Runs the machine's +before+ callbacks for this transition. Only
|
353
|
+
# callbacks that are configured to match the event, from state, and to
|
354
|
+
# state will be invoked.
|
355
|
+
#
|
356
|
+
# Once the callbacks are run, they cannot be run again until this transition
|
357
|
+
# is reset.
|
358
|
+
def before(complete = true, index = 0, &block)
|
359
|
+
unless @before_run
|
360
|
+
while callback = machine.callbacks[:before][index]
|
361
|
+
index += 1
|
362
|
+
|
363
|
+
if callback.type == :around
|
364
|
+
# Around callback: need to handle recursively. Execution only gets
|
365
|
+
# paused if:
|
366
|
+
# * The block fails and the callback doesn't run on failures OR
|
367
|
+
# * The block succeeds, but after callbacks are disabled (in which
|
368
|
+
# case a continuation is stored for later execution)
|
369
|
+
return if catch(:cancel) do
|
370
|
+
callback.call(object, context, self) do
|
371
|
+
before(complete, index, &block)
|
372
|
+
|
373
|
+
pause if @success && !complete
|
374
|
+
throw :cancel, true unless @success
|
361
375
|
end
|
362
|
-
else
|
363
|
-
# Normal before callback
|
364
|
-
callback.call(object, context, self)
|
365
376
|
end
|
377
|
+
else
|
378
|
+
# Normal before callback
|
379
|
+
callback.call(object, context, self)
|
366
380
|
end
|
367
|
-
|
368
|
-
@before_run = true
|
369
381
|
end
|
370
|
-
|
371
|
-
|
372
|
-
@result, @success = action[:result], action[:success]
|
382
|
+
|
383
|
+
@before_run = true
|
373
384
|
end
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
385
|
+
|
386
|
+
action = { success: true }.merge(block_given? ? yield : {})
|
387
|
+
@result = action[:result]
|
388
|
+
@success = action[:success]
|
389
|
+
end
|
390
|
+
|
391
|
+
# Runs the machine's +after+ callbacks for this transition. Only
|
392
|
+
# callbacks that are configured to match the event, from state, and to
|
393
|
+
# state will be invoked.
|
394
|
+
#
|
395
|
+
# Once the callbacks are run, they cannot be run again until this transition
|
396
|
+
# is reset.
|
397
|
+
#
|
398
|
+
# == Halting
|
399
|
+
#
|
400
|
+
# If any callback throws a <tt>:halt</tt> exception, it will be caught
|
401
|
+
# and the callback chain will be automatically stopped. However, this
|
402
|
+
# exception will not bubble up to the caller since +after+ callbacks
|
403
|
+
# should never halt the execution of a +perform+.
|
404
|
+
def after
|
405
|
+
return if @after_run
|
406
|
+
|
407
|
+
# First resume previously paused callbacks
|
408
|
+
if resume
|
409
|
+
catch(:halt) do
|
410
|
+
type = @success ? :after : :failure
|
411
|
+
machine.callbacks[type].each { |callback| callback.call(object, context, self) }
|
399
412
|
end
|
400
413
|
end
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
414
|
+
|
415
|
+
@after_run = true
|
416
|
+
end
|
417
|
+
|
418
|
+
# Gets a hash of the context defining this unique transition (including
|
419
|
+
# event, from state, and to state).
|
420
|
+
#
|
421
|
+
# == Example
|
422
|
+
#
|
423
|
+
# machine = StateMachine.new(Vehicle)
|
424
|
+
# transition = StateMachines::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling)
|
425
|
+
# transition.context # => {:on => :ignite, :from => :parked, :to => :idling}
|
426
|
+
def context
|
427
|
+
@context ||= { on: event, from: from_name, to: to_name }
|
428
|
+
end
|
413
429
|
end
|
414
430
|
end
|