diff --git a/.rubocop.yml b/.rubocop.yml index d799642763..a9761c8286 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -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: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ea6d12eabb..3d8b64115b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -91,17 +91,6 @@ RSpec/InstanceVariable: - 'spec/money/formatting_spec.rb' - 'spec/money_spec.rb' -# Configuration parameters: EnforcedStyle. -# SupportedStyles: have_received, receive -RSpec/MessageSpies: - Exclude: - - 'spec/bank/variable_exchange_spec.rb' - - 'spec/currency/loader_spec.rb' - - 'spec/money/arithmetic_spec.rb' - - 'spec/money/formatting_spec.rb' - - 'spec/money_spec.rb' - - 'spec/rates_store/memory_spec.rb' - RSpec/MultipleExpectations: Max: 18 diff --git a/spec/bank/variable_exchange_spec.rb b/spec/bank/variable_exchange_spec.rb index 34fa6206eb..281a2b296d 100644 --- a/spec/bank/variable_exchange_spec.rb +++ b/spec/bank/variable_exchange_spec.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/spec/currency/loader_spec.rb b/spec/currency/loader_spec.rb index 6107da5150..bf5f686237 100644 --- a/spec/currency/loader_spec.rb +++ b/spec/currency/loader_spec.rb @@ -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 diff --git a/spec/money/arithmetic_spec.rb b/spec/money/arithmetic_spec.rb index 206901c3ba..129685ffd2 100644 --- a/spec/money/arithmetic_spec.rb +++ b/spec/money/arithmetic_spec.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/spec/money/formatting_spec.rb b/spec/money/formatting_spec.rb index fb1e50758a..58abd78988 100644 --- a/spec/money/formatting_spec.rb +++ b/spec/money/formatting_spec.rb @@ -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 diff --git a/spec/money_spec.rb b/spec/money_spec.rb index 98c15eea98..fe5343b0e6 100644 --- a/spec/money_spec.rb +++ b/spec/money_spec.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 } @@ -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 diff --git a/spec/rates_store/memory_spec.rb b/spec/rates_store/memory_spec.rb index 2ea36a113b..22fac7e2c4 100644 --- a/spec/rates_store/memory_spec.rb +++ b/spec/rates_store/memory_spec.rb @@ -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 @@ -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