money 3.0.4 → 3.0.5
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.
- data/CHANGELOG.rdoc +13 -0
- data/README.rdoc +11 -2
- data/VERSION +1 -1
- data/lib/money/core_extensions.rb +18 -4
- data/lib/money/defaults.rb +1 -1
- data/lib/money/money.rb +9 -4
- data/lib/money/variable_exchange_bank.rb +12 -3
- data/money.gemspec +2 -2
- data/test/core_extensions_spec.rb +18 -0
- data/test/exchange_bank_spec.rb +40 -0
- data/test/money_spec.rb +8 -2
- metadata +4 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== Money 3.0.5
|
2
|
+
* Added Money#abs
|
3
|
+
* Updated Currency#subunit_to_unit documentation (it's an integer not a
|
4
|
+
string)
|
5
|
+
* Fixed issue when exchanging currencies with different :subunit_to_unit
|
6
|
+
values
|
7
|
+
* Added ability to pass a block to VariableExchangeBank#new or #exchange,
|
8
|
+
specifying a custom truncation method
|
9
|
+
* Added optional currency argument to Numeric#to_money
|
10
|
+
* Added optional currency argument to String#to_money
|
11
|
+
* Numeric#to_money now respects :subunit_to_unit
|
12
|
+
* Use '¤' as the default currency symbol
|
13
|
+
|
1
14
|
== Money 3.0.4
|
2
15
|
* Updated #exchange to avoid floating point rounding errors
|
3
16
|
* Use :subunit_to_unit in #to_s, #to_f and #format
|
data/README.rdoc
CHANGED
@@ -19,6 +19,15 @@ Resources:
|
|
19
19
|
- RDoc API: http://money.rubyforge.org
|
20
20
|
- Git repository: http://github.com/FooBarWidget/money
|
21
21
|
|
22
|
+
== Attention
|
23
|
+
|
24
|
+
Starting in v3.1.0 we will be making two changes to the exchange process. First
|
25
|
+
a new `Bank::Base` class will be available. This will allow users to more
|
26
|
+
easily create custom `Bank` classes. Secondly the default `#exchange` method
|
27
|
+
will be depreciated and a new `#exchange_with` method will be used. Currently
|
28
|
+
`#exchange` passes the `cents` attribute. `#exchange_with` will pass the
|
29
|
+
actual `Money` object instead.
|
30
|
+
|
22
31
|
== Download
|
23
32
|
|
24
33
|
Install stable releases with the following command:
|
@@ -73,9 +82,9 @@ containing all the currency attributes.
|
|
73
82
|
:name => "United States Dollar",
|
74
83
|
:symbol => "$",
|
75
84
|
:subunit => "Cent"
|
76
|
-
:subunit_to_unit =>
|
85
|
+
:subunit_to_unit => 100,
|
77
86
|
:separator => ".",
|
78
|
-
:delimiter
|
87
|
+
:delimiter => ","
|
79
88
|
}
|
80
89
|
|
81
90
|
The pre-defined set of attributes includes:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.
|
1
|
+
3.0.5
|
@@ -6,8 +6,9 @@ class Numeric
|
|
6
6
|
# 100.37.to_money => #<Money @cents=10037>
|
7
7
|
# require 'bigdecimal'
|
8
8
|
# BigDecimal.new('100').to_money => #<Money @cents=10000>
|
9
|
-
def to_money
|
10
|
-
Money.new(
|
9
|
+
def to_money(currency = Money.default_currency)
|
10
|
+
currency = Money::Currency.new(currency) unless currency.is_a?(Money::Currency)
|
11
|
+
Money.new((self * currency.subunit_to_unit).to_int, currency)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
@@ -22,10 +23,23 @@ class String
|
|
22
23
|
# 'USD 100'.to_money # => #<Money @cents=10000, @currency="USD">
|
23
24
|
# '$100 USD'.to_money # => #<Money @cents=10000, @currency="USD">
|
24
25
|
# 'hello 2000 world'.to_money # => #<Money @cents=200000 @currency="USD")>
|
25
|
-
def to_money
|
26
|
+
def to_money(currency = nil)
|
26
27
|
# Get the currency.
|
27
28
|
matches = scan /([A-Z]{2,3})/
|
28
|
-
|
29
|
+
_currency_ = matches[0] ? matches[0][0] : nil
|
30
|
+
|
31
|
+
# check that currency passed and embedded currency are the same, or only
|
32
|
+
# one or the other is present.
|
33
|
+
if currency.nil? and _currency_.nil?
|
34
|
+
currency = Money.default_currency
|
35
|
+
elsif currency.nil?
|
36
|
+
currency = _currency_
|
37
|
+
elsif _currency_.nil?
|
38
|
+
currency = currency
|
39
|
+
elsif currency != _currency_
|
40
|
+
raise "mismatching currencies"
|
41
|
+
end
|
42
|
+
|
29
43
|
cents = calculate_cents(self)
|
30
44
|
Money.new(cents, currency)
|
31
45
|
end
|
data/lib/money/defaults.rb
CHANGED
data/lib/money/money.rb
CHANGED
@@ -218,6 +218,11 @@ class Money
|
|
218
218
|
a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency))
|
219
219
|
end
|
220
220
|
|
221
|
+
# Return absolute value of self as a new Money object
|
222
|
+
def abs
|
223
|
+
Money.new(self.cents.abs, self.currency)
|
224
|
+
end
|
225
|
+
|
221
226
|
# Test if the money amount is zero
|
222
227
|
def zero?
|
223
228
|
cents == 0
|
@@ -232,9 +237,9 @@ class Money
|
|
232
237
|
# Attempts to pick a symbol that's suitable for the given currency
|
233
238
|
# looking up the Currency::TABLE hashtable.
|
234
239
|
# If the symbol for the given currency isn't known,
|
235
|
-
# then it will default to "
|
240
|
+
# then it will default to "¤".
|
236
241
|
def symbol
|
237
|
-
currency.symbol || "
|
242
|
+
currency.symbol || "¤"
|
238
243
|
end
|
239
244
|
|
240
245
|
# Uses :delimiter from the Currency hash. If it is not specified defaults to
|
@@ -303,9 +308,9 @@ class Money
|
|
303
308
|
#
|
304
309
|
#
|
305
310
|
# If the symbol for the given currency isn't known, then it will default
|
306
|
-
# to "
|
311
|
+
# to "¤" as symbol:
|
307
312
|
#
|
308
|
-
# Money.new(100, "AWG").format(:symbol => true) => "
|
313
|
+
# Money.new(100, "AWG").format(:symbol => true) => "¤1.00"
|
309
314
|
#
|
310
315
|
# You can specify a string as value to enforce using a particular symbol:
|
311
316
|
#
|
@@ -27,9 +27,10 @@ class Money
|
|
27
27
|
@@singleton
|
28
28
|
end
|
29
29
|
|
30
|
-
def initialize
|
30
|
+
def initialize(&block)
|
31
31
|
@rates = {}
|
32
32
|
@mutex = Mutex.new
|
33
|
+
@rounding_method = block
|
33
34
|
end
|
34
35
|
|
35
36
|
# Registers a conversion rate. +from+ and +to+ are both currency names.
|
@@ -60,12 +61,20 @@ class Money
|
|
60
61
|
# Returns the amount of cents in +to_currency+ as an integer, rounded down.
|
61
62
|
#
|
62
63
|
# If the conversion rate is unknown, then Money::UnknownRate will be raised.
|
63
|
-
def exchange(cents, from_currency, to_currency)
|
64
|
+
def exchange(cents, from_currency, to_currency, &block)
|
64
65
|
rate = get_rate(from_currency, to_currency)
|
65
66
|
if !rate
|
66
67
|
raise Money::UnknownRate, "No conversion rate known for '#{from_currency}' -> '#{to_currency}'"
|
67
68
|
end
|
68
|
-
|
69
|
+
_from_currency_ = Currency.wrap(from_currency)
|
70
|
+
_to_currency_ = Currency.wrap(to_currency)
|
71
|
+
|
72
|
+
_cents_ = cents / (_from_currency_.subunit_to_unit.to_f / _to_currency_.subunit_to_unit.to_f)
|
73
|
+
|
74
|
+
ex = _cents_ * rate
|
75
|
+
return block.call(ex) if block_given?
|
76
|
+
return @rounding_method.call(ex) unless @rounding_method.nil?
|
77
|
+
ex.to_s.to_i
|
69
78
|
end
|
70
79
|
|
71
80
|
@@singleton = VariableExchangeBank.new
|
data/money.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{money}
|
8
|
-
s.version = "3.0.
|
8
|
+
s.version = "3.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin", "Shane Emmons"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-07-16}
|
13
13
|
s.description = %q{Money and currency exchange support library.}
|
14
14
|
s.email = %q{hongli@phusion.nl}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,6 +17,17 @@ describe "Money core extensions" do
|
|
17
17
|
money.cents.should == 1234_00
|
18
18
|
money.currency.should == Money.default_currency
|
19
19
|
end
|
20
|
+
|
21
|
+
specify "Numeric#to_money accepts optional currency" do
|
22
|
+
1234.to_money('USD').should == Money.new(123400, 'USD')
|
23
|
+
1234.to_money('EUR').should == Money.new(123400, 'EUR')
|
24
|
+
end
|
25
|
+
|
26
|
+
specify "Numeric#to_money should respect :subunit_to_unit" do
|
27
|
+
10.to_money('USD').should == Money.new(10_00, 'USD')
|
28
|
+
10.to_money('TND').should == Money.new(10_000, 'TND')
|
29
|
+
10.to_money('CLP').should == Money.new(10, 'CLP')
|
30
|
+
end
|
20
31
|
|
21
32
|
specify "String#to_money works" do
|
22
33
|
"20.15".to_money.should == Money.new(20_15)
|
@@ -73,6 +84,13 @@ describe "Money core extensions" do
|
|
73
84
|
"$1.99000 USD".to_money.should == Money.new(1_99, "USD")
|
74
85
|
end
|
75
86
|
|
87
|
+
specify "String#to_money should accept optional currency" do
|
88
|
+
"10.10".to_money('USD').should == Money.new(1010, 'USD')
|
89
|
+
"10.10".to_money('EUR').should == Money.new(1010, 'EUR')
|
90
|
+
"10.10 USD".to_money('USD').should == Money.new(1010, 'USD')
|
91
|
+
lambda{"10.10 USD".to_money('EUR')}.should raise_error
|
92
|
+
end
|
93
|
+
|
76
94
|
specify "String#to_money ignores unrecognized data" do
|
77
95
|
"hello 2000 world".to_money.should == Money.new(2000_00)
|
78
96
|
end
|
data/test/exchange_bank_spec.rb
CHANGED
@@ -57,5 +57,45 @@ describe Money::VariableExchangeBank do
|
|
57
57
|
@bank.exchange(10000, 'USD', 'EUR').should == 8600
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
context 'TND to USD using a rate of 0.67138' do
|
62
|
+
it 'returns the correct amount' do
|
63
|
+
@bank.add_rate('TND', 'USD', 0.67138)
|
64
|
+
@bank.exchange(1000, 'TND', 'USD').should == 67
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'USD to TND using a rate of 1.32862' do
|
69
|
+
it 'returns the correct amount' do
|
70
|
+
@bank.add_rate('USD', 'TND', 1.32862)
|
71
|
+
@bank.exchange(1000, 'USD', 'TND').should == 13286
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'using custom rounding methods' do
|
77
|
+
describe 'passing a rounding method to #new' do
|
78
|
+
before :each do
|
79
|
+
mth = Proc.new{|ex| ex.ceil }
|
80
|
+
@bank = Money::VariableExchangeBank.new(&mth)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should use @rounding_method' do
|
84
|
+
@bank.add_rate('USD', 'EUR', 0.86)
|
85
|
+
@bank.exchange(10, 'USD', 'EUR').should == 9
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'passing a rounding method to #exchange' do
|
90
|
+
it 'should use &block' do
|
91
|
+
@bank.add_rate('USD', 'EUR', 0.86)
|
92
|
+
@bank.exchange(10, 'USD', 'EUR').should == 8
|
93
|
+
|
94
|
+
mth = Proc.new{|ex| ex.ceil }
|
95
|
+
@bank.exchange(10, 'USD', 'EUR', &mth).should == 9
|
96
|
+
|
97
|
+
@bank.exchange(10, 'USD', 'EUR'){|ex| ex.ceil }.should == 9
|
98
|
+
end
|
99
|
+
end
|
60
100
|
end
|
61
101
|
end
|
data/test/money_spec.rb
CHANGED
@@ -430,6 +430,12 @@ describe Money do
|
|
430
430
|
end
|
431
431
|
end
|
432
432
|
|
433
|
+
specify "#abs correctly returns the absolute value as a new Money object" do
|
434
|
+
n = Money.new(-1, :USD)
|
435
|
+
n.abs.should == Money.new( 1, :USD)
|
436
|
+
n.should == Money.new(-1, :USD)
|
437
|
+
end
|
438
|
+
|
433
439
|
specify "Money.empty creates a new Money object of 0 cents" do
|
434
440
|
Money.empty.should == Money.new(0)
|
435
441
|
end
|
@@ -556,7 +562,7 @@ describe Money do
|
|
556
562
|
|
557
563
|
currency = Money::Currency.new("EUR")
|
558
564
|
currency.should_receive(:symbol).and_return(nil)
|
559
|
-
Money.empty(currency).symbol.should == "
|
565
|
+
Money.empty(currency).symbol.should == "¤"
|
560
566
|
end
|
561
567
|
|
562
568
|
specify "#delimiter works as documented" do
|
@@ -647,7 +653,7 @@ describe Money do
|
|
647
653
|
specify "#format(:symbol => true) returns $ when currency code is not recognized" do
|
648
654
|
currency = Money::Currency.new("EUR")
|
649
655
|
currency.should_receive(:symbol).and_return(nil)
|
650
|
-
Money.new(100, currency).format(:symbol => true).should == "
|
656
|
+
Money.new(100, currency).format(:symbol => true).should == "¤1.00"
|
651
657
|
end
|
652
658
|
|
653
659
|
specify "#format(:symbol => some non-Boolean value that evaluates to true) returs symbol based on the given currency code" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 3.0.
|
9
|
+
- 5
|
10
|
+
version: 3.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tobias Luetke
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2010-
|
21
|
+
date: 2010-07-16 00:00:00 -04:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|