state_machines 0.5.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +99 -16
- data/lib/state_machines/branch.rb +88 -82
- data/lib/state_machines/callback.rb +24 -21
- data/lib/state_machines/core.rb +3 -2
- 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 +2 -0
- data/lib/state_machines/eval_helpers.rb +51 -22
- data/lib/state_machines/event.rb +53 -35
- data/lib/state_machines/event_collection.rb +28 -25
- data/lib/state_machines/extensions.rb +3 -1
- data/lib/state_machines/helper_module.rb +3 -1
- data/lib/state_machines/integrations/base.rb +2 -0
- data/lib/state_machines/integrations.rb +10 -8
- data/lib/state_machines/machine/class_methods.rb +79 -0
- data/lib/state_machines/machine.rb +386 -429
- data/lib/state_machines/machine_collection.rb +16 -11
- data/lib/state_machines/macro_methods.rb +102 -100
- data/lib/state_machines/matcher.rb +26 -23
- data/lib/state_machines/matcher_helpers.rb +13 -11
- data/lib/state_machines/node_collection.rb +20 -14
- data/lib/state_machines/options_validator.rb +72 -0
- data/lib/state_machines/path.rb +61 -56
- data/lib/state_machines/path_collection.rb +40 -36
- data/lib/state_machines/state.rb +72 -43
- data/lib/state_machines/state_collection.rb +22 -19
- data/lib/state_machines/state_context.rb +38 -36
- data/lib/state_machines/stdio_renderer.rb +74 -0
- data/lib/state_machines/test_helper.rb +305 -0
- data/lib/state_machines/transition.rb +182 -178
- data/lib/state_machines/transition_collection.rb +175 -169
- data/lib/state_machines/version.rb +3 -1
- data/lib/state_machines.rb +4 -1
- metadata +12 -440
- 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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Provides a set of helper methods for evaluating methods within the context
|
3
5
|
# of an object.
|
@@ -7,62 +9,60 @@ module StateMachines
|
|
7
9
|
# * Symbol
|
8
10
|
# * Method / Proc
|
9
11
|
# * String
|
10
|
-
#
|
12
|
+
#
|
11
13
|
# == Examples
|
12
|
-
#
|
14
|
+
#
|
13
15
|
# Below are examples of the various ways that a method can be evaluated
|
14
16
|
# on an object:
|
15
|
-
#
|
17
|
+
#
|
16
18
|
# class Person
|
17
19
|
# def initialize(name)
|
18
20
|
# @name = name
|
19
21
|
# end
|
20
|
-
#
|
22
|
+
#
|
21
23
|
# def name
|
22
24
|
# @name
|
23
25
|
# end
|
24
26
|
# end
|
25
|
-
#
|
27
|
+
#
|
26
28
|
# class PersonCallback
|
27
29
|
# def self.run(person)
|
28
30
|
# person.name
|
29
31
|
# end
|
30
32
|
# end
|
31
|
-
#
|
33
|
+
#
|
32
34
|
# person = Person.new('John Smith')
|
33
|
-
#
|
35
|
+
#
|
34
36
|
# evaluate_method(person, :name) # => "John Smith"
|
35
37
|
# evaluate_method(person, PersonCallback.method(:run)) # => "John Smith"
|
36
38
|
# evaluate_method(person, Proc.new {|person| person.name}) # => "John Smith"
|
37
39
|
# evaluate_method(person, lambda {|person| person.name}) # => "John Smith"
|
38
40
|
# evaluate_method(person, '@name') # => "John Smith"
|
39
|
-
#
|
41
|
+
#
|
40
42
|
# == Additional arguments
|
41
|
-
#
|
43
|
+
#
|
42
44
|
# Additional arguments can be passed to the methods being evaluated. If
|
43
45
|
# the method defines additional arguments other than the object context,
|
44
46
|
# then all arguments are required.
|
45
|
-
#
|
47
|
+
#
|
46
48
|
# For example,
|
47
|
-
#
|
49
|
+
#
|
48
50
|
# person = Person.new('John Smith')
|
49
|
-
#
|
51
|
+
#
|
50
52
|
# evaluate_method(person, lambda {|person| person.name}, 21) # => "John Smith"
|
51
53
|
# evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21) # => "John Smith is 21"
|
52
54
|
# evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21, 'male') # => ArgumentError: wrong number of arguments (3 for 2)
|
53
|
-
def evaluate_method(object, method, *args, &block)
|
55
|
+
def evaluate_method(object, method, *args, **kwargs, &block)
|
54
56
|
case method
|
55
57
|
when Symbol
|
56
58
|
klass = (class << object; self; end)
|
57
59
|
args = [] if (klass.method_defined?(method) || klass.private_method_defined?(method)) && object.method(method).arity == 0
|
58
|
-
object.send(method, *args, &block)
|
59
|
-
when Proc
|
60
|
+
object.send(method, *args, **kwargs, &block)
|
61
|
+
when Proc
|
60
62
|
args.unshift(object)
|
61
63
|
arity = method.arity
|
62
|
-
|
63
|
-
|
64
|
-
# argument for consistency across versions of Ruby
|
65
|
-
if block_given? && Proc === method && arity != 0
|
64
|
+
# Handle blocks for Procs
|
65
|
+
if block_given? && arity != 0
|
66
66
|
if [1, 2].include?(arity)
|
67
67
|
# Force the block to be either the only argument or the 2nd one
|
68
68
|
# after the object (may mean additional arguments get discarded)
|
@@ -75,10 +75,39 @@ module StateMachines
|
|
75
75
|
# These method types are only called with 0, 1, or n arguments
|
76
76
|
args = args[0, arity] if [0, 1].include?(arity)
|
77
77
|
end
|
78
|
-
|
79
|
-
|
78
|
+
|
79
|
+
# Call the Proc with the arguments
|
80
|
+
method.call(*args, **kwargs)
|
81
|
+
|
82
|
+
when Method
|
83
|
+
args.unshift(object)
|
84
|
+
arity = method.arity
|
85
|
+
|
86
|
+
# Methods handle blocks via &block, not as arguments
|
87
|
+
# Only limit arguments if necessary based on arity
|
88
|
+
args = args[0, arity] if [0, 1].include?(arity)
|
89
|
+
|
90
|
+
# Call the Method with the arguments and pass the block
|
91
|
+
method.call(*args, **kwargs, &block)
|
80
92
|
when String
|
81
|
-
|
93
|
+
if block_given?
|
94
|
+
if StateMachines::Transition.pause_supported?
|
95
|
+
eval(method, object.instance_eval { binding }, &block)
|
96
|
+
else
|
97
|
+
# Support for JRuby and Truffle Ruby, which don't support binding blocks
|
98
|
+
eigen = class << object; self; end
|
99
|
+
eigen.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
100
|
+
def __temp_eval_method__(*args, &b)
|
101
|
+
#{method}
|
102
|
+
end
|
103
|
+
RUBY
|
104
|
+
result = object.__temp_eval_method__(*args, &block)
|
105
|
+
eigen.send(:remove_method, :__temp_eval_method__)
|
106
|
+
result
|
107
|
+
end
|
108
|
+
else
|
109
|
+
eval(method, object.instance_eval { binding })
|
110
|
+
end
|
82
111
|
else
|
83
112
|
raise ArgumentError, 'Methods must be a symbol denoting the method to call, a block to be invoked, or a string to be evaluated'
|
84
113
|
end
|
data/lib/state_machines/event.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'options_validator'
|
4
|
+
|
1
5
|
module StateMachines
|
2
6
|
# An event defines an action that transitions an attribute from one state to
|
3
7
|
# another. The state that an attribute is transitioned to depends on the
|
@@ -12,7 +16,7 @@ module StateMachines
|
|
12
16
|
# The name of the event
|
13
17
|
attr_reader :name
|
14
18
|
|
15
|
-
# The fully-qualified name of the event, scoped by the machine's namespace
|
19
|
+
# The fully-qualified name of the event, scoped by the machine's namespace
|
16
20
|
attr_reader :qualified_name
|
17
21
|
|
18
22
|
# The human-readable name for the event
|
@@ -27,20 +31,29 @@ module StateMachines
|
|
27
31
|
attr_reader :known_states
|
28
32
|
|
29
33
|
# Creates a new event within the context of the given machine
|
30
|
-
#
|
34
|
+
#
|
31
35
|
# Configuration options:
|
32
36
|
# * <tt>:human_name</tt> - The human-readable version of this event's name
|
33
|
-
def initialize(machine, name, options =
|
34
|
-
|
37
|
+
def initialize(machine, name, options = nil, human_name: nil, **extra_options) #:nodoc:
|
38
|
+
# Handle both old hash style and new kwargs style for backward compatibility
|
39
|
+
if options.is_a?(Hash)
|
40
|
+
# Old style: initialize(machine, name, {human_name: 'Custom Name'})
|
41
|
+
StateMachines::OptionsValidator.assert_valid_keys!(options, :human_name)
|
42
|
+
human_name = options[:human_name]
|
43
|
+
else
|
44
|
+
# New style: initialize(machine, name, human_name: 'Custom Name')
|
45
|
+
raise ArgumentError, "Unexpected positional argument: #{options.inspect}" unless options.nil?
|
46
|
+
StateMachines::OptionsValidator.assert_valid_keys!(extra_options, :human_name) unless extra_options.empty?
|
47
|
+
end
|
35
48
|
|
36
49
|
@machine = machine
|
37
50
|
@name = name
|
38
51
|
@qualified_name = machine.namespace ? :"#{name}_#{machine.namespace}" : name
|
39
|
-
@human_name =
|
52
|
+
@human_name = human_name || @name.to_s.tr('_', ' ')
|
40
53
|
reset
|
41
54
|
|
42
55
|
# Output a warning if another event has a conflicting qualified name
|
43
|
-
if conflict = machine.owner_class.state_machines.detect { |_other_name, other_machine| other_machine != @machine && other_machine.events[qualified_name, :qualified_name] }
|
56
|
+
if (conflict = machine.owner_class.state_machines.detect { |_other_name, other_machine| other_machine != @machine && other_machine.events[qualified_name, :qualified_name] })
|
44
57
|
_name, other_machine = conflict
|
45
58
|
warn "Event #{qualified_name.inspect} for #{machine.name.inspect} is already defined in #{other_machine.name.inspect}"
|
46
59
|
else
|
@@ -70,18 +83,18 @@ module StateMachines
|
|
70
83
|
|
71
84
|
# Creates a new transition that determines what to change the current state
|
72
85
|
# to when this event fires.
|
73
|
-
#
|
86
|
+
#
|
74
87
|
# Since this transition is being defined within an event context, you do
|
75
88
|
# *not* need to specify the <tt>:on</tt> option for the transition. For
|
76
89
|
# example:
|
77
|
-
#
|
90
|
+
#
|
78
91
|
# state_machine do
|
79
92
|
# event :ignite do
|
80
93
|
# transition :parked => :idling, :idling => same, :if => :seatbelt_on? # Transitions to :idling if seatbelt is on
|
81
94
|
# transition all => :parked, :unless => :seatbelt_on? # Transitions to :parked if seatbelt is off
|
82
95
|
# end
|
83
96
|
# end
|
84
|
-
#
|
97
|
+
#
|
85
98
|
# See StateMachines::Machine#transition for a description of the possible
|
86
99
|
# configurations for defining transitions.
|
87
100
|
def transition(options)
|
@@ -89,18 +102,20 @@ module StateMachines
|
|
89
102
|
|
90
103
|
# Only a certain subset of explicit options are allowed for transition
|
91
104
|
# requirements
|
92
|
-
|
105
|
+
if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on, :if, :unless]).empty?
|
106
|
+
StateMachines::OptionsValidator.assert_valid_keys!(options, :from, :to, :except_from, :except_to, :if, :unless)
|
107
|
+
end
|
93
108
|
|
94
|
-
branches << branch = Branch.new(options.merge(:
|
109
|
+
branches << branch = Branch.new(options.merge(on: name))
|
95
110
|
@known_states |= branch.known_states
|
96
111
|
branch
|
97
112
|
end
|
98
113
|
|
99
114
|
# Determines whether any transitions can be performed for this event based
|
100
115
|
# on the current state of the given object.
|
101
|
-
#
|
116
|
+
#
|
102
117
|
# If the event can't be fired, then this will return false, otherwise true.
|
103
|
-
#
|
118
|
+
#
|
104
119
|
# *Note* that this will not take the object context into account. Although
|
105
120
|
# a transition may be possible based on the state machine definition,
|
106
121
|
# object-specific behaviors (like validations) may prevent it from firing.
|
@@ -110,7 +125,7 @@ module StateMachines
|
|
110
125
|
|
111
126
|
# Finds and builds the next transition that can be performed on the given
|
112
127
|
# object. If no transitions can be made, then this will return nil.
|
113
|
-
#
|
128
|
+
#
|
114
129
|
# Valid requirement options:
|
115
130
|
# * <tt>:from</tt> - One or more states being transitioned from. If none
|
116
131
|
# are specified, then this will be the object's current state.
|
@@ -119,11 +134,11 @@ module StateMachines
|
|
119
134
|
# * <tt>:guard</tt> - Whether to guard transitions with the if/unless
|
120
135
|
# conditionals defined for each one. Default is true.
|
121
136
|
def transition_for(object, requirements = {})
|
122
|
-
|
123
|
-
requirements[:from] = machine.states.match!(object).name unless custom_from_state = requirements.include?(:from)
|
137
|
+
StateMachines::OptionsValidator.assert_valid_keys!(requirements, :from, :to, :guard)
|
138
|
+
requirements[:from] = machine.states.match!(object).name unless (custom_from_state = requirements.include?(:from))
|
124
139
|
|
125
140
|
branches.each do |branch|
|
126
|
-
if match = branch.match(object, requirements)
|
141
|
+
if (match = branch.match(object, requirements))
|
127
142
|
# Branch allows for the transition to occur
|
128
143
|
from = requirements[:from]
|
129
144
|
to = if match[:to].is_a?(LoopbackMatcher)
|
@@ -145,27 +160,29 @@ module StateMachines
|
|
145
160
|
# Attempts to perform the next available transition on the given object.
|
146
161
|
# If no transitions can be made, then this will return false, otherwise
|
147
162
|
# true.
|
148
|
-
#
|
163
|
+
#
|
149
164
|
# Any additional arguments are passed to the StateMachines::Transition#perform
|
150
165
|
# instance method.
|
151
166
|
def fire(object, *args)
|
152
167
|
machine.reset(object)
|
153
168
|
|
154
|
-
if transition = transition_for(object)
|
169
|
+
if (transition = transition_for(object))
|
155
170
|
transition.perform(*args)
|
156
171
|
else
|
157
|
-
on_failure(object)
|
172
|
+
on_failure(object, *args)
|
158
173
|
false
|
159
174
|
end
|
160
175
|
end
|
161
176
|
|
162
177
|
# Marks the object as invalid and runs any failure callbacks associated with
|
163
178
|
# this event. This should get called anytime this event fails to transition.
|
164
|
-
def on_failure(object)
|
179
|
+
def on_failure(object, *args)
|
165
180
|
state = machine.states.match!(object)
|
166
181
|
machine.invalidate(object, :state, :invalid_transition, [[:event, human_name(object.class)], [:state, state.human_name(object.class)]])
|
167
182
|
|
168
|
-
Transition.new(object, machine, name, state.name, state.name)
|
183
|
+
transition = Transition.new(object, machine, name, state.name, state.name)
|
184
|
+
transition.args = args if args.any?
|
185
|
+
transition.run_callbacks(before: false)
|
169
186
|
end
|
170
187
|
|
171
188
|
# Resets back to the initial state of the event, with no branches / known
|
@@ -178,14 +195,14 @@ module StateMachines
|
|
178
195
|
end
|
179
196
|
|
180
197
|
|
181
|
-
def draw(graph, options = {})
|
182
|
-
|
198
|
+
def draw(graph, options = {}, io = $stdout)
|
199
|
+
machine.renderer.draw_event(self, graph, options, io)
|
183
200
|
end
|
184
201
|
|
185
202
|
# Generates a nicely formatted description of this event's contents.
|
186
|
-
#
|
203
|
+
#
|
187
204
|
# For example,
|
188
|
-
#
|
205
|
+
#
|
189
206
|
# event = StateMachines::Event.new(machine, :park)
|
190
207
|
# event.transition all - :idling => :parked, :idling => same
|
191
208
|
# event # => #<StateMachines::Event name=:park transitions=[all - :idling => :parked, :idling => same]>
|
@@ -199,29 +216,30 @@ module StateMachines
|
|
199
216
|
"#<#{self.class} name=#{name.inspect} transitions=[#{transitions * ', '}]>"
|
200
217
|
end
|
201
218
|
|
202
|
-
|
219
|
+
protected
|
220
|
+
|
203
221
|
# Add the various instance methods that can transition the object using
|
204
222
|
# the current event
|
205
223
|
def add_actions
|
206
224
|
# Checks whether the event can be fired on the current object
|
207
|
-
machine.define_helper(:instance, "can_#{qualified_name}?") do |machine, object, *args|
|
208
|
-
machine.event(name).can_fire?(object, *args)
|
225
|
+
machine.define_helper(:instance, "can_#{qualified_name}?") do |machine, object, *args, **kwargs|
|
226
|
+
machine.event(name).can_fire?(object, *args, **kwargs)
|
209
227
|
end
|
210
228
|
|
211
229
|
# Gets the next transition that would be performed if the event were
|
212
230
|
# fired now
|
213
|
-
machine.define_helper(:instance, "#{qualified_name}_transition") do |machine, object, *args|
|
214
|
-
machine.event(name).transition_for(object, *args)
|
231
|
+
machine.define_helper(:instance, "#{qualified_name}_transition") do |machine, object, *args, **kwargs|
|
232
|
+
machine.event(name).transition_for(object, *args, **kwargs)
|
215
233
|
end
|
216
234
|
|
217
235
|
# Fires the event
|
218
|
-
machine.define_helper(:instance, qualified_name) do |machine, object, *args|
|
219
|
-
machine.event(name).fire(object, *args)
|
236
|
+
machine.define_helper(:instance, qualified_name) do |machine, object, *args, **kwargs|
|
237
|
+
machine.event(name).fire(object, *args, **kwargs)
|
220
238
|
end
|
221
239
|
|
222
240
|
# Fires the event, raising an exception if it fails
|
223
|
-
machine.define_helper(:instance, "#{qualified_name}!") do |machine, object, *args|
|
224
|
-
object.send(qualified_name, *args) || raise(StateMachines::InvalidTransition.new(object, machine, name))
|
241
|
+
machine.define_helper(:instance, "#{qualified_name}!") do |machine, object, *args, **kwargs|
|
242
|
+
object.send(qualified_name, *args, **kwargs) || raise(StateMachines::InvalidTransition.new(object, machine, name))
|
225
243
|
end
|
226
244
|
end
|
227
245
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Represents a collection of events in a state machine
|
3
5
|
class EventCollection < NodeCollection
|
4
6
|
def initialize(machine) #:nodoc:
|
5
|
-
super(machine, :
|
7
|
+
super(machine, index: [:name, :qualified_name])
|
6
8
|
end
|
7
9
|
|
8
10
|
# Gets the list of events that can be fired on the given object.
|
9
|
-
#
|
11
|
+
#
|
10
12
|
# Valid requirement options:
|
11
13
|
# * <tt>:from</tt> - One or more states being transitioned from. If none
|
12
14
|
# are specified, then this will be the object's current state.
|
@@ -16,26 +18,26 @@ module StateMachines
|
|
16
18
|
# are specified, then this will match any event.
|
17
19
|
# * <tt>:guard</tt> - Whether to guard transitions with the if/unless
|
18
20
|
# conditionals defined for each one. Default is true.
|
19
|
-
#
|
21
|
+
#
|
20
22
|
# == Examples
|
21
|
-
#
|
23
|
+
#
|
22
24
|
# class Vehicle
|
23
25
|
# state_machine :initial => :parked do
|
24
26
|
# event :park do
|
25
27
|
# transition :idling => :parked
|
26
28
|
# end
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# event :ignite do
|
29
31
|
# transition :parked => :idling
|
30
32
|
# end
|
31
33
|
# end
|
32
34
|
# end
|
33
|
-
#
|
35
|
+
#
|
34
36
|
# events = Vehicle.state_machine(:state).events
|
35
|
-
#
|
37
|
+
#
|
36
38
|
# vehicle = Vehicle.new # => #<Vehicle:0xb7c464b0 @state="parked">
|
37
39
|
# events.valid_for(vehicle) # => [#<StateMachines::Event name=:ignite transitions=[:parked => :idling]>]
|
38
|
-
#
|
40
|
+
#
|
39
41
|
# vehicle.state = 'idling'
|
40
42
|
# events.valid_for(vehicle) # => [#<StateMachines::Event name=:park transitions=[:idling => :parked]>]
|
41
43
|
def valid_for(object, requirements = {})
|
@@ -43,7 +45,7 @@ module StateMachines
|
|
43
45
|
end
|
44
46
|
|
45
47
|
# Gets the list of transitions that can be run on the given object.
|
46
|
-
#
|
48
|
+
#
|
47
49
|
# Valid requirement options:
|
48
50
|
# * <tt>:from</tt> - One or more states being transitioned from. If none
|
49
51
|
# are specified, then this will be the object's current state.
|
@@ -53,29 +55,29 @@ module StateMachines
|
|
53
55
|
# are specified, then this will match any event.
|
54
56
|
# * <tt>:guard</tt> - Whether to guard transitions with the if/unless
|
55
57
|
# conditionals defined for each one. Default is true.
|
56
|
-
#
|
58
|
+
#
|
57
59
|
# == Examples
|
58
|
-
#
|
60
|
+
#
|
59
61
|
# class Vehicle
|
60
62
|
# state_machine :initial => :parked do
|
61
63
|
# event :park do
|
62
64
|
# transition :idling => :parked
|
63
65
|
# end
|
64
|
-
#
|
66
|
+
#
|
65
67
|
# event :ignite do
|
66
68
|
# transition :parked => :idling
|
67
69
|
# end
|
68
70
|
# end
|
69
71
|
# end
|
70
|
-
#
|
72
|
+
#
|
71
73
|
# events = Vehicle.state_machine.events
|
72
|
-
#
|
74
|
+
#
|
73
75
|
# vehicle = Vehicle.new # => #<Vehicle:0xb7c464b0 @state="parked">
|
74
76
|
# events.transitions_for(vehicle) # => [#<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>]
|
75
|
-
#
|
77
|
+
#
|
76
78
|
# vehicle.state = 'idling'
|
77
79
|
# events.transitions_for(vehicle) # => [#<StateMachines::Transition attribute=:state event=:park from="idling" from_name=:idling to="parked" to_name=:parked>]
|
78
|
-
#
|
80
|
+
#
|
79
81
|
# # Search for explicit transitions regardless of the current state
|
80
82
|
# events.transitions_for(vehicle, :from => :parked) # => [#<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>]
|
81
83
|
def transitions_for(object, requirements = {})
|
@@ -86,12 +88,12 @@ module StateMachines
|
|
86
88
|
# given object's event attribute. This also takes an additional parameter
|
87
89
|
# for automatically invalidating the object if the event or transition are
|
88
90
|
# invalid. By default, this is turned off.
|
89
|
-
#
|
91
|
+
#
|
90
92
|
# *Note* that if a transition has already been generated for the event, then
|
91
93
|
# that transition will be used.
|
92
|
-
#
|
94
|
+
#
|
93
95
|
# == Examples
|
94
|
-
#
|
96
|
+
#
|
95
97
|
# class Vehicle < ActiveRecord::Base
|
96
98
|
# state_machine :initial => :parked do
|
97
99
|
# event :ignite do
|
@@ -99,16 +101,16 @@ module StateMachines
|
|
99
101
|
# end
|
100
102
|
# end
|
101
103
|
# end
|
102
|
-
#
|
104
|
+
#
|
103
105
|
# vehicle = Vehicle.new # => #<Vehicle id: nil, state: "parked">
|
104
106
|
# events = Vehicle.state_machine.events
|
105
|
-
#
|
107
|
+
#
|
106
108
|
# vehicle.state_event = nil
|
107
109
|
# events.attribute_transition_for(vehicle) # => nil # Event isn't defined
|
108
|
-
#
|
110
|
+
#
|
109
111
|
# vehicle.state_event = 'invalid'
|
110
112
|
# events.attribute_transition_for(vehicle) # => false # Event is invalid
|
111
|
-
#
|
113
|
+
#
|
112
114
|
# vehicle.state_event = 'ignite'
|
113
115
|
# events.attribute_transition_for(vehicle) # => #<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>
|
114
116
|
def attribute_transition_for(object, invalidate = false)
|
@@ -118,7 +120,7 @@ module StateMachines
|
|
118
120
|
machine.read(object, :event_transition) || if event_name = machine.read(object, :event)
|
119
121
|
if event = self[event_name.to_sym, :name]
|
120
122
|
event.transition_for(object) || begin
|
121
|
-
|
123
|
+
# No valid transition: invalidate
|
122
124
|
machine.invalidate(object, :event, :invalid_event, [[:state, machine.states.match!(object).human_name(object.class)]]) if invalidate
|
123
125
|
false
|
124
126
|
end
|
@@ -131,7 +133,8 @@ module StateMachines
|
|
131
133
|
|
132
134
|
end
|
133
135
|
|
134
|
-
|
136
|
+
private
|
137
|
+
|
135
138
|
def match(requirements) #:nodoc:
|
136
139
|
requirements && requirements[:on] ? [fetch(requirements.delete(:on))] : self
|
137
140
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
module ClassMethods
|
3
5
|
def self.extended(base) #:nodoc:
|
@@ -139,7 +141,7 @@ module StateMachines
|
|
139
141
|
fire_events(*(events + [run_action])) || fail(StateMachines::InvalidParallelTransition.new(self, events))
|
140
142
|
end
|
141
143
|
|
142
|
-
|
144
|
+
protected
|
143
145
|
|
144
146
|
def initialize_state_machines(options = {}, &block) #:nodoc:
|
145
147
|
self.class.state_machines.initialize_states(self, options, &block)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Represents a type of module that defines instance / class methods for a
|
3
5
|
# state machine
|
@@ -6,7 +8,7 @@ module StateMachines
|
|
6
8
|
@machine = machine
|
7
9
|
@kind = kind
|
8
10
|
end
|
9
|
-
|
11
|
+
|
10
12
|
# Provides a human-readable description of the module
|
11
13
|
def to_s
|
12
14
|
owner_class = @machine.owner_class
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Integrations allow state machines to take advantage of features within the
|
3
5
|
# context of a particular library. This is currently most useful with
|
@@ -9,10 +11,10 @@ module StateMachines
|
|
9
11
|
# * Scopes
|
10
12
|
# * Callbacks
|
11
13
|
# * Validation errors
|
12
|
-
#
|
14
|
+
#
|
13
15
|
# This type of integration allows the user to work with state machines in a
|
14
16
|
# fashion similar to other object models in their application.
|
15
|
-
#
|
17
|
+
#
|
16
18
|
# The integration interface is loosely defined by various unimplemented
|
17
19
|
# methods in the StateMachines::Machine class. See that class or the various
|
18
20
|
# built-in integrations for more information about how to define additional
|
@@ -55,20 +57,20 @@ module StateMachines
|
|
55
57
|
# Attempts to find an integration that matches the given class. This will
|
56
58
|
# look through all of the built-in integrations under the StateMachines::Integrations
|
57
59
|
# namespace and find one that successfully matches the class.
|
58
|
-
#
|
60
|
+
#
|
59
61
|
# == Examples
|
60
|
-
#
|
62
|
+
#
|
61
63
|
# class Vehicle
|
62
64
|
# end
|
63
|
-
#
|
65
|
+
#
|
64
66
|
# class ActiveModelVehicle
|
65
67
|
# include ActiveModel::Observing
|
66
68
|
# include ActiveModel::Validations
|
67
69
|
# end
|
68
|
-
#
|
70
|
+
#
|
69
71
|
# class ActiveRecordVehicle < ActiveRecord::Base
|
70
72
|
# end
|
71
|
-
#
|
73
|
+
#
|
72
74
|
# StateMachines::Integrations.match(Vehicle) # => nil
|
73
75
|
# StateMachines::Integrations.match(ActiveModelVehicle) # => StateMachines::Integrations::ActiveModel
|
74
76
|
# StateMachines::Integrations.match(ActiveRecordVehicle) # => StateMachines::Integrations::ActiveRecord
|
@@ -100,7 +102,7 @@ module StateMachines
|
|
100
102
|
integrations.detect { |integration| integration.integration_name == name } || raise(IntegrationNotFound.new(name))
|
101
103
|
end
|
102
104
|
|
103
|
-
|
105
|
+
private
|
104
106
|
|
105
107
|
def add(integration)
|
106
108
|
if integration.respond_to?(:integration_name)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StateMachines
|
4
|
+
class Machine
|
5
|
+
module ClassMethods
|
6
|
+
# Attempts to find or create a state machine for the given class. For
|
7
|
+
# example,
|
8
|
+
#
|
9
|
+
# StateMachines::Machine.find_or_create(Vehicle)
|
10
|
+
# StateMachines::Machine.find_or_create(Vehicle, :initial => :parked)
|
11
|
+
# StateMachines::Machine.find_or_create(Vehicle, :status)
|
12
|
+
# StateMachines::Machine.find_or_create(Vehicle, :status, :initial => :parked)
|
13
|
+
#
|
14
|
+
# If a machine of the given name already exists in one of the class's
|
15
|
+
# superclasses, then a copy of that machine will be created and stored
|
16
|
+
# in the new owner class (the original will remain unchanged).
|
17
|
+
def find_or_create(owner_class, *args, &block)
|
18
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
19
|
+
name = args.first || :state
|
20
|
+
|
21
|
+
# Find an existing machine
|
22
|
+
machine = owner_class.respond_to?(:state_machines) &&
|
23
|
+
(args.first && owner_class.state_machines[name] || !args.first &&
|
24
|
+
owner_class.state_machines.values.first) || nil
|
25
|
+
|
26
|
+
if machine
|
27
|
+
# Only create a new copy if changes are being made to the machine in
|
28
|
+
# a subclass
|
29
|
+
if machine.owner_class != owner_class && (options.any? || block_given?)
|
30
|
+
machine = machine.clone
|
31
|
+
machine.initial_state = options[:initial] if options.include?(:initial)
|
32
|
+
machine.owner_class = owner_class
|
33
|
+
end
|
34
|
+
|
35
|
+
# Evaluate DSL
|
36
|
+
machine.instance_eval(&block) if block_given?
|
37
|
+
else
|
38
|
+
# No existing machine: create a new one
|
39
|
+
machine = new(owner_class, name, options, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
machine
|
43
|
+
end
|
44
|
+
|
45
|
+
def draw(*)
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
# Default messages to use for validation errors in ORM integrations
|
50
|
+
attr_accessor :ignore_method_conflicts
|
51
|
+
|
52
|
+
def default_messages
|
53
|
+
@default_messages ||= {
|
54
|
+
invalid: 'is invalid',
|
55
|
+
invalid_event: 'cannot transition when %s',
|
56
|
+
invalid_transition: 'cannot transition via "%1$s"'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def default_messages=(messages)
|
61
|
+
@default_messages = messages
|
62
|
+
end
|
63
|
+
|
64
|
+
def replace_messages(message_hash)
|
65
|
+
message_hash.each do |key, value|
|
66
|
+
default_messages[key] = value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_writer :renderer
|
71
|
+
|
72
|
+
def renderer
|
73
|
+
return @renderer if @renderer
|
74
|
+
|
75
|
+
STDIORenderer
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|