decouplio 1.0.0alpha1 → 1.0.0alpha2
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 +4 -4
- data/.rubocop.yml +4 -0
- data/README.md +26 -2
- data/benchmarks/Gemfile +2 -1
- data/benchmarks/multi_step_benchmark.rb +335 -0
- data/benchmarks/single_step_benchmark.rb +159 -0
- data/docker-compose.yml +13 -2
- data/docs/deny.rb +59 -0
- data/docs/doby.rb +1 -1
- data/docs/doby_deny.md +171 -0
- data/docs/fail.md +143 -0
- data/docs/fail.rb +126 -29
- data/docs/resq.md +2 -2
- data/docs/step.md +148 -0
- data/docs/step.rb +119 -18
- data/docs/step_as_a_service.md +25 -11
- data/docs/step_as_a_service.rb +2 -2
- data/docs/wrap.md +8 -0
- data/lib/decouplio/action.rb +22 -3
- data/lib/decouplio/composer.rb +78 -12
- data/lib/decouplio/const/reserved_methods.rb +13 -9
- data/lib/decouplio/const/results.rb +2 -0
- data/lib/decouplio/const/types.rb +11 -5
- data/lib/decouplio/const/validations/deny.rb +11 -0
- data/lib/decouplio/const/validations/fail.rb +1 -1
- data/lib/decouplio/errors/deny_can_not_be_first_step_error.rb +18 -0
- data/lib/decouplio/errors/{fail_is_first_step_error.rb → fail_can_not_be_first_step_error.rb} +1 -1
- data/lib/decouplio/logic_dsl.rb +14 -2
- data/lib/decouplio/options_validator.rb +8 -3
- data/lib/decouplio/steps/deny.rb +31 -0
- data/lib/decouplio/steps/doby.rb +5 -1
- data/lib/decouplio/steps/fail.rb +7 -22
- data/lib/decouplio/steps/inner_action_fail.rb +7 -22
- data/lib/decouplio/steps/inner_action_step.rb +7 -18
- data/lib/decouplio/steps/service_fail.rb +11 -23
- data/lib/decouplio/steps/service_pass.rb +4 -1
- data/lib/decouplio/steps/service_step.rb +11 -19
- data/lib/decouplio/steps/shared/fail_resolver.rb +40 -0
- data/lib/decouplio/steps/shared/step_resolver.rb +43 -0
- data/lib/decouplio/steps/step.rb +7 -18
- data/lib/decouplio/steps/wrap.rb +7 -18
- data/lib/decouplio/version.rb +1 -1
- metadata +12 -5
- data/benchmarks/benchmarks.rb +0 -527
- data/docs/doby.md +0 -80
    
        data/docs/doby_deny.md
    ADDED
    
    | @@ -0,0 +1,171 @@ | |
| 1 | 
            +
            # Doby/Deny
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            It's a step type to make configurable manipulations with action context.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            ## Signature
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            ```ruby
         | 
| 9 | 
            +
            doby(class_constant, **options)
         | 
| 10 | 
            +
            deny(class_constant, **options)
         | 
| 11 | 
            +
            ```
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## Behavior
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ### Doby
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            - `doby` behaves similar to `step`, depending on `.call` method returning value(truthy or falsy) the execution will be moved to `success or failure` track accordingly.
         | 
| 18 | 
            +
            - `doby` doesn't have `on_success, on_failure, if, unless, finish_him` options.
         | 
| 19 | 
            +
            - All options passed after class constant will be passed as kwargs for `.call` method.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            ### Deny
         | 
| 22 | 
            +
            - `deny` behaves similar to `fail`, no matter which value will be returned by `.call` method, it moves to `failure` track.
         | 
| 23 | 
            +
            - `deny` doesn't have `on_success, on_failure, if, unless, finish_him` options.
         | 
| 24 | 
            +
            - All options passed after class constant will be passed as kwargs for `.call` method.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## How to use?
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Create the ruby class which has `.call` class method.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            `.call` method signature:
         | 
| 32 | 
            +
            ```ruby
         | 
| 33 | 
            +
            # :ctx - it's a ctx from Decouplio::Action
         | 
| 34 | 
            +
            # :error_store - it's an error_store from Decouplio::Action
         | 
| 35 | 
            +
            #                you can call #add_error method on it.
         | 
| 36 | 
            +
            # ** - kwargs passed from action.
         | 
| 37 | 
            +
            def self.call(ctx:, error_store:, **)
         | 
| 38 | 
            +
            end
         | 
| 39 | 
            +
            ```
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            ```ruby
         | 
| 42 | 
            +
            class AssignDoby
         | 
| 43 | 
            +
              def self.call(ctx:, to:, from: nil, value: nil, **)
         | 
| 44 | 
            +
                raise 'from/value is empty' unless from || value
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                ctx[to] = value || ctx[from]
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            # OR
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            class SemanticDeny
         | 
| 53 | 
            +
              def self.call(ctx:, error_store:, semantic:, error_message:)
         | 
| 54 | 
            +
                ctx[:semantic] = semantic
         | 
| 55 | 
            +
                error_store.add_error(semantic, error_message)
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            # OR
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            # If you don't need ctx and error_store, you can omit them
         | 
| 62 | 
            +
            class DummyDoby
         | 
| 63 | 
            +
              def self.call(dummy:, **)
         | 
| 64 | 
            +
                puts dummy
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
            ```
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            `AssignDoby` example.
         | 
| 70 | 
            +
            ```ruby
         | 
| 71 | 
            +
            require 'decouplio'
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            class AssignDoby
         | 
| 74 | 
            +
              def self.call(ctx:, to:, from: nil, value: nil, **)
         | 
| 75 | 
            +
                raise 'from/value is empty' unless from || value
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                ctx[to] = value || ctx[from]
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            class SomeAction < Decouplio::Action
         | 
| 82 | 
            +
              logic do
         | 
| 83 | 
            +
                step :user
         | 
| 84 | 
            +
                step AssignDoby, to: :current_user, from: :user
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
              def user(id:, **)
         | 
| 88 | 
            +
                ctx[:user] = "User with id: #{id}"
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
            end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
            action = SomeAction.call(id: 1)
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            action[:user] # => "User with id: 1"
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            action[:current_user] # => "User with id: 1"
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            action # =>
         | 
| 99 | 
            +
            # Result: success
         | 
| 100 | 
            +
             | 
| 101 | 
            +
            # Railway Flow:
         | 
| 102 | 
            +
            #   user -> AssignDoby
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            # Context:
         | 
| 105 | 
            +
            #   {:id=>1, :user=>"User with id: 1", :current_user=>"User with id: 1"}
         | 
| 106 | 
            +
             | 
| 107 | 
            +
            # Errors:
         | 
| 108 | 
            +
            #   {}
         | 
| 109 | 
            +
            ```
         | 
| 110 | 
            +
            `SemanticDeny` example.
         | 
| 111 | 
            +
            ```ruby
         | 
| 112 | 
            +
            require 'decouplio'
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            class SemanticDeny
         | 
| 115 | 
            +
              def self.call(ctx:, error_store:, semantic:, error_message:)
         | 
| 116 | 
            +
                ctx[:semantic] = semantic
         | 
| 117 | 
            +
                error_store.add_error(semantic, error_message)
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
            end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
            class SomeAction < Decouplio::Action
         | 
| 122 | 
            +
              logic do
         | 
| 123 | 
            +
                step :step_one
         | 
| 124 | 
            +
                deny SemanticDeny, semantic: :bad_request, error_message: 'Bad request'
         | 
| 125 | 
            +
                step :step_two
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
              def step_one(step_one_param:, **)
         | 
| 129 | 
            +
                ctx[:step_one] = step_one_param
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              def step_two(**)
         | 
| 133 | 
            +
                ctx[:step_two] = 'Success'
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
              def fail_one(**)
         | 
| 137 | 
            +
                ctx[:fail_one] = 'Failure'
         | 
| 138 | 
            +
              end
         | 
| 139 | 
            +
            end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            success_action = SomeAction.call(step_one_param: true)
         | 
| 142 | 
            +
            failure_action = SomeAction.call(step_one_param: false)
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            success_action # =>
         | 
| 145 | 
            +
            # Result: success
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            # Railway Flow:
         | 
| 148 | 
            +
            #   step_one -> step_two
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            # Context:
         | 
| 151 | 
            +
            #   :step_one_param => true
         | 
| 152 | 
            +
            #   :step_one => true
         | 
| 153 | 
            +
            #   :step_two => "Success"
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            # Errors:
         | 
| 156 | 
            +
            #   None
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            failure_action # =>
         | 
| 159 | 
            +
            # Result: failure
         | 
| 160 | 
            +
             | 
| 161 | 
            +
            # Railway Flow:
         | 
| 162 | 
            +
            #   step_one -> SemanticDeny
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            # Context:
         | 
| 165 | 
            +
            #   :step_one_param => false
         | 
| 166 | 
            +
            #   :step_one => false
         | 
| 167 | 
            +
            #   :semantic => :bad_request
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            # Errors:
         | 
| 170 | 
            +
            #   :bad_request => ["Bad request"]
         | 
| 171 | 
            +
            ```
         | 
    
        data/docs/fail.md
    CHANGED
    
    | @@ -88,6 +88,8 @@ fail(step_name, **options) | |
| 88 88 | 
             
            |-|-|
         | 
| 89 89 | 
             
            |:finish_him|action stops execution if `fail` method returns truthy value|
         | 
| 90 90 | 
             
            |symbol with next step name|step with specified symbol name performs if step method returns truthy value|
         | 
| 91 | 
            +
            |:PASS|will direct execution flow to nearest success track step. If current step is the last step when action will finish as `success`|
         | 
| 92 | 
            +
            |:FAIL|will direct execution flow to nearest failure track step. If current step is the last step when action will finish as `failure`|
         | 
| 91 93 |  | 
| 92 94 | 
             
            ### on_success: :finish_him
         | 
| 93 95 |  | 
| @@ -387,11 +389,83 @@ fail(step_name, **options) | |
| 387 389 |  | 
| 388 390 | 
             
            ***
         | 
| 389 391 |  | 
| 392 | 
            +
            ### on_success: :PASS
         | 
| 393 | 
            +
            <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
         | 
| 394 | 
            +
            <p>
         | 
| 395 | 
            +
             | 
| 396 | 
            +
              ```ruby
         | 
| 397 | 
            +
                require 'decouplio'
         | 
| 398 | 
            +
                class SomeActionOnSuccessPass < Decouplio::Action
         | 
| 399 | 
            +
                  logic do
         | 
| 400 | 
            +
                    step :step_one
         | 
| 401 | 
            +
                    fail :fail_one, on_success: :PASS
         | 
| 402 | 
            +
                  end
         | 
| 403 | 
            +
             | 
| 404 | 
            +
                  def step_one(**)
         | 
| 405 | 
            +
                    ctx[:step_one] = false
         | 
| 406 | 
            +
                  end
         | 
| 407 | 
            +
             | 
| 408 | 
            +
                  def fail_one(fail_one_param:, **)
         | 
| 409 | 
            +
                    ctx[:fail_one] = fail_one_param
         | 
| 410 | 
            +
                  end
         | 
| 411 | 
            +
                end
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                fail_step_success = SomeActionOnSuccessPass.call(fail_one_param: true)
         | 
| 414 | 
            +
                fail_step_failure = SomeActionOnSuccessPass.call(fail_one_param: false)
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                fail_step_success # =>
         | 
| 417 | 
            +
                # Result: success
         | 
| 418 | 
            +
             | 
| 419 | 
            +
                # Railway Flow:
         | 
| 420 | 
            +
                #   step_one -> fail_one
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                # Context:
         | 
| 423 | 
            +
                #   :fail_one_param => true
         | 
| 424 | 
            +
                #   :step_one => false
         | 
| 425 | 
            +
                #   :fail_one => true
         | 
| 426 | 
            +
             | 
| 427 | 
            +
                # Errors:
         | 
| 428 | 
            +
                #   {}
         | 
| 429 | 
            +
             | 
| 430 | 
            +
                fail_step_failure # =>
         | 
| 431 | 
            +
                # Result: failure
         | 
| 432 | 
            +
             | 
| 433 | 
            +
                # Railway Flow:
         | 
| 434 | 
            +
                #   step_one -> fail_one
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                # Context:
         | 
| 437 | 
            +
                #   :fail_one_param => false
         | 
| 438 | 
            +
                #   :step_one => false
         | 
| 439 | 
            +
                #   :fail_one => false
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                # Errors:
         | 
| 442 | 
            +
                #   {}
         | 
| 443 | 
            +
              ```
         | 
| 444 | 
            +
             | 
| 445 | 
            +
              ```mermaid
         | 
| 446 | 
            +
              flowchart LR
         | 
| 447 | 
            +
                  1(start)-->2(step_one);
         | 
| 448 | 
            +
                  2(step_one)-->|failure track|3(fail_one);
         | 
| 449 | 
            +
                  3(fail_one)-->|on_success: :PASS|5(finish_success);
         | 
| 450 | 
            +
                  3(fail_one)-->|failure track|4(finish_failure);
         | 
| 451 | 
            +
              ```
         | 
| 452 | 
            +
            </p>
         | 
| 453 | 
            +
            </details>
         | 
| 454 | 
            +
             | 
| 455 | 
            +
            ***
         | 
| 456 | 
            +
             | 
| 457 | 
            +
            ### on_success: :FAIL
         | 
| 458 | 
            +
            It will perform like regular `fail` step, just move to next failure track step.
         | 
| 459 | 
            +
             | 
| 460 | 
            +
            ***
         | 
| 461 | 
            +
             | 
| 390 462 | 
             
            ### on_failure:
         | 
| 391 463 | 
             
            |Allowed values|Description|
         | 
| 392 464 | 
             
            |-|-|
         | 
| 393 465 | 
             
            |:finish_him|action stops execution if `fail` method returns falsy value|
         | 
| 394 466 | 
             
            |symbol with next step name|step with specified symbol name performs if step method returns falsy value|
         | 
| 467 | 
            +
            |:PASS|will direct execution flow to nearest success track step. If current step is the last step when action will finish as `success`|
         | 
| 468 | 
            +
            |:FAIL|will direct execution flow to nearest failure track step. If current step is the last step when action will finish as `failure`|
         | 
| 395 469 |  | 
| 396 470 | 
             
            ### on_failure: :finish_him
         | 
| 397 471 |  | 
| @@ -693,6 +767,75 @@ fail(step_name, **options) | |
| 693 767 |  | 
| 694 768 | 
             
            ***
         | 
| 695 769 |  | 
| 770 | 
            +
            ### on_failure: :PASS
         | 
| 771 | 
            +
             | 
| 772 | 
            +
            <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
         | 
| 773 | 
            +
            <p>
         | 
| 774 | 
            +
             | 
| 775 | 
            +
              ```ruby
         | 
| 776 | 
            +
                require 'decouplio'
         | 
| 777 | 
            +
              class SomeActionOnFailurePass < Decouplio::Action
         | 
| 778 | 
            +
                logic do
         | 
| 779 | 
            +
                  step :step_one
         | 
| 780 | 
            +
                  fail :fail_one, on_failure: :PASS
         | 
| 781 | 
            +
                end
         | 
| 782 | 
            +
             | 
| 783 | 
            +
                def step_one(**)
         | 
| 784 | 
            +
                  false
         | 
| 785 | 
            +
                end
         | 
| 786 | 
            +
             | 
| 787 | 
            +
                def fail_one(fail_one_param:, **)
         | 
| 788 | 
            +
                  ctx[:fail_one] = fail_one_param
         | 
| 789 | 
            +
                end
         | 
| 790 | 
            +
              end
         | 
| 791 | 
            +
             | 
| 792 | 
            +
              fail_step_success = SomeActionOnFailurePass.call(fail_one_param: true)
         | 
| 793 | 
            +
              fail_step_failure = SomeActionOnFailurePass.call(fail_one_param: false)
         | 
| 794 | 
            +
             | 
| 795 | 
            +
              fail_step_success # =>
         | 
| 796 | 
            +
              # Result: failure
         | 
| 797 | 
            +
             | 
| 798 | 
            +
              # Railway Flow:
         | 
| 799 | 
            +
              #   step_one -> fail_one
         | 
| 800 | 
            +
             | 
| 801 | 
            +
              # Context:
         | 
| 802 | 
            +
              #   :fail_one_param => true
         | 
| 803 | 
            +
              #   :fail_one => true
         | 
| 804 | 
            +
             | 
| 805 | 
            +
              # Errors:
         | 
| 806 | 
            +
              #   {}
         | 
| 807 | 
            +
             | 
| 808 | 
            +
              fail_step_failure # =>
         | 
| 809 | 
            +
              # Result: success
         | 
| 810 | 
            +
             | 
| 811 | 
            +
              # Railway Flow:
         | 
| 812 | 
            +
              #   step_one -> fail_one
         | 
| 813 | 
            +
             | 
| 814 | 
            +
              # Context:
         | 
| 815 | 
            +
              #   :fail_one_param => false
         | 
| 816 | 
            +
              #   :fail_one => false
         | 
| 817 | 
            +
             | 
| 818 | 
            +
              # Errors:
         | 
| 819 | 
            +
              #   {}
         | 
| 820 | 
            +
              ```
         | 
| 821 | 
            +
             | 
| 822 | 
            +
              ```mermaid
         | 
| 823 | 
            +
              flowchart LR
         | 
| 824 | 
            +
                  1(start)-->2(step_one);
         | 
| 825 | 
            +
                  2(step_one)-->|failure track|3(fail_one);
         | 
| 826 | 
            +
                  3(fail_one)-->|failure track|4(finish_failure);
         | 
| 827 | 
            +
                  3(fail_one)-->|on_failure: :PASS|5(finish_success);
         | 
| 828 | 
            +
              ```
         | 
| 829 | 
            +
            </p>
         | 
| 830 | 
            +
            </details>
         | 
| 831 | 
            +
             | 
| 832 | 
            +
            ***
         | 
| 833 | 
            +
             | 
| 834 | 
            +
            ### on_failure: :FAIL
         | 
| 835 | 
            +
            It will perform like regular `fail` step, just move to next failure track step.
         | 
| 836 | 
            +
             | 
| 837 | 
            +
            ***
         | 
| 838 | 
            +
             | 
| 696 839 | 
             
            ### if: condition method name
         | 
| 697 840 | 
             
            Can be used in case if for some reason step shouldn't be executed
         | 
| 698 841 |  | 
    
        data/docs/fail.rb
    CHANGED
    
    | @@ -26,7 +26,7 @@ end | |
| 26 26 | 
             
            success_action = SomeAction.call(param_for_step_one: true)
         | 
| 27 27 | 
             
            failure_action = SomeAction.call(param_for_step_one: false)
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 29 | 
            +
            success_action # =>
         | 
| 30 30 | 
             
            # Result: success
         | 
| 31 31 |  | 
| 32 32 | 
             
            # Railway Flow:
         | 
| @@ -39,7 +39,7 @@ puts success_action # => | |
| 39 39 | 
             
            #   {}
         | 
| 40 40 |  | 
| 41 41 |  | 
| 42 | 
            -
             | 
| 42 | 
            +
            failure_action # =>
         | 
| 43 43 | 
             
            # Result: failure
         | 
| 44 44 |  | 
| 45 45 | 
             
            # Railway Flow:
         | 
| @@ -86,7 +86,7 @@ fail_step_failure = SomeActionOnSuccessFinishHim.call( | |
| 86 86 | 
             
              fail_one_param: false
         | 
| 87 87 | 
             
            )
         | 
| 88 88 |  | 
| 89 | 
            -
             | 
| 89 | 
            +
            success_action # =>
         | 
| 90 90 | 
             
            # Result: success
         | 
| 91 91 |  | 
| 92 92 | 
             
            # Railway Flow:
         | 
| @@ -98,7 +98,7 @@ puts success_action # => | |
| 98 98 | 
             
            # Errors:
         | 
| 99 99 | 
             
            #   {}
         | 
| 100 100 |  | 
| 101 | 
            -
             | 
| 101 | 
            +
            fail_step_success # =>
         | 
| 102 102 | 
             
            # Result: failure
         | 
| 103 103 |  | 
| 104 104 | 
             
            # Railway Flow:
         | 
| @@ -110,7 +110,7 @@ puts fail_step_success # => | |
| 110 110 | 
             
            # Errors:
         | 
| 111 111 | 
             
            #   {}
         | 
| 112 112 |  | 
| 113 | 
            -
             | 
| 113 | 
            +
            fail_step_failure  # =>
         | 
| 114 114 | 
             
            # Result: failure
         | 
| 115 115 |  | 
| 116 116 | 
             
            # Railway Flow:
         | 
| @@ -162,7 +162,7 @@ fail_step_failure = SomeActionOnSuccessToSuccessTrack.call( | |
| 162 162 | 
             
              fail_one_param: false
         | 
| 163 163 | 
             
            )
         | 
| 164 164 |  | 
| 165 | 
            -
             | 
| 165 | 
            +
            success_action # =>
         | 
| 166 166 | 
             
            # Result: success
         | 
| 167 167 |  | 
| 168 168 | 
             
            # Railway Flow:
         | 
| @@ -174,7 +174,7 @@ puts success_action # => | |
| 174 174 | 
             
            # Errors:
         | 
| 175 175 | 
             
            #   {}
         | 
| 176 176 |  | 
| 177 | 
            -
             | 
| 177 | 
            +
            fail_step_success # =>
         | 
| 178 178 | 
             
            # Result: success
         | 
| 179 179 |  | 
| 180 180 | 
             
            # Railway Flow:
         | 
| @@ -186,7 +186,7 @@ puts fail_step_success # => | |
| 186 186 | 
             
            # Errors:
         | 
| 187 187 | 
             
            #   {}
         | 
| 188 188 |  | 
| 189 | 
            -
             | 
| 189 | 
            +
            fail_step_failure  # =>
         | 
| 190 190 | 
             
            # Result: failure
         | 
| 191 191 |  | 
| 192 192 | 
             
            # Railway Flow:
         | 
| @@ -243,7 +243,7 @@ fail_step_failure = SomeActionOnSuccessToFailureTrack.call( | |
| 243 243 | 
             
              fail_one_param: false
         | 
| 244 244 | 
             
            )
         | 
| 245 245 |  | 
| 246 | 
            -
             | 
| 246 | 
            +
            success_action # =>
         | 
| 247 247 | 
             
            # Result: success
         | 
| 248 248 |  | 
| 249 249 | 
             
            # Railway Flow:
         | 
| @@ -256,7 +256,7 @@ puts success_action # => | |
| 256 256 | 
             
            #   {}
         | 
| 257 257 |  | 
| 258 258 |  | 
| 259 | 
            -
             | 
| 259 | 
            +
            fail_step_success # =>
         | 
| 260 260 | 
             
            # Result: failure
         | 
| 261 261 |  | 
| 262 262 | 
             
            # Railway Flow:
         | 
| @@ -269,7 +269,7 @@ puts fail_step_success # => | |
| 269 269 | 
             
            #   {}
         | 
| 270 270 |  | 
| 271 271 |  | 
| 272 | 
            -
             | 
| 272 | 
            +
            fail_step_failure  # =>
         | 
| 273 273 | 
             
            # Result: failure
         | 
| 274 274 |  | 
| 275 275 | 
             
            # Railway Flow:
         | 
| @@ -283,6 +283,56 @@ puts fail_step_failure  # => | |
| 283 283 |  | 
| 284 284 |  | 
| 285 285 |  | 
| 286 | 
            +
            # on_success: :PASS
         | 
| 287 | 
            +
            class SomeActionOnSuccessPass < Decouplio::Action
         | 
| 288 | 
            +
              logic do
         | 
| 289 | 
            +
                step :step_one
         | 
| 290 | 
            +
                fail :fail_one, on_success: :PASS
         | 
| 291 | 
            +
              end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
              def step_one(**)
         | 
| 294 | 
            +
                ctx[:step_one] = false
         | 
| 295 | 
            +
              end
         | 
| 296 | 
            +
             | 
| 297 | 
            +
              def fail_one(fail_one_param:, **)
         | 
| 298 | 
            +
                ctx[:fail_one] = fail_one_param
         | 
| 299 | 
            +
              end
         | 
| 300 | 
            +
            end
         | 
| 301 | 
            +
             | 
| 302 | 
            +
            fail_step_success = SomeActionOnSuccessPass.call(fail_one_param: true)
         | 
| 303 | 
            +
            fail_step_failure = SomeActionOnSuccessPass.call(fail_one_param: false)
         | 
| 304 | 
            +
             | 
| 305 | 
            +
            fail_step_success # =>
         | 
| 306 | 
            +
            # Result: success
         | 
| 307 | 
            +
             | 
| 308 | 
            +
            # Railway Flow:
         | 
| 309 | 
            +
            #   step_one -> fail_one
         | 
| 310 | 
            +
             | 
| 311 | 
            +
            # Context:
         | 
| 312 | 
            +
            #   :fail_one_param => true
         | 
| 313 | 
            +
            #   :step_one => false
         | 
| 314 | 
            +
            #   :fail_one => true
         | 
| 315 | 
            +
             | 
| 316 | 
            +
            # Errors:
         | 
| 317 | 
            +
            #   {}
         | 
| 318 | 
            +
             | 
| 319 | 
            +
            fail_step_failure # =>
         | 
| 320 | 
            +
            # Result: failure
         | 
| 321 | 
            +
             | 
| 322 | 
            +
            # Railway Flow:
         | 
| 323 | 
            +
            #   step_one -> fail_one
         | 
| 324 | 
            +
             | 
| 325 | 
            +
            # Context:
         | 
| 326 | 
            +
            #   :fail_one_param => false
         | 
| 327 | 
            +
            #   :step_one => false
         | 
| 328 | 
            +
            #   :fail_one => false
         | 
| 329 | 
            +
             | 
| 330 | 
            +
            # Errors:
         | 
| 331 | 
            +
            #   {}
         | 
| 332 | 
            +
             | 
| 333 | 
            +
             | 
| 334 | 
            +
             | 
| 335 | 
            +
             | 
| 286 336 | 
             
            # on_failure: :finish_him
         | 
| 287 337 | 
             
            class SomeActionOnFailureFinishHim < Decouplio::Action
         | 
| 288 338 | 
             
              logic do
         | 
| @@ -321,7 +371,7 @@ fail_step_failure = SomeActionOnFailureFinishHim.call( | |
| 321 371 | 
             
              fail_one_param: false
         | 
| 322 372 | 
             
            )
         | 
| 323 373 |  | 
| 324 | 
            -
             | 
| 374 | 
            +
            success_action # =>
         | 
| 325 375 | 
             
            # Result: success
         | 
| 326 376 |  | 
| 327 377 | 
             
            # Railway Flow:
         | 
| @@ -334,7 +384,7 @@ puts success_action # => | |
| 334 384 | 
             
            #   {}
         | 
| 335 385 |  | 
| 336 386 |  | 
| 337 | 
            -
             | 
| 387 | 
            +
            fail_step_success # =>
         | 
| 338 388 | 
             
            # Result: failure
         | 
| 339 389 |  | 
| 340 390 | 
             
            # Railway Flow:
         | 
| @@ -347,7 +397,7 @@ puts fail_step_success # => | |
| 347 397 | 
             
            #   {}
         | 
| 348 398 |  | 
| 349 399 |  | 
| 350 | 
            -
             | 
| 400 | 
            +
            fail_step_failure  # =>
         | 
| 351 401 | 
             
            # Result: failure
         | 
| 352 402 |  | 
| 353 403 | 
             
            # Railway Flow:
         | 
| @@ -399,7 +449,7 @@ fail_step_failure = SomeActionOnFailureToSuccessTrack.call( | |
| 399 449 | 
             
              fail_one_param: false
         | 
| 400 450 | 
             
            )
         | 
| 401 451 |  | 
| 402 | 
            -
             | 
| 452 | 
            +
            success_action # =>
         | 
| 403 453 | 
             
            # Result: success
         | 
| 404 454 |  | 
| 405 455 | 
             
            # Railway Flow:
         | 
| @@ -411,7 +461,7 @@ puts success_action # => | |
| 411 461 | 
             
            # Errors:
         | 
| 412 462 | 
             
            #   {}
         | 
| 413 463 |  | 
| 414 | 
            -
             | 
| 464 | 
            +
            fail_step_success # =>
         | 
| 415 465 | 
             
            # Result: failure
         | 
| 416 466 |  | 
| 417 467 | 
             
            # Railway Flow:
         | 
| @@ -424,7 +474,7 @@ puts fail_step_success # => | |
| 424 474 | 
             
            #   {}
         | 
| 425 475 |  | 
| 426 476 |  | 
| 427 | 
            -
             | 
| 477 | 
            +
            fail_step_failure  # =>
         | 
| 428 478 | 
             
            # Result: success
         | 
| 429 479 |  | 
| 430 480 | 
             
            # Railway Flow:
         | 
| @@ -481,7 +531,7 @@ fail_step_failure = SomeActionOnFailureToFailureTrack.call( | |
| 481 531 | 
             
              fail_one_param: false
         | 
| 482 532 | 
             
            )
         | 
| 483 533 |  | 
| 484 | 
            -
             | 
| 534 | 
            +
            success_action # =>
         | 
| 485 535 | 
             
            # Result: success
         | 
| 486 536 |  | 
| 487 537 | 
             
            # Railway Flow:
         | 
| @@ -492,7 +542,7 @@ puts success_action # => | |
| 492 542 |  | 
| 493 543 | 
             
            # Errors:
         | 
| 494 544 | 
             
            #   {}
         | 
| 495 | 
            -
             | 
| 545 | 
            +
            fail_step_success # =>
         | 
| 496 546 | 
             
            # Result: failure
         | 
| 497 547 |  | 
| 498 548 | 
             
            # Railway Flow:
         | 
| @@ -503,7 +553,7 @@ puts fail_step_success # => | |
| 503 553 |  | 
| 504 554 | 
             
            # Errors:
         | 
| 505 555 | 
             
            #   {}
         | 
| 506 | 
            -
             | 
| 556 | 
            +
            fail_step_failure  # =>
         | 
| 507 557 | 
             
            # Result: failure
         | 
| 508 558 |  | 
| 509 559 | 
             
            # Railway Flow:
         | 
| @@ -517,6 +567,53 @@ puts fail_step_failure  # => | |
| 517 567 |  | 
| 518 568 |  | 
| 519 569 |  | 
| 570 | 
            +
            # on_failure: :PASS
         | 
| 571 | 
            +
            class SomeActionOnFailurePass < Decouplio::Action
         | 
| 572 | 
            +
              logic do
         | 
| 573 | 
            +
                step :step_one
         | 
| 574 | 
            +
                fail :fail_one, on_failure: :PASS
         | 
| 575 | 
            +
              end
         | 
| 576 | 
            +
             | 
| 577 | 
            +
              def step_one(**)
         | 
| 578 | 
            +
                false
         | 
| 579 | 
            +
              end
         | 
| 580 | 
            +
             | 
| 581 | 
            +
              def fail_one(fail_one_param:, **)
         | 
| 582 | 
            +
                ctx[:fail_one] = fail_one_param
         | 
| 583 | 
            +
              end
         | 
| 584 | 
            +
            end
         | 
| 585 | 
            +
             | 
| 586 | 
            +
            fail_step_success = SomeActionOnFailurePass.call(fail_one_param: true)
         | 
| 587 | 
            +
            fail_step_failure = SomeActionOnFailurePass.call(fail_one_param: false)
         | 
| 588 | 
            +
             | 
| 589 | 
            +
            fail_step_success # =>
         | 
| 590 | 
            +
            # Result: failure
         | 
| 591 | 
            +
             | 
| 592 | 
            +
            # Railway Flow:
         | 
| 593 | 
            +
            #   step_one -> fail_one
         | 
| 594 | 
            +
             | 
| 595 | 
            +
            # Context:
         | 
| 596 | 
            +
            #   :fail_one_param => true
         | 
| 597 | 
            +
            #   :fail_one => true
         | 
| 598 | 
            +
             | 
| 599 | 
            +
            # Errors:
         | 
| 600 | 
            +
            #   {}
         | 
| 601 | 
            +
             | 
| 602 | 
            +
            fail_step_failure # =>
         | 
| 603 | 
            +
            # Result: success
         | 
| 604 | 
            +
             | 
| 605 | 
            +
            # Railway Flow:
         | 
| 606 | 
            +
            #   step_one -> fail_one
         | 
| 607 | 
            +
             | 
| 608 | 
            +
            # Context:
         | 
| 609 | 
            +
            #   :fail_one_param => false
         | 
| 610 | 
            +
            #   :fail_one => false
         | 
| 611 | 
            +
             | 
| 612 | 
            +
            # Errors:
         | 
| 613 | 
            +
            #   {}
         | 
| 614 | 
            +
             | 
| 615 | 
            +
             | 
| 616 | 
            +
             | 
| 520 617 | 
             
            # if: condition method name
         | 
| 521 618 | 
             
            class SomeActionOnIfCondition < Decouplio::Action
         | 
| 522 619 | 
             
              logic do
         | 
| @@ -564,7 +661,7 @@ fail_condition_negative = SomeActionOnIfCondition.call( | |
| 564 661 | 
             
              if_condition_param: false
         | 
| 565 662 | 
             
            )
         | 
| 566 663 |  | 
| 567 | 
            -
             | 
| 664 | 
            +
            success_action # =>
         | 
| 568 665 | 
             
            # Result: success
         | 
| 569 666 |  | 
| 570 667 | 
             
            # Railway Flow:
         | 
| @@ -576,7 +673,7 @@ puts success_action # => | |
| 576 673 | 
             
            # Errors:
         | 
| 577 674 | 
             
            #   {}
         | 
| 578 675 |  | 
| 579 | 
            -
             | 
| 676 | 
            +
            fail_condition_positive # =>
         | 
| 580 677 | 
             
            # Result: failure
         | 
| 581 678 |  | 
| 582 679 | 
             
            # Railway Flow:
         | 
| @@ -588,7 +685,7 @@ puts fail_condition_positive # => | |
| 588 685 | 
             
            # Errors:
         | 
| 589 686 | 
             
            #   {}
         | 
| 590 687 |  | 
| 591 | 
            -
             | 
| 688 | 
            +
            fail_condition_negative  # =>
         | 
| 592 689 | 
             
            # Result: failure
         | 
| 593 690 |  | 
| 594 691 | 
             
            # Railway Flow:
         | 
| @@ -649,7 +746,7 @@ fail_condition_negative = SomeActionOnUnlessCondition.call( | |
| 649 746 | 
             
              if_condition_param: true
         | 
| 650 747 | 
             
            )
         | 
| 651 748 |  | 
| 652 | 
            -
             | 
| 749 | 
            +
            success_action # =>
         | 
| 653 750 | 
             
            # Result: success
         | 
| 654 751 |  | 
| 655 752 | 
             
            # Railway Flow:
         | 
| @@ -661,7 +758,7 @@ puts success_action # => | |
| 661 758 | 
             
            # Errors:
         | 
| 662 759 | 
             
            #   {}
         | 
| 663 760 |  | 
| 664 | 
            -
             | 
| 761 | 
            +
            fail_condition_positive # =>
         | 
| 665 762 | 
             
            # Result: failure
         | 
| 666 763 |  | 
| 667 764 | 
             
            # Railway Flow:
         | 
| @@ -673,7 +770,7 @@ puts fail_condition_positive # => | |
| 673 770 | 
             
            # Errors:
         | 
| 674 771 | 
             
            #   {}
         | 
| 675 772 |  | 
| 676 | 
            -
             | 
| 773 | 
            +
            fail_condition_negative  # =>
         | 
| 677 774 | 
             
            # Result: failure
         | 
| 678 775 |  | 
| 679 776 | 
             
            # Railway Flow:
         | 
| @@ -725,7 +822,7 @@ fail_step_failure = SomeActionFinishHimTrue.call( | |
| 725 822 | 
             
              fail_one_param: false
         | 
| 726 823 | 
             
            )
         | 
| 727 824 |  | 
| 728 | 
            -
             | 
| 825 | 
            +
            success_action # =>
         | 
| 729 826 | 
             
            # Result: success
         | 
| 730 827 |  | 
| 731 828 | 
             
            # Railway Flow:
         | 
| @@ -737,7 +834,7 @@ puts success_action # => | |
| 737 834 | 
             
            # Errors:
         | 
| 738 835 | 
             
            #   {}
         | 
| 739 836 |  | 
| 740 | 
            -
             | 
| 837 | 
            +
            fail_step_success # =>
         | 
| 741 838 | 
             
            # Result: failure
         | 
| 742 839 |  | 
| 743 840 | 
             
            # Railway Flow:
         | 
| @@ -749,7 +846,7 @@ puts fail_step_success # => | |
| 749 846 | 
             
            # Errors:
         | 
| 750 847 | 
             
            #   {}
         | 
| 751 848 |  | 
| 752 | 
            -
             | 
| 849 | 
            +
            fail_step_failure  # =>
         | 
| 753 850 | 
             
            # Result: failure
         | 
| 754 851 |  | 
| 755 852 | 
             
            # Railway Flow:
         | 
    
        data/docs/resq.md
    CHANGED
    
    | @@ -41,7 +41,7 @@ resq(**options) | |
| 41 41 |  | 
| 42 42 | 
             
            ## Behavior
         | 
| 43 43 |  | 
| 44 | 
            -
            When `resq` step is defined after allowed step then it will catch error with class specified in options and call handler method.
         | 
| 44 | 
            +
            When `resq` step is defined after allowed step then it will catch error with class specified in options and call handler method. `resq` applies only for step which is defined above.
         | 
| 45 45 |  | 
| 46 46 | 
             
            <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
         | 
| 47 47 | 
             
            <p>
         | 
| @@ -143,7 +143,7 @@ When `resq` step is defined after allowed step then it will catch error with cla | |
| 143 143 | 
             
                  logic do
         | 
| 144 144 | 
             
                    step :step_one
         | 
| 145 145 | 
             
                    resq handler_method_one: [ArgumentError, NoMethodError],
         | 
| 146 | 
            -
             | 
| 146 | 
            +
                         handler_method_two: NotImplementedError
         | 
| 147 147 | 
             
                    step :step_two
         | 
| 148 148 | 
             
                    fail :fail_one
         | 
| 149 149 | 
             
                  end
         |