diff --git a/lib/money/money.rb b/lib/money/money.rb index bae1cafd..ea380618 100644 --- a/lib/money/money.rb +++ b/lib/money/money.rb @@ -348,15 +348,14 @@ def calculate_splits(num) # # @example # Money.new(50, "CAD").clamp(1, 100) #=> Money.new(50, "CAD") + # Money.new(50, "CAD").clamp(1..100) #=> Money.new(50, "CAD") + # Money.new(50, "CAD").clamp(1, nil) #=> Money.new(1, "CAD") # # Money.new(120, "CAD").clamp(0, 100) #=> Money.new(100, "CAD") - def clamp(min, max) - raise ArgumentError, 'min cannot be greater than max' if min > max + def clamp(...) + clamped_value = value.clamp(...) - clamped_value = min if value < min - clamped_value = max if value > max - - if clamped_value.nil? + if clamped_value == value self else Money.new(clamped_value, currency) diff --git a/spec/money_spec.rb b/spec/money_spec.rb index c03b5001..949fa570 100644 --- a/spec/money_spec.rb +++ b/spec/money_spec.rb @@ -1144,6 +1144,18 @@ let(:min) { -max } it 'returns the same value if the value is within the min..max range' do + money = Money.new(5000, 'EUR').clamp(min..max) + expect(money.value).to eq(5000) + expect(money.currency.iso_code).to eq('EUR') + end + + it 'returns the same value if the value is larger and the max value is nil' do + money = Money.new(min + 1, 'EUR').clamp(min, nil) + expect(money.value).to eq(min + 1) + expect(money.currency.iso_code).to eq('EUR') + end + + it 'returns the same value if the value is between the min and max' do money = Money.new(5000, 'EUR').clamp(min, max) expect(money.value).to eq(5000) expect(money.currency.iso_code).to eq('EUR') @@ -1160,6 +1172,17 @@ expect(money.value).to eq(-9000) expect(money.currency.iso_code).to eq('EUR') end + + it 'returns the min value if the original value is smaller and the max value is nil' do + money = Money.new(min - 1, 'EUR').clamp(min, nil) + expect(money.value).to eq(min) + expect(money.currency.iso_code).to eq('EUR') + end + + it 'raises an Argument error if the max value is less than the min value' do + money = Money.new(-9001, 'EUR').clamp(min, nil) + expect { money.clamp(max, min) }.to raise_error(ArgumentError, 'min argument must be less than or equal to max argument') + end end describe ".current_currency" do