Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ RSpec/DescribedClass:
- 'spec/money_spec.rb'
- 'spec/money/formatting_spec.rb'

RSpec/MultipleExpectations:
# Do not limit the amount of expectations in a spec
Enabled: false

# Style

Style/ClassAndModuleChildren:
Expand Down
11 changes: 0 additions & 11 deletions .rubocop_todo.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 17 additions & 9 deletions spec/bank/variable_exchange_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,18 @@

describe "#add_rate" do
it 'delegates to store#add_rate' do
expect(bank.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
allow(bank.store).to receive(:add_rate).and_return 1.25
expect(bank.add_rate('USD', 'EUR', 1.25)).to be 1.25
expect(bank.store).to have_received(:add_rate).with('USD', 'EUR', 1.25)
end

it "adds rates with correct ISO codes" do
expect(bank.store).to receive(:add_rate).with('USD', 'EUR', 0.788332676)
allow(bank.store).to receive(:add_rate)
bank.add_rate("USD", "EUR", 0.788332676)
expect(bank.store).to have_received(:add_rate).with('USD', 'EUR', 0.788332676)

expect(bank.store).to receive(:add_rate).with('EUR', 'JPY', 122.631477)
bank.add_rate("EUR", "YEN", 122.631477)
expect(bank.store).to have_received(:add_rate).with('EUR', 'JPY', 122.631477)
end

it "treats currency names case-insensitively" do
Expand All @@ -130,8 +132,9 @@

describe "#set_rate" do
it 'delegates to store#add_rate' do
expect(bank.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
allow(bank.store).to receive(:add_rate).and_return 1.25
expect(bank.set_rate('USD', 'EUR', 1.25)).to be 1.25
expect(bank.store).to have_received(:add_rate).with('USD', 'EUR', 1.25)
end

it "sets a rate" do
Expand All @@ -155,8 +158,9 @@
end

it "delegates options to store, options are a no-op" do
expect(bank.store).to receive(:get_rate).with('USD', 'EUR')
allow(bank.store).to receive(:get_rate)
bank.get_rate('USD', 'EUR')
expect(bank.store).to have_received(:get_rate).with('USD', 'EUR')
end
end

Expand Down Expand Up @@ -197,16 +201,19 @@
context "with :file provided" do
it "writes rates to file" do
f = double('IO')
expect(File).to receive(:open).with('null', 'w').and_yield(f)
expect(f).to receive(:write).with(JSON.dump(@rates))
allow(File).to receive(:open).with('null', 'w').and_yield(f)
allow(f).to receive(:write)

bank.export_rates(:json, 'null')

expect(f).to have_received(:write).with(JSON.dump(@rates))
end
end

it "delegates execution to store, options are a no-op" do
expect(bank.store).to receive(:transaction)
allow(bank.store).to receive(:transaction)
bank.export_rates(:yaml, nil, foo: 1)
expect(bank.store).to have_received(:transaction)
end
end

Expand Down Expand Up @@ -260,9 +267,10 @@
end

it "delegates execution to store#transaction" do
expect(bank.store).to receive(:transaction)
allow(bank.store).to receive(:transaction)
s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
bank.import_rates(:yaml, s, foo: 1)
expect(bank.store).to have_received(:transaction)
end
end

Expand Down
4 changes: 3 additions & 1 deletion spec/currency/loader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
end

it "parse currency_iso.json & currency_non_iso.json & currency_backwards_compatible.json" do
expect(described_class).to receive(:parse_currency_file).exactly(3).times.and_return({})
allow(described_class).to receive(:parse_currency_file).and_return({})

described_class.load_currencies

expect(described_class).to have_received(:parse_currency_file).exactly(3).times
end
end
33 changes: 22 additions & 11 deletions spec/money/arithmetic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,26 @@

it "converts other object amount to current currency, then compares the two object amounts (different currency)" do
target = Money.new(200_00, "EUR")
expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(300_00, "USD"))
allow(target).to receive(:exchange_to).and_return(Money.new(300_00, "USD"))
expect(Money.new(100_00, "USD") <=> target).to be < 0
expect(target).to have_received(:exchange_to).with(Money::Currency.new("USD"))

target = Money.new(200_00, "EUR")
expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
allow(target).to receive(:exchange_to).and_return(Money.new(100_00, "USD"))
expect(Money.new(100_00, "USD") <=> target).to eq 0
expect(target).to have_received(:exchange_to).with(Money::Currency.new("USD"))

target = Money.new(200_00, "EUR")
expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(99_00, "USD"))
allow(target).to receive(:exchange_to).and_return(Money.new(99_00, "USD"))
expect(Money.new(100_00, "USD") <=> target).to be > 0
expect(target).to have_received(:exchange_to).with(Money::Currency.new("USD"))
end

it "returns nil if currency conversion fails, and therefore cannot be compared" do
target = Money.new(200_00, "EUR")
expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_raise(Money::Bank::UnknownRate)
allow(target).to receive(:exchange_to).and_raise(Money::Bank::UnknownRate)
expect(Money.new(100_00, "USD") <=> target).to be_nil
expect(target).to have_received(:exchange_to).with(Money::Currency.new("USD"))
end

it "can be used to compare with an object that inherits from Money" do
Expand Down Expand Up @@ -254,8 +258,9 @@

it "converts other object amount to current currency and adds other amount to current amount (different currency)" do
other = Money.new(90, "EUR")
expect(other).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
allow(other).to receive(:exchange_to).and_return(Money.new(9_00, "USD"))
expect(Money.new(10_00, "USD") + other).to eq Money.new(19_00, "USD")
expect(other).to have_received(:exchange_to).with(Money::Currency.new("USD"))
end

it "adds Integer 0 to money and returns the same amount" do
Expand Down Expand Up @@ -285,8 +290,9 @@

it "converts other object amount to current currency and subtracts other amount from current amount (different currency)" do
other = Money.new(90, "EUR")
expect(other).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
allow(other).to receive(:exchange_to).and_return(Money.new(9_00, "USD"))
expect(Money.new(10_00, "USD") - other).to eq Money.new(1_00, "USD")
expect(other).to have_received(:exchange_to).with(Money::Currency.new("USD"))
end

it "subtract Integer 0 to money and returns the same amount" do
Expand Down Expand Up @@ -422,8 +428,9 @@
{ a: Money.new(-13, :USD), b: Money.new(-4, :EUR), c: 1.625 },
]
ts.each do |t|
expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
allow(t[:b]).to receive(:exchange_to).and_return(Money.new(t[:b].cents * 2, :USD))
expect(t[:a] / t[:b]).to eq t[:c]
expect(t[:b]).to have_received(:exchange_to).once.with(t[:a].currency)
end
end

Expand Down Expand Up @@ -499,8 +506,9 @@
{ a: Money.new(-13, :USD), b: Money.new(-4, :EUR), c: 1.625 },
]
ts.each do |t|
expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
allow(t[:b]).to receive(:exchange_to).and_return(Money.new(t[:b].cents * 2, :USD))
expect(t[:a].div(t[:b])).to eq t[:c]
expect(t[:b]).to have_received(:exchange_to).once.with(t[:a].currency)
end
end

Expand Down Expand Up @@ -552,8 +560,9 @@
{ a: Money.new(-13, :USD), b: Money.new(-4, :EUR), c: [1, Money.new(-5, :USD)] },
]
ts.each do |t|
expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
allow(t[:b]).to receive(:exchange_to).and_return(Money.new(t[:b].cents * 2, :USD))
expect(t[:a].divmod(t[:b])).to eq t[:c]
expect(t[:b]).to have_received(:exchange_to).once.with(t[:a].currency)
end
end

Expand Down Expand Up @@ -640,8 +649,9 @@
{ a: Money.new(-13, :USD), b: Money.new(-4, :EUR), c: Money.new(-5, :USD) },
]
ts.each do |t|
expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
allow(t[:b]).to receive(:exchange_to).and_return(Money.new(t[:b].cents * 2, :USD))
expect(t[:a].modulo(t[:b])).to eq t[:c]
expect(t[:b]).to have_received(:exchange_to).once.with(t[:a].currency)
end
end
end
Expand Down Expand Up @@ -679,8 +689,9 @@
{ a: Money.new(-13, :USD), b: Money.new(-4, :EUR), c: Money.new(-5, :USD) },
]
ts.each do |t|
expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
allow(t[:b]).to receive(:exchange_to).and_return(Money.new(t[:b].cents * 2, :USD))
expect(t[:a] % t[:b]).to eq t[:c]
expect(t[:b]).to have_received(:exchange_to).once.with(t[:a].currency)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/money/formatting_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@

specify "(symbol: true) returns $ when currency code is not recognized" do
currency = Money::Currency.new("EUR")
expect(currency).to receive(:symbol).and_return(nil)
allow(currency).to receive(:symbol).and_return(nil)
expect(Money.new(100, currency).format(symbol: true)).to eq "¤1,00"
end

Expand Down
57 changes: 44 additions & 13 deletions spec/money_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,20 @@

it "uses the correct bank inside block" do
old_bank = Money.default_bank
custom_store = double
custom_store = double :store

allow(old_bank).to receive(:add_rate)
allow(custom_store).to receive(:add_rate)

bank = Money::Bank::VariableExchange.new(custom_store)
Money.with_bank(bank) do
expect(custom_store).to receive(:add_rate).with("USD", "EUR", 0.5)
Money.add_rate("USD", "EUR", 0.5)
end

expect(old_bank).to receive(:add_rate).with("UAH", "NOK", 0.8)
Money.add_rate("UAH", "NOK", 0.8)

expect(custom_store).to have_received(:add_rate).with("USD", "EUR", 0.5)
expect(old_bank).to have_received(:add_rate).with("UAH", "NOK", 0.8)
end

it 'safely handles concurrent usage in different threads' do
Expand Down Expand Up @@ -660,7 +665,7 @@
let(:currency) { Money::Currency.new("EUR") }

before do
expect(currency).to receive(:symbol).and_return(nil)
allow(currency).to receive(:symbol).and_return(nil)
end

it "returns a generic currency symbol" do
Expand Down Expand Up @@ -773,10 +778,15 @@
describe "#to_money" do
it "works as documented" do
money = Money.new(10_00, "DKK")
allow(money.bank)
.to receive(:exchange_with)
.and_return(Money.new(200_00, Money::Currency.new("EUR")))
expect(money).to eq money.to_money
expect(money).to eq money.to_money("DKK")
expect(money.bank).to receive(:exchange_with).with(Money.new(10_00, Money::Currency.new("DKK")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
expect(money.to_money("EUR")).to eq Money.new(200_00, "EUR")
expect(money.bank)
.to have_received(:exchange_with)
.with(Money.new(10_00, Money::Currency.new("DKK")), Money::Currency.new("EUR"))
end
end

Expand All @@ -802,14 +812,24 @@
describe "#exchange_to" do
it "exchanges the amount via its exchange bank" do
money = Money.new(100_00, "USD")
expect(money.bank).to receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
allow(money.bank)
.to receive(:exchange_with)
.and_return(Money.new(200_00, Money::Currency.new('EUR')))
money.exchange_to("EUR")
expect(money.bank)
.to have_received(:exchange_with)
.with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR"))
end

it "exchanges the amount properly" do
money = Money.new(100_00, "USD")
expect(money.bank).to receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
allow(money.bank)
.to receive(:exchange_with)
.and_return(Money.new(200_00, Money::Currency.new('EUR')))
expect(money.exchange_to("EUR")).to eq Money.new(200_00, "EUR")
expect(money.bank)
.to have_received(:exchange_with)
.with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR"))
end

it "allows double conversion using same bank" do
Expand All @@ -822,14 +842,17 @@

it 'uses the block given as rounding method' do
money = Money.new(100_00, 'USD')
expect(money.bank).to receive(:exchange_with).and_yield(300_00)
expect { |block| money.exchange_to(Money::Currency.new('EUR'), &block) }.to yield_successive_args(300_00)
allow(money.bank).to receive(:exchange_with).and_yield(300_00)
expect { |block| money.exchange_to(Money::Currency.new('EUR'), &block) }
.to yield_successive_args(300_00)
expect(money.bank).to have_received(:exchange_with)
end

it "does no exchange when the currencies are the same" do
money = Money.new(100_00, "USD")
expect(money.bank).not_to receive(:exchange_with)
allow(money.bank).to receive(:exchange_with)
expect(money.exchange_to("USD")).to eq money
expect(money.bank).not_to have_received(:exchange_with)
end
end

Expand Down Expand Up @@ -1071,8 +1094,15 @@
end

describe ".default_currency" do
before { Money.setup_defaults }
after { Money.setup_defaults }
before do
allow(Money).to receive(:warn)

Money.setup_defaults
end

after do
Money.setup_defaults
end

it "accepts a lambda" do
Money.default_currency = lambda { :eur }
Expand All @@ -1087,8 +1117,9 @@
it 'does not warn if the default_currency has been changed' do
Money.default_currency = Money::Currency.new(:usd)

expect(Money).not_to receive(:warn)
Money.default_currency

expect(Money).not_to have_received(:warn)
end
end

Expand Down
18 changes: 16 additions & 2 deletions spec/rates_store/memory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@
end

describe 'add_rate' do
let(:guard) { store.instance_variable_get(:@guard) }

before do
allow(guard).to receive(:synchronize)
end

it "uses a mutex by default" do
expect(store.instance_variable_get(:@guard)).to receive(:synchronize)
store.add_rate('USD', 'EUR', 1.25)

expect(guard).to have_received(:synchronize)
end
end

Expand All @@ -35,9 +42,16 @@
end

describe '#transaction' do
let(:guard) { store.instance_variable_get("@guard") }

before do
allow(guard).to receive(:synchronize)
end

it 'uses mutex' do
expect(store.instance_variable_get('@guard')).to receive(:synchronize)
store.transaction { 1 + 1 }

expect(guard).to have_received(:synchronize)
end

it 'wraps block in mutex transaction only once' do
Expand Down