currency 0.3.1 → 0.3.2
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/Rakefile +37 -3
- data/Releases +7 -0
- data/lib/currency/core_extensions.rb +14 -3
- data/lib/currency/currency.rb +5 -1
- data/lib/currency/currency_factory.rb +49 -22
- data/lib/currency/currency_version.rb +1 -1
- data/lib/currency/exchange/base.rb +12 -1
- data/lib/currency/exchange/xe.rb +103 -15
- data/lib/currency/money.rb +13 -10
- data/test/money_test.rb +60 -3
- data/test/xe_test.rb +1 -1
- metadata +1 -1
data/Rakefile
CHANGED
@@ -7,16 +7,50 @@
|
|
7
7
|
require 'rubygems'
|
8
8
|
require 'hoe'
|
9
9
|
|
10
|
+
PKG_Name = 'Currency'
|
11
|
+
PKG_DESCRIPTION = %{Currency models currencies, monetary values, foreign exchanges.}
|
12
|
+
|
13
|
+
#################################################################
|
14
|
+
# Release notes
|
15
|
+
#
|
16
|
+
|
17
|
+
def get_release_notes(relfile = "Releases")
|
18
|
+
|
19
|
+
release = nil
|
20
|
+
notes = [ ]
|
21
|
+
|
22
|
+
File.open(relfile) do |f|
|
23
|
+
while line = f.readline
|
24
|
+
if md = /^== Release ([\d\.]+)/i.match(line)
|
25
|
+
release = md[1]
|
26
|
+
notes << line
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
while line = f.readline
|
32
|
+
if md = /^== Release ([\d\.]+)/i.match(line)
|
33
|
+
break
|
34
|
+
end
|
35
|
+
notes << line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
[ release, notes.join('') ]
|
40
|
+
end
|
41
|
+
|
10
42
|
#################################################################
|
11
43
|
|
12
|
-
PKG_Name = 'Currency'
|
13
44
|
PKG_NAME = PKG_Name.gsub(/[a-z][A-Z]/) {|x| "#{x[0,1]}_#{x[1,1]}"}.downcase
|
14
45
|
|
15
|
-
|
46
|
+
release, release_notes = get_release_notes
|
47
|
+
|
48
|
+
hoe = Hoe.new("currency", release) do |p|
|
16
49
|
p.author = 'Kurt Stephens'
|
17
|
-
p.description =
|
50
|
+
p.description = PKG_DESCRIPTION
|
18
51
|
p.email = "ruby-#{PKG_NAME}@umleta.com"
|
19
52
|
p.summary = p.description
|
53
|
+
p.changes = release_notes
|
20
54
|
p.url = "http://rubyforge.org/projects/#{PKG_NAME}"
|
21
55
|
|
22
56
|
p.test_globs = ['test/**/*.rb']
|
data/Releases
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
= Currency Release History
|
2
2
|
|
3
|
+
== Release 0.3.2: 2006/10/31
|
4
|
+
|
5
|
+
* BOO!
|
6
|
+
* Fixed Currency.symbol formatting when Currency.symbol.nil?
|
7
|
+
* Added expiration of rates in Xe.
|
8
|
+
* Added more Money tests.
|
9
|
+
|
3
10
|
== Release 0.3.1: 2006/10/31
|
4
11
|
|
5
12
|
* Remove debug puts.
|
@@ -1,6 +1,17 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
# External representation mixin
|
4
|
+
class Object
|
5
|
+
# Exact conversion to Money representation value.
|
6
|
+
def money(*opts)
|
7
|
+
Currency::Money(self, *opts)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
1
12
|
# External representation mixin
|
2
13
|
class Integer
|
3
|
-
# Exact
|
14
|
+
# Exact conversion to Money representation value.
|
4
15
|
def Money_rep(currency)
|
5
16
|
Integer(self * currency.scale)
|
6
17
|
end
|
@@ -9,7 +20,7 @@ end
|
|
9
20
|
|
10
21
|
# External representation mixin
|
11
22
|
class Float
|
12
|
-
# Inexact
|
23
|
+
# Inexact conversion to Money representation value.
|
13
24
|
def Money_rep(currency)
|
14
25
|
Integer(self * currency.scale)
|
15
26
|
end
|
@@ -18,7 +29,7 @@ end
|
|
18
29
|
|
19
30
|
# External representation mixin
|
20
31
|
class String
|
21
|
-
# Exact
|
32
|
+
# Exact conversion to Money representation value.
|
22
33
|
def Money_rep(currency)
|
23
34
|
x = currency.parse(self, :currency => currency)
|
24
35
|
x.rep if x.kind_of?(Currency::Money)
|
data/lib/currency/currency.rb
CHANGED
@@ -212,7 +212,7 @@ module Currency
|
|
212
212
|
x = "-" + x if neg
|
213
213
|
|
214
214
|
# Add symbol?
|
215
|
-
x = @symbol + x unless opt.include?(:no_symbol)
|
215
|
+
x = (@symbol || '') + x unless opt.include?(:no_symbol)
|
216
216
|
|
217
217
|
# Suffix currency code.
|
218
218
|
if opt.include?(:with_currency)
|
@@ -233,6 +233,10 @@ module Currency
|
|
233
233
|
def self.default
|
234
234
|
CurrencyFactory.default.currency
|
235
235
|
end
|
236
|
+
# Sets the default CurrencyFactory's currency.
|
237
|
+
def self.default=(x)
|
238
|
+
CurrencyFactory.default.currency = x
|
239
|
+
end
|
236
240
|
|
237
241
|
# Returns the USD Currency.
|
238
242
|
def self.USD
|
@@ -1,12 +1,17 @@
|
|
1
1
|
module Currency
|
2
2
|
class CurrencyFactory
|
3
|
-
# Default factory.
|
4
3
|
@@default = nil
|
4
|
+
|
5
|
+
# Returns the default CurrencyFactory.
|
5
6
|
def self.default
|
6
7
|
@@default ||= CurrencyFactory.new
|
7
8
|
end
|
9
|
+
# Sets the default CurrencyFactory.
|
10
|
+
def self.default=(x)
|
11
|
+
@@default = x
|
12
|
+
end
|
8
13
|
|
9
|
-
def initialize
|
14
|
+
def initialize(*opts)
|
10
15
|
@currency_by_code = { }
|
11
16
|
@currency_by_symbol = { }
|
12
17
|
@currency = nil
|
@@ -14,60 +19,82 @@ module Currency
|
|
14
19
|
@CAD = nil
|
15
20
|
end
|
16
21
|
|
17
|
-
# Lookup
|
22
|
+
# Lookup Currency by code.
|
18
23
|
def get_by_code(x)
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
x = Currency.cast_code(x)
|
25
|
+
# $stderr.puts "get_by_code(#{x})"
|
26
|
+
@currency_by_code[x] ||= install(load(Currency.new(x)))
|
22
27
|
end
|
23
28
|
|
24
|
-
# Lookup
|
29
|
+
# Lookup Currency by symbol.
|
25
30
|
def get_by_symbol(symbol)
|
26
|
-
@currency_by_symbol[symbol] ||= load(Currency.new(nil, symbol))
|
31
|
+
@currency_by_symbol[symbol] ||= install(load(Currency.new(nil, symbol)))
|
27
32
|
end
|
28
33
|
|
34
|
+
# This method initializes a Currency object as
|
35
|
+
# requested from #get_by_code or #get_by_symbol.
|
36
|
+
#
|
37
|
+
# This method must initialize:
|
38
|
+
#
|
39
|
+
# currency.code
|
40
|
+
# currency.symbol
|
41
|
+
# currency.scale
|
42
|
+
#
|
43
|
+
# Subclasses that provide Currency metadata should override this method.
|
44
|
+
# For example, loading Currency metadata from a database or YAML file.
|
29
45
|
def load(currency)
|
30
46
|
# $stderr.puts "BEFORE: load(#{currency.code})"
|
31
47
|
|
32
|
-
#
|
48
|
+
# Basic
|
33
49
|
if currency.code == :USD || currency.symbol == '$'
|
34
50
|
# $stderr.puts "load('USD')"
|
35
|
-
currency.code= :USD
|
36
|
-
currency.symbol= '$'
|
37
|
-
currency.scale= 100
|
51
|
+
currency.code = :USD
|
52
|
+
currency.symbol = '$'
|
53
|
+
currency.scale = 100
|
38
54
|
elsif currency.code == :CAD
|
39
55
|
# $stderr.puts "load('CAD')"
|
40
|
-
currency.symbol= '$'
|
41
|
-
currency.scale= 100
|
56
|
+
currency.symbol = '$'
|
57
|
+
currency.scale = 100
|
42
58
|
else
|
43
|
-
currency.symbol= nil
|
44
|
-
currency.scale= 100
|
59
|
+
currency.symbol = nil
|
60
|
+
currency.scale = 100
|
45
61
|
end
|
46
62
|
|
47
63
|
# $stderr.puts "AFTER: load(#{currency.inspect})"
|
48
64
|
|
49
|
-
|
65
|
+
currency
|
50
66
|
end
|
51
67
|
|
68
|
+
# Installs a new Currency for #get_by_symbol and #get_by_code.
|
52
69
|
def install(currency)
|
70
|
+
raise Exception::UnknownCurrency.new() unless currency
|
53
71
|
@currency_by_symbol[currency.symbol] ||= currency unless currency.symbol.nil?
|
54
72
|
@currency_by_code[currency.code] = currency
|
55
73
|
end
|
56
74
|
|
57
|
-
# Standard
|
75
|
+
# Standard Currency: US Dollars, :USD.
|
58
76
|
def USD
|
59
77
|
@USD ||= self.get_by_code(:USD)
|
60
78
|
end
|
61
79
|
|
80
|
+
# Standard Currency: Canadian Dollars, :CAD.
|
62
81
|
def CAD
|
63
82
|
@CAD ||= self.get_by_code(:CAD)
|
64
83
|
end
|
65
84
|
|
66
|
-
#
|
85
|
+
# Returns the default Currency.
|
86
|
+
# Defaults to self.USD.
|
67
87
|
def currency
|
68
88
|
@currency ||= self.USD
|
69
89
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
90
|
+
|
91
|
+
# Sets the default Currency.
|
92
|
+
def currency=(x)
|
93
|
+
@currency = x
|
94
|
+
end
|
95
|
+
|
96
|
+
end # class
|
97
|
+
end # module
|
98
|
+
|
99
|
+
|
73
100
|
|
@@ -14,11 +14,18 @@ module Exchange
|
|
14
14
|
|
15
15
|
# Represents a method of converting between two currencies
|
16
16
|
class Base
|
17
|
+
|
18
|
+
# The name of this Exchange.
|
17
19
|
attr_accessor :name
|
18
20
|
|
21
|
+
# If true, this Exchange will log information.
|
22
|
+
attr_accessor :verbose
|
23
|
+
|
19
24
|
def initialize(*opt)
|
20
25
|
@name = nil
|
21
26
|
@rate = { }
|
27
|
+
opt = Hash[*opt]
|
28
|
+
opt.each{|k,v| self.send(k, v)}
|
22
29
|
end
|
23
30
|
|
24
31
|
# Converts Money m in Currency c1 to a new
|
@@ -34,7 +41,7 @@ module Exchange
|
|
34
41
|
|
35
42
|
# Flush all cached Rate.
|
36
43
|
def clear_rates
|
37
|
-
@rate.
|
44
|
+
@rate.clear
|
38
45
|
end
|
39
46
|
|
40
47
|
# Flush any cached Rate between Currency c1 and c2.
|
@@ -47,6 +54,10 @@ module Exchange
|
|
47
54
|
#
|
48
55
|
# This will call #get_rate(c1, c2) if the
|
49
56
|
# Rate has not already been cached.
|
57
|
+
#
|
58
|
+
# Subclasses can override this method to implement
|
59
|
+
# rate expiration rules.
|
60
|
+
#
|
50
61
|
def rate(c1, c2)
|
51
62
|
(@rate[c1.code.to_s + c2.code.to_s] ||= get_rate(c1, c2)) ||
|
52
63
|
(@rate[c2.code.to_s + c1.code.to_s] ||= get_rate(c2, c1))
|
data/lib/currency/exchange/xe.rb
CHANGED
@@ -9,7 +9,6 @@ module Exchange
|
|
9
9
|
|
10
10
|
class Xe < Base
|
11
11
|
@@instance = nil
|
12
|
-
|
13
12
|
# Returns a singleton instance.
|
14
13
|
def self.instance(*opts)
|
15
14
|
@@instance ||= self.new(*opts)
|
@@ -18,33 +17,118 @@ module Exchange
|
|
18
17
|
# Defaults to "http://xe.com/"
|
19
18
|
attr_accessor :uri
|
20
19
|
|
20
|
+
# Defines the number of seconds rates until rates
|
21
|
+
# become invalid, causing a request of new rates.
|
22
|
+
#
|
23
|
+
# Defaults to 600 seconds.
|
24
|
+
attr_accessor :time_to_live
|
25
|
+
|
26
|
+
# Defines the number of random seconds to add before
|
27
|
+
# rates become invalid.
|
28
|
+
#
|
29
|
+
# Defaults to 30 seconds.
|
30
|
+
attr_accessor :time_to_live_fudge
|
31
|
+
|
21
32
|
# This Exchange's name is the same as its #uri.
|
22
33
|
def name
|
23
34
|
uri
|
24
35
|
end
|
25
36
|
|
26
37
|
def initialize(*opt)
|
27
|
-
super(*opt)
|
28
38
|
self.uri = 'http://xe.com/'
|
29
|
-
|
39
|
+
self.time_to_live = 600
|
40
|
+
self.time_to_live_fudge = 30
|
41
|
+
@xe_rates = nil
|
42
|
+
super(*opt)
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear_rates
|
46
|
+
@xe_rates && @xe_rates.clear
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def expired?
|
51
|
+
if @time_to_live &&
|
52
|
+
@xe_rates_renew_time &&
|
53
|
+
(Time.now > @xe_rates_renew_time)
|
54
|
+
|
55
|
+
if @xe_rates
|
56
|
+
$stderr.puts "#{self}: rates expired on #{@xe_rates_renew_time}" if @verbose
|
57
|
+
|
58
|
+
@old_rates ||= @xe_rates
|
59
|
+
|
60
|
+
@xe_rates = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check expired? before returning a Rate.
|
70
|
+
def rate(c1, c2)
|
71
|
+
if expired?
|
72
|
+
clear_rates
|
73
|
+
end
|
74
|
+
super(c1, c2)
|
30
75
|
end
|
31
76
|
|
32
77
|
# Returns a cached Hash of rates:
|
33
78
|
#
|
34
|
-
# xe.
|
79
|
+
# xe.xe_rates[:USD][:CAD] => 1.0134
|
35
80
|
#
|
36
|
-
def
|
37
|
-
|
81
|
+
def xe_rates
|
82
|
+
old_rates = nil
|
83
|
+
# Check expiration.
|
84
|
+
expired?
|
38
85
|
|
39
|
-
|
40
|
-
return @
|
86
|
+
# Return rates, if cached.
|
87
|
+
return @xe_rates if @xe_rates
|
41
88
|
|
42
|
-
|
43
|
-
@
|
89
|
+
# Force load of rates
|
90
|
+
@xe_rates = xe_rates_load
|
91
|
+
|
92
|
+
# Flush old rates.
|
93
|
+
@old_rates = nil
|
94
|
+
|
95
|
+
# Update expiration.
|
96
|
+
if time_to_live
|
97
|
+
@xe_rates_renew_time = @rate_timestamp + (time_to_live + (time_to_live_fudge || 0))
|
98
|
+
$stderr.puts "#{self}: rates expire on #{@xe_rates_renew_time}" if @verbose
|
99
|
+
end
|
100
|
+
|
101
|
+
@xe_rates
|
102
|
+
end
|
103
|
+
|
104
|
+
def xe_rates_load
|
105
|
+
# Do not allow re-entrancy
|
106
|
+
raise "Reentrant!" if @processing_rates
|
107
|
+
|
108
|
+
# Begin processing new rate request.
|
109
|
+
@processing_rates = true
|
110
|
+
|
111
|
+
# Clear cached Rates.
|
112
|
+
clear_rates
|
113
|
+
|
114
|
+
# Parse rates from HTML page.
|
115
|
+
rates = parse_page_rates
|
44
116
|
|
45
|
-
|
117
|
+
unless rates
|
118
|
+
# FIXME: raise Exception::???
|
119
|
+
return rates
|
120
|
+
end
|
121
|
+
|
122
|
+
# Compute new rate timeps
|
123
|
+
@rate_timestamp = Time.now # TODO: Extract this from HTML page!
|
124
|
+
|
125
|
+
# End processsing new rate request.
|
126
|
+
@processing_rates = false
|
127
|
+
|
128
|
+
rates
|
46
129
|
end
|
47
130
|
|
131
|
+
|
48
132
|
# Returns the URI content.
|
49
133
|
def get_page
|
50
134
|
data = open(uri) { |data| data.read }
|
@@ -131,18 +215,22 @@ module Exchange
|
|
131
215
|
# Loads cached rates from xe.com and creates Rate objects
|
132
216
|
# for 10 currencies.
|
133
217
|
def get_rate(c1, c2)
|
134
|
-
rates # Load rates
|
218
|
+
rates = xe_rates # Load rates
|
135
219
|
|
136
220
|
# $stderr.puts "load_exchange_rate(#{c1}, #{c2})"
|
137
221
|
rate = 0.0
|
138
222
|
r1 = nil
|
139
223
|
r2 = nil
|
140
224
|
|
141
|
-
|
225
|
+
rates_usd = rates[:USD]
|
226
|
+
|
227
|
+
raise Exception::UnknownRate.new("#{self}: base rate :USD") unless rates_usd
|
228
|
+
|
229
|
+
if ( c1.code == :USD && (r2 = rates_usd[c2.code]) )
|
142
230
|
rate = r2
|
143
|
-
elsif ( c2.code == :USD && (r1 =
|
231
|
+
elsif ( c2.code == :USD && (r1 = rates_usd[c2.code]) )
|
144
232
|
rate = 1.0 / r1
|
145
|
-
elsif ( (r1 =
|
233
|
+
elsif ( (r1 = rates_usd[c1.code]) && (r2 = rates_usd[c2.code]) )
|
146
234
|
rate = r2 / r1
|
147
235
|
end
|
148
236
|
|
data/lib/currency/money.rb
CHANGED
@@ -106,17 +106,19 @@ module Currency
|
|
106
106
|
@rep
|
107
107
|
end
|
108
108
|
|
109
|
-
# Returns the
|
109
|
+
# Returns the Money representation (usually an Integer).
|
110
110
|
def rep
|
111
111
|
@rep
|
112
112
|
end
|
113
113
|
|
114
|
-
# Get the
|
114
|
+
# Get the Money's Currency.
|
115
115
|
def currency
|
116
116
|
@currency
|
117
117
|
end
|
118
118
|
|
119
119
|
# Convert Money to another Currency.
|
120
|
+
# currency can be a Symbol or a Currency object.
|
121
|
+
# If currency is nil, the Currency.default is used.
|
120
122
|
def convert(currency)
|
121
123
|
currency = Currency.default if currency.nil?
|
122
124
|
currency = Currency.get(currency) unless currency.kind_of?(Currency)
|
@@ -147,6 +149,8 @@ module Currency
|
|
147
149
|
@currency == x.currency
|
148
150
|
end
|
149
151
|
|
152
|
+
# Compares Money values.
|
153
|
+
# Will convert x currency before comparision.
|
150
154
|
def <=>(x)
|
151
155
|
if @currency == x.currency
|
152
156
|
@rep <=> x.rep
|
@@ -155,32 +159,31 @@ module Currency
|
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
158
|
-
# Operations on Money values.
|
159
|
-
|
160
162
|
|
161
163
|
# - Money => Money
|
164
|
+
#
|
162
165
|
# Negates a Money value.
|
163
166
|
def -@
|
164
167
|
new_rep(- @rep)
|
165
168
|
end
|
166
169
|
|
167
|
-
# Money + (Number
|
170
|
+
# Money + (Money | Number) => Money
|
168
171
|
#
|
169
|
-
# Right side
|
172
|
+
# Right side may be coerced to left side's Currency.
|
170
173
|
def +(x)
|
171
174
|
new_rep(@rep + x.Money_rep(@currency))
|
172
175
|
end
|
173
176
|
|
174
|
-
# Money - (Number
|
177
|
+
# Money - (Money | Number) => Money
|
175
178
|
#
|
176
|
-
# Right side
|
179
|
+
# Right side may be coerced to left side's Currency.
|
177
180
|
def -(x)
|
178
181
|
new_rep(@rep - x.Money_rep(@currency))
|
179
182
|
end
|
180
183
|
|
181
184
|
# Money * Number => Money
|
182
185
|
#
|
183
|
-
# Right side must be
|
186
|
+
# Right side must be Number.
|
184
187
|
def *(x)
|
185
188
|
new_rep(@rep * x)
|
186
189
|
end
|
@@ -188,7 +191,7 @@ module Currency
|
|
188
191
|
# Money / Money => Number (ratio)
|
189
192
|
# Money / Number => Money
|
190
193
|
#
|
191
|
-
# Right side must be
|
194
|
+
# Right side must be Money or Number.
|
192
195
|
# Right side Integers are not coerced to Float before
|
193
196
|
# division.
|
194
197
|
def /(x)
|
data/test/money_test.rb
CHANGED
@@ -16,12 +16,27 @@ class MoneyTest < TestBase
|
|
16
16
|
#
|
17
17
|
|
18
18
|
def test_create
|
19
|
-
|
20
|
-
|
19
|
+
assert_kind_of Money, m = Money.new(1.99)
|
20
|
+
assert_equal m.currency, Currency.default
|
21
|
+
assert_equal m.currency.code, :USD
|
21
22
|
|
22
23
|
m
|
23
24
|
end
|
24
25
|
|
26
|
+
def test_object_money_method
|
27
|
+
assert_kind_of Money, m = 1.99.money(:USD)
|
28
|
+
assert_equal m.currency.code, :USD
|
29
|
+
assert_equal m.rep, 199
|
30
|
+
|
31
|
+
assert_kind_of Money, m = 199.money(:CAD)
|
32
|
+
assert_equal m.currency.code, :CAD
|
33
|
+
assert_equal m.rep, 19900
|
34
|
+
|
35
|
+
assert_kind_of Money, m = "13.98".money(:CAD)
|
36
|
+
assert_equal m.currency.code, :CAD
|
37
|
+
assert_equal m.rep, 1398
|
38
|
+
end
|
39
|
+
|
25
40
|
def test_zero
|
26
41
|
m = Money.new(0)
|
27
42
|
assert ! m.negative?
|
@@ -70,6 +85,20 @@ class MoneyTest < TestBase
|
|
70
85
|
assert z == test_zero
|
71
86
|
end
|
72
87
|
|
88
|
+
def test_compare
|
89
|
+
n = test_negative
|
90
|
+
z = test_zero
|
91
|
+
p = test_positive
|
92
|
+
|
93
|
+
assert (n <=> p) == -1
|
94
|
+
assert (p <=> n) == 1
|
95
|
+
assert (p <=> z) == 1
|
96
|
+
|
97
|
+
assert (n <=> n) == 0
|
98
|
+
assert (z <=> z) == 0
|
99
|
+
assert (p <=> p) == 0
|
100
|
+
end
|
101
|
+
|
73
102
|
def test_rep
|
74
103
|
assert_not_nil m = Money.new(123, :USD)
|
75
104
|
assert m.rep == 12300
|
@@ -91,6 +120,34 @@ class MoneyTest < TestBase
|
|
91
120
|
end
|
92
121
|
|
93
122
|
def test_eql
|
123
|
+
assert_not_nil usd1 = Money.new(123, :USD)
|
124
|
+
assert_not_nil usd2 = Money.new("123", :USD)
|
125
|
+
|
126
|
+
assert_equal :USD, usd1.currency.code
|
127
|
+
assert_equal :USD, usd2.currency.code
|
128
|
+
|
129
|
+
assert_equal usd1.rep, usd2.rep
|
130
|
+
|
131
|
+
assert usd1 == usd2
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_not_eql
|
136
|
+
|
137
|
+
assert_not_nil usd1 = Money.new(123, :USD)
|
138
|
+
assert_not_nil usd2 = Money.new("123.01", :USD)
|
139
|
+
|
140
|
+
assert_equal :USD, usd1.currency.code
|
141
|
+
assert_equal :USD, usd2.currency.code
|
142
|
+
|
143
|
+
assert_not_equal usd1.rep, usd2.rep
|
144
|
+
|
145
|
+
assert usd1 != usd2
|
146
|
+
|
147
|
+
################
|
148
|
+
# currency !=
|
149
|
+
# rep ==
|
150
|
+
|
94
151
|
assert_not_nil usd = Money.new(123, :USD)
|
95
152
|
assert_not_nil cad = Money.new(123, :CAD)
|
96
153
|
|
@@ -101,7 +158,7 @@ class MoneyTest < TestBase
|
|
101
158
|
assert usd.currency != cad.currency
|
102
159
|
|
103
160
|
assert usd != cad
|
104
|
-
|
161
|
+
|
105
162
|
end
|
106
163
|
|
107
164
|
def test_op
|
data/test/xe_test.rb
CHANGED
metadata
CHANGED