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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5aa5d105c78cb53f15f42e8662dd7f8e0d0d5f8807b88dcbd8b4201f13718384
|
4
|
+
data.tar.gz: d761cedbe052c5c8829626e0875f54dce064f7156162119b4a040594b439068c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37398c9ca5f2de7413dfb7a8a467984d0fc4d47f8367ea0747fec6d9c1eaca5a7c3439f37988c02dd8ce27622a9a9e54cf5cc0b2d84404f00f92a862c168bb23
|
7
|
+
data.tar.gz: 159022534eb3c308bc2f2c8e960f111053631d3e10adafc9ae8156c95a26165f48690c682229a577bdfecf918b335ebe5b6d57e82e095c924585ad8d11b9d1ee
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
[](https://codeclimate.com/github/state-machines/state_machines)
|
1
|
+

|
3
2
|
# State Machines
|
4
3
|
|
5
4
|
State Machines adds support for creating state machines for attributes on any Ruby class.
|
@@ -237,6 +236,10 @@ vehicle.state_paths # => [[#<StateMachines
|
|
237
236
|
vehicle.state_paths.to_states # => [:parked, :idling, :first_gear, :stalled, :second_gear, :third_gear]
|
238
237
|
vehicle.state_paths.events # => [:park, :ignite, :shift_up, :idle, :crash, :repair, :shift_down]
|
239
238
|
|
239
|
+
# Possible states can be analyzed for a class
|
240
|
+
Vehicle.state_machine.states.to_a # [#<StateMachines::State name=:parked value="parked" initial=true>, #<StateMachines::State name=:idling value="idling" initial=false>, ...]
|
241
|
+
Vehicle.state_machines[:state].states.to_a # [#<StateMachines::State name=:parked value="parked" initial=true>, #<StateMachines::State name=:idling value="idling" initial=false>, ...]
|
242
|
+
|
240
243
|
# Find all paths that start and end on certain states
|
241
244
|
vehicle.state_paths(:from => :parked, :to => :first_gear) # => [[
|
242
245
|
# #<StateMachines:Transition attribute=:state event=:ignite from="parked" ...>,
|
@@ -251,6 +254,71 @@ vehicle.state_name # => :parked
|
|
251
254
|
# vehicle.state = :parked
|
252
255
|
```
|
253
256
|
|
257
|
+
## Testing
|
258
|
+
|
259
|
+
State Machines provides a `TestHelper` module with assertion methods to make testing state machines easier and more expressive.
|
260
|
+
|
261
|
+
### Setup
|
262
|
+
|
263
|
+
Include the test helper in your test class:
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
# For Minitest
|
267
|
+
class VehicleTest < Minitest::Test
|
268
|
+
include StateMachines::TestHelper
|
269
|
+
|
270
|
+
def test_initial_state
|
271
|
+
vehicle = Vehicle.new
|
272
|
+
assert_state vehicle, :state, :parked
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# For RSpec
|
277
|
+
RSpec.describe Vehicle do
|
278
|
+
include StateMachines::TestHelper
|
279
|
+
|
280
|
+
it "starts in parked state" do
|
281
|
+
vehicle = Vehicle.new
|
282
|
+
assert_state vehicle, :state, :parked
|
283
|
+
end
|
284
|
+
end
|
285
|
+
```
|
286
|
+
|
287
|
+
### Available Assertions
|
288
|
+
|
289
|
+
The TestHelper provides both basic assertions and comprehensive state machine-specific assertions with `sm_` prefixes:
|
290
|
+
|
291
|
+
#### Basic Assertions
|
292
|
+
|
293
|
+
```ruby
|
294
|
+
vehicle = Vehicle.new
|
295
|
+
assert_state vehicle, :state, :parked
|
296
|
+
assert_can_transition vehicle, :ignite
|
297
|
+
assert_cannot_transition vehicle, :shift_up
|
298
|
+
assert_transition vehicle, :ignite, :state, :idling
|
299
|
+
```
|
300
|
+
|
301
|
+
#### Extended State Machine Assertions
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
machine = Vehicle.state_machine(:state)
|
305
|
+
vehicle = Vehicle.new
|
306
|
+
|
307
|
+
# State configuration
|
308
|
+
assert_sm_states_list machine, [:parked, :idling, :stalled]
|
309
|
+
assert_sm_initial_state machine, :parked
|
310
|
+
|
311
|
+
# Event behavior
|
312
|
+
assert_sm_event_triggers vehicle, :ignite
|
313
|
+
refute_sm_event_triggers vehicle, :shift_up
|
314
|
+
assert_sm_event_raises_error vehicle, :invalid_event, StateMachines::InvalidTransition
|
315
|
+
|
316
|
+
# Persistence (with ActiveRecord integration)
|
317
|
+
assert_sm_state_persisted record, expected: :active
|
318
|
+
```
|
319
|
+
|
320
|
+
The test helper works with both Minitest and RSpec, automatically detecting your testing framework.
|
321
|
+
|
254
322
|
## Additional Topics
|
255
323
|
|
256
324
|
### Explicit vs. Implicit Event Transitions
|
@@ -424,7 +492,7 @@ easily migrate from a different library, you can do so as shown below:
|
|
424
492
|
```ruby
|
425
493
|
class Vehicle
|
426
494
|
state_machine initial: :parked do
|
427
|
-
...
|
495
|
+
# ...
|
428
496
|
|
429
497
|
state :parked do
|
430
498
|
transition to: :idling, :on => [:ignite, :shift_up], if: :seatbelt_on?
|
@@ -460,12 +528,11 @@ example below:
|
|
460
528
|
```ruby
|
461
529
|
class Vehicle
|
462
530
|
state_machine initial: :parked do
|
463
|
-
...
|
531
|
+
# ...
|
464
532
|
|
465
533
|
transition parked: :idling, :on => [:ignite, :shift_up]
|
466
534
|
transition first_gear: :second_gear, second_gear: :third_gear, on: :shift_up
|
467
535
|
transition [:idling, :first_gear] => :parked, on: :park
|
468
|
-
transition [:idling, :first_gear] => :parked, on: :park
|
469
536
|
transition all - [:parked, :stalled]: :stalled, unless: :auto_shop_busy?
|
470
537
|
end
|
471
538
|
end
|
@@ -493,12 +560,31 @@ class Vehicle
|
|
493
560
|
transition [:idling, :first_gear] => :parked
|
494
561
|
end
|
495
562
|
|
496
|
-
...
|
563
|
+
# ...
|
497
564
|
end
|
498
565
|
end
|
499
566
|
```
|
500
567
|
|
501
|
-
|
568
|
+
#### Draw state machines
|
569
|
+
|
570
|
+
State machines includes a default STDIORenderer for debugging state machines without external dependencies.
|
571
|
+
This renderer can be used to visualize the state machine in the console.
|
572
|
+
|
573
|
+
To use the renderer, simply call the `draw` method on the state machine:
|
574
|
+
|
575
|
+
```ruby
|
576
|
+
Vehicle.state_machine.draw # Outputs the state machine diagram to the console
|
577
|
+
```
|
578
|
+
|
579
|
+
You can customize the output by passing in options to the `draw` method, such as the output stream:
|
580
|
+
|
581
|
+
```ruby
|
582
|
+
Vehicle.state_machine.draw(io: $stderr) # Outputs the state machine diagram to stderr
|
583
|
+
```
|
584
|
+
|
585
|
+
#### Dynamic definitions
|
586
|
+
|
587
|
+
There may be cases where the definition of a state machine is **dynamic**.
|
502
588
|
This means that you don't know the possible states or events for a machine until
|
503
589
|
runtime. For example, you may allow users in your application to manage the
|
504
590
|
state machine of a project or task in your system. This means that the list of
|
@@ -563,7 +649,7 @@ end
|
|
563
649
|
vehicle = Vehicle.new # => #<Vehicle:0xb708412c @state="parked" ...>
|
564
650
|
vehicle.state # => "parked"
|
565
651
|
vehicle.machine.ignite # => true
|
566
|
-
vehicle.machine.state # => "idling
|
652
|
+
vehicle.machine.state # => "idling"
|
567
653
|
vehicle.state # => "idling"
|
568
654
|
vehicle.machine.state_transitions # => [#<StateMachines:Transition ...>]
|
569
655
|
vehicle.machine.definition.states.keys # => :first_gear, :second_gear, :parked, :idling
|
@@ -577,22 +663,19 @@ transitions.
|
|
577
663
|
|
578
664
|
Ruby versions officially supported and tested:
|
579
665
|
|
580
|
-
* Ruby (MRI)
|
581
|
-
* JRuby
|
582
|
-
* Rubinius
|
666
|
+
* Ruby (MRI) 3.0.0+
|
583
667
|
|
584
668
|
For graphing state machine:
|
585
669
|
|
586
|
-
* [state_machines-graphviz](
|
670
|
+
* [state_machines-graphviz](https://github.com/state-machines/state_machines-graphviz)
|
587
671
|
|
588
672
|
For documenting state machines:
|
589
673
|
|
590
|
-
* [state_machines-yard](
|
591
|
-
|
674
|
+
* [state_machines-yard](https://github.com/state-machines/state_machines-yard)
|
592
675
|
|
593
|
-
|
676
|
+
For RSpec testing, use the custom RSpec matchers:
|
594
677
|
|
595
|
-
*
|
678
|
+
* [state_machines-rspec](https://github.com/state-machines/state_machines-rspec)
|
596
679
|
|
597
680
|
## Contributing
|
598
681
|
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'options_validator'
|
4
|
+
|
1
5
|
module StateMachines
|
2
6
|
# Represents a set of requirements that must be met in order for a transition
|
3
7
|
# or callback to occur. Branches verify that the event, from state, and to
|
@@ -6,68 +10,68 @@ module StateMachines
|
|
6
10
|
class Branch
|
7
11
|
|
8
12
|
include EvalHelpers
|
9
|
-
|
13
|
+
|
10
14
|
# The condition that must be met on an object
|
11
15
|
attr_reader :if_condition
|
12
|
-
|
16
|
+
|
13
17
|
# The condition that must *not* be met on an object
|
14
18
|
attr_reader :unless_condition
|
15
|
-
|
19
|
+
|
16
20
|
# The requirement for verifying the event being matched
|
17
21
|
attr_reader :event_requirement
|
18
|
-
|
22
|
+
|
19
23
|
# One or more requirements for verifying the states being matched. All
|
20
24
|
# requirements contain a mapping of {:from => matcher, :to => matcher}.
|
21
25
|
attr_reader :state_requirements
|
22
|
-
|
26
|
+
|
23
27
|
# A list of all of the states known to this branch. This will pull states
|
24
28
|
# from the following options (in the same order):
|
25
29
|
# * +from+ / +except_from+
|
26
30
|
# * +to+ / +except_to+
|
27
31
|
attr_reader :known_states
|
28
|
-
|
32
|
+
|
29
33
|
# Creates a new branch
|
30
34
|
def initialize(options = {}) #:nodoc:
|
31
35
|
# Build conditionals
|
32
36
|
@if_condition = options.delete(:if)
|
33
37
|
@unless_condition = options.delete(:unless)
|
34
|
-
|
38
|
+
|
35
39
|
# Build event requirement
|
36
40
|
@event_requirement = build_matcher(options, :on, :except_on)
|
37
|
-
|
41
|
+
|
38
42
|
if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on]).empty?
|
39
43
|
# Explicit from/to requirements specified
|
40
|
-
@state_requirements = [{:
|
44
|
+
@state_requirements = [{from: build_matcher(options, :from, :except_from), to: build_matcher(options, :to, :except_to)}]
|
41
45
|
else
|
42
46
|
# Separate out the event requirement
|
43
47
|
options.delete(:on)
|
44
48
|
options.delete(:except_on)
|
45
|
-
|
49
|
+
|
46
50
|
# Implicit from/to requirements specified
|
47
51
|
@state_requirements = options.collect do |from, to|
|
48
52
|
from = WhitelistMatcher.new(from) unless from.is_a?(Matcher)
|
49
53
|
to = WhitelistMatcher.new(to) unless to.is_a?(Matcher)
|
50
|
-
{:
|
54
|
+
{from: from, to: to}
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
# Track known states. The order that requirements are iterated is based
|
55
59
|
# on the priority in which tracked states should be added.
|
56
60
|
@known_states = []
|
57
61
|
@state_requirements.each do |state_requirement|
|
58
|
-
[:from, :to].each {|option| @known_states |= state_requirement[option].values}
|
62
|
+
[:from, :to].each { |option| @known_states |= state_requirement[option].values }
|
59
63
|
end
|
60
64
|
end
|
61
|
-
|
65
|
+
|
62
66
|
# Determines whether the given object / query matches the requirements
|
63
67
|
# configured for this branch. In addition to matching the event, from state,
|
64
68
|
# and to state, this will also check whether the configured :if/:unless
|
65
69
|
# conditions pass on the given object.
|
66
|
-
#
|
70
|
+
#
|
67
71
|
# == Examples
|
68
|
-
#
|
72
|
+
#
|
69
73
|
# branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
|
70
|
-
#
|
74
|
+
#
|
71
75
|
# # Successful
|
72
76
|
# branch.matches?(object, :on => :ignite) # => true
|
73
77
|
# branch.matches?(object, :from => nil) # => true
|
@@ -75,7 +79,7 @@ module StateMachines
|
|
75
79
|
# branch.matches?(object, :to => :idling) # => true
|
76
80
|
# branch.matches?(object, :from => :parked, :to => :idling) # => true
|
77
81
|
# branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
|
78
|
-
#
|
82
|
+
#
|
79
83
|
# # Unsuccessful
|
80
84
|
# branch.matches?(object, :on => :park) # => false
|
81
85
|
# branch.matches?(object, :from => :idling) # => false
|
@@ -85,16 +89,16 @@ module StateMachines
|
|
85
89
|
def matches?(object, query = {})
|
86
90
|
!match(object, query).nil?
|
87
91
|
end
|
88
|
-
|
92
|
+
|
89
93
|
# Attempts to match the given object / query against the set of requirements
|
90
94
|
# configured for this branch. In addition to matching the event, from state,
|
91
95
|
# and to state, this will also check whether the configured :if/:unless
|
92
96
|
# conditions pass on the given object.
|
93
|
-
#
|
97
|
+
#
|
94
98
|
# If a match is found, then the event/state requirements that the query
|
95
99
|
# passed successfully will be returned. Otherwise, nil is returned if there
|
96
100
|
# was no match.
|
97
|
-
#
|
101
|
+
#
|
98
102
|
# Query options:
|
99
103
|
# * <tt>:from</tt> - One or more states being transitioned from. If none
|
100
104
|
# are specified, then this will always match.
|
@@ -104,80 +108,82 @@ module StateMachines
|
|
104
108
|
# are specified, then this will always match.
|
105
109
|
# * <tt>:guard</tt> - Whether to guard matches with the if/unless
|
106
110
|
# conditionals defined for this branch. Default is true.
|
107
|
-
#
|
111
|
+
#
|
108
112
|
# == Examples
|
109
|
-
#
|
113
|
+
#
|
110
114
|
# branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
|
111
|
-
#
|
115
|
+
#
|
112
116
|
# branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
|
113
117
|
# branch.match(object, :on => :park) # => nil
|
114
118
|
def match(object, query = {})
|
115
|
-
|
116
|
-
|
119
|
+
StateMachines::OptionsValidator.assert_valid_keys!(query, :from, :to, :on, :guard)
|
120
|
+
|
117
121
|
if (match = match_query(query)) && matches_conditions?(object, query)
|
118
122
|
match
|
119
123
|
end
|
120
124
|
end
|
121
125
|
|
122
|
-
def draw(graph, event, valid_states)
|
123
|
-
|
126
|
+
def draw(graph, event, valid_states, io = $stdout)
|
127
|
+
machine.renderer.draw_branch(self, graph, event, valid_states, io)
|
124
128
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
# Verifies that all configured requirements (event and state) match the
|
146
|
-
# given query. If a match is found, then a hash containing the
|
147
|
-
# event/state requirements that passed will be returned; otherwise, nil.
|
148
|
-
def match_query(query)
|
149
|
-
query ||= {}
|
150
|
-
|
151
|
-
if match_event(query) && (state_requirement = match_states(query))
|
152
|
-
state_requirement.merge(:on => event_requirement)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Verifies that the event requirement matches the given query
|
157
|
-
def match_event(query)
|
158
|
-
matches_requirement?(query, :on, event_requirement)
|
159
|
-
end
|
160
|
-
|
161
|
-
# Verifies that the state requirements match the given query. If a
|
162
|
-
# matching requirement is found, then it is returned.
|
163
|
-
def match_states(query)
|
164
|
-
state_requirements.detect do |state_requirement|
|
165
|
-
[:from, :to].all? {|option| matches_requirement?(query, option, state_requirement[option])}
|
166
|
-
end
|
129
|
+
|
130
|
+
protected
|
131
|
+
|
132
|
+
# Builds a matcher strategy to use for the given options. If neither a
|
133
|
+
# whitelist nor a blacklist option is specified, then an AllMatcher is
|
134
|
+
# built.
|
135
|
+
def build_matcher(options, whitelist_option, blacklist_option)
|
136
|
+
StateMachines::OptionsValidator.assert_exclusive_keys!(options, whitelist_option, blacklist_option)
|
137
|
+
|
138
|
+
if options.include?(whitelist_option)
|
139
|
+
value = options[whitelist_option]
|
140
|
+
value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
|
141
|
+
elsif options.include?(blacklist_option)
|
142
|
+
value = options[blacklist_option]
|
143
|
+
raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
|
144
|
+
|
145
|
+
BlacklistMatcher.new(value)
|
146
|
+
else
|
147
|
+
AllMatcher.instance
|
167
148
|
end
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
149
|
+
end
|
150
|
+
|
151
|
+
# Verifies that all configured requirements (event and state) match the
|
152
|
+
# given query. If a match is found, then a hash containing the
|
153
|
+
# event/state requirements that passed will be returned; otherwise, nil.
|
154
|
+
def match_query(query)
|
155
|
+
query ||= {}
|
156
|
+
|
157
|
+
if match_event(query) && (state_requirement = match_states(query))
|
158
|
+
state_requirement.merge(on: event_requirement)
|
173
159
|
end
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
160
|
+
end
|
161
|
+
|
162
|
+
# Verifies that the event requirement matches the given query
|
163
|
+
def match_event(query)
|
164
|
+
matches_requirement?(query, :on, event_requirement)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Verifies that the state requirements match the given query. If a
|
168
|
+
# matching requirement is found, then it is returned.
|
169
|
+
def match_states(query)
|
170
|
+
state_requirements.detect do |state_requirement|
|
171
|
+
[:from, :to].all? { |option| matches_requirement?(query, option, state_requirement[option]) }
|
181
172
|
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Verifies that an option in the given query matches the values required
|
176
|
+
# for that option
|
177
|
+
def matches_requirement?(query, option, requirement)
|
178
|
+
!query.include?(option) || requirement.matches?(query[option], query)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Verifies that the conditionals for this branch evaluate to true for the
|
182
|
+
# given object
|
183
|
+
def matches_conditions?(object, query)
|
184
|
+
query[:guard] == false ||
|
185
|
+
Array(if_condition).all? { |condition| evaluate_method(object, condition) } &&
|
186
|
+
!Array(unless_condition).any? { |condition| evaluate_method(object, condition) }
|
187
|
+
end
|
182
188
|
end
|
183
189
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'state_machines/branch'
|
2
4
|
require 'state_machines/eval_helpers'
|
3
5
|
|
@@ -16,38 +18,38 @@ module StateMachines
|
|
16
18
|
# the callback. This can be configured on an application-wide basis by
|
17
19
|
# setting this configuration to +true+ or +false+. The default value
|
18
20
|
# is +false+.
|
19
|
-
#
|
21
|
+
#
|
20
22
|
# *Note* that the DataMapper and Sequel integrations automatically
|
21
23
|
# configure this value on a per-callback basis, so it does not have to
|
22
24
|
# be enabled application-wide.
|
23
|
-
#
|
25
|
+
#
|
24
26
|
# == Examples
|
25
|
-
#
|
27
|
+
#
|
26
28
|
# When not bound to the object:
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# class Vehicle
|
29
31
|
# state_machine do
|
30
32
|
# before_transition do |vehicle|
|
31
33
|
# vehicle.set_alarm
|
32
34
|
# end
|
33
35
|
# end
|
34
|
-
#
|
36
|
+
#
|
35
37
|
# def set_alarm
|
36
38
|
# ...
|
37
39
|
# end
|
38
40
|
# end
|
39
|
-
#
|
41
|
+
#
|
40
42
|
# When bound to the object:
|
41
|
-
#
|
43
|
+
#
|
42
44
|
# StateMachines::Callback.bind_to_object = true
|
43
|
-
#
|
45
|
+
#
|
44
46
|
# class Vehicle
|
45
47
|
# state_machine do
|
46
48
|
# before_transition do
|
47
49
|
# self.set_alarm
|
48
50
|
# end
|
49
51
|
# end
|
50
|
-
#
|
52
|
+
#
|
51
53
|
# def set_alarm
|
52
54
|
# ...
|
53
55
|
# end
|
@@ -57,7 +59,7 @@ module StateMachines
|
|
57
59
|
# The application-wide terminator to use for callbacks when not
|
58
60
|
# explicitly defined. Terminators determine whether to cancel a
|
59
61
|
# callback chain based on the return value of the callback.
|
60
|
-
#
|
62
|
+
#
|
61
63
|
# See StateMachines::Callback#terminator for more information.
|
62
64
|
attr_accessor :terminator
|
63
65
|
end
|
@@ -75,11 +77,11 @@ module StateMachines
|
|
75
77
|
# chain never cancels based on the return value (i.e. there is no implicit
|
76
78
|
# terminator). Certain integrations, such as ActiveRecord and Sequel,
|
77
79
|
# change this default value.
|
78
|
-
#
|
80
|
+
#
|
79
81
|
# == Examples
|
80
|
-
#
|
82
|
+
#
|
81
83
|
# Canceling the callback chain without a terminator:
|
82
|
-
#
|
84
|
+
#
|
83
85
|
# class Vehicle
|
84
86
|
# state_machine do
|
85
87
|
# before_transition do |vehicle|
|
@@ -87,9 +89,9 @@ module StateMachines
|
|
87
89
|
# end
|
88
90
|
# end
|
89
91
|
# end
|
90
|
-
#
|
92
|
+
#
|
91
93
|
# Canceling the callback chain with a terminator value of +false+:
|
92
|
-
#
|
94
|
+
#
|
93
95
|
# class Vehicle
|
94
96
|
# state_machine do
|
95
97
|
# before_transition do |vehicle|
|
@@ -102,13 +104,13 @@ module StateMachines
|
|
102
104
|
# The branch that determines whether or not this callback can be invoked
|
103
105
|
# based on the context of the transition. The event, from state, and
|
104
106
|
# to state must all match in order for the branch to pass.
|
105
|
-
#
|
107
|
+
#
|
106
108
|
# See StateMachines::Branch for more information.
|
107
109
|
attr_reader :branch
|
108
110
|
|
109
111
|
# Creates a new callback that can get called based on the configured
|
110
112
|
# options.
|
111
|
-
#
|
113
|
+
#
|
112
114
|
# In addition to the possible configuration options for branches, the
|
113
115
|
# following options can be configured:
|
114
116
|
# * <tt>:bind_to_object</tt> - Whether to bind the callback to the object involved.
|
@@ -117,7 +119,7 @@ module StateMachines
|
|
117
119
|
# * <tt>:terminator</tt> - A block/proc that determines what callback
|
118
120
|
# results should cause the callback chain to halt (if not using the
|
119
121
|
# default <tt>throw :halt</tt> technique).
|
120
|
-
#
|
122
|
+
#
|
121
123
|
# More information about how those options affect the behavior of the
|
122
124
|
# callback can be found in their attribute definitions.
|
123
125
|
def initialize(type, *args, &block)
|
@@ -130,7 +132,7 @@ module StateMachines
|
|
130
132
|
@methods << block if block_given?
|
131
133
|
raise ArgumentError, 'Method(s) for callback must be specified' unless @methods.any?
|
132
134
|
|
133
|
-
options = {:
|
135
|
+
options = {bind_to_object: self.class.bind_to_object, terminator: self.class.terminator}.merge(options)
|
134
136
|
|
135
137
|
# Proxy lambda blocks so that they're bound to the object
|
136
138
|
bind_to_object = options.delete(:bind_to_object)
|
@@ -151,7 +153,7 @@ module StateMachines
|
|
151
153
|
# Runs the callback as long as the transition context matches the branch
|
152
154
|
# requirements configured for this callback. If a block is provided, it
|
153
155
|
# will be called when the last method has run.
|
154
|
-
#
|
156
|
+
#
|
155
157
|
# If a terminator has been configured and it matches the result from the
|
156
158
|
# evaluated method, then the callback chain should be halted.
|
157
159
|
def call(object, context = {}, *args, &block)
|
@@ -163,7 +165,8 @@ module StateMachines
|
|
163
165
|
end
|
164
166
|
end
|
165
167
|
|
166
|
-
|
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
|
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'
|
@@ -40,4 +41,4 @@ require 'state_machines/path_collection'
|
|
40
41
|
require 'state_machines/machine'
|
41
42
|
require 'state_machines/machine_collection'
|
42
43
|
|
43
|
-
require 'state_machines/macro_methods'
|
44
|
+
require 'state_machines/macro_methods'
|