money 6.13.2 → 6.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/money/currency.rb +3 -3
- data/lib/money/currency/loader.rb +15 -13
- data/lib/money/money.rb +21 -17
- data/lib/money/money/arithmetic.rb +17 -7
- data/lib/money/version.rb +1 -1
- data/money.gemspec +3 -3
- metadata +5 -47
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.travis.yml +0 -32
- data/AUTHORS +0 -131
- data/CONTRIBUTING.md +0 -17
- data/Gemfile +0 -17
- data/Rakefile +0 -17
- data/spec/bank/base_spec.rb +0 -79
- data/spec/bank/single_currency_spec.rb +0 -13
- data/spec/bank/variable_exchange_spec.rb +0 -265
- data/spec/currency/heuristics_spec.rb +0 -11
- data/spec/currency/loader_spec.rb +0 -19
- data/spec/currency_spec.rb +0 -400
- data/spec/locale_backend/currency_spec.rb +0 -15
- data/spec/locale_backend/i18n_spec.rb +0 -70
- data/spec/locale_backend/legacy_spec.rb +0 -74
- data/spec/money/allocation_spec.rb +0 -135
- data/spec/money/arithmetic_spec.rb +0 -756
- data/spec/money/constructors_spec.rb +0 -91
- data/spec/money/formatting_spec.rb +0 -859
- data/spec/money/locale_backend_spec.rb +0 -14
- data/spec/money_spec.rb +0 -894
- data/spec/rates_store/memory_spec.rb +0 -80
- data/spec/spec_helper.rb +0 -30
- data/spec/support/shared_examples/money_examples.rb +0 -14
data/CONTRIBUTING.md
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# Contribution Guidelines
|
2
|
-
|
3
|
-
## Steps
|
4
|
-
|
5
|
-
1. Fork [the repo](https://github.com/RubyMoney/money)
|
6
|
-
2. Grab dependencies: `bundle install`
|
7
|
-
3. Make sure everything is working: `bundle exec rake spec`
|
8
|
-
4. Make your changes
|
9
|
-
5. Test your changes
|
10
|
-
5. Create a Pull Request
|
11
|
-
6. Celebrate!!!!!
|
12
|
-
|
13
|
-
## Notes
|
14
|
-
|
15
|
-
When contributing, please make sure to update the CHANGELOG and AUTHORS files
|
16
|
-
when you submit your pull request. Upon merging of your first pull request,
|
17
|
-
you will be given commit access to the repository.
|
data/Gemfile
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'coveralls', '>= 0.8.17', require: false
|
4
|
-
gem 'pry', require: false
|
5
|
-
|
6
|
-
# JSON gem no longer supports ruby < 2.0.0
|
7
|
-
if defined?(JRUBY_VERSION)
|
8
|
-
gem 'json'
|
9
|
-
elsif RUBY_VERSION =~ /^1/
|
10
|
-
# Legacy gem locks for ruby 1.9.x
|
11
|
-
gem 'json', '~> 1.8.3'
|
12
|
-
gem 'tins', '~> 1.6.0'
|
13
|
-
gem 'term-ansicolor', '< 1.4'
|
14
|
-
end
|
15
|
-
gem 'i18n', '<= 1.2.0' if RUBY_VERSION < '2.3'
|
16
|
-
|
17
|
-
gemspec
|
data/Rakefile
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rake/clean"
|
3
|
-
require "rspec/core/rake_task"
|
4
|
-
|
5
|
-
CLOBBER.include('doc', '.yardoc')
|
6
|
-
|
7
|
-
require "yard"
|
8
|
-
|
9
|
-
YARD::Rake::YardocTask.new do |t|
|
10
|
-
t.options << "--files" << "CHANGELOG.md,LICENSE"
|
11
|
-
end
|
12
|
-
|
13
|
-
RSpec::Core::RakeTask.new(:spec) do |t|
|
14
|
-
t.fail_on_error = false
|
15
|
-
end
|
16
|
-
|
17
|
-
task default: :spec
|
data/spec/bank/base_spec.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
class Money
|
2
|
-
module Bank
|
3
|
-
describe Base do
|
4
|
-
|
5
|
-
describe ".instance" do
|
6
|
-
it "is local to one class" do
|
7
|
-
klass = Base
|
8
|
-
subclass = Class.new(Base)
|
9
|
-
expect(klass.instance).not_to eq subclass.instance
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "#initialize" do
|
14
|
-
it "accepts a block and stores @rounding_method" do
|
15
|
-
proc = Proc.new { |n| n.ceil }
|
16
|
-
bank = Base.new(&proc)
|
17
|
-
expect(bank.rounding_method).to eq proc
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "#setup" do
|
22
|
-
it "calls #setup after #initialize" do
|
23
|
-
class MyBank < Base
|
24
|
-
attr_reader :setup_called
|
25
|
-
|
26
|
-
def setup
|
27
|
-
@setup_called = true
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
bank = MyBank.new
|
32
|
-
expect(bank.setup_called).to eq true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "#exchange_with" do
|
37
|
-
it "is not implemented" do
|
38
|
-
expect { subject.exchange_with(Money.new(100, 'USD'), 'EUR') }.to raise_exception(NotImplementedError)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "#same_currency?" do
|
43
|
-
it "accepts str/str" do
|
44
|
-
expect { subject.send(:same_currency?, 'USD', 'EUR') }.to_not raise_exception
|
45
|
-
end
|
46
|
-
|
47
|
-
it "accepts currency/str" do
|
48
|
-
expect { subject.send(:same_currency?, Currency.wrap('USD'), 'EUR') }.to_not raise_exception
|
49
|
-
end
|
50
|
-
|
51
|
-
it "accepts str/currency" do
|
52
|
-
expect { subject.send(:same_currency?, 'USD', Currency.wrap('EUR')) }.to_not raise_exception
|
53
|
-
end
|
54
|
-
|
55
|
-
it "accepts currency/currency" do
|
56
|
-
expect { subject.send(:same_currency?, Currency.wrap('USD'), Currency.wrap('EUR')) }.to_not raise_exception
|
57
|
-
end
|
58
|
-
|
59
|
-
it "returns true when currencies match" do
|
60
|
-
expect(subject.send(:same_currency?, 'USD', 'USD')).to be true
|
61
|
-
expect(subject.send(:same_currency?, Currency.wrap('USD'), 'USD')).to be true
|
62
|
-
expect(subject.send(:same_currency?, 'USD', Currency.wrap('USD'))).to be true
|
63
|
-
expect(subject.send(:same_currency?, Currency.wrap('USD'), Currency.wrap('USD'))).to be true
|
64
|
-
end
|
65
|
-
|
66
|
-
it "returns false when currencies do not match" do
|
67
|
-
expect(subject.send(:same_currency?, 'USD', 'EUR')).to be false
|
68
|
-
expect(subject.send(:same_currency?, Currency.wrap('USD'), 'EUR')).to be false
|
69
|
-
expect(subject.send(:same_currency?, 'USD', Currency.wrap('EUR'))).to be false
|
70
|
-
expect(subject.send(:same_currency?, Currency.wrap('USD'), Currency.wrap('EUR'))).to be false
|
71
|
-
end
|
72
|
-
|
73
|
-
it "raises an UnknownCurrency exception when an unknown currency is passed" do
|
74
|
-
expect { subject.send(:same_currency?, 'AAA', 'BBB') }.to raise_exception(Currency::UnknownCurrency)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class Money
|
2
|
-
module Bank
|
3
|
-
describe SingleCurrency do
|
4
|
-
describe "#exchange_with" do
|
5
|
-
it "raises when called" do
|
6
|
-
expect {
|
7
|
-
subject.exchange_with(Money.new(100, 'USD'), 'EUR')
|
8
|
-
}.to raise_exception(DifferentCurrencyError, "No exchanging of currencies allowed: 1.00 USD to EUR")
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,265 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
class Money
|
5
|
-
module Bank
|
6
|
-
describe VariableExchange do
|
7
|
-
|
8
|
-
describe "#initialize" do
|
9
|
-
context "without &block" do
|
10
|
-
let(:bank) {
|
11
|
-
VariableExchange.new.tap do |bank|
|
12
|
-
bank.add_rate('USD', 'EUR', 1.33)
|
13
|
-
end
|
14
|
-
}
|
15
|
-
|
16
|
-
describe '#store' do
|
17
|
-
it 'defaults to Memory store' do
|
18
|
-
expect(bank.store).to be_a(Money::RatesStore::Memory)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'custom store' do
|
23
|
-
let(:custom_store) { Object.new }
|
24
|
-
|
25
|
-
let(:bank) { VariableExchange.new(custom_store) }
|
26
|
-
|
27
|
-
it 'sets #store to be custom store' do
|
28
|
-
expect(bank.store).to eql(custom_store)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "#exchange_with" do
|
33
|
-
it "accepts str" do
|
34
|
-
expect { bank.exchange_with(Money.new(100, 'USD'), 'EUR') }.to_not raise_exception
|
35
|
-
end
|
36
|
-
|
37
|
-
it "accepts currency" do
|
38
|
-
expect { bank.exchange_with(Money.new(100, 'USD'), Currency.wrap('EUR')) }.to_not raise_exception
|
39
|
-
end
|
40
|
-
|
41
|
-
it "exchanges one currency to another" do
|
42
|
-
expect(bank.exchange_with(Money.new(100, 'USD'), 'EUR')).to eq Money.new(133, 'EUR')
|
43
|
-
end
|
44
|
-
|
45
|
-
it "truncates extra digits" do
|
46
|
-
expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR')).to eq Money.new(13, 'EUR')
|
47
|
-
end
|
48
|
-
|
49
|
-
it "raises an UnknownCurrency exception when an unknown currency is requested" do
|
50
|
-
expect { bank.exchange_with(Money.new(100, 'USD'), 'BBB') }.to raise_exception(Currency::UnknownCurrency)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "raises an UnknownRate exception when an unknown rate is requested" do
|
54
|
-
expect { bank.exchange_with(Money.new(100, 'USD'), 'JPY') }.to raise_exception(UnknownRate)
|
55
|
-
end
|
56
|
-
|
57
|
-
#it "rounds the exchanged result down" do
|
58
|
-
# bank.add_rate("USD", "EUR", 0.788332676)
|
59
|
-
# bank.add_rate("EUR", "YEN", 122.631477)
|
60
|
-
# expect(bank.exchange_with(Money.new(10_00, "USD"), "EUR")).to eq Money.new(788, "EUR")
|
61
|
-
# expect(bank.exchange_with(Money.new(500_00, "EUR"), "YEN")).to eq Money.new(6131573, "YEN")
|
62
|
-
#end
|
63
|
-
|
64
|
-
it "accepts a custom truncation method" do
|
65
|
-
proc = Proc.new { |n| n.ceil }
|
66
|
-
expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc)).to eq Money.new(14, 'EUR')
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'works with big numbers' do
|
70
|
-
amount = 10**20
|
71
|
-
expect(bank.exchange_with(Money.usd(amount), :EUR)).to eq Money.eur(1.33 * amount)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "preserves the class in the result when given a subclass of Money" do
|
75
|
-
special_money_class = Class.new(Money)
|
76
|
-
expect(bank.exchange_with(special_money_class.new(100, 'USD'), 'EUR')).to be_a special_money_class
|
77
|
-
end
|
78
|
-
|
79
|
-
it "doesn't loose precision when handling larger amounts" do
|
80
|
-
expect(bank.exchange_with(Money.new(100_000_000_000_000_01, 'USD'), 'EUR')).to eq Money.new(133_000_000_000_000_01, 'EUR')
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
context "with &block" do
|
86
|
-
let(:bank) {
|
87
|
-
proc = Proc.new { |n| n.ceil }
|
88
|
-
VariableExchange.new(&proc).tap do |bank|
|
89
|
-
bank.add_rate('USD', 'EUR', 1.33)
|
90
|
-
end
|
91
|
-
}
|
92
|
-
|
93
|
-
describe "#exchange_with" do
|
94
|
-
it "uses the stored truncation method" do
|
95
|
-
expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR')).to eq Money.new(14, 'EUR')
|
96
|
-
end
|
97
|
-
|
98
|
-
it "accepts a custom truncation method" do
|
99
|
-
proc = Proc.new { |n| n.ceil + 1 }
|
100
|
-
expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc)).to eq Money.new(15, 'EUR')
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe "#add_rate" do
|
107
|
-
it 'delegates to store#add_rate' do
|
108
|
-
expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
|
109
|
-
expect(subject.add_rate('USD', 'EUR', 1.25)).to eql 1.25
|
110
|
-
end
|
111
|
-
|
112
|
-
it "adds rates with correct ISO codes" do
|
113
|
-
expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 0.788332676)
|
114
|
-
subject.add_rate("USD", "EUR", 0.788332676)
|
115
|
-
|
116
|
-
expect(subject.store).to receive(:add_rate).with('EUR', 'JPY', 122.631477)
|
117
|
-
subject.add_rate("EUR", "YEN", 122.631477)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "treats currency names case-insensitively" do
|
121
|
-
subject.add_rate("usd", "eur", 1)
|
122
|
-
expect(subject.get_rate('USD', 'EUR')).to eq 1
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "#set_rate" do
|
127
|
-
it 'delegates to store#add_rate' do
|
128
|
-
expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
|
129
|
-
expect(subject.set_rate('USD', 'EUR', 1.25)).to eql 1.25
|
130
|
-
end
|
131
|
-
|
132
|
-
it "sets a rate" do
|
133
|
-
subject.set_rate('USD', 'EUR', 1.25)
|
134
|
-
expect(subject.store.get_rate('USD', 'EUR')).to eq 1.25
|
135
|
-
end
|
136
|
-
|
137
|
-
it "raises an UnknownCurrency exception when an unknown currency is passed" do
|
138
|
-
expect { subject.set_rate('AAA', 'BBB', 1.25) }.to raise_exception(Currency::UnknownCurrency)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe "#get_rate" do
|
143
|
-
it "returns a rate" do
|
144
|
-
subject.set_rate('USD', 'EUR', 1.25)
|
145
|
-
expect(subject.get_rate('USD', 'EUR')).to eq 1.25
|
146
|
-
end
|
147
|
-
|
148
|
-
it "raises an UnknownCurrency exception when an unknown currency is passed" do
|
149
|
-
expect { subject.get_rate('AAA', 'BBB') }.to raise_exception(Currency::UnknownCurrency)
|
150
|
-
end
|
151
|
-
|
152
|
-
it "delegates options to store, options are a no-op" do
|
153
|
-
expect(subject.store).to receive(:get_rate).with('USD', 'EUR')
|
154
|
-
subject.get_rate('USD', 'EUR', without_mutex: true)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
describe "#export_rates" do
|
159
|
-
before :each do
|
160
|
-
subject.set_rate('USD', 'EUR', 1.25)
|
161
|
-
subject.set_rate('USD', 'JPY', 2.55)
|
162
|
-
|
163
|
-
@rates = { "USD_TO_EUR" => 1.25, "USD_TO_JPY" => 2.55 }
|
164
|
-
end
|
165
|
-
|
166
|
-
context "with format == :json" do
|
167
|
-
it "should return rates formatted as json" do
|
168
|
-
json = subject.export_rates(:json)
|
169
|
-
expect(JSON.load(json)).to eq @rates
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context "with format == :ruby" do
|
174
|
-
it "should return rates formatted as ruby objects" do
|
175
|
-
expect(Marshal.load(subject.export_rates(:ruby))).to eq @rates
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
context "with format == :yaml" do
|
180
|
-
it "should return rates formatted as yaml" do
|
181
|
-
yaml = subject.export_rates(:yaml)
|
182
|
-
expect(YAML.load(yaml)).to eq @rates
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
context "with unknown format" do
|
187
|
-
it "raises Money::Bank::UnknownRateFormat" do
|
188
|
-
expect { subject.export_rates(:foo)}.to raise_error UnknownRateFormat
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
context "with :file provided" do
|
193
|
-
it "writes rates to file" do
|
194
|
-
f = double('IO')
|
195
|
-
expect(File).to receive(:open).with('null', 'w').and_yield(f)
|
196
|
-
expect(f).to receive(:write).with(JSON.dump(@rates))
|
197
|
-
|
198
|
-
subject.export_rates(:json, 'null')
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
it "delegates execution to store, options are a no-op" do
|
203
|
-
expect(subject.store).to receive(:transaction)
|
204
|
-
subject.export_rates(:yaml, nil, foo: 1)
|
205
|
-
end
|
206
|
-
|
207
|
-
end
|
208
|
-
|
209
|
-
describe "#import_rates" do
|
210
|
-
context "with format == :json" do
|
211
|
-
it "loads the rates provided" do
|
212
|
-
s = '{"USD_TO_EUR":1.25,"USD_TO_JPY":2.55}'
|
213
|
-
subject.import_rates(:json, s)
|
214
|
-
expect(subject.get_rate('USD', 'EUR')).to eq 1.25
|
215
|
-
expect(subject.get_rate('USD', 'JPY')).to eq 2.55
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context "with format == :ruby" do
|
220
|
-
it "loads the rates provided" do
|
221
|
-
s = Marshal.dump({"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55})
|
222
|
-
subject.import_rates(:ruby, s)
|
223
|
-
expect(subject.get_rate('USD', 'EUR')).to eq 1.25
|
224
|
-
expect(subject.get_rate('USD', 'JPY')).to eq 2.55
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context "with format == :yaml" do
|
229
|
-
it "loads the rates provided" do
|
230
|
-
s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
|
231
|
-
subject.import_rates(:yaml, s)
|
232
|
-
expect(subject.get_rate('USD', 'EUR')).to eq 1.25
|
233
|
-
expect(subject.get_rate('USD', 'JPY')).to eq 2.55
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
context "with unknown format" do
|
238
|
-
it "raises Money::Bank::UnknownRateFormat" do
|
239
|
-
expect { subject.import_rates(:foo, "")}.to raise_error UnknownRateFormat
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
it "delegates execution to store#transaction" do
|
244
|
-
expect(subject.store).to receive(:transaction)
|
245
|
-
s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
|
246
|
-
subject.import_rates(:yaml, s, foo: 1)
|
247
|
-
end
|
248
|
-
|
249
|
-
end
|
250
|
-
|
251
|
-
describe "#marshal_dump" do
|
252
|
-
it "does not raise an error" do
|
253
|
-
expect { Marshal.dump(subject) }.to_not raise_error
|
254
|
-
end
|
255
|
-
|
256
|
-
it "works with Marshal.load" do
|
257
|
-
bank = Marshal.load(Marshal.dump(subject))
|
258
|
-
|
259
|
-
expect(bank.rates).to eq subject.rates
|
260
|
-
expect(bank.rounding_method).to eq subject.rounding_method
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe Money::Currency::Heuristics do
|
4
|
-
describe "#analyze_string" do
|
5
|
-
let(:it) { Money::Currency }
|
6
|
-
|
7
|
-
it "it raises deprecation error" do
|
8
|
-
expect{ it.analyze('123') }.to raise_error(StandardError, 'Heuristics deprecated, add `gem "money-heuristics"` to Gemfile')
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe Money::Currency::Loader do
|
4
|
-
class CurrencyLoader
|
5
|
-
include Money::Currency::Loader
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:loader) { CurrencyLoader.new }
|
9
|
-
|
10
|
-
it "returns a currency table hash" do
|
11
|
-
expect(loader.load_currencies).to be_a Hash
|
12
|
-
end
|
13
|
-
|
14
|
-
it "parse currency_iso.json & currency_non_iso.json & currency_backwards_compatible.json" do
|
15
|
-
expect(loader).to receive(:parse_currency_file).exactly(3).times.and_return({})
|
16
|
-
|
17
|
-
loader.load_currencies
|
18
|
-
end
|
19
|
-
end
|