money 6.6.0 → 6.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c65fe09cbae38c4022a53cdc0c6b5cba47e72930
4
- data.tar.gz: 5de5a0732f90ab4af46ef801378a7a6161b5324d
3
+ metadata.gz: f3285f9f76aec95f56d6f73d260330c3bc0f6984
4
+ data.tar.gz: 956b5acb84b6b2100d31e49b4a4c79bfbc71e612
5
5
  SHA512:
6
- metadata.gz: bba3d4bc1dfc26c28ed9e4720a815c0bf36c6dd0376c17a664cb70d066d5c436c29da795abade5bd61c0797808f5969f52fa696d7bfeb874333ad11411745583
7
- data.tar.gz: 1a38008c4890e953e1002485fd1098c935ed370cf4e05648846327302d2202fed8adf96df22b37cb98abf7de5b36a8cc87bc7d168d7ab606f2d87a28d87e4f32
6
+ metadata.gz: 2892ac7ef0eb825da0e0d2d37c1c794703f781d3667bf265f72f032d2de0f132fe061965561dbbbf5d70f6de57a6658c4a11608e83462bee46a263a27c49b320
7
+ data.tar.gz: ee6ac428822ff9c7783b684d50374fb6bb2e9b41722c4e20d57f57328c972dcb0055d62efb0684c4fc29dace6bc6340b5e36bbcfa2c58a75e19f63179b6ae49a
data/.travis.yml CHANGED
@@ -3,12 +3,12 @@ sudo: false
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
- - 2.1.2
7
- - 2.2.0
6
+ - 2.1.6
7
+ - 2.2.2
8
8
  - rbx-2
9
9
  script: bundle exec rspec spec
10
10
  notifications:
11
- recipients:
11
+ email:
12
12
  - semmons99@gmail.com
13
13
  - andreas@aloop.org
14
14
  - weppos@weppos.net
data/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  ## Next release
4
4
 
5
+ TBD
6
+
7
+ ## 6.6.0
5
8
  - Fixed VariableExchange#exchange_with for big numbers.
6
9
  - Add Currency symbol translation support
7
10
  - `Currency.all` raises a more helpful error message
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # RubyMoney - Money
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/money.png)](http://badge.fury.io/rb/money)
4
- [![Build Status](https://travis-ci.org/RubyMoney/money.png?branch=master)](https://travis-ci.org/RubyMoney/money)
5
- [![Code Climate](https://codeclimate.com/github/RubyMoney/money.png)](https://codeclimate.com/github/RubyMoney/money)
6
- [![Coverage Status](https://coveralls.io/repos/RubyMoney/money/badge.png?branch=master)](https://coveralls.io/r/RubyMoney/money?branch=master)
7
- [![Inline docs](http://inch-ci.org/github/RubyMoney/money.png)](http://inch-ci.org/github/RubyMoney/money)
8
- [![Dependency Status](https://gemnasium.com/RubyMoney/money.png)](https://gemnasium.com/RubyMoney/money)
9
- [![License](http://img.shields.io/license/MIT.png?color=green)](http://opensource.org/licenses/MIT)
3
+ [![Gem Version](https://badge.fury.io/rb/money.svg)](http://badge.fury.io/rb/money)
4
+ [![Build Status](https://travis-ci.org/RubyMoney/money.svg?branch=master)](https://travis-ci.org/RubyMoney/money)
5
+ [![Code Climate](https://codeclimate.com/github/RubyMoney/money.svg)](https://codeclimate.com/github/RubyMoney/money)
6
+ [![Coverage Status](https://coveralls.io/repos/RubyMoney/money/badge.svg?branch=master)](https://coveralls.io/r/RubyMoney/money?branch=master)
7
+ [![Inline docs](http://inch-ci.org/github/RubyMoney/money.svg)](http://inch-ci.org/github/RubyMoney/money)
8
+ [![Dependency Status](https://gemnasium.com/RubyMoney/money.svg)](https://gemnasium.com/RubyMoney/money)
9
+ [![License](https://img.shields.io/github/license/RubyMoney/money.svg)](http://opensource.org/licenses/MIT)
10
10
 
11
11
  :warning: Please read the [migration notes](#migration-notes) before upgrading to a new major version.
12
12
 
@@ -108,7 +108,7 @@ class Money
108
108
  else
109
109
  if rate = get_rate(from.currency, to_currency)
110
110
  fractional = calculate_fractional(from, to_currency)
111
- Money.new(
111
+ from.class.new(
112
112
  exchange(fractional, rate, &block), to_currency
113
113
  )
114
114
  else
@@ -18,6 +18,7 @@ class Money
18
18
 
19
19
  # Keeping cached instances in sync between threads
20
20
  @@mutex = Mutex.new
21
+ @@instances = {}
21
22
 
22
23
  # Thrown when a Currency has been registered without all the attributes
23
24
  # which are required for the current action.
@@ -34,18 +35,17 @@ class Money
34
35
  class UnknownCurrency < ArgumentError; end
35
36
 
36
37
  class << self
37
- alias_method :original_new, :new
38
38
  def new(id)
39
39
  id = id.to_s.downcase
40
40
  unless stringified_keys.include?(id)
41
41
  raise UnknownCurrency, "Unknown currency '#{id}'"
42
42
  end
43
43
 
44
- @@mutex.synchronize { instances[id] } || super
44
+ _instances[id] || @@mutex.synchronize { _instances[id] ||= super }
45
45
  end
46
46
 
47
- def instances
48
- @instances ||= Hash.new { |h, k| h[k] = original_new(k) }
47
+ def _instances
48
+ @@instances
49
49
  end
50
50
 
51
51
  # Lookup a currency with given +id+ an returns a +Currency+ instance on
@@ -168,7 +168,7 @@ class Money
168
168
  # @option delimiter [String] character between each thousands place
169
169
  def register(curr)
170
170
  key = curr.fetch(:iso_code).downcase.to_sym
171
- @@mutex.synchronize { instances.delete(key.to_s) }
171
+ @@mutex.synchronize { _instances.delete(key.to_s) }
172
172
  @table[key] = curr
173
173
  @stringified_keys = stringify_keys
174
174
  end
data/lib/money/money.rb CHANGED
@@ -340,7 +340,7 @@ class Money
340
340
  #
341
341
  # @return [String]
342
342
  def inspect
343
- "#<Money fractional:#{fractional} currency:#{currency}>"
343
+ "#<#{self.class.name} fractional:#{fractional} currency:#{currency}>"
344
344
  end
345
345
 
346
346
  # Returns the amount of money as a string.
@@ -497,7 +497,7 @@ class Money
497
497
  left_over.to_i.times { |i| amounts[i % amounts.length] += 1 }
498
498
  end
499
499
 
500
- amounts.collect { |fractional| Money.new(fractional, currency) }
500
+ amounts.collect { |fractional| self.class.new(fractional, currency) }
501
501
  end
502
502
 
503
503
  # Split money amongst parties evenly without losing pennies.
@@ -535,7 +535,7 @@ class Money
535
535
  #
536
536
  def round(rounding_mode = self.class.rounding_mode)
537
537
  if self.class.infinite_precision
538
- Money.new(fractional.round(0, rounding_mode), self.currency)
538
+ self.class.new(fractional.round(0, rounding_mode), self.currency)
539
539
  else
540
540
  self
541
541
  end
@@ -605,8 +605,8 @@ class Money
605
605
  end
606
606
 
607
607
  def split_flat(num)
608
- low = Money.new(fractional / num, currency)
609
- high = Money.new(low.fractional + 1, currency)
608
+ low = self.class.new(fractional / num, currency)
609
+ high = self.class.new(low.fractional + 1, currency)
610
610
 
611
611
  remainder = fractional % num
612
612
 
@@ -8,7 +8,7 @@ class Money
8
8
  # @example
9
9
  # - Money.new(100) #=> #<Money @fractional=-100>
10
10
  def -@
11
- Money.new(-fractional, currency)
11
+ self.class.new(-fractional, currency)
12
12
  end
13
13
 
14
14
  # Checks whether two money objects have the same currency and the same
@@ -83,7 +83,7 @@ class Money
83
83
  def +(other_money)
84
84
  return self if other_money == 0
85
85
  other_money = other_money.exchange_to(currency)
86
- Money.new(fractional + other_money.fractional, currency)
86
+ self.class.new(fractional + other_money.fractional, currency)
87
87
  end
88
88
 
89
89
  # Returns a new Money object containing the difference between the two
@@ -100,7 +100,7 @@ class Money
100
100
  def -(other_money)
101
101
  return self if other_money == 0
102
102
  other_money = other_money.exchange_to(currency)
103
- Money.new(fractional - other_money.fractional, currency)
103
+ self.class.new(fractional - other_money.fractional, currency)
104
104
  end
105
105
 
106
106
  # Multiplies the monetary value with the given number and returns a new
@@ -119,9 +119,9 @@ class Money
119
119
  #
120
120
  def *(value)
121
121
  if value.is_a? Numeric
122
- Money.new(fractional * value, currency)
122
+ self.class.new(fractional * value, currency)
123
123
  else
124
- raise ArgumentError, "Can't multiply a Money by a #{value.class.name}'s value"
124
+ raise ArgumentError, "Can't multiply a #{self.class.name} by a #{value.class.name}'s value"
125
125
  end
126
126
  end
127
127
 
@@ -141,10 +141,10 @@ class Money
141
141
  # Money.new(100) / Money.new(10) #=> 10.0
142
142
  #
143
143
  def /(value)
144
- if value.is_a?(Money)
144
+ if value.is_a?(self.class)
145
145
  fractional / as_d(value.exchange_to(currency).fractional).to_f
146
146
  else
147
- Money.new(fractional / as_d(value), currency)
147
+ self.class.new(fractional / as_d(value), currency)
148
148
  end
149
149
  end
150
150
 
@@ -182,16 +182,16 @@ class Money
182
182
  def divmod_money(val)
183
183
  cents = val.exchange_to(currency).cents
184
184
  quotient, remainder = fractional.divmod(cents)
185
- [quotient, Money.new(remainder, currency)]
185
+ [quotient, self.class.new(remainder, currency)]
186
186
  end
187
187
  private :divmod_money
188
188
 
189
189
  def divmod_other(val)
190
190
  if self.class.infinite_precision
191
191
  quotient, remainder = fractional.divmod(as_d(val))
192
- [Money.new(quotient, currency), Money.new(remainder, currency)]
192
+ [self.class.new(quotient, currency), self.class.new(remainder, currency)]
193
193
  else
194
- [div(val), Money.new(fractional.modulo(val), currency)]
194
+ [div(val), self.class.new(fractional.modulo(val), currency)]
195
195
  end
196
196
  end
197
197
  private :divmod_other
@@ -236,7 +236,7 @@ class Money
236
236
  if (fractional < 0 && val < 0) || (fractional > 0 && val > 0)
237
237
  self.modulo(val)
238
238
  else
239
- self.modulo(val) - (val.is_a?(Money) ? val : Money.new(val, currency))
239
+ self.modulo(val) - (val.is_a?(Money) ? val : self.class.new(val, currency))
240
240
  end
241
241
  end
242
242
 
@@ -247,7 +247,7 @@ class Money
247
247
  # @example
248
248
  # Money.new(-100).abs #=> #<Money @fractional=100>
249
249
  def abs
250
- Money.new(fractional.abs, currency)
250
+ self.class.new(fractional.abs, currency)
251
251
  end
252
252
 
253
253
  # Test if the money amount is zero.
@@ -11,7 +11,7 @@ class Money
11
11
  # Money.empty #=> #<Money @fractional=0>
12
12
  def empty(currency = default_currency)
13
13
  @empty ||= {}
14
- @empty[currency] ||= Money.new(0, currency).freeze
14
+ @empty[currency] ||= new(0, currency).freeze
15
15
  end
16
16
  alias_method :zero, :empty
17
17
 
@@ -28,7 +28,7 @@ class Money
28
28
  # n.cents #=> 100
29
29
  # n.currency #=> #<Money::Currency id: cad>
30
30
  def ca_dollar(cents)
31
- Money.new(cents, "CAD")
31
+ new(cents, "CAD")
32
32
  end
33
33
  alias_method :cad, :ca_dollar
34
34
 
@@ -45,7 +45,7 @@ class Money
45
45
  # n.cents #=> 100
46
46
  # n.currency #=> #<Money::Currency id: usd>
47
47
  def us_dollar(cents)
48
- Money.new(cents, "USD")
48
+ new(cents, "USD")
49
49
  end
50
50
  alias_method :usd, :us_dollar
51
51
 
@@ -61,7 +61,7 @@ class Money
61
61
  # n.cents #=> 100
62
62
  # n.currency #=> #<Money::Currency id: eur>
63
63
  def euro(cents)
64
- Money.new(cents, "EUR")
64
+ new(cents, "EUR")
65
65
  end
66
66
  alias_method :eur, :euro
67
67
 
@@ -77,7 +77,7 @@ class Money
77
77
  # n.fractional #=> 100
78
78
  # n.currency #=> #<Money::Currency id: gbp>
79
79
  def pound_sterling(pence)
80
- Money.new(pence, "GBP")
80
+ new(pence, "GBP")
81
81
  end
82
82
  alias_method :gbp, :pound_sterling
83
83
 
data/lib/money/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Money
2
- VERSION = "6.6.0"
2
+ VERSION = "6.6.1"
3
3
  end
@@ -71,6 +71,11 @@ class Money
71
71
  amount = 10**20
72
72
  expect(bank.exchange_with(Money.usd(amount), :EUR)).to eq Money.eur(1.33 * amount)
73
73
  end
74
+
75
+ it "preserves the class in the result when given a subclass of Money" do
76
+ special_money_class = Class.new(Money)
77
+ expect(bank.exchange_with(special_money_class.new(100, 'USD'), 'EUR')).to be_a special_money_class
78
+ end
74
79
  end
75
80
  end
76
81
 
@@ -170,7 +170,8 @@ class Money
170
170
 
171
171
 
172
172
  describe "#initialize" do
173
- before { Currency.instances.clear }
173
+ before { Currency._instances.clear }
174
+
174
175
  it "lookups data from loaded config" do
175
176
  currency = Currency.new("USD")
176
177
  expect(currency.id).to eq :usd
@@ -185,6 +186,13 @@ class Money
185
186
  expect(currency.smallest_denomination).to eq 1
186
187
  end
187
188
 
189
+ it 'caches instances' do
190
+ currency = Currency.new("USD")
191
+
192
+ expect(Currency._instances.length).to eq 1
193
+ expect(Currency._instances["usd"].object_id).to eq currency.object_id
194
+ end
195
+
188
196
  it "raises UnknownCurrency with unknown currency" do
189
197
  expect { Currency.new("xxx") }.to raise_error(Currency::UnknownCurrency, /xxx/)
190
198
  end
@@ -9,6 +9,11 @@ describe Money do
9
9
  expect((- Money.new(1))).to eq Money.new(-1)
10
10
  expect((- Money.new(-1))).to eq Money.new(1)
11
11
  end
12
+
13
+ it "preserves the class in the result when using a subclass of Money" do
14
+ special_money_class = Class.new(Money)
15
+ expect(- special_money_class.new(10_00)).to be_a special_money_class
16
+ end
12
17
  end
13
18
 
14
19
  describe "#==" do
@@ -173,6 +178,11 @@ describe Money do
173
178
  it "adds Fixnum 0 to money and returns the same ammount" do
174
179
  expect(Money.new(10_00) + 0).to eq Money.new(10_00)
175
180
  end
181
+
182
+ it "preserves the class in the result when using a subclass of Money" do
183
+ special_money_class = Class.new(Money)
184
+ expect(special_money_class.new(10_00, "USD") + Money.new(90, "USD")).to be_a special_money_class
185
+ end
176
186
  end
177
187
 
178
188
  describe "#-" do
@@ -189,6 +199,11 @@ describe Money do
189
199
  it "subtract Fixnum 0 to money and returns the same ammount" do
190
200
  expect(Money.new(10_00) - 0).to eq Money.new(10_00)
191
201
  end
202
+
203
+ it "preserves the class in the result when using a subclass of Money" do
204
+ special_money_class = Class.new(Money)
205
+ expect(special_money_class.new(10_00, "USD") - Money.new(90, "USD")).to be_a special_money_class
206
+ end
192
207
  end
193
208
 
194
209
  describe "#*" do
@@ -215,6 +230,11 @@ describe Money do
215
230
  it "does not multiply Money by an object which is NOT a number" do
216
231
  expect { Money.new( 10, :USD) * 'abc' }.to raise_error(ArgumentError)
217
232
  end
233
+
234
+ it "preserves the class in the result when using a subclass of Money" do
235
+ special_money_class = Class.new(Money)
236
+ expect(special_money_class.new(10_00, "USD") * 2).to be_a special_money_class
237
+ end
218
238
  end
219
239
 
220
240
  describe "#/" do
@@ -230,6 +250,11 @@ describe Money do
230
250
  end
231
251
  end
232
252
 
253
+ it "preserves the class in the result when using a subclass of Money" do
254
+ special_money_class = Class.new(Money)
255
+ expect(special_money_class.new(10_00, "USD") / 2).to be_a special_money_class
256
+ end
257
+
233
258
  context 'rounding preference' do
234
259
  before do
235
260
  allow(Money).to receive(:rounding_mode).and_return(rounding_mode)
@@ -412,6 +437,16 @@ describe Money do
412
437
  end
413
438
  end
414
439
  end
440
+
441
+ it "preserves the class in the result when dividing a subclass of Money by a fixnum" do
442
+ special_money_class = Class.new(Money)
443
+ expect(special_money_class.new(10_00, "USD").divmod(4).last).to be_a special_money_class
444
+ end
445
+
446
+ it "preserves the class in the result when using a subclass of Money by a subclass of Money" do
447
+ special_money_class = Class.new(Money)
448
+ expect(special_money_class.new(10_00, "USD").divmod(special_money_class.new(4_00)).last).to be_a special_money_class
449
+ end
415
450
  end
416
451
 
417
452
  describe "#modulo" do
@@ -512,6 +547,11 @@ describe Money do
512
547
  expect(n.abs).to eq Money.new( 1, :USD)
513
548
  expect(n).to eq Money.new(-1, :USD)
514
549
  end
550
+
551
+ it "preserves the class in the result when using a subclass of Money" do
552
+ special_money_class = Class.new(Money)
553
+ expect(special_money_class.new(-1).abs).to be_a special_money_class
554
+ end
515
555
  end
516
556
 
517
557
  describe "#zero?" do
@@ -20,12 +20,22 @@ describe Money::Constructors do
20
20
  it "doesn't allow money to be modified for a currency" do
21
21
  expect(Money.empty).to be_frozen
22
22
  end
23
+
24
+ it "instantiates a subclass when inheritance is used" do
25
+ special_money_class = Class.new(Money)
26
+ expect(special_money_class.empty).to be_a special_money_class
27
+ end
23
28
  end
24
29
 
25
30
 
26
31
  describe "::zero" do
27
32
  subject { Money.zero }
28
33
  it { is_expected.to eq Money.empty }
34
+
35
+ it "instantiates a subclass when inheritance is used" do
36
+ special_money_class = Class.new(Money)
37
+ expect(special_money_class.zero).to be_a special_money_class
38
+ end
29
39
  end
30
40
 
31
41
 
@@ -37,6 +47,11 @@ describe Money::Constructors do
37
47
  it "is aliased to ::cad" do
38
48
  expect(Money.cad(50)).to eq Money.ca_dollar(50)
39
49
  end
50
+
51
+ it "instantiates a subclass when inheritance is used" do
52
+ special_money_class = Class.new(Money)
53
+ expect(special_money_class.ca_dollar(0)).to be_a special_money_class
54
+ end
40
55
  end
41
56
 
42
57
 
@@ -48,6 +63,11 @@ describe Money::Constructors do
48
63
  it "is aliased to ::usd" do
49
64
  expect(Money.usd(50)).to eq Money.us_dollar(50)
50
65
  end
66
+
67
+ it "instantiates a subclass when inheritance is used" do
68
+ special_money_class = Class.new(Money)
69
+ expect(special_money_class.us_dollar(0)).to be_a special_money_class
70
+ end
51
71
  end
52
72
 
53
73
 
@@ -59,6 +79,11 @@ describe Money::Constructors do
59
79
  it "is aliased to ::eur" do
60
80
  expect(Money.eur(50)).to eq Money.euro(50)
61
81
  end
82
+
83
+ it "instantiates a subclass when inheritance is used" do
84
+ special_money_class = Class.new(Money)
85
+ expect(special_money_class.euro(0)).to be_a special_money_class
86
+ end
62
87
  end
63
88
 
64
89
 
@@ -70,6 +95,11 @@ describe Money::Constructors do
70
95
  it "is aliased to ::gbp" do
71
96
  expect(Money.gbp(50)).to eq Money.pound_sterling(50)
72
97
  end
98
+
99
+ it "instantiates a subclass when inheritance is used" do
100
+ special_money_class = Class.new(Money)
101
+ expect(special_money_class.pound_sterling(0)).to be_a special_money_class
102
+ end
73
103
  end
74
104
 
75
105
  end
data/spec/money_spec.rb CHANGED
@@ -590,6 +590,11 @@ YAML
590
590
  expect { Money.us_dollar(0.05).allocate([0.5, 0.6]) }.to raise_error(ArgumentError)
591
591
  end
592
592
 
593
+ it "keeps subclasses intact" do
594
+ special_money_class = Class.new(Money)
595
+ expect(special_money_class.new(005).allocate([1]).first).to be_a special_money_class
596
+ end
597
+
593
598
  context "with infinite_precision", :infinite_precision do
594
599
  it "allows for fractional cents allocation" do
595
600
  one_third = BigDecimal("1") / BigDecimal("3")
@@ -627,6 +632,11 @@ YAML
627
632
  expect(moneys[2].cents).to eq 33
628
633
  end
629
634
 
635
+ it "preserves the class in the result when using a subclass of Money" do
636
+ special_money_class = Class.new(Money)
637
+ expect(special_money_class.new(10_00).split(1).first).to be_a special_money_class
638
+ end
639
+
630
640
  context "with infinite_precision", :infinite_precision do
631
641
  it "allows for splitting by fractional cents" do
632
642
  thirty_three_and_one_third = BigDecimal("100") / BigDecimal("3")
@@ -669,18 +679,23 @@ YAML
669
679
  rounded = money.round(BigDecimal::ROUND_DOWN)
670
680
  expect(rounded.cents).to eq 15
671
681
  end
682
+
683
+ context "when using a subclass of Money" do
684
+ let(:special_money_class) { Class.new(Money) }
685
+ let(:money) { special_money_class.new(15.75, 'NZD') }
686
+
687
+ it "preserves the class in the result" do
688
+ expect(rounded).to be_a special_money_class
689
+ end
690
+ end
672
691
  end
673
692
  end
674
693
 
675
- describe "inheritance" do
676
- it "allows inheritance" do
677
- # TypeError:
678
- # wrong argument type nil (expected Fixnum)
679
- # ./lib/money/money.rb:63:in `round'
680
- # ./lib/money/money.rb:63:in `fractional'
681
- # ./lib/money/money/arithmetic.rb:115:in `-'
682
- MoneyChild = Class.new(Money)
683
- expect(MoneyChild.new(1000) - Money.new(500)).to eq Money.new(500)
694
+ describe "#inspect" do
695
+ it "reports the class name properly when using inheritance" do
696
+ expect(Money.new(1).inspect).to start_with '#<Money'
697
+ Subclass = Class.new(Money)
698
+ expect(Subclass.new(1).inspect).to start_with '#<Subclass'
684
699
  end
685
700
  end
686
701
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.0
4
+ version: 6.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Emmons
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-15 00:00:00.000000000 Z
11
+ date: 2015-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n