state_machines 0.5.0 → 0.10.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 +34 -15
- data/lib/state_machines/assertions.rb +2 -0
- data/lib/state_machines/branch.rb +85 -81
- data/lib/state_machines/callback.rb +24 -21
- data/lib/state_machines/core.rb +2 -0
- 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 +35 -30
- 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 +381 -425
- data/lib/state_machines/machine_collection.rb +13 -10
- 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 +17 -13
- data/lib/state_machines/path.rb +58 -55
- data/lib/state_machines/path_collection.rb +37 -35
- data/lib/state_machines/state.rb +50 -38
- data/lib/state_machines/state_collection.rb +22 -19
- data/lib/state_machines/state_context.rb +35 -35
- data/lib/state_machines/stdio_renderer.rb +74 -0
- data/lib/state_machines/transition.rb +182 -178
- data/lib/state_machines/transition_collection.rb +172 -168
- data/lib/state_machines/version.rb +3 -1
- data/lib/state_machines.rb +4 -1
- metadata +10 -439
- 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/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 general strategy pattern for determining whether a match is found
|
3
5
|
# for a value. The algorithm that actually determines the match depends on
|
@@ -5,114 +7,115 @@ module StateMachines
|
|
5
7
|
class Matcher
|
6
8
|
# The list of values against which queries are matched
|
7
9
|
attr_reader :values
|
8
|
-
|
10
|
+
|
9
11
|
# Creates a new matcher for querying against the given set of values
|
10
12
|
def initialize(values = [])
|
11
13
|
@values = values.is_a?(Array) ? values : [values]
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
# Generates a subset of values that exists in both the set of values being
|
15
17
|
# filtered and the values configured for the matcher
|
16
18
|
def filter(values)
|
17
19
|
self.values & values
|
18
20
|
end
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
# Matches any given value. Since there is no configuration for this type of
|
22
24
|
# matcher, it must be used as a singleton.
|
23
25
|
class AllMatcher < Matcher
|
24
26
|
include Singleton
|
25
|
-
|
27
|
+
|
26
28
|
# Generates a blacklist matcher based on the given set of values
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# == Examples
|
29
|
-
#
|
31
|
+
#
|
30
32
|
# matcher = StateMachines::AllMatcher.instance - [:parked, :idling]
|
31
33
|
# matcher.matches?(:parked) # => false
|
32
34
|
# matcher.matches?(:first_gear) # => true
|
33
35
|
def -(blacklist)
|
34
36
|
BlacklistMatcher.new(blacklist)
|
35
37
|
end
|
36
|
-
|
38
|
+
alias_method :except, :-
|
39
|
+
|
37
40
|
# Always returns true
|
38
41
|
def matches?(value, context = {})
|
39
42
|
true
|
40
43
|
end
|
41
|
-
|
44
|
+
|
42
45
|
# Always returns the given set of values
|
43
46
|
def filter(values)
|
44
47
|
values
|
45
48
|
end
|
46
|
-
|
49
|
+
|
47
50
|
# A human-readable description of this matcher. Always "all".
|
48
51
|
def description
|
49
52
|
'all'
|
50
53
|
end
|
51
54
|
end
|
52
|
-
|
55
|
+
|
53
56
|
# Matches a specific set of values
|
54
57
|
class WhitelistMatcher < Matcher
|
55
58
|
# Checks whether the given value exists within the whitelist configured
|
56
59
|
# for this matcher.
|
57
|
-
#
|
60
|
+
#
|
58
61
|
# == Examples
|
59
|
-
#
|
62
|
+
#
|
60
63
|
# matcher = StateMachines::WhitelistMatcher.new([:parked, :idling])
|
61
64
|
# matcher.matches?(:parked) # => true
|
62
65
|
# matcher.matches?(:first_gear) # => false
|
63
66
|
def matches?(value, context = {})
|
64
67
|
values.include?(value)
|
65
68
|
end
|
66
|
-
|
69
|
+
|
67
70
|
# A human-readable description of this matcher
|
68
71
|
def description
|
69
72
|
values.length == 1 ? values.first.inspect : values.inspect
|
70
73
|
end
|
71
74
|
end
|
72
|
-
|
75
|
+
|
73
76
|
# Matches everything but a specific set of values
|
74
77
|
class BlacklistMatcher < Matcher
|
75
78
|
# Checks whether the given value exists outside the blacklist configured
|
76
79
|
# for this matcher.
|
77
|
-
#
|
80
|
+
#
|
78
81
|
# == Examples
|
79
|
-
#
|
82
|
+
#
|
80
83
|
# matcher = StateMachines::BlacklistMatcher.new([:parked, :idling])
|
81
84
|
# matcher.matches?(:parked) # => false
|
82
85
|
# matcher.matches?(:first_gear) # => true
|
83
86
|
def matches?(value, context = {})
|
84
87
|
!values.include?(value)
|
85
88
|
end
|
86
|
-
|
89
|
+
|
87
90
|
# Finds all values that are *not* within the blacklist configured for this
|
88
91
|
# matcher
|
89
92
|
def filter(values)
|
90
93
|
values - self.values
|
91
94
|
end
|
92
|
-
|
95
|
+
|
93
96
|
# A human-readable description of this matcher
|
94
97
|
def description
|
95
98
|
"all - #{values.length == 1 ? values.first.inspect : values.inspect}"
|
96
99
|
end
|
97
100
|
end
|
98
|
-
|
101
|
+
|
99
102
|
# Matches a loopback of two values within a context. Since there is no
|
100
103
|
# configuration for this type of matcher, it must be used as a singleton.
|
101
104
|
class LoopbackMatcher < Matcher
|
102
105
|
include Singleton
|
103
|
-
|
106
|
+
|
104
107
|
# Checks whether the given value matches what the value originally was.
|
105
108
|
# This value should be defined in the context.
|
106
|
-
#
|
109
|
+
#
|
107
110
|
# == Examples
|
108
|
-
#
|
111
|
+
#
|
109
112
|
# matcher = StateMachines::LoopbackMatcher.instance
|
110
113
|
# matcher.matches?(:parked, :from => :parked) # => true
|
111
114
|
# matcher.matches?(:parked, :from => :idling) # => false
|
112
115
|
def matches?(value, context)
|
113
116
|
context[:from] == value
|
114
117
|
end
|
115
|
-
|
118
|
+
|
116
119
|
# A human-readable description of this matcher. Always "same".
|
117
120
|
def description
|
118
121
|
'same'
|
@@ -1,25 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Provides a set of helper methods for generating matchers
|
3
5
|
module MatcherHelpers
|
4
6
|
# Represents a state that matches all known states in a machine.
|
5
|
-
#
|
7
|
+
#
|
6
8
|
# == Examples
|
7
|
-
#
|
9
|
+
#
|
8
10
|
# class Vehicle
|
9
11
|
# state_machine do
|
10
12
|
# before_transition any => :parked, :do => lambda {...}
|
11
13
|
# before_transition all - :parked => all - :idling, :do => lambda {}
|
12
|
-
#
|
14
|
+
#
|
13
15
|
# event :park
|
14
16
|
# transition all => :parked
|
15
17
|
# end
|
16
|
-
#
|
18
|
+
#
|
17
19
|
# event :crash
|
18
20
|
# transition all - :parked => :stalled
|
19
21
|
# end
|
20
22
|
# end
|
21
23
|
# end
|
22
|
-
#
|
24
|
+
#
|
23
25
|
# In the above example, +all+ will match the following states since they
|
24
26
|
# are known:
|
25
27
|
# * +parked+
|
@@ -29,12 +31,12 @@ module StateMachines
|
|
29
31
|
AllMatcher.instance
|
30
32
|
end
|
31
33
|
alias_method :any, :all
|
32
|
-
|
34
|
+
|
33
35
|
# Represents a state that matches the original +from+ state. This is useful
|
34
36
|
# for defining transitions which are loopbacks.
|
35
|
-
#
|
37
|
+
#
|
36
38
|
# == Examples
|
37
|
-
#
|
39
|
+
#
|
38
40
|
# class Vehicle
|
39
41
|
# state_machine do
|
40
42
|
# event :ignite
|
@@ -42,11 +44,11 @@ module StateMachines
|
|
42
44
|
# end
|
43
45
|
# end
|
44
46
|
# end
|
45
|
-
#
|
47
|
+
#
|
46
48
|
# In the above example, +same+ will match whichever the from state is. In
|
47
49
|
# the case of the +ignite+ event, it is essential the same as the following:
|
48
|
-
#
|
49
|
-
# transition :
|
50
|
+
#
|
51
|
+
# transition :idling => :idling, :first_gear => :first_gear
|
50
52
|
def same
|
51
53
|
LoopbackMatcher.instance
|
52
54
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Represents a collection of nodes in a state machine, be it events or states.
|
3
5
|
# Nodes will not differentiate between the String and Symbol versions of the
|
@@ -162,37 +164,39 @@ module StateMachines
|
|
162
164
|
self[key, index_name] || fail(IndexError, "#{key.inspect} is an invalid #{index_name}")
|
163
165
|
end
|
164
166
|
|
165
|
-
|
166
|
-
|
167
|
-
|
167
|
+
protected
|
168
|
+
|
169
|
+
# Gets the given index. If the index does not exist, then an ArgumentError
|
170
|
+
# is raised.
|
168
171
|
def index(name)
|
169
172
|
fail ArgumentError, 'No indices configured' unless @indices.any?
|
173
|
+
|
170
174
|
@indices[name] || fail(ArgumentError, "Invalid index: #{name.inspect}")
|
171
175
|
end
|
172
176
|
|
173
|
-
|
177
|
+
# Gets the value for the given attribute on the node
|
174
178
|
def value(node, attribute)
|
175
179
|
node.send(attribute)
|
176
180
|
end
|
177
181
|
|
178
|
-
|
179
|
-
|
182
|
+
# Adds the given key / node combination to an index, including the string
|
183
|
+
# and symbol versions of the index
|
180
184
|
def add_to_index(name, key, node)
|
181
185
|
index(name)[key] = node
|
182
186
|
index(:"#{name}_to_s")[key.to_s] = node
|
183
187
|
index(:"#{name}_to_sym")[:"#{key}"] = node if to_sym?(key)
|
184
188
|
end
|
185
189
|
|
186
|
-
|
187
|
-
|
190
|
+
# Removes the given key from an index, including the string and symbol
|
191
|
+
# versions of the index
|
188
192
|
def remove_from_index(name, key)
|
189
193
|
index(name).delete(key)
|
190
194
|
index(:"#{name}_to_s").delete(key.to_s)
|
191
195
|
index(:"#{name}_to_sym").delete(:"#{key}") if to_sym?(key)
|
192
196
|
end
|
193
197
|
|
194
|
-
|
195
|
-
|
198
|
+
# Updates the node for the given index, including the string and symbol
|
199
|
+
# versions of the index
|
196
200
|
def update_index(name, node)
|
197
201
|
index = self.index(name)
|
198
202
|
old_key = index.key(node)
|
@@ -205,13 +209,13 @@ module StateMachines
|
|
205
209
|
end
|
206
210
|
end
|
207
211
|
|
208
|
-
|
212
|
+
# Determines whether the given value can be converted to a symbol
|
209
213
|
def to_sym?(value)
|
210
214
|
"#{value}" != ''
|
211
215
|
end
|
212
216
|
|
213
|
-
|
214
|
-
|
217
|
+
# Evaluates the given context for a particular node. This will only
|
218
|
+
# evaluate the context if the node matches.
|
215
219
|
def eval_context(context, node)
|
216
220
|
node.context(&context[:block]) if context[:nodes].matches?(node.name)
|
217
221
|
end
|
data/lib/state_machines/path.rb
CHANGED
@@ -1,82 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# A path represents a sequence of transitions that can be run for a particular
|
3
5
|
# object. Paths can walk to new transitions, revealing all of the possible
|
4
6
|
# branches that can be encountered in the object's state machine.
|
5
7
|
class Path < Array
|
6
8
|
|
7
|
-
|
9
|
+
|
8
10
|
# The object whose state machine is being walked
|
9
11
|
attr_reader :object
|
10
|
-
|
12
|
+
|
11
13
|
# The state machine this path is walking
|
12
14
|
attr_reader :machine
|
13
|
-
|
15
|
+
|
14
16
|
# Creates a new transition path for the given object. Initially this is an
|
15
17
|
# empty path. In order to start walking the path, it must be populated with
|
16
18
|
# an initial transition.
|
17
|
-
#
|
19
|
+
#
|
18
20
|
# Configuration options:
|
19
21
|
# * <tt>:target</tt> - The target state to end the path on
|
20
22
|
# * <tt>:guard</tt> - Whether to guard transitions with the if/unless
|
21
23
|
# conditionals defined for each one
|
22
24
|
def initialize(object, machine, options = {})
|
23
25
|
options.assert_valid_keys(:target, :guard)
|
24
|
-
|
26
|
+
|
25
27
|
@object = object
|
26
28
|
@machine = machine
|
27
29
|
@target = options[:target]
|
28
30
|
@guard = options[:guard]
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
def initialize_copy(orig) #:nodoc:
|
32
34
|
super
|
33
35
|
@transitions = nil
|
34
36
|
end
|
35
|
-
|
37
|
+
|
36
38
|
# The initial state name for this path
|
37
39
|
def from_name
|
38
|
-
first
|
40
|
+
first&.from_name
|
39
41
|
end
|
40
|
-
|
42
|
+
|
41
43
|
# Lists all of the from states that can be reached through this path.
|
42
|
-
#
|
44
|
+
#
|
43
45
|
# For example,
|
44
|
-
#
|
46
|
+
#
|
45
47
|
# path.to_states # => [:parked, :idling, :first_gear, ...]
|
46
48
|
def from_states
|
47
|
-
map {|transition| transition.from_name}.uniq
|
49
|
+
map { |transition| transition.from_name }.uniq
|
48
50
|
end
|
49
|
-
|
51
|
+
|
50
52
|
# The end state name for this path. If a target state was specified for
|
51
53
|
# the path, then that will be returned if the path is complete.
|
52
54
|
def to_name
|
53
|
-
last
|
55
|
+
last&.to_name
|
54
56
|
end
|
55
|
-
|
57
|
+
|
56
58
|
# Lists all of the to states that can be reached through this path.
|
57
|
-
#
|
59
|
+
#
|
58
60
|
# For example,
|
59
|
-
#
|
61
|
+
#
|
60
62
|
# path.to_states # => [:parked, :idling, :first_gear, ...]
|
61
63
|
def to_states
|
62
|
-
map {|transition| transition.to_name}.uniq
|
64
|
+
map { |transition| transition.to_name }.uniq
|
63
65
|
end
|
64
|
-
|
66
|
+
|
65
67
|
# Lists all of the events that can be fired through this path.
|
66
|
-
#
|
68
|
+
#
|
67
69
|
# For example,
|
68
|
-
#
|
70
|
+
#
|
69
71
|
# path.events # => [:park, :ignite, :shift_up, ...]
|
70
72
|
def events
|
71
|
-
map {|transition| transition.event}.uniq
|
73
|
+
map { |transition| transition.event }.uniq
|
72
74
|
end
|
73
|
-
|
75
|
+
|
74
76
|
# Walks down the next transitions at the end of this path. This will only
|
75
77
|
# walk down paths that are considered valid.
|
76
78
|
def walk
|
77
|
-
transitions.each {|transition| yield dup.push(transition)}
|
79
|
+
transitions.each { |transition| yield dup.push(transition) }
|
78
80
|
end
|
79
|
-
|
81
|
+
|
80
82
|
# Determines whether or not this path has completed. A path is considered
|
81
83
|
# complete when one of the following conditions is met:
|
82
84
|
# * The last transition in the path ends on the target state
|
@@ -85,36 +87,37 @@ module StateMachines
|
|
85
87
|
def complete?
|
86
88
|
!empty? && (@target ? to_name == @target : transitions.empty?)
|
87
89
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
transitions.include?(transition)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Determines whether it's possible to walk to the given transition from
|
107
|
-
# the current path. A transition can be walked to if:
|
108
|
-
# * It has not been recently walked and
|
109
|
-
# * If a target is specified, it has not been walked to twice yet
|
110
|
-
def can_walk_to?(transition)
|
111
|
-
!recently_walked?(transition) && (!@target || times_walked_to(@target) < 2)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Get the next set of transitions that can be walked to starting from the
|
115
|
-
# end of this path
|
116
|
-
def transitions
|
117
|
-
@transitions ||= empty? ? [] : machine.events.transitions_for(object, :from => to_name, :guard => @guard).select {|transition| can_walk_to?(transition)}
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
# Calculates the number of times the given state has been walked to
|
94
|
+
def times_walked_to(state)
|
95
|
+
select { |transition| transition.to_name == state }.length
|
96
|
+
end
|
97
|
+
|
98
|
+
# Determines whether the given transition has been recently walked down in
|
99
|
+
# this path. If a target is configured for this path, then this will only
|
100
|
+
# look at transitions walked down since the target was last reached.
|
101
|
+
def recently_walked?(transition)
|
102
|
+
transitions = self
|
103
|
+
if @target && @target != to_name && (target_transition = detect { |t| t.to_name == @target })
|
104
|
+
transitions = transitions[index(target_transition) + 1..-1]
|
118
105
|
end
|
106
|
+
transitions.include?(transition)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Determines whether it's possible to walk to the given transition from
|
110
|
+
# the current path. A transition can be walked to if:
|
111
|
+
# * It has not been recently walked and
|
112
|
+
# * If a target is specified, it has not been walked to twice yet
|
113
|
+
def can_walk_to?(transition)
|
114
|
+
!recently_walked?(transition) && (!@target || times_walked_to(@target) < 2)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Get the next set of transitions that can be walked to starting from the
|
118
|
+
# end of this path
|
119
|
+
def transitions
|
120
|
+
@transitions ||= empty? ? [] : machine.events.transitions_for(object, from: to_name, guard: @guard).select { |transition| can_walk_to?(transition) }
|
121
|
+
end
|
119
122
|
end
|
120
123
|
end
|
@@ -1,23 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StateMachines
|
2
4
|
# Represents a collection of paths that are generated based on a set of
|
3
5
|
# requirements regarding what states to start and end on
|
4
6
|
class PathCollection < Array
|
5
7
|
|
6
|
-
|
7
8
|
# The object whose state machine is being walked
|
8
9
|
attr_reader :object
|
9
|
-
|
10
|
+
|
10
11
|
# The state machine these path are walking
|
11
12
|
attr_reader :machine
|
12
|
-
|
13
|
+
|
13
14
|
# The initial state to start each path from
|
14
15
|
attr_reader :from_name
|
15
|
-
|
16
|
+
|
16
17
|
# The target state for each path
|
17
18
|
attr_reader :to_name
|
18
|
-
|
19
|
+
|
19
20
|
# Creates a new collection of paths with the given requirements.
|
20
|
-
#
|
21
|
+
#
|
21
22
|
# Configuration options:
|
22
23
|
# * <tt>:from</tt> - The initial state to start from
|
23
24
|
# * <tt>:to</tt> - The target end state
|
@@ -25,64 +26,65 @@ module StateMachines
|
|
25
26
|
# * <tt>:guard</tt> - Whether to guard transitions with the if/unless
|
26
27
|
# conditionals defined for each one
|
27
28
|
def initialize(object, machine, options = {})
|
28
|
-
options = {:
|
29
|
+
options = {deep: false, from: machine.states.match!(object).name}.merge(options)
|
29
30
|
options.assert_valid_keys( :from, :to, :deep, :guard)
|
30
|
-
|
31
|
+
|
31
32
|
@object = object
|
32
33
|
@machine = machine
|
33
34
|
@from_name = machine.states.fetch(options[:from]).name
|
34
35
|
@to_name = options[:to] && machine.states.fetch(options[:to]).name
|
35
36
|
@guard = options[:guard]
|
36
37
|
@deep = options[:deep]
|
37
|
-
|
38
|
-
initial_paths.each {|path| walk(path)}
|
38
|
+
|
39
|
+
initial_paths.each { |path| walk(path) }
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
# Lists all of the states that can be transitioned from through the paths in
|
42
43
|
# this collection.
|
43
|
-
#
|
44
|
+
#
|
44
45
|
# For example,
|
45
|
-
#
|
46
|
+
#
|
46
47
|
# paths.from_states # => [:parked, :idling, :first_gear, ...]
|
47
48
|
def from_states
|
48
49
|
flat_map(&:from_states).uniq
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
# Lists all of the states that can be transitioned to through the paths in
|
52
53
|
# this collection.
|
53
|
-
#
|
54
|
+
#
|
54
55
|
# For example,
|
55
|
-
#
|
56
|
+
#
|
56
57
|
# paths.to_states # => [:idling, :first_gear, :second_gear, ...]
|
57
58
|
def to_states
|
58
59
|
flat_map(&:to_states).uniq
|
59
60
|
end
|
60
|
-
|
61
|
+
|
61
62
|
# Lists all of the events that can be fired through the paths in this
|
62
63
|
# collection.
|
63
|
-
#
|
64
|
+
#
|
64
65
|
# For example,
|
65
|
-
#
|
66
|
+
#
|
66
67
|
# paths.events # => [:park, :ignite, :shift_up, ...]
|
67
68
|
def events
|
68
69
|
flat_map(&:events).uniq
|
69
70
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
# Walks down the given path. Each new path that matches the configured
|
82
|
-
# requirements will be added to this collection.
|
83
|
-
def walk(path)
|
84
|
-
self << path if path.complete?
|
85
|
-
path.walk {|next_path| walk(next_path)} unless to_name && path.complete? && !@deep
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Gets the initial set of paths to walk
|
75
|
+
def initial_paths
|
76
|
+
machine.events.transitions_for(object, from: from_name, guard: @guard).map do |transition|
|
77
|
+
path = Path.new(object, machine, target: to_name, guard: @guard)
|
78
|
+
path << transition
|
79
|
+
path
|
86
80
|
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Walks down the given path. Each new path that matches the configured
|
84
|
+
# requirements will be added to this collection.
|
85
|
+
def walk(path)
|
86
|
+
self << path if path.complete?
|
87
|
+
path.walk { |next_path| walk(next_path) } unless to_name && path.complete? && !@deep
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|