Skip to content

Commit

Permalink
raise on Money.new is attempting to change currency of an existing mo…
Browse files Browse the repository at this point in the history
…ney object
  • Loading branch information
elfassy committed Apr 17, 2024
1 parent 241365b commit 6dfbfe3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/money/money.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ def configure
end

def new(value = 0, currency = nil)
return new_from_money(value, currency) if value.is_a?(Money)

value = Helpers.value_to_decimal(value)
currency = Helpers.value_to_currency(currency)

Expand Down Expand Up @@ -100,6 +102,20 @@ def with_currency(new_currency)
Money.current_currency = old_currency
end
end

private

def new_from_money(amount, currency)
return amount if amount.currency.compatible?(Helpers.value_to_currency(currency))

msg = "Money.new is attempting to change currency of an existing money object"
if Money.config.legacy_deprecations
Money.deprecate("#{msg}. A Money::IncompatibleCurrencyError will raise in the next major release")
return Money.new(amount.value, currency)
else
raise Money::IncompatibleCurrencyError, msg
end
end
end
configure

Expand Down
23 changes: 23 additions & 0 deletions spec/money_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,29 @@
expect(Money.new('')).to eq(Money.new(0))
end

it "can be constructed with a string" do
expect(Money.new('1')).to eq(Money.new(1))
end

it "can be constructed with a numeric" do
expect(Money.new(1.00)).to eq(Money.new(1))
end

it "can be constructed with a money object" do
expect(Money.new(Money.new(1))).to eq(Money.new(1))
end

it "constructor raises when changing currency" do
expect { Money.new(Money.new(1, 'USD'), 'CAD') }.to raise_error(Money::IncompatibleCurrencyError)
end

it "legacy_deprecations constructor with money used the constructor currency" do
configure(legacy_deprecations: true) do
expect(Money).to receive(:deprecate).with(match(/Money.new is attempting to change currency of an existing money object/)).once
expect(Money.new(Money.new(1, 'USD'), 'CAD')).to eq(Money.new(1, 'CAD'))
end
end

it "legacy_deprecations defaults to 0 when constructed with an invalid string" do
configure(legacy_deprecations: true) do
expect(Money).to receive(:deprecate).once
Expand Down

0 comments on commit 6dfbfe3

Please sign in to comment.