light-service 0.13.0 → 0.17.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 +4 -4
- data/.github/workflows/project-build.yml +28 -0
- data/.travis.yml +3 -9
- data/Appraisals +0 -4
- data/Gemfile +0 -2
- data/README.md +287 -51
- data/RELEASES.md +21 -2
- data/gemfiles/activesupport_5.gemfile +0 -1
- data/gemfiles/activesupport_6.gemfile +0 -1
- data/lib/generators/light_service/action_generator.rb +90 -0
- data/lib/generators/light_service/generator_utils.rb +45 -0
- data/lib/generators/light_service/organizer_generator.rb +66 -0
- data/lib/generators/light_service/templates/action_spec_template.erb +31 -0
- data/lib/generators/light_service/templates/action_template.erb +30 -0
- data/lib/generators/light_service/templates/organizer_spec_template.erb +20 -0
- data/lib/generators/light_service/templates/organizer_template.erb +22 -0
- data/lib/light-service/action.rb +61 -4
- data/lib/light-service/context/key_verifier.rb +18 -1
- data/lib/light-service/context.rb +5 -3
- data/lib/light-service/errors.rb +1 -0
- data/lib/light-service/organizer/reduce_if_else.rb +21 -0
- data/lib/light-service/organizer/with_reducer.rb +12 -7
- data/lib/light-service/organizer/with_reducer_factory.rb +1 -1
- data/lib/light-service/organizer/with_reducer_log_decorator.rb +3 -0
- data/lib/light-service/organizer.rb +16 -3
- data/lib/light-service/version.rb +1 -1
- data/lib/light-service.rb +1 -0
- data/light-service.gemspec +6 -1
- data/spec/acceptance/after_actions_spec.rb +17 -0
- data/spec/acceptance/around_each_spec.rb +15 -0
- data/spec/acceptance/log_from_organizer_spec.rb +1 -1
- data/spec/acceptance/organizer/add_to_context_spec.rb +27 -0
- data/spec/acceptance/organizer/execute_with_add_to_context_spec.rb +28 -0
- data/spec/acceptance/organizer/iterate_spec.rb +7 -0
- data/spec/acceptance/organizer/reduce_if_else_spec.rb +60 -0
- data/spec/acceptance/organizer/reduce_if_spec.rb +6 -0
- data/spec/acceptance/organizer/reduce_until_spec.rb +6 -0
- data/spec/action_optional_expected_keys_spec.rb +82 -0
- data/spec/action_spec.rb +8 -0
- data/spec/lib/generators/action_generator_advanced_spec.rb +43 -0
- data/spec/lib/generators/action_generator_simple_spec.rb +37 -0
- data/spec/lib/generators/full_generator_test_blobs.rb +193 -0
- data/spec/lib/generators/organizer_generator_advanced_spec.rb +37 -0
- data/spec/lib/generators/organizer_generator_simple_spec.rb +37 -0
- data/spec/organizer_spec.rb +5 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/test_doubles.rb +37 -0
- metadata +87 -9
- data/gemfiles/activesupport_3.gemfile +0 -8
- data/gemfiles/activesupport_4.gemfile +0 -8
- data/resources/orchestrators_deprecated.svg +0 -10
| @@ -111,7 +111,24 @@ module LightService | |
| 111 111 | 
             
                  end
         | 
| 112 112 |  | 
| 113 113 | 
             
                  def reserved_keys
         | 
| 114 | 
            -
                    %i[message error_code current_action].freeze
         | 
| 114 | 
            +
                    %i[message error_code current_action organized_by].freeze
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                class ReservedKeysViaOrganizerVerifier < ReservedKeysVerifier
         | 
| 119 | 
            +
                  def initialize(context_data)
         | 
| 120 | 
            +
                    @context = LightService::Context.make(context_data)
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  def violated_keys
         | 
| 124 | 
            +
                    context.keys.map(&:to_sym) & reserved_keys
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  def error_message
         | 
| 128 | 
            +
                    <<~ERR
         | 
| 129 | 
            +
                      reserved keys cannot be added to the context
         | 
| 130 | 
            +
                      reserved key: [#{format_keys(violated_keys)}]
         | 
| 131 | 
            +
                    ERR
         | 
| 115 132 | 
             
                  end
         | 
| 116 133 | 
             
                end
         | 
| 117 134 | 
             
              end
         | 
| @@ -8,7 +8,8 @@ module LightService | |
| 8 8 |  | 
| 9 9 | 
             
              # rubocop:disable ClassLength
         | 
| 10 10 | 
             
              class Context < Hash
         | 
| 11 | 
            -
                attr_accessor :message, :error_code, :current_action
         | 
| 11 | 
            +
                attr_accessor :message, :error_code, :current_action, :around_actions,
         | 
| 12 | 
            +
                              :organized_by
         | 
| 12 13 |  | 
| 13 14 | 
             
                def initialize(context = {},
         | 
| 14 15 | 
             
                               outcome = Outcomes::SUCCESS,
         | 
| @@ -18,6 +19,7 @@ module LightService | |
| 18 19 | 
             
                  @message = message
         | 
| 19 20 | 
             
                  @error_code = error_code
         | 
| 20 21 | 
             
                  @skip_remaining = false
         | 
| 22 | 
            +
             | 
| 21 23 | 
             
                  context.to_hash.each { |k, v| self[k] = v }
         | 
| 22 24 | 
             
                end
         | 
| 23 25 |  | 
| @@ -114,9 +116,9 @@ module LightService | |
| 114 116 | 
             
                end
         | 
| 115 117 |  | 
| 116 118 | 
             
                def define_accessor_methods_for_keys(keys)
         | 
| 117 | 
            -
                  return if keys. | 
| 119 | 
            +
                  return if keys.blank?
         | 
| 118 120 |  | 
| 119 | 
            -
                  keys.each do |key|
         | 
| 121 | 
            +
                  Array(keys).each do |key|
         | 
| 120 122 | 
             
                    next if respond_to?(key.to_sym)
         | 
| 121 123 |  | 
| 122 124 | 
             
                    define_singleton_method(key.to_s) { fetch(key) }
         | 
    
        data/lib/light-service/errors.rb
    CHANGED
    
    
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module LightService
         | 
| 2 | 
            +
              module Organizer
         | 
| 3 | 
            +
                class ReduceIfElse
         | 
| 4 | 
            +
                  extend ScopedReducable
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def self.run(organizer, condition_block, if_steps, else_steps)
         | 
| 7 | 
            +
                    lambda do |ctx|
         | 
| 8 | 
            +
                      return ctx if ctx.stop_processing?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                      ctx = if condition_block.call(ctx)
         | 
| 11 | 
            +
                              scoped_reduce(organizer, ctx, if_steps)
         | 
| 12 | 
            +
                            else
         | 
| 13 | 
            +
                              scoped_reduce(organizer, ctx, else_steps)
         | 
| 14 | 
            +
                            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      ctx
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -1,10 +1,16 @@ | |
| 1 1 | 
             
            module LightService
         | 
| 2 2 | 
             
              module Organizer
         | 
| 3 3 | 
             
                class WithReducer
         | 
| 4 | 
            -
                  attr_reader | 
| 4 | 
            +
                  attr_reader   :context
         | 
| 5 | 
            +
                  attr_accessor :organizer
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def initialize(monitored_organizer = nil)
         | 
| 8 | 
            +
                    @organizer = monitored_organizer
         | 
| 9 | 
            +
                  end
         | 
| 5 10 |  | 
| 6 11 | 
             
                  def with(data = {})
         | 
| 7 12 | 
             
                    @context = LightService::Context.make(data)
         | 
| 13 | 
            +
                    @context.organized_by = organizer
         | 
| 8 14 | 
             
                    self
         | 
| 9 15 | 
             
                  end
         | 
| 10 16 |  | 
| @@ -24,6 +30,7 @@ module LightService | |
| 24 30 | 
             
                  def reduce(*actions)
         | 
| 25 31 | 
             
                    raise "No action(s) were provided" if actions.empty?
         | 
| 26 32 |  | 
| 33 | 
            +
                    @context.around_actions ||= around_each_handler
         | 
| 27 34 | 
             
                    actions.flatten!
         | 
| 28 35 |  | 
| 29 36 | 
             
                    actions.each_with_object(context) do |action, current_context|
         | 
| @@ -53,12 +60,10 @@ module LightService | |
| 53 60 | 
             
                  private
         | 
| 54 61 |  | 
| 55 62 | 
             
                  def invoke_action(current_context, action)
         | 
| 56 | 
            -
                     | 
| 57 | 
            -
                       | 
| 58 | 
            -
             | 
| 59 | 
            -
                       | 
| 60 | 
            -
                        action.execute(current_context)
         | 
| 61 | 
            -
                      end
         | 
| 63 | 
            +
                    if action.respond_to?(:call)
         | 
| 64 | 
            +
                      action.call(current_context)
         | 
| 65 | 
            +
                    else
         | 
| 66 | 
            +
                      action.execute(current_context)
         | 
| 62 67 | 
             
                    end
         | 
| 63 68 | 
             
                  end
         | 
| 64 69 |  | 
| @@ -41,6 +41,10 @@ module LightService | |
| 41 41 | 
             
                    ReduceIf.run(self, condition_block, steps)
         | 
| 42 42 | 
             
                  end
         | 
| 43 43 |  | 
| 44 | 
            +
                  def reduce_if_else(condition_block, if_steps, else_steps)
         | 
| 45 | 
            +
                    ReduceIfElse.run(self, condition_block, if_steps, else_steps)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 44 48 | 
             
                  def reduce_until(condition_block, steps)
         | 
| 45 49 | 
             
                    ReduceUntil.run(self, condition_block, steps)
         | 
| 46 50 | 
             
                  end
         | 
| @@ -65,9 +69,18 @@ module LightService | |
| 65 69 | 
             
                    @logger
         | 
| 66 70 | 
             
                  end
         | 
| 67 71 |  | 
| 68 | 
            -
                   | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 72 | 
            +
                  # Set the value as a key on the context hash
         | 
| 73 | 
            +
                  # and also create convenience accessors for the keys
         | 
| 74 | 
            +
                  def add_to_context(args)
         | 
| 75 | 
            +
                    Context::ReservedKeysViaOrganizerVerifier.new(args).verify
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    Hash(args).map do |key, value|
         | 
| 78 | 
            +
                      context_key = lambda do |ctx|
         | 
| 79 | 
            +
                        ctx[key.to_sym] = value
         | 
| 80 | 
            +
                        ctx.define_accessor_methods_for_keys(key)
         | 
| 81 | 
            +
                      end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                      execute(context_key)
         | 
| 71 84 | 
             
                    end
         | 
| 72 85 | 
             
                  end
         | 
| 73 86 |  | 
    
        data/lib/light-service.rb
    CHANGED
    
    | @@ -13,6 +13,7 @@ require 'light-service/organizer/with_reducer' | |
| 13 13 | 
             
            require 'light-service/organizer/with_reducer_log_decorator'
         | 
| 14 14 | 
             
            require 'light-service/organizer/with_reducer_factory'
         | 
| 15 15 | 
             
            require 'light-service/organizer/reduce_if'
         | 
| 16 | 
            +
            require 'light-service/organizer/reduce_if_else'
         | 
| 16 17 | 
             
            require 'light-service/organizer/reduce_until'
         | 
| 17 18 | 
             
            require 'light-service/organizer/iterate'
         | 
| 18 19 | 
             
            require 'light-service/organizer/execute'
         | 
    
        data/light-service.gemspec
    CHANGED
    
    | @@ -15,11 +15,16 @@ Gem::Specification.new do |gem| | |
| 15 15 | 
             
              gem.name          = "light-service"
         | 
| 16 16 | 
             
              gem.require_paths = ["lib"]
         | 
| 17 17 | 
             
              gem.version       = LightService::VERSION
         | 
| 18 | 
            +
              gem.required_ruby_version = '>= 2.5.0'
         | 
| 18 19 |  | 
| 19 | 
            -
              gem.add_runtime_dependency("activesupport", ">=  | 
| 20 | 
            +
              gem.add_runtime_dependency("activesupport", ">= 4.0.0")
         | 
| 20 21 |  | 
| 22 | 
            +
              gem.add_development_dependency("generator_spec", "~> 0.9.4")
         | 
| 23 | 
            +
              gem.add_development_dependency("test-unit", "~> 3.0") # Needed for generator specs.
         | 
| 24 | 
            +
              gem.add_development_dependency("appraisal", "~> 2.3")
         | 
| 21 25 | 
             
              gem.add_development_dependency("rspec", "~> 3.0")
         | 
| 22 26 | 
             
              gem.add_development_dependency("simplecov", "~> 0.17")
         | 
| 27 | 
            +
              gem.add_development_dependency("codecov", "~> 0.1")
         | 
| 23 28 | 
             
              gem.add_development_dependency("rubocop", "~> 0.68.0")
         | 
| 24 29 | 
             
              gem.add_development_dependency("rubocop-performance", "~> 1.2.0")
         | 
| 25 30 | 
             
              gem.add_development_dependency("pry", "~> 0.12.2")
         | 
| @@ -65,6 +65,23 @@ RSpec.describe 'Action after_actions' do | |
| 65 65 | 
             
                end
         | 
| 66 66 | 
             
              end
         | 
| 67 67 |  | 
| 68 | 
            +
              context 'with callbacks' do
         | 
| 69 | 
            +
                it 'ensures the correct :current_action is set' do
         | 
| 70 | 
            +
                  TestDoubles::TestWithCallback.after_actions = [
         | 
| 71 | 
            +
                    lambda do |ctx|
         | 
| 72 | 
            +
                      if ctx.current_action == TestDoubles::IterateCollectionAction
         | 
| 73 | 
            +
                        ctx.total -= 1000
         | 
| 74 | 
            +
                      end
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  ]
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  result = TestDoubles::TestWithCallback.call
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  expect(result.counter).to eq(3)
         | 
| 81 | 
            +
                  expect(result.total).to eq(-994)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 68 85 | 
             
              describe 'after_actions can be appended' do
         | 
| 69 86 | 
             
                it 'adds to the :_after_actions collection' do
         | 
| 70 87 | 
             
                  TestDoubles::AdditionOrganizer.append_after_actions(
         | 
| @@ -16,4 +16,19 @@ describe 'Executing arbitrary code around each action' do | |
| 16 16 | 
             
                  }]
         | 
| 17 17 | 
             
                )
         | 
| 18 18 | 
             
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              it 'logs data with nested actions' do
         | 
| 21 | 
            +
                context = { :number => 1, :logger => TestDoubles::TestLogger.new }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                result = TestDoubles::AroundEachWithReduceIfOrganizer.call(context)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                expect(result.fetch(:number)).to eq(7)
         | 
| 26 | 
            +
                expect(result[:logger].logs).to eq(
         | 
| 27 | 
            +
                  [
         | 
| 28 | 
            +
                    { :action => TestDoubles::AddsOneAction, :before => 1, :after => 2 },
         | 
| 29 | 
            +
                    { :action => TestDoubles::AddsTwoAction, :before => 2, :after => 4 },
         | 
| 30 | 
            +
                    { :action => TestDoubles::AddsThreeAction, :before => 4, :after => 7 }
         | 
| 31 | 
            +
                  ]
         | 
| 32 | 
            +
                )
         | 
| 33 | 
            +
              end
         | 
| 19 34 | 
             
            end
         | 
| @@ -59,7 +59,7 @@ describe "Logs from organizer" do | |
| 59 59 | 
             
                  expect(log_message).to include(organizer_log_message)
         | 
| 60 60 | 
             
                end
         | 
| 61 61 |  | 
| 62 | 
            -
                it "lists the keys in  | 
| 62 | 
            +
                it "lists the keys in context after the actions are executed" do
         | 
| 63 63 | 
             
                  organizer_log_message = "[LightService] -     keys in context: " \
         | 
| 64 64 | 
             
                                          ":tea, :milk, :coffee, :milk_tea, :latte"
         | 
| 65 65 | 
             
                  expect(log_message).to include(organizer_log_message)
         | 
| @@ -20,6 +20,20 @@ RSpec.describe LightService::Organizer do | |
| 20 20 | 
             
                end
         | 
| 21 21 | 
             
              end
         | 
| 22 22 |  | 
| 23 | 
            +
              class TestAddToContextReservedWords
         | 
| 24 | 
            +
                extend LightService::Organizer
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.call(context = LightService::Context.make)
         | 
| 27 | 
            +
                  with(context).reduce(steps)
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def self.steps
         | 
| 31 | 
            +
                  [
         | 
| 32 | 
            +
                    add_to_context(:message => "yo", "error_code" => "00P5")
         | 
| 33 | 
            +
                  ]
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 23 37 | 
             
              it 'adds items to the context on the fly' do
         | 
| 24 38 | 
             
                result = TestAddToContext.call
         | 
| 25 39 |  | 
| @@ -27,4 +41,17 @@ RSpec.describe LightService::Organizer do | |
| 27 41 | 
             
                expect(result.number).to eq(1)
         | 
| 28 42 | 
             
                expect(result[:something]).to eq('hello')
         | 
| 29 43 | 
             
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              it 'adds items to the context as accessors' do
         | 
| 46 | 
            +
                result = TestAddToContext.call
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                expect(result).to be_success
         | 
| 49 | 
            +
                expect(result.something).to eq('hello')
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it "will not add items as accessors when they are reserved" do
         | 
| 53 | 
            +
                expect { TestAddToContextReservedWords.call }.to \
         | 
| 54 | 
            +
                  raise_error(LightService::ReservedKeysInContextError)
         | 
| 55 | 
            +
                  .with_message(/:message, :error_code/)
         | 
| 56 | 
            +
              end
         | 
| 30 57 | 
             
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'test_doubles'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            RSpec.describe LightService::Organizer do
         | 
| 5 | 
            +
              class TestExecuteWithAddToContext
         | 
| 6 | 
            +
                extend LightService::Organizer
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def self.call
         | 
| 9 | 
            +
                  with.reduce(steps)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.steps
         | 
| 13 | 
            +
                  [
         | 
| 14 | 
            +
                    add_to_context(:greeting => "hello"),
         | 
| 15 | 
            +
                    execute(->(ctx) { ctx.greeting.upcase! })
         | 
| 16 | 
            +
                  ]
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              context "when using context values created by add_to_context" do
         | 
| 21 | 
            +
                it "is expected to reference them as accessors" do
         | 
| 22 | 
            +
                  result = TestExecuteWithAddToContext.call
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  expect(result).to be_a_success
         | 
| 25 | 
            +
                  expect(result.greeting).to eq "HELLO"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -20,6 +20,13 @@ RSpec.describe LightService::Organizer do | |
| 20 20 | 
             
                expect(result.number).to eq(5)
         | 
| 21 21 | 
             
              end
         | 
| 22 22 |  | 
| 23 | 
            +
              it "knows that it's being iterated from within an organizer" do
         | 
| 24 | 
            +
                result = TestDoubles::TestIterate.call(:number => 1,
         | 
| 25 | 
            +
                                                       :counters => [1, 2, 3, 4])
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                expect(result.organized_by).to eq TestDoubles::TestIterate
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 23 30 | 
             
              it 'will not iterate over a failed context' do
         | 
| 24 31 | 
             
                empty_context.fail!('Something bad happened')
         | 
| 25 32 |  | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'test_doubles'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            RSpec.describe LightService::Organizer do
         | 
| 5 | 
            +
              class TestReduceIfElse
         | 
| 6 | 
            +
                extend LightService::Organizer
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def self.call(context)
         | 
| 9 | 
            +
                  with(context).reduce(actions)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.actions
         | 
| 13 | 
            +
                  [
         | 
| 14 | 
            +
                    TestDoubles::AddsOneAction,
         | 
| 15 | 
            +
                    reduce_if_else(
         | 
| 16 | 
            +
                      ->(ctx) { ctx.number == 1 },
         | 
| 17 | 
            +
                      [TestDoubles::AddsOneAction],
         | 
| 18 | 
            +
                      [TestDoubles::AddsTwoAction]
         | 
| 19 | 
            +
                    )
         | 
| 20 | 
            +
                  ]
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              let(:empty_context) { LightService::Context.make }
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              it 'reduces the if_steps if the condition is true' do
         | 
| 27 | 
            +
                result = TestReduceIfElse.call(:number => 0)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                expect(result).to be_success
         | 
| 30 | 
            +
                expect(result[:number]).to eq(2)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              it 'reduces the else_steps if the condition is false' do
         | 
| 34 | 
            +
                result = TestReduceIfElse.call(:number => 2)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                expect(result).to be_success
         | 
| 37 | 
            +
                expect(result[:number]).to eq(5)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              it 'will not reduce over a failed context' do
         | 
| 41 | 
            +
                empty_context.fail!('Something bad happened')
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                result = TestReduceIfElse.call(empty_context)
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                expect(result).to be_failure
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              it 'does not reduce over a skipped context' do
         | 
| 49 | 
            +
                empty_context.skip_remaining!('No more needed')
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                result = TestReduceIfElse.call(empty_context)
         | 
| 52 | 
            +
                expect(result).to be_success
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              it "knows that it's being conditionally reduced from within an organizer" do
         | 
| 56 | 
            +
                result = TestReduceIfElse.call(:number => 2)
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                expect(result.organized_by).to eq TestReduceIfElse
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -49,6 +49,12 @@ RSpec.describe LightService::Organizer do | |
| 49 49 | 
             
                expect(result).to be_success
         | 
| 50 50 | 
             
              end
         | 
| 51 51 |  | 
| 52 | 
            +
              it "knows that it's being conditionally reduced from within an organizer" do
         | 
| 53 | 
            +
                result = TestReduceIf.call(:number => 2)
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                expect(result.organized_by).to eq TestReduceIf
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 52 58 | 
             
              it 'skips actions within in its own scope' do
         | 
| 53 59 | 
             
                org = Class.new do
         | 
| 54 60 | 
             
                  extend LightService::Organizer
         | 
| @@ -40,4 +40,10 @@ RSpec.describe LightService::Organizer do | |
| 40 40 | 
             
                result = TestReduceUntil.call(empty_context)
         | 
| 41 41 | 
             
                expect(result).to be_success
         | 
| 42 42 | 
             
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              it "is expected to know its organizer when reducing until a condition" do
         | 
| 45 | 
            +
                result = TestReduceUntil.call(:number => 1)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                expect(result.organized_by).to eq TestReduceUntil
         | 
| 48 | 
            +
              end
         | 
| 43 49 | 
             
            end
         |