Skip to content

Commit 6b1d791

Browse files
authored
Merge pull request #474 from Shopify/infinity-and-beyond
correctly handle Float::INFINITY
2 parents 257cb74 + 9e12982 commit 6b1d791

2 files changed

Lines changed: 49 additions & 3 deletions

File tree

lib/money/money.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ def new_from_money(amount, currency)
126126

127127
def initialize(value, currency)
128128
raise ArgumentError if value.nan?
129+
if value.infinite?
130+
Money.deprecate("Initializing Money with infinity is deprecated and will raise an ArgumentError in v4")
131+
end
132+
129133
@currency = Helpers.value_to_currency(currency)
130134
@value = BigDecimal(value.round(@currency.minor_units))
131135
freeze
@@ -153,9 +157,14 @@ def -@
153157
end
154158

155159
def <=>(other)
156-
return unless other.respond_to?(:to_money)
157-
arithmetic(other) do |money|
158-
value <=> money.value
160+
if other.is_a?(Numeric)
161+
return value <=> other
162+
end
163+
164+
if other.respond_to?(:to_money)
165+
arithmetic(other) do |money|
166+
value <=> money.value
167+
end
159168
end
160169
end
161170

spec/money_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,16 @@
457457
expect { Money.new( 0.0 / 0) }.to raise_error(ArgumentError)
458458
end
459459

460+
it "raises when constructed with positive infinity" do
461+
expect(Money).to receive(:deprecate).once
462+
Money.new(Float::INFINITY)
463+
end
464+
465+
it "raises when constructed with negative infinity" do
466+
expect(Money).to receive(:deprecate).once
467+
Money.new(-Float::INFINITY)
468+
end
469+
460470
it "is comparable with non-money objects" do
461471
expect(money).not_to eq(nil)
462472
end
@@ -548,6 +558,7 @@
548558
let (:nil_10) { Money.new(10.00, Money::NULL_CURRENCY) }
549559
let (:nil_20) { Money.new(20.00, Money::NULL_CURRENCY) }
550560
let (:usd_10) { Money.new(10.00, 'USD') }
561+
let (:jpy_10) { Money.new(10, 'JPY') }
551562

552563
it "<=> can compare with and without currency" do
553564
expect(Money.new(1000, Money::NULL_CURRENCY) <=> Money.new(2000, 'JPY')).to eq(-1)
@@ -680,6 +691,32 @@
680691
it { expect { cad_10 <= nil }.to(raise_error(ArgumentError)) }
681692
it { expect { cad_10 < nil }.to(raise_error(ArgumentError)) }
682693
end
694+
695+
describe('infinity comparisons') do
696+
it { expect(cad_10 <=> Float::INFINITY).to(eq(-1)) }
697+
it { expect(cad_10 < Float::INFINITY).to(eq(true)) }
698+
it { expect(cad_10 <= Float::INFINITY).to(eq(true)) }
699+
it { expect(cad_10 > Float::INFINITY).to(eq(false)) }
700+
it { expect(cad_10 >= Float::INFINITY).to(eq(false)) }
701+
702+
it { expect(cad_10 <=> -Float::INFINITY).to(eq(1)) }
703+
it { expect(cad_10 > -Float::INFINITY).to(eq(true)) }
704+
it { expect(cad_10 >= -Float::INFINITY).to(eq(true)) }
705+
it { expect(cad_10 < -Float::INFINITY).to(eq(false)) }
706+
it { expect(cad_10 <= -Float::INFINITY).to(eq(false)) }
707+
708+
it { expect(jpy_10 <=> Float::INFINITY).to(eq(-1)) }
709+
it { expect(jpy_10 < Float::INFINITY).to(eq(true)) }
710+
it { expect(jpy_10 <= Float::INFINITY).to(eq(true)) }
711+
it { expect(jpy_10 > Float::INFINITY).to(eq(false)) }
712+
it { expect(jpy_10 >= Float::INFINITY).to(eq(false)) }
713+
714+
it { expect(jpy_10 <=> -Float::INFINITY).to(eq(1)) }
715+
it { expect(jpy_10 > -Float::INFINITY).to(eq(true)) }
716+
it { expect(jpy_10 >= -Float::INFINITY).to(eq(true)) }
717+
it { expect(jpy_10 < -Float::INFINITY).to(eq(false)) }
718+
it { expect(jpy_10 <= -Float::INFINITY).to(eq(false)) }
719+
end
683720
end
684721

685722
describe "#subunits" do

0 commit comments

Comments
 (0)