Skip to content

Commit

Permalink
Raise error when trying to expose an invalid key
Browse files Browse the repository at this point in the history
  • Loading branch information
serradura committed Jan 25, 2024
1 parent c9187d1 commit e9546fd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
20 changes: 18 additions & 2 deletions lib/bcdd/result/context/success.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
# frozen_string_literal: true

class BCDD::Result
class Context::Error < BCDD::Result::Error
InvalidExposure = ::Class.new(self)
end

class Context::Success < Context
include ::BCDD::Result::Success::Methods

FetchValues = ->(acc_values, keys) do
fetched_values = acc_values.fetch_values(*keys)

keys.zip(fetched_values).to_h
rescue ::KeyError => e
message = "#{e.message}. Available to expose: #{acc_values.keys.map(&:inspect).join(', ')}"

raise Context::Error::InvalidExposure, message
end

def and_expose(type, keys, terminal: true)
unless keys.is_a?(::Array) && !keys.empty? && keys.all?(::Symbol)
raise ::ArgumentError, 'keys must be an Array of Symbols'
end

Transitions.tracking.reset_and_then!

exposed_value = acc.merge(value).slice(*keys)
acc_values = acc.merge(value)

value_to_expose = FetchValues.call(acc_values, keys)

self.class.new(type: type, value: exposed_value, source: source, terminal: terminal)
self.class.new(type: type, value: value_to_expose, source: source, terminal: terminal)
end
end
end
9 changes: 9 additions & 0 deletions sig/bcdd/result/context.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,19 @@ class BCDD::Result::Context < BCDD::Result
def raise_unexpected_outcome_error: (BCDD::Result::Context | untyped, Symbol) -> void
end

class BCDD::Result::Context
class Error < BCDD::Result::Error
class InvalidExposure < BCDD::Result::Context::Error
end
end
end

class BCDD::Result::Context
class Success < BCDD::Result::Context
include BCDD::Result::Success::Methods

FetchValues: Proc

def and_expose: (Symbol, Array[Symbol], terminal: bool) -> BCDD::Result::Context::Success
end

Expand Down
37 changes: 37 additions & 0 deletions test/bcdd/result/context/and_expose/invalid_keys_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require 'test_helper'

class BCDD::Result
class ContextAndExposeInvalidKeysTest < Minitest::Test
class Divide
include BCDD::Result::Context.mixin

def call(arg1, arg2)
validate_numbers(arg1, arg2)
.and_then(:divide, extra_division: 2)
.and_expose(:division_completed, %i[final_numbers extra_division number1 number2])
end

private

def validate_numbers(arg1, arg2)
arg1.is_a?(Numeric) or return Failure(:invalid_arg, message: 'arg1 must be numeric')
arg2.is_a?(Numeric) or return Failure(:invalid_arg, message: 'arg2 must be numeric')

Success(:ok, number1: arg1, number2: arg2)
end

def divide(number1:, number2:, extra_division:)
Success(:division_completed, final_number: (number1 / number2) / extra_division)
end
end

test '#and_expose receive an invalid key' do
err = assert_raises(BCDD::Result::Context::Error::InvalidExposure) { Divide.new.call(12, 2) }

assert err.message.start_with?('key not found: :final_numbers')
assert err.message.end_with?('. Available to expose: :number1, :number2, :extra_division, :final_number')
end
end
end

0 comments on commit e9546fd

Please sign in to comment.