sevenwire-money 2.0.0 → 2.1.0

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/MIT-LICENSE CHANGED
@@ -1,5 +1,6 @@
1
1
  Copyright (c) 2005 Tobias Lutke
2
2
  Copyright (c) 2008 Phusion
3
+ Copyright (c) 2009 Sevenwire
3
4
 
4
5
  Permission is hereby granted, free of charge, to any person obtaining
5
6
  a copy of this software and associated documentation files (the
@@ -1,15 +1,24 @@
1
1
  class Numeric
2
+
2
3
  # Converts this numeric to a Money object in the default currency. It
3
4
  # multiplies the numeric value by 100 and treats that as cents.
4
5
  #
5
6
  # 100.to_money => #<Money @cents=10000>
6
7
  # 100.37.to_money => #<Money @cents=10037>
7
- def to_money
8
- Money.new(self * 100)
8
+ # 1000.to_money(:millicents) => #<Money @cents=1>
9
+ def to_money(units=:cents)
10
+ if units == :millicents
11
+ Money.new(self, :units => :millicents)
12
+ else
13
+ Money.new(self * 100)
14
+ end
9
15
  end
16
+
10
17
  end
11
18
 
19
+
12
20
  class String
21
+
13
22
  # Parses the current string and converts it to a Money object.
14
23
  # Excess characters will be discarded.
15
24
  #
@@ -18,21 +27,27 @@ class String
18
27
  # '100 USD'.to_money # => #<Money @cents=10000, @currency="USD">
19
28
  # 'USD 100'.to_money # => #<Money @cents=10000, @currency="USD">
20
29
  # '$100 USD'.to_money # => #<Money @cents=10000, @currency="USD">
21
- def to_money
30
+ # '1000'.to_money(:millicents) # => #<Money @cents=1, @currency="USD">
31
+ def to_money(units=:cents)
22
32
  # Get the currency.
23
- matches = scan /([A-Z]{2,3})/
33
+ matches = scan /([A-Z]{2,3})/
24
34
  currency = matches[0] ? matches[0][0] : Money.default_currency
25
-
35
+
26
36
  # Get the cents amount
27
37
  sans_spaces = gsub(/\s+/, '')
28
38
  matches = sans_spaces.scan /(\-?\d+(?:[\.,]\d+)?)/
29
- cents = if matches[0]
39
+ money = if matches[0]
30
40
  value = matches[0][0].gsub(/,/, '.')
31
- value.to_f * 100
41
+ value.to_f
32
42
  else
33
43
  0
34
44
  end
35
-
36
- Money.new(cents, currency)
45
+
46
+ if units == :millicents
47
+ Money.new(money, currency, :units => :millicents)
48
+ else
49
+ Money.new(money * 100, currency)
50
+ end
37
51
  end
52
+
38
53
  end
data/lib/money/errors.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  class Money
2
- class UnknownRate < StandardError
3
- end
2
+ class UnknownRate < StandardError; end
4
3
  end
data/lib/money/money.rb CHANGED
@@ -1,23 +1,24 @@
1
- require 'money/variable_exchange_bank'
2
-
3
1
  # Represents an amount of money in a certain currency.
4
2
  class Money
3
+
5
4
  include Comparable
6
-
7
- attr_reader :cents, :currency, :bank
8
-
5
+
6
+
7
+ ### ATTRIBUTES
8
+
9
9
  class << self
10
+
10
11
  # Each Money object is associated to a bank object, which is responsible
11
12
  # for currency exchange. This property allows one to specify the default
12
13
  # bank object.
13
14
  #
14
15
  # bank1 = MyBank.new
15
16
  # bank2 = MyOtherBank.new
16
- #
17
+ #
17
18
  # Money.default_bank = bank1
18
19
  # money1 = Money.new(10)
19
20
  # money1.bank # => bank1
20
- #
21
+ #
21
22
  # Money.default_bank = bank2
22
23
  # money2 = Money.new(10)
23
24
  # money2.bank # => bank2
@@ -31,117 +32,131 @@ class Money
31
32
  # Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
32
33
  # Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
33
34
  attr_accessor :default_bank
34
-
35
+
35
36
  # The default currency, which is used when <tt>Money.new</tt> is called
36
37
  # without an explicit currency argument. The default value is "USD".
37
38
  attr_accessor :default_currency
39
+
38
40
  end
39
-
41
+
42
+ # Set the default bank and currency.
40
43
  self.default_bank = VariableExchangeBank.instance
41
44
  self.default_currency = "USD"
42
-
43
-
45
+
46
+ # Set up attribute accessors for millicents, currency, and bank.
47
+ attr_reader :cents, :millicents, :currency, :bank
48
+
49
+
50
+ ### INSTANTIATION
51
+
52
+ # Creates a new money object.
53
+ # Money.new(100)
54
+ #
55
+ # By default, it will accept money in cents, however,
56
+ # you can also pass millicents by specifying :units => :millicents.
57
+ def initialize(money, *args)
58
+ options = args.last.is_a?(Hash) ? args.pop : {}
59
+
60
+ if options[:units] == :millicents
61
+ @millicents = money.round
62
+ @cents = (money / 1000.0).round
63
+ else
64
+ @millicents = (money * 1000.0).round
65
+ @cents = money.round
66
+ end
67
+ @currency = args[0] || Money.default_currency
68
+ @bank = args[1] || Money.default_bank
69
+ end
70
+
44
71
  # Create a new money object with value 0.
45
72
  def self.empty(currency = default_currency)
46
- Money.new(0, currency)
73
+ new(0, currency)
47
74
  end
48
75
 
49
- # Creates a new Money object of the given value, using the Canadian dollar currency.
50
- def self.ca_dollar(cents)
51
- Money.new(cents, "CAD")
52
- end
53
76
 
54
- # Creates a new Money object of the given value, using the American dollar currency.
55
- def self.us_dollar(cents)
56
- Money.new(cents, "USD")
57
- end
58
-
59
- # Creates a new Money object of the given value, using the Euro currency.
60
- def self.euro(cents)
61
- Money.new(cents, "EUR")
62
- end
63
-
77
+ ### EXHANGES
78
+
79
+ # Adds a new exchange rate from one currency to another.
64
80
  def self.add_rate(from_currency, to_currency, rate)
65
- Money.default_bank.add_rate(from_currency, to_currency, rate)
81
+ default_bank.add_rate(from_currency, to_currency, rate)
66
82
  end
67
-
68
-
69
- # Creates a new money object.
70
- # Money.new(100)
71
- #
72
- # Alternativly you can use the convinience methods like
73
- # Money.ca_dollar and Money.us_dollar
74
- def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
75
- @cents = cents.round
76
- @currency = currency
77
- @bank = bank
83
+
84
+ # Recieve the amount of this money object in another currency.
85
+ def exchange_to(other_currency)
86
+ self.class.new(@bank.exchange(millicents, currency, other_currency), other_currency, :units => :millicents)
78
87
  end
79
88
 
80
- # Do two money objects equal? Only works if both objects are of the same currency
89
+
90
+ ### COMPARISONS
91
+
92
+ # Are two money objects equal? Only works if both objects are of the same currency.
81
93
  def ==(other_money)
82
- cents == other_money.cents && bank.same_currency?(currency, other_money.currency)
94
+ millicents == other_money.millicents && bank.same_currency?(currency, other_money.currency)
83
95
  end
84
96
 
97
+ # Compare two money objects.
85
98
  def <=>(other_money)
86
99
  if bank.same_currency?(currency, other_money.currency)
87
- cents <=> other_money.cents
100
+ millicents <=> other_money.millicents
88
101
  else
89
- cents <=> other_money.exchange_to(currency).cents
102
+ millicents <=> other_money.exchange_to(currency).millicents
90
103
  end
91
104
  end
92
105
 
106
+
107
+ ### MATH
108
+
109
+ # Add two money objects.
93
110
  def +(other_money)
94
111
  if currency == other_money.currency
95
- Money.new(cents + other_money.cents, other_money.currency)
112
+ self.class.new(millicents + other_money.millicents, other_money.currency, :units => :millicents)
96
113
  else
97
- Money.new(cents + other_money.exchange_to(currency).cents,currency)
98
- end
114
+ self.class.new(millicents + other_money.exchange_to(currency).millicents, currency, :units => :millicents)
115
+ end
99
116
  end
100
117
 
118
+ # Subtract two money objects.
101
119
  def -(other_money)
102
120
  if currency == other_money.currency
103
- Money.new(cents - other_money.cents, other_money.currency)
121
+ self.class.new(millicents - other_money.millicents, other_money.currency, :units => :millicents)
104
122
  else
105
- Money.new(cents - other_money.exchange_to(currency).cents, currency)
106
- end
107
- end
108
-
109
- # get the cents value of the object
110
- def cents
111
- @cents
123
+ self.class.new(millicents - other_money.exchange_to(currency).millicents, currency, :units => :millicents)
124
+ end
112
125
  end
113
126
 
114
- # multiply money by fixnum
127
+ # Multiply money by fixnum.
115
128
  def *(fixnum)
116
- Money.new(cents * fixnum, currency)
129
+ self.class.new(millicents * fixnum, currency, :units => :millicents)
117
130
  end
118
131
 
119
- # divide money by fixnum
132
+ # Divide money by fixnum.
120
133
  def /(fixnum)
121
- Money.new(cents / fixnum, currency)
134
+ self.class.new(millicents / fixnum, currency, :units => :millicents)
122
135
  end
123
-
124
- # Test if the money amount is zero
136
+
137
+ # Test if the money amount is zero.
125
138
  def zero?
126
- cents == 0
139
+ millicents == 0
127
140
  end
128
141
 
129
142
 
143
+ ### OUTPUT/CONVERSIONS
144
+
130
145
  # Format the price according to several rules
131
146
  # Currently supported are :with_currency, :no_cents and :html
132
147
  #
133
- # with_currency:
148
+ # with_currency:
134
149
  #
135
150
  # Money.ca_dollar(0).format => "free"
136
151
  # Money.ca_dollar(100).format => "$1.00"
137
152
  # Money.ca_dollar(100).format(:with_currency) => "$1.00 CAD"
138
153
  # Money.us_dollar(85).format(:with_currency) => "$0.85 USD"
139
154
  #
140
- # no_cents:
155
+ # no_cents:
141
156
  #
142
157
  # Money.ca_dollar(100).format(:no_cents) => "$1"
143
158
  # Money.ca_dollar(599).format(:no_cents) => "$5"
144
- #
159
+ #
145
160
  # Money.ca_dollar(570).format(:no_cents, :with_currency) => "$5 CAD"
146
161
  # Money.ca_dollar(39000).format(:no_cents) => "$390"
147
162
  #
@@ -152,9 +167,9 @@ class Money
152
167
  rules = rules.flatten
153
168
 
154
169
  if rules.include?(:no_cents)
155
- formatted = sprintf("$%d", cents.to_f / 100 )
170
+ formatted = sprintf("$%d", cents.to_f / 100)
156
171
  else
157
- formatted = sprintf("$%.2f", cents.to_f / 100 )
172
+ formatted = sprintf("$%.2f", cents.to_f / 100)
158
173
  end
159
174
 
160
175
  if rules.include?(:with_currency)
@@ -165,37 +180,17 @@ class Money
165
180
  end
166
181
  formatted
167
182
  end
168
-
169
- # Money.ca_dollar(100).to_s => "1.00"
183
+
184
+ # Output a money object as a string.
185
+ # Example:
186
+ # Money.new(100).to_s => "1.00"
170
187
  def to_s
171
- sprintf("%.2f", cents / 100.00)
172
- end
173
-
174
- # Recieve the amount of this money object in another currency.
175
- def exchange_to(other_currency)
176
- Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
177
- end
178
-
179
- # Recieve a money object with the same amount as the current Money object
180
- # in american dollar
181
- def as_us_dollar
182
- exchange_to("USD")
183
- end
184
-
185
- # Recieve a money object with the same amount as the current Money object
186
- # in canadian dollar
187
- def as_ca_dollar
188
- exchange_to("CAD")
189
- end
190
-
191
- # Recieve a money object with the same amount as the current Money object
192
- # in euro
193
- def as_euro
194
- exchange_to("EUR")
188
+ sprintf("%.2f", cents.to_f / 100)
195
189
  end
196
-
190
+
197
191
  # Conversation to self
198
192
  def to_money
199
193
  self
200
- end
194
+ end
195
+
201
196
  end
@@ -1,5 +1,4 @@
1
1
  require 'thread'
2
- require 'money/errors'
3
2
 
4
3
  # Class for aiding in exchanging money between different currencies.
5
4
  # By default, the Money class uses an object of this class (accessible through
@@ -12,12 +11,13 @@ require 'money/errors'
12
11
  # bank = Money::VariableExchangeBank.new
13
12
  # bank.add_rate("USD", "CAD", 1.24515)
14
13
  # bank.add_rate("CAD", "USD", 0.803115)
15
- #
14
+ #
16
15
  # # Exchange 100 CAD to USD:
17
16
  # bank.exchange(100_00, "CAD", "USD") # => 124
18
17
  # # Exchange 100 USD to CAD:
19
18
  # bank.exchange(100_00, "USD", "CAD") # => 80
20
19
  class Money
20
+
21
21
  class VariableExchangeBank
22
22
  # Returns the singleton instance of VariableExchangeBank.
23
23
  #
@@ -25,27 +25,27 @@ class Money
25
25
  def self.instance
26
26
  @@singleton
27
27
  end
28
-
28
+
29
29
  def initialize
30
30
  @rates = {}
31
31
  @mutex = Mutex.new
32
32
  end
33
-
33
+
34
34
  # Registers a conversion rate. +from+ and +to+ are both currency names.
35
35
  def add_rate(from, to, rate)
36
36
  @mutex.synchronize do
37
37
  @rates["#{from}_TO_#{to}".upcase] = rate
38
38
  end
39
39
  end
40
-
40
+
41
41
  # Gets the rate for exchanging the currency named +from+ to the currency
42
42
  # named +to+. Returns nil if the rate is unknown.
43
43
  def get_rate(from, to)
44
44
  @mutex.synchronize do
45
- @rates["#{from}_TO_#{to}".upcase]
45
+ @rates["#{from}_TO_#{to}".upcase]
46
46
  end
47
47
  end
48
-
48
+
49
49
  # Given two currency names, checks whether they're both the same currency.
50
50
  #
51
51
  # bank = VariableExchangeBank.new
@@ -54,19 +54,20 @@ class Money
54
54
  def same_currency?(currency1, currency2)
55
55
  currency1.upcase == currency2.upcase
56
56
  end
57
-
57
+
58
58
  # Exchange the given amount of cents in +from_currency+ to +to_currency+.
59
59
  # Returns the amount of cents in +to_currency+ as an integer, rounded down.
60
60
  #
61
61
  # If the conversion rate is unknown, then Money::UnknownRate will be raised.
62
- def exchange(cents, from_currency, to_currency)
62
+ def exchange(millicents, from_currency, to_currency)
63
63
  rate = get_rate(from_currency, to_currency)
64
64
  if !rate
65
65
  raise Money::UnknownRate, "No conversion rate known for '#{from_currency}' -> '#{to_currency}'"
66
66
  end
67
- (cents * rate).floor
67
+ (millicents * rate).floor
68
68
  end
69
-
69
+
70
70
  @@singleton = VariableExchangeBank.new
71
71
  end
72
+
72
73
  end
data/lib/money.rb CHANGED
@@ -1,25 +1,6 @@
1
- # Copyright (c) 2005 Tobias Luetke
2
- # Copyright (c) 2008 Phusion
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
-
23
1
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
24
- require 'money/money'
2
+ require 'money/variable_exchange_bank'
3
+ require 'money/currencies'
4
+ require 'money/errors'
25
5
  require 'money/core_extensions'
6
+ require 'money/money'
data/money.gemspec CHANGED
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "money"
3
- s.version = "2.0.0"
3
+ s.version = "2.1.0"
4
4
  s.summary = "Money and currency exchange support library"
5
- s.email = "hongli@phusion.nl"
6
- s.homepage = "http://money.rubyforge.org/"
7
- s.description = "Money and currency exchange support library. Patched by Sevenwire."
5
+ s.email = "brandon@sevenwire.com"
6
+ s.homepage = "http://github.com/sevenwire/money"
7
+ s.description = "Money and currency exchange support library."
8
8
  s.has_rdoc = true
9
9
  s.rubyforge_project = "money"
10
- s.authors = ["Tobias Luetke", "Hongli Lai"]
10
+ s.authors = ["Tobias Luetke", "Hongli Lai", "Brandon Arbini"]
11
11
 
12
12
  s.files = [
13
13
  "README.rdoc", "MIT-LICENSE", "money.gemspec", "Rakefile",
@@ -2,35 +2,37 @@ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
2
  require 'money/core_extensions'
3
3
 
4
4
  describe "Money core extensions" do
5
- specify "Numberic#to_money works" do
6
- money = 1234.to_money
7
- money.cents.should == 1234_00
8
- money.currency.should == Money.default_currency
9
-
10
- money = 100.37.to_money
11
- money.cents.should == 100_37
12
- money.currency.should == Money.default_currency
13
- end
14
-
15
- specify "String#to_money works" do
16
- "100".to_money.should == Money.new(100_00)
17
- "100.37".to_money.should == Money.new(100_37)
18
- "100,37".to_money.should == Money.new(100_37)
19
- "100 000".to_money.should == Money.new(100_000_00)
20
-
21
- "100 USD".to_money.should == Money.new(100_00, "USD")
22
- "-100 USD".to_money.should == Money.new(-100_00, "USD")
23
- "100 EUR".to_money.should == Money.new(100_00, "EUR")
24
- "100.37 EUR".to_money.should == Money.new(100_37, "EUR")
25
- "100,37 EUR".to_money.should == Money.new(100_37, "EUR")
26
-
27
- "USD 100".to_money.should == Money.new(100_00, "USD")
28
- "EUR 100".to_money.should == Money.new(100_00, "EUR")
29
- "EUR 100.37".to_money.should == Money.new(100_37, "EUR")
30
- "CAD -100.37".to_money.should == Money.new(-100_37, "CAD")
31
- "EUR 100,37".to_money.should == Money.new(100_37, "EUR")
32
- "EUR -100,37".to_money.should == Money.new(-100_37, "EUR")
33
-
34
- "$100 USD".to_money.should == Money.new(100_00, "USD")
35
- end
5
+
6
+ specify "Numeric#to_money works" do
7
+ money = 1234.to_money
8
+ money.cents.should == 1234_00
9
+ money.currency.should == Money.default_currency
10
+
11
+ money = 100.37.to_money
12
+ money.cents.should == 100_37
13
+ money.currency.should == Money.default_currency
14
+ end
15
+
16
+ specify "String#to_money works" do
17
+ "100".to_money.should == Money.new(100_00)
18
+ "100.37".to_money.should == Money.new(100_37)
19
+ "100,37".to_money.should == Money.new(100_37)
20
+ "100 000".to_money.should == Money.new(100_000_00)
21
+
22
+ "100 USD".to_money.should == Money.new(100_00, "USD")
23
+ "-100 USD".to_money.should == Money.new(-100_00, "USD")
24
+ "100 EUR".to_money.should == Money.new(100_00, "EUR")
25
+ "100.37 EUR".to_money.should == Money.new(100_37, "EUR")
26
+ "100,37 EUR".to_money.should == Money.new(100_37, "EUR")
27
+
28
+ "USD 100".to_money.should == Money.new(100_00, "USD")
29
+ "EUR 100".to_money.should == Money.new(100_00, "EUR")
30
+ "EUR 100.37".to_money.should == Money.new(100_37, "EUR")
31
+ "CAD -100.37".to_money.should == Money.new(-100_37, "CAD")
32
+ "EUR 100,37".to_money.should == Money.new(100_37, "EUR")
33
+ "EUR -100,37".to_money.should == Money.new(-100_37, "EUR")
34
+
35
+ "$100 USD".to_money.should == Money.new(100_00, "USD")
36
+ end
37
+
36
38
  end
@@ -1,45 +1,48 @@
1
1
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
2
  require 'money/variable_exchange_bank'
3
+ require 'money/errors'
3
4
 
4
5
  describe Money::VariableExchangeBank do
5
- before :each do
6
- @bank = Money::VariableExchangeBank.new
7
- end
8
-
9
- it "returns the previously specified conversion rate" do
10
- @bank.add_rate("USD", "EUR", 0.788332676)
11
- @bank.add_rate("EUR", "YEN", 122.631477)
12
- @bank.get_rate("USD", "EUR").should == 0.788332676
13
- @bank.get_rate("EUR", "YEN").should == 122.631477
14
- end
15
-
16
- it "treats currency names case-insensitively" do
17
- @bank.add_rate("usd", "eur", 1)
18
- @bank.get_rate("USD", "EUR").should == 1
19
- @bank.same_currency?("USD", "usd").should be_true
20
- @bank.same_currency?("EUR", "usd").should be_false
21
- end
22
-
23
- it "returns nil if the conversion rate is unknown" do
24
- @bank.get_rate("American Pesos", "EUR").should be_nil
25
- end
26
-
27
- it "exchanges money from one currency to another according to the specified conversion rates" do
28
- @bank.add_rate("USD", "EUR", 0.5)
29
- @bank.add_rate("EUR", "YEN", 10)
30
- @bank.exchange(10_00, "USD", "EUR").should == 5_00
31
- @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
32
- end
33
-
34
- it "rounds the exchanged result down" do
35
- @bank.add_rate("USD", "EUR", 0.788332676)
36
- @bank.add_rate("EUR", "YEN", 122.631477)
37
- @bank.exchange(10_00, "USD", "EUR").should == 788
38
- @bank.exchange(500_00, "EUR", "YEN").should == 6131573
39
- end
40
-
41
- it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
42
- block = lambda { @bank.exchange(10, "USD", "EUR") }
43
- block.should raise_error(Money::UnknownRate)
44
- end
6
+
7
+ before :each do
8
+ @bank = Money::VariableExchangeBank.new
9
+ end
10
+
11
+ it "returns the previously specified conversion rate" do
12
+ @bank.add_rate("USD", "EUR", 0.788332676)
13
+ @bank.add_rate("EUR", "YEN", 122.631477)
14
+ @bank.get_rate("USD", "EUR").should == 0.788332676
15
+ @bank.get_rate("EUR", "YEN").should == 122.631477
16
+ end
17
+
18
+ it "treats currency names case-insensitively" do
19
+ @bank.add_rate("usd", "eur", 1)
20
+ @bank.get_rate("USD", "EUR").should == 1
21
+ @bank.same_currency?("USD", "usd").should be_true
22
+ @bank.same_currency?("EUR", "usd").should be_false
23
+ end
24
+
25
+ it "returns nil if the conversion rate is unknown" do
26
+ @bank.get_rate("American Pesos", "EUR").should be_nil
27
+ end
28
+
29
+ it "exchanges money from one currency to another according to the specified conversion rates" do
30
+ @bank.add_rate("USD", "EUR", 0.5)
31
+ @bank.add_rate("EUR", "YEN", 10)
32
+ @bank.exchange(10_00, "USD", "EUR").should == 5_00
33
+ @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
34
+ end
35
+
36
+ it "rounds the exchanged result down" do
37
+ @bank.add_rate("USD", "EUR", 0.788332676)
38
+ @bank.add_rate("EUR", "YEN", 122.631477)
39
+ @bank.exchange(10_00, "USD", "EUR").should == 788
40
+ @bank.exchange(500_00, "EUR", "YEN").should == 6131573
41
+ end
42
+
43
+ it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
44
+ block = lambda { @bank.exchange(10, "USD", "EUR") }
45
+ block.should raise_error(Money::UnknownRate)
46
+ end
47
+
45
48
  end
data/test/money_spec.rb CHANGED
@@ -1,124 +1,127 @@
1
1
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
2
  require 'money/money'
3
+ require 'money/currencies'
3
4
 
4
5
  describe Money do
5
- it "is associated to the singleton instance of VariableExchangeBank by default" do
6
- Money.new(0).bank.object_id.should == Money::VariableExchangeBank.instance.object_id
7
- end
8
-
9
- specify "#cents returns the amount of cents passed to the constructor" do
10
- Money.new(200_00, "USD").cents.should == 200_00
11
- end
12
-
13
- it "rounds the given cents to an integer" do
14
- Money.new(1.00, "USD").cents.should == 1
15
- Money.new(1.01, "USD").cents.should == 1
16
- Money.new(1.50, "USD").cents.should == 2
17
- end
18
-
19
- specify "#currency returns the currency passed to the constructor" do
20
- Money.new(200_00, "USD").currency.should == "USD"
21
- end
22
-
23
- specify "#zero? returns whether the amount is 0" do
24
- Money.new(0, "USD").should be_zero
25
- Money.new(0, "EUR").should be_zero
26
- Money.new(1, "USD").should_not be_zero
27
- Money.new(10, "YEN").should_not be_zero
28
- Money.new(-1, "EUR").should_not be_zero
29
- end
30
-
31
- specify "#exchange_to exchanges the amount via its exchange bank" do
32
- money = Money.new(100_00, "USD")
33
- money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
34
- money.exchange_to("EUR")
35
- end
36
-
37
- specify "#exchange_to exchanges the amount properly" do
38
- money = Money.new(100_00, "USD")
39
- money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
40
- money.exchange_to("EUR").should == Money.new(200_00, "EUR")
41
- end
42
-
43
- specify "#== returns true if and only if their amount and currency are equal" do
44
- Money.new(1_00, "USD").should == Money.new(1_00, "USD")
45
- Money.new(1_00, "USD").should_not == Money.new(1_00, "EUR")
46
- Money.new(1_00, "USD").should_not == Money.new(2_00, "USD")
47
- Money.new(1_00, "USD").should_not == Money.new(99_00, "EUR")
48
- end
49
-
50
- specify "#* multiplies the money's amount by the multiplier while retaining the currency" do
51
- (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
52
- end
53
-
54
- specify "#* divides the money's amount by the divisor while retaining the currency" do
55
- (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
56
- end
57
-
58
- specify "Money.empty creates a new Money object of 0 cents" do
59
- Money.empty.should == Money.new(0)
60
- end
61
-
62
- specify "Money.ca_dollar creates a new Money object of the given value in CAD" do
63
- Money.ca_dollar(50).should == Money.new(50, "CAD")
64
- end
65
-
66
- specify "Money.ca_dollar creates a new Money object of the given value in USD" do
67
- Money.us_dollar(50).should == Money.new(50, "USD")
68
- end
69
-
70
- specify "Money.ca_dollar creates a new Money object of the given value in EUR" do
71
- Money.euro(50).should == Money.new(50, "EUR")
72
- end
73
-
74
- specify "Money.add_rate works" do
75
- Money.add_rate("EUR", "USD", 10)
76
- Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
77
- end
6
+
7
+ it "is associated to the singleton instance of VariableExchangeBank by default" do
8
+ Money.new(0).bank.object_id.should == Money::VariableExchangeBank.instance.object_id
9
+ end
10
+
11
+ specify "#cents returns the amount of cents passed to the constructor" do
12
+ Money.new(200_00, "USD").cents.should == 200_00
13
+ end
14
+
15
+ it "rounds the given cents to an integer" do
16
+ Money.new(1.00, "USD").cents.should == 1
17
+ Money.new(1.01, "USD").cents.should == 1
18
+ Money.new(1.50, "USD").cents.should == 2
19
+ end
20
+
21
+ specify "#currency returns the currency passed to the constructor" do
22
+ Money.new(200_00, "USD").currency.should == "USD"
23
+ end
24
+
25
+ specify "#zero? returns whether the amount is 0" do
26
+ Money.new(0, "USD").should be_zero
27
+ Money.new(0, "EUR").should be_zero
28
+ Money.new(1, "USD").should_not be_zero
29
+ Money.new(10, "YEN").should_not be_zero
30
+ Money.new(-1, "EUR").should_not be_zero
31
+ end
32
+
33
+ specify "#exchange_to exchanges the amount via its exchange bank" do
34
+ money = Money.new(100_00, "USD")
35
+ money.bank.should_receive(:exchange).with(100000_00, "USD", "EUR").and_return(200_00)
36
+ money.exchange_to("EUR")
37
+ end
38
+
39
+ specify "#exchange_to exchanges the amount properly" do
40
+ money = Money.new(100_00, "USD")
41
+ money.bank.should_receive(:exchange).with(100000_00, "USD", "EUR").and_return(200000_00)
42
+ money.exchange_to("EUR").should == Money.new(200_00, "EUR")
43
+ end
44
+
45
+ specify "#== returns true if and only if their amount and currency are equal" do
46
+ Money.new(1_00, "USD").should == Money.new(1_00, "USD")
47
+ Money.new(1_00, "USD").should_not == Money.new(1_00, "EUR")
48
+ Money.new(1_00, "USD").should_not == Money.new(2_00, "USD")
49
+ Money.new(1_00, "USD").should_not == Money.new(99_00, "EUR")
50
+ end
51
+
52
+ specify "#* multiplies the money's amount by the multiplier while retaining the currency" do
53
+ (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
54
+ end
55
+
56
+ specify "#* divides the money's amount by the divisor while retaining the currency" do
57
+ (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
58
+ end
59
+
60
+ specify "Money.empty creates a new Money object of 0 cents" do
61
+ Money.empty.should == Money.new(0)
62
+ end
63
+
64
+ specify "Money.ca_dollar creates a new Money object of the given value in CAD" do
65
+ Money.ca_dollar(50).should == Money.new(50, "CAD")
66
+ end
67
+
68
+ specify "Money.ca_dollar creates a new Money object of the given value in USD" do
69
+ Money.us_dollar(50).should == Money.new(50, "USD")
70
+ end
71
+
72
+ specify "Money.ca_dollar creates a new Money object of the given value in EUR" do
73
+ Money.euro(50).should == Money.new(50, "EUR")
74
+ end
75
+
76
+ specify "Money.add_rate works" do
77
+ Money.add_rate("EUR", "USD", 10)
78
+ Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
79
+ end
78
80
  end
79
81
 
80
82
  describe "Actions involving two Money objects" do
81
- describe "if the other Money object has the same currency" do
82
- specify "#<=> compares the two objects' amounts" do
83
- (Money.new(1_00, "USD") <=> Money.new(1_00, "USD")).should == 0
84
- (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
85
- (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
86
- end
87
-
88
- specify "#+ adds the other object's amount to the current object's amount while retaining the currency" do
89
- (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
90
- end
91
-
92
- specify "#- substracts the other object's amount from the current object's amount while retaining the currency" do
93
- (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
94
- end
95
- end
96
-
97
- describe "if the other Money object has a different currency" do
98
- specify "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
99
- target = Money.new(200_00, "EUR")
100
- target.should_receive(:exchange_to).with("USD").and_return(Money.new(300_00, "USD"))
101
- (Money.new(100_00, "USD") <=> target).should < 0
102
-
103
- target = Money.new(200_00, "EUR")
104
- target.should_receive(:exchange_to).with("USD").and_return(Money.new(100_00, "USD"))
105
- (Money.new(100_00, "USD") <=> target).should == 0
106
-
107
- target = Money.new(200_00, "EUR")
108
- target.should_receive(:exchange_to).with("USD").and_return(Money.new(99_00, "USD"))
109
- (Money.new(100_00, "USD") <=> target).should > 0
110
- end
111
-
112
- specify "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
113
- other = Money.new(90, "EUR")
114
- other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
115
- (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
116
- end
117
-
118
- specify "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
119
- other = Money.new(90, "EUR")
120
- other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
121
- (Money.new(10_00, "USD") - other).should == Money.new(1_00, "USD")
122
- end
123
- end
83
+ describe "if the other Money object has the same currency" do
84
+ specify "#<=> compares the two objects' amounts" do
85
+ (Money.new(1_00, "USD") <=> Money.new(1_00, "USD")).should == 0
86
+ (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
87
+ (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
88
+ end
89
+
90
+ specify "#+ adds the other object's amount to the current object's amount while retaining the currency" do
91
+ (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
92
+ end
93
+
94
+ specify "#- substracts the other object's amount from the current object's amount while retaining the currency" do
95
+ (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
96
+ end
97
+ end
98
+
99
+ describe "if the other Money object has a different currency" do
100
+ specify "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
101
+ target = Money.new(200_00, "EUR")
102
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(300_00, "USD"))
103
+ (Money.new(100_00, "USD") <=> target).should < 0
104
+
105
+ target = Money.new(200_00, "EUR")
106
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(100_00, "USD"))
107
+ (Money.new(100_00, "USD") <=> target).should == 0
108
+
109
+ target = Money.new(200_00, "EUR")
110
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(99_00, "USD"))
111
+ (Money.new(100_00, "USD") <=> target).should > 0
112
+ end
113
+
114
+ specify "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
115
+ other = Money.new(90, "EUR")
116
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
117
+ (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
118
+ end
119
+
120
+ specify "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
121
+ other = Money.new(90, "EUR")
122
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
123
+ (Money.new(10_00, "USD") - other).should == Money.new(1_00, "USD")
124
+ end
125
+ end
126
+
124
127
  end
metadata CHANGED
@@ -1,11 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sevenwire-money
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
8
8
  - Hongli Lai
9
+ - Brandon Arbini
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
@@ -14,8 +15,8 @@ date: 2008-12-22 00:00:00 -08:00
14
15
  default_executable:
15
16
  dependencies: []
16
17
 
17
- description: Money and currency exchange support library. Patched by Sevenwire.
18
- email: hongli@phusion.nl
18
+ description: Money and currency exchange support library.
19
+ email: brandon@sevenwire.com
19
20
  executables: []
20
21
 
21
22
  extensions: []
@@ -36,7 +37,7 @@ files:
36
37
  - test/exchange_bank_spec.rb
37
38
  - test/money_spec.rb
38
39
  has_rdoc: true
39
- homepage: http://money.rubyforge.org/
40
+ homepage: http://github.com/sevenwire/money
40
41
  post_install_message:
41
42
  rdoc_options: []
42
43