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,73 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'options_validator'
|
4
|
+
|
1
5
|
module StateMachines
|
2
6
|
# Represents a set of requirements that must be met in order for a transition
|
3
7
|
# or callback to occur. Branches verify that the event, from state, and to
|
4
8
|
# state of the transition match, in addition to if/unless conditionals for
|
5
9
|
# an object's state.
|
6
10
|
class Branch
|
7
|
-
|
8
11
|
include EvalHelpers
|
9
|
-
|
12
|
+
|
10
13
|
# The condition that must be met on an object
|
11
14
|
attr_reader :if_condition
|
12
|
-
|
15
|
+
|
13
16
|
# The condition that must *not* be met on an object
|
14
17
|
attr_reader :unless_condition
|
15
|
-
|
18
|
+
|
16
19
|
# The requirement for verifying the event being matched
|
17
20
|
attr_reader :event_requirement
|
18
|
-
|
21
|
+
|
19
22
|
# One or more requirements for verifying the states being matched. All
|
20
23
|
# requirements contain a mapping of {:from => matcher, :to => matcher}.
|
21
24
|
attr_reader :state_requirements
|
22
|
-
|
25
|
+
|
23
26
|
# A list of all of the states known to this branch. This will pull states
|
24
27
|
# from the following options (in the same order):
|
25
28
|
# * +from+ / +except_from+
|
26
29
|
# * +to+ / +except_to+
|
27
30
|
attr_reader :known_states
|
28
|
-
|
31
|
+
|
29
32
|
# Creates a new branch
|
30
|
-
def initialize(options = {})
|
33
|
+
def initialize(options = {}) # :nodoc:
|
31
34
|
# Build conditionals
|
32
35
|
@if_condition = options.delete(:if)
|
33
36
|
@unless_condition = options.delete(:unless)
|
34
|
-
|
37
|
+
@if_state_condition = options.delete(:if_state)
|
38
|
+
@unless_state_condition = options.delete(:unless_state)
|
39
|
+
@if_all_states_condition = options.delete(:if_all_states)
|
40
|
+
@unless_all_states_condition = options.delete(:unless_all_states)
|
41
|
+
@if_any_state_condition = options.delete(:if_any_state)
|
42
|
+
@unless_any_state_condition = options.delete(:unless_any_state)
|
43
|
+
|
35
44
|
# Build event requirement
|
36
45
|
@event_requirement = build_matcher(options, :on, :except_on)
|
37
|
-
|
38
|
-
if (options.keys - [
|
46
|
+
|
47
|
+
if (options.keys - %i[from to on except_from except_to except_on]).empty?
|
39
48
|
# Explicit from/to requirements specified
|
40
|
-
@state_requirements = [{:
|
49
|
+
@state_requirements = [{ from: build_matcher(options, :from, :except_from), to: build_matcher(options, :to, :except_to) }]
|
41
50
|
else
|
42
51
|
# Separate out the event requirement
|
43
52
|
options.delete(:on)
|
44
53
|
options.delete(:except_on)
|
45
|
-
|
54
|
+
|
46
55
|
# Implicit from/to requirements specified
|
47
56
|
@state_requirements = options.collect do |from, to|
|
48
57
|
from = WhitelistMatcher.new(from) unless from.is_a?(Matcher)
|
49
58
|
to = WhitelistMatcher.new(to) unless to.is_a?(Matcher)
|
50
|
-
{:
|
59
|
+
{ from: from, to: to }
|
51
60
|
end
|
52
61
|
end
|
53
|
-
|
62
|
+
|
54
63
|
# Track known states. The order that requirements are iterated is based
|
55
64
|
# on the priority in which tracked states should be added.
|
56
65
|
@known_states = []
|
57
66
|
@state_requirements.each do |state_requirement|
|
58
|
-
[
|
67
|
+
%i[from to].each { |option| @known_states |= state_requirement[option].values }
|
59
68
|
end
|
60
69
|
end
|
61
|
-
|
70
|
+
|
62
71
|
# Determines whether the given object / query matches the requirements
|
63
72
|
# configured for this branch. In addition to matching the event, from state,
|
64
73
|
# and to state, this will also check whether the configured :if/:unless
|
65
74
|
# conditions pass on the given object.
|
66
|
-
#
|
75
|
+
#
|
67
76
|
# == Examples
|
68
|
-
#
|
77
|
+
#
|
69
78
|
# branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
|
70
|
-
#
|
79
|
+
#
|
71
80
|
# # Successful
|
72
81
|
# branch.matches?(object, :on => :ignite) # => true
|
73
82
|
# branch.matches?(object, :from => nil) # => true
|
@@ -75,7 +84,7 @@ module StateMachines
|
|
75
84
|
# branch.matches?(object, :to => :idling) # => true
|
76
85
|
# branch.matches?(object, :from => :parked, :to => :idling) # => true
|
77
86
|
# branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
|
78
|
-
#
|
87
|
+
#
|
79
88
|
# # Unsuccessful
|
80
89
|
# branch.matches?(object, :on => :park) # => false
|
81
90
|
# branch.matches?(object, :from => :idling) # => false
|
@@ -85,16 +94,16 @@ module StateMachines
|
|
85
94
|
def matches?(object, query = {})
|
86
95
|
!match(object, query).nil?
|
87
96
|
end
|
88
|
-
|
97
|
+
|
89
98
|
# Attempts to match the given object / query against the set of requirements
|
90
99
|
# configured for this branch. In addition to matching the event, from state,
|
91
100
|
# and to state, this will also check whether the configured :if/:unless
|
92
101
|
# conditions pass on the given object.
|
93
|
-
#
|
102
|
+
#
|
94
103
|
# If a match is found, then the event/state requirements that the query
|
95
104
|
# passed successfully will be returned. Otherwise, nil is returned if there
|
96
105
|
# was no match.
|
97
|
-
#
|
106
|
+
#
|
98
107
|
# Query options:
|
99
108
|
# * <tt>:from</tt> - One or more states being transitioned from. If none
|
100
109
|
# are specified, then this will always match.
|
@@ -104,80 +113,131 @@ module StateMachines
|
|
104
113
|
# are specified, then this will always match.
|
105
114
|
# * <tt>:guard</tt> - Whether to guard matches with the if/unless
|
106
115
|
# conditionals defined for this branch. Default is true.
|
107
|
-
#
|
116
|
+
#
|
117
|
+
# Event arguments are passed to guard conditions if they accept multiple parameters.
|
118
|
+
#
|
108
119
|
# == Examples
|
109
|
-
#
|
120
|
+
#
|
110
121
|
# branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
|
111
|
-
#
|
122
|
+
#
|
112
123
|
# branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
|
113
124
|
# branch.match(object, :on => :park) # => nil
|
114
|
-
def match(object, query = {})
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
125
|
+
def match(object, query = {}, event_args = [])
|
126
|
+
StateMachines::OptionsValidator.assert_valid_keys!(query, :from, :to, :on, :guard)
|
127
|
+
|
128
|
+
return unless (match = match_query(query)) && matches_conditions?(object, query, event_args)
|
129
|
+
|
130
|
+
match
|
120
131
|
end
|
121
132
|
|
122
|
-
def draw(graph, event, valid_states)
|
123
|
-
|
133
|
+
def draw(graph, event, valid_states, io = $stdout)
|
134
|
+
machine.renderer.draw_branch(self, graph, event, valid_states, io)
|
124
135
|
end
|
125
|
-
|
136
|
+
|
126
137
|
protected
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
138
|
+
|
139
|
+
# Builds a matcher strategy to use for the given options. If neither a
|
140
|
+
# whitelist nor a blacklist option is specified, then an AllMatcher is
|
141
|
+
# built.
|
142
|
+
def build_matcher(options, whitelist_option, blacklist_option)
|
143
|
+
StateMachines::OptionsValidator.assert_exclusive_keys!(options, whitelist_option, blacklist_option)
|
144
|
+
|
145
|
+
if options.include?(whitelist_option)
|
146
|
+
value = options[whitelist_option]
|
147
|
+
value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
|
148
|
+
elsif options.include?(blacklist_option)
|
149
|
+
value = options[blacklist_option]
|
150
|
+
raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
|
151
|
+
|
152
|
+
BlacklistMatcher.new(value)
|
153
|
+
else
|
154
|
+
AllMatcher.instance
|
143
155
|
end
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
156
|
+
end
|
157
|
+
|
158
|
+
# Verifies that all configured requirements (event and state) match the
|
159
|
+
# given query. If a match is found, then a hash containing the
|
160
|
+
# event/state requirements that passed will be returned; otherwise, nil.
|
161
|
+
def match_query(query)
|
162
|
+
query ||= {}
|
163
|
+
|
164
|
+
if match_event(query) && (state_requirement = match_states(query))
|
165
|
+
state_requirement.merge(on: event_requirement)
|
154
166
|
end
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
167
|
+
end
|
168
|
+
|
169
|
+
# Verifies that the event requirement matches the given query
|
170
|
+
def match_event(query)
|
171
|
+
matches_requirement?(query, :on, event_requirement)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Verifies that the state requirements match the given query. If a
|
175
|
+
# matching requirement is found, then it is returned.
|
176
|
+
def match_states(query)
|
177
|
+
state_requirements.detect do |state_requirement|
|
178
|
+
%i[from to].all? { |option| matches_requirement?(query, option, state_requirement[option]) }
|
159
179
|
end
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
180
|
+
end
|
181
|
+
|
182
|
+
# Verifies that an option in the given query matches the values required
|
183
|
+
# for that option
|
184
|
+
def matches_requirement?(query, option, requirement)
|
185
|
+
!query.include?(option) || requirement.matches?(query[option], query)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Verifies that the conditionals for this branch evaluate to true for the
|
189
|
+
# given object. Event arguments are passed to guards that accept multiple parameters.
|
190
|
+
def matches_conditions?(object, query, event_args = [])
|
191
|
+
return true if query[:guard] == false
|
192
|
+
|
193
|
+
# Evaluate original if/unless conditions
|
194
|
+
if_passes = !if_condition || Array(if_condition).all? { |condition| evaluate_method_with_event_args(object, condition, event_args) }
|
195
|
+
unless_passes = !unless_condition || Array(unless_condition).none? { |condition| evaluate_method_with_event_args(object, condition, event_args) }
|
196
|
+
|
197
|
+
return false unless if_passes && unless_passes
|
198
|
+
|
199
|
+
# Consolidate all state guards
|
200
|
+
state_guards = {
|
201
|
+
if_state: @if_state_condition,
|
202
|
+
unless_state: @unless_state_condition,
|
203
|
+
if_all_states: @if_all_states_condition,
|
204
|
+
unless_all_states: @unless_all_states_condition,
|
205
|
+
if_any_state: @if_any_state_condition,
|
206
|
+
unless_any_state: @unless_any_state_condition
|
207
|
+
}.compact
|
208
|
+
|
209
|
+
return true if state_guards.empty?
|
210
|
+
|
211
|
+
validate_and_check_state_guards(object, state_guards)
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
def validate_and_check_state_guards(object, guards)
|
217
|
+
guards.all? do |guard_type, conditions|
|
218
|
+
case guard_type
|
219
|
+
when :if_state, :if_all_states
|
220
|
+
conditions.all? { |machine, state| check_state(object, machine, state) }
|
221
|
+
when :unless_state
|
222
|
+
conditions.none? { |machine, state| check_state(object, machine, state) }
|
223
|
+
when :if_any_state
|
224
|
+
conditions.any? { |machine, state| check_state(object, machine, state) }
|
225
|
+
when :unless_all_states
|
226
|
+
!conditions.all? { |machine, state| check_state(object, machine, state) }
|
227
|
+
when :unless_any_state
|
228
|
+
conditions.none? { |machine, state| check_state(object, machine, state) }
|
166
229
|
end
|
167
230
|
end
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
Array(if_condition).all? {|condition| evaluate_method(object, condition)} &&
|
180
|
-
!Array(unless_condition).any? {|condition| evaluate_method(object, condition)}
|
181
|
-
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def check_state(object, machine_name, state_name)
|
234
|
+
machine = object.class.state_machines[machine_name]
|
235
|
+
raise ArgumentError, "State machine '#{machine_name}' is not defined for #{object.class.name}" unless machine
|
236
|
+
|
237
|
+
state = machine.states[state_name]
|
238
|
+
raise ArgumentError, "State '#{state_name}' is not defined in state machine '#{machine_name}'" unless state
|
239
|
+
|
240
|
+
state.matches?(object.send(machine_name))
|
241
|
+
end
|
182
242
|
end
|
183
243
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'state_machines/branch'
|
2
4
|
require 'state_machines/eval_helpers'
|
3
5
|
|
@@ -16,38 +18,38 @@ module StateMachines
|
|
16
18
|
# the callback. This can be configured on an application-wide basis by
|
17
19
|
# setting this configuration to +true+ or +false+. The default value
|
18
20
|
# is +false+.
|
19
|
-
#
|
21
|
+
#
|
20
22
|
# *Note* that the DataMapper and Sequel integrations automatically
|
21
23
|
# configure this value on a per-callback basis, so it does not have to
|
22
24
|
# be enabled application-wide.
|
23
|
-
#
|
25
|
+
#
|
24
26
|
# == Examples
|
25
|
-
#
|
27
|
+
#
|
26
28
|
# When not bound to the object:
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# class Vehicle
|
29
31
|
# state_machine do
|
30
32
|
# before_transition do |vehicle|
|
31
33
|
# vehicle.set_alarm
|
32
34
|
# end
|
33
35
|
# end
|
34
|
-
#
|
36
|
+
#
|
35
37
|
# def set_alarm
|
36
38
|
# ...
|
37
39
|
# end
|
38
40
|
# end
|
39
|
-
#
|
41
|
+
#
|
40
42
|
# When bound to the object:
|
41
|
-
#
|
43
|
+
#
|
42
44
|
# StateMachines::Callback.bind_to_object = true
|
43
|
-
#
|
45
|
+
#
|
44
46
|
# class Vehicle
|
45
47
|
# state_machine do
|
46
48
|
# before_transition do
|
47
49
|
# self.set_alarm
|
48
50
|
# end
|
49
51
|
# end
|
50
|
-
#
|
52
|
+
#
|
51
53
|
# def set_alarm
|
52
54
|
# ...
|
53
55
|
# end
|
@@ -57,7 +59,7 @@ module StateMachines
|
|
57
59
|
# The application-wide terminator to use for callbacks when not
|
58
60
|
# explicitly defined. Terminators determine whether to cancel a
|
59
61
|
# callback chain based on the return value of the callback.
|
60
|
-
#
|
62
|
+
#
|
61
63
|
# See StateMachines::Callback#terminator for more information.
|
62
64
|
attr_accessor :terminator
|
63
65
|
end
|
@@ -75,11 +77,11 @@ module StateMachines
|
|
75
77
|
# chain never cancels based on the return value (i.e. there is no implicit
|
76
78
|
# terminator). Certain integrations, such as ActiveRecord and Sequel,
|
77
79
|
# change this default value.
|
78
|
-
#
|
80
|
+
#
|
79
81
|
# == Examples
|
80
|
-
#
|
82
|
+
#
|
81
83
|
# Canceling the callback chain without a terminator:
|
82
|
-
#
|
84
|
+
#
|
83
85
|
# class Vehicle
|
84
86
|
# state_machine do
|
85
87
|
# before_transition do |vehicle|
|
@@ -87,9 +89,9 @@ module StateMachines
|
|
87
89
|
# end
|
88
90
|
# end
|
89
91
|
# end
|
90
|
-
#
|
92
|
+
#
|
91
93
|
# Canceling the callback chain with a terminator value of +false+:
|
92
|
-
#
|
94
|
+
#
|
93
95
|
# class Vehicle
|
94
96
|
# state_machine do
|
95
97
|
# before_transition do |vehicle|
|
@@ -102,13 +104,13 @@ module StateMachines
|
|
102
104
|
# The branch that determines whether or not this callback can be invoked
|
103
105
|
# based on the context of the transition. The event, from state, and
|
104
106
|
# to state must all match in order for the branch to pass.
|
105
|
-
#
|
107
|
+
#
|
106
108
|
# See StateMachines::Branch for more information.
|
107
109
|
attr_reader :branch
|
108
110
|
|
109
111
|
# Creates a new callback that can get called based on the configured
|
110
112
|
# options.
|
111
|
-
#
|
113
|
+
#
|
112
114
|
# In addition to the possible configuration options for branches, the
|
113
115
|
# following options can be configured:
|
114
116
|
# * <tt>:bind_to_object</tt> - Whether to bind the callback to the object involved.
|
@@ -117,12 +119,12 @@ module StateMachines
|
|
117
119
|
# * <tt>:terminator</tt> - A block/proc that determines what callback
|
118
120
|
# results should cause the callback chain to halt (if not using the
|
119
121
|
# default <tt>throw :halt</tt> technique).
|
120
|
-
#
|
122
|
+
#
|
121
123
|
# More information about how those options affect the behavior of the
|
122
124
|
# callback can be found in their attribute definitions.
|
123
125
|
def initialize(type, *args, &block)
|
124
126
|
@type = type
|
125
|
-
raise ArgumentError, 'Type must be :before, :after, :around, or :failure' unless [
|
127
|
+
raise ArgumentError, 'Type must be :before, :after, :around, or :failure' unless %i[before after around failure].include?(type)
|
126
128
|
|
127
129
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
128
130
|
@methods = args
|
@@ -130,7 +132,7 @@ module StateMachines
|
|
130
132
|
@methods << block if block_given?
|
131
133
|
raise ArgumentError, 'Method(s) for callback must be specified' unless @methods.any?
|
132
134
|
|
133
|
-
options = {:
|
135
|
+
options = { bind_to_object: self.class.bind_to_object, terminator: self.class.terminator }.merge(options)
|
134
136
|
|
135
137
|
# Proxy lambda blocks so that they're bound to the object
|
136
138
|
bind_to_object = options.delete(:bind_to_object)
|
@@ -151,12 +153,12 @@ module StateMachines
|
|
151
153
|
# Runs the callback as long as the transition context matches the branch
|
152
154
|
# requirements configured for this callback. If a block is provided, it
|
153
155
|
# will be called when the last method has run.
|
154
|
-
#
|
156
|
+
#
|
155
157
|
# If a terminator has been configured and it matches the result from the
|
156
158
|
# evaluated method, then the callback chain should be halted.
|
157
|
-
def call(object, context = {},
|
159
|
+
def call(object, context = {}, *, &)
|
158
160
|
if @branch.matches?(object, context)
|
159
|
-
run_methods(object, context, 0,
|
161
|
+
run_methods(object, context, 0, *, &)
|
160
162
|
true
|
161
163
|
else
|
162
164
|
false
|
@@ -164,6 +166,7 @@ module StateMachines
|
|
164
166
|
end
|
165
167
|
|
166
168
|
private
|
169
|
+
|
167
170
|
# Runs all of the methods configured for this callback.
|
168
171
|
#
|
169
172
|
# When running +around+ callbacks, this will evaluate each method and
|
@@ -174,9 +177,10 @@ module StateMachines
|
|
174
177
|
# order. The callback will only halt if the resulting value from the
|
175
178
|
# method passes the terminator.
|
176
179
|
def run_methods(object, context = {}, index = 0, *args, &block)
|
177
|
-
|
180
|
+
case type
|
181
|
+
when :around
|
178
182
|
current_method = @methods[index]
|
179
|
-
if
|
183
|
+
if current_method
|
180
184
|
yielded = false
|
181
185
|
evaluate_method(object, current_method, *args) do
|
182
186
|
yielded = true
|
@@ -184,13 +188,13 @@ module StateMachines
|
|
184
188
|
end
|
185
189
|
|
186
190
|
throw :halt unless yielded
|
187
|
-
|
188
|
-
yield
|
191
|
+
elsif block_given?
|
192
|
+
yield
|
189
193
|
end
|
190
194
|
else
|
191
195
|
@methods.each do |method|
|
192
196
|
result = evaluate_method(object, method, *args)
|
193
|
-
throw :halt if @terminator
|
197
|
+
throw :halt if @terminator&.call(result)
|
194
198
|
end
|
195
199
|
end
|
196
200
|
end
|
@@ -203,13 +207,12 @@ module StateMachines
|
|
203
207
|
arity += 1 if arity >= 0 # Make sure the object gets passed
|
204
208
|
arity += 1 if arity == 1 && type == :around # Make sure the block gets passed
|
205
209
|
|
206
|
-
method =
|
207
|
-
|
210
|
+
method = ->(object, *args) { object.instance_exec(*args, &block) }
|
208
211
|
|
209
212
|
# Proxy arity to the original block
|
210
213
|
(
|
211
|
-
class << method
|
212
|
-
self
|
214
|
+
class << method
|
215
|
+
self
|
213
216
|
end).class_eval do
|
214
217
|
define_method(:arity) { arity }
|
215
218
|
end
|
data/lib/state_machines/core.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Load all of the core implementation required to use state_machine. This
|
2
4
|
# includes:
|
3
5
|
# * StateMachines::MacroMethods which adds the state_machine DSL to your class
|
4
6
|
# * A set of initializers for setting state_machine defaults based on the current
|
5
7
|
# running environment (such as within Rails)
|
6
|
-
require 'state_machines/assertions'
|
7
8
|
require 'state_machines/error'
|
8
9
|
|
9
10
|
require 'state_machines/extensions'
|
@@ -23,7 +24,6 @@ require 'state_machines/transition_collection'
|
|
23
24
|
require 'state_machines/branch'
|
24
25
|
|
25
26
|
require 'state_machines/helper_module'
|
26
|
-
require 'state_machines/state'
|
27
27
|
require 'state_machines/callback'
|
28
28
|
require 'state_machines/node_collection'
|
29
29
|
|
@@ -40,4 +40,4 @@ require 'state_machines/path_collection'
|
|
40
40
|
require 'state_machines/machine'
|
41
41
|
require 'state_machines/machine_collection'
|
42
42
|
|
43
|
-
require 'state_machines/macro_methods'
|
43
|
+
require 'state_machines/macro_methods'
|
data/lib/state_machines/error.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# An error occurred during a state machine invocation
|
3
5
|
class Error < StandardError
|
4
6
|
# The object that failed
|
5
7
|
attr_reader :object
|
6
8
|
|
7
|
-
def initialize(object, message = nil)
|
9
|
+
def initialize(object, message = nil) # :nodoc:
|
8
10
|
@object = object
|
9
11
|
|
10
12
|
super(message)
|
@@ -47,12 +49,13 @@ module StateMachines
|
|
47
49
|
# The event that was attempted to be run
|
48
50
|
attr_reader :event
|
49
51
|
|
50
|
-
def initialize(object, event_name)
|
52
|
+
def initialize(object, event_name) # :nodoc:
|
51
53
|
@event = event_name
|
52
54
|
|
53
55
|
super(object, "#{event.inspect} is an unknown state machine event")
|
54
56
|
end
|
55
57
|
end
|
58
|
+
|
56
59
|
# An invalid transition was attempted
|
57
60
|
class InvalidTransition < Error
|
58
61
|
# The machine attempting to be transitioned
|
@@ -61,7 +64,7 @@ module StateMachines
|
|
61
64
|
# The current state value for the machine
|
62
65
|
attr_reader :from
|
63
66
|
|
64
|
-
def initialize(object, machine, event)
|
67
|
+
def initialize(object, machine, event) # :nodoc:
|
65
68
|
@machine = machine
|
66
69
|
@from_state = machine.states.match!(object)
|
67
70
|
@from = machine.read(object, :state)
|
@@ -99,7 +102,7 @@ module StateMachines
|
|
99
102
|
# The set of events that failed the transition(s)
|
100
103
|
attr_reader :events
|
101
104
|
|
102
|
-
def initialize(object, events)
|
105
|
+
def initialize(object, events) # :nodoc:
|
103
106
|
@events = events
|
104
107
|
|
105
108
|
super(object, "Cannot run events in parallel: #{events * ', '}")
|