acvwilson-currency 0.6.1 → 0.6.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/Manifest.txt +0 -1
- data/currency.gemspec +3 -3
- data/lib/currency/active_record.rb +3 -4
- data/lib/currency/money.rb +3 -3
- data/lib/currency/parser.rb +12 -9
- data/lib/currency.rb +1 -1
- data/spec/money_spec.rb +40 -20
- data/spec/parser_spec.rb +74 -74
- metadata +2 -3
- data/lib/currency/currency_version.rb +0 -6
data/Manifest.txt
CHANGED
data/currency.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{currency}
|
3
|
-
s.version = "0.6.
|
3
|
+
s.version = "0.6.2"
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.authors = ["Asa Wilson"]
|
@@ -8,11 +8,11 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.description = %q{Currency conversions for Ruby}
|
9
9
|
s.email = ["acvwilson@gmail.com"]
|
10
10
|
s.extra_rdoc_files = ["ChangeLog", "COPYING.txt", "LICENSE.txt", "Manifest.txt", "README.txt", "Releases.txt", "TODO.txt"]
|
11
|
-
s.files = ["COPYING.txt", "currency.gemspec", "examples/ex1.rb", "examples/xe1.rb", "lib/currency/active_record.rb", "lib/currency/config.rb", "lib/currency/core_extensions.rb", "lib/currency/currency/factory.rb", "lib/currency/currency.rb", "lib/currency/
|
11
|
+
s.files = ["COPYING.txt", "currency.gemspec", "examples/ex1.rb", "examples/xe1.rb", "lib/currency/active_record.rb", "lib/currency/config.rb", "lib/currency/core_extensions.rb", "lib/currency/currency/factory.rb", "lib/currency/currency.rb", "lib/currency/exception.rb", "lib/currency/exchange/rate/deriver.rb", "lib/currency/exchange/rate/source/base.rb", "lib/currency/exchange/rate/source/failover.rb", "lib/currency/exchange/rate/source/federal_reserve.rb", "lib/currency/exchange/rate/source/historical/rate.rb", "lib/currency/exchange/rate/source/historical/rate_loader.rb", "lib/currency/exchange/rate/source/historical/writer.rb", "lib/currency/exchange/rate/source/historical.rb", "lib/currency/exchange/rate/source/new_york_fed.rb", "lib/currency/exchange/rate/source/provider.rb", "lib/currency/exchange/rate/source/test.rb", "lib/currency/exchange/rate/source/the_financials.rb", "lib/currency/exchange/rate/source/timed_cache.rb", "lib/currency/exchange/rate/source/xe.rb", "lib/currency/exchange/rate/source.rb", "lib/currency/exchange/rate.rb", "lib/currency/exchange/time_quantitizer.rb", "lib/currency/exchange.rb", "lib/currency/formatter.rb", "lib/currency/macro.rb", "lib/currency/money.rb", "lib/currency/money_helper.rb", "lib/currency/parser.rb", "lib/currency.rb", "LICENSE.txt", "Manifest.txt", "README.txt", "Releases.txt", "spec/ar_spec_helper.rb", "spec/ar_column_spec.rb", "spec/ar_simple_spec.rb", "spec/config_spec.rb", "spec/federal_reserve_spec.rb", "spec/formatter_spec.rb", "spec/historical_writer_spec.rb", "spec/macro_spec.rb", "spec/money_spec.rb", "spec/new_york_fed_spec.rb", "spec/parser_spec.rb", "spec/spec_helper.rb", "spec/time_quantitizer_spec.rb", "spec/timed_cache_spec.rb", "spec/xe_spec.rb", "TODO.txt"]
|
12
12
|
s.has_rdoc = true
|
13
13
|
s.homepage = %q{http://currency.rubyforge.org/}
|
14
14
|
s.rdoc_options = ["--main", "README.txt"]
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
s.rubygems_version = %q{1.2.0}
|
17
17
|
s.summary = %q{#{s.name} #{s.version}}
|
18
|
-
end
|
18
|
+
end
|
@@ -139,7 +139,7 @@ module Currency::ActiveRecord
|
|
139
139
|
attr_name = attr_name.to_s
|
140
140
|
opts[:class] = self
|
141
141
|
opts[:table] = self.table_name
|
142
|
-
opts[:attr_name] = attr_name.
|
142
|
+
opts[:attr_name] = attr_name.to_sym
|
143
143
|
::ActiveRecord::Base.register_money_attribute(opts)
|
144
144
|
|
145
145
|
column = opts[:column] || opts[:attr_name]
|
@@ -204,7 +204,6 @@ end_eval
|
|
204
204
|
validate << "\nvalidates_numericality_of :#{attr_name}#{validate_allow_nil}\n"
|
205
205
|
validate << "\nvalidates_format_of :#{currency_column}, :with => /^[A-Z][A-Z][A-Z]$/#{validate_allow_nil}\n" if currency_column
|
206
206
|
|
207
|
-
|
208
207
|
alias_accessor ||= ''
|
209
208
|
|
210
209
|
module_eval (opts[:module_eval] = x = <<-"end_eval"), __FILE__, __LINE__
|
@@ -225,7 +224,7 @@ def #{attr_name}
|
|
225
224
|
end
|
226
225
|
|
227
226
|
def #{attr_name}=(value)
|
228
|
-
if value.nil?
|
227
|
+
if value.nil? || value.to_s.strip == ''
|
229
228
|
#{attr_name}_money = nil
|
230
229
|
elsif value.kind_of?(Integer) || value.kind_of?(String) || value.kind_of?(Float)
|
231
230
|
#{attr_name}_money = ::Currency::Money(value, #{currency})
|
@@ -238,7 +237,7 @@ def #{attr_name}=(value)
|
|
238
237
|
raise ::Currency::Exception::InvalidMoneyValue, value
|
239
238
|
end
|
240
239
|
|
241
|
-
@#{attr_name} = #{attr_name}_money
|
240
|
+
@#{attr_name} = #{attr_name}_money # TODO: Really needed? Isn't the write_attribute enough?
|
242
241
|
|
243
242
|
write_attribute(:#{column}, #{attr_name}_money.nil? ? nil : #{money_rep})
|
244
243
|
#{write_time}
|
data/lib/currency/money.rb
CHANGED
@@ -58,9 +58,9 @@ class Currency::Money
|
|
58
58
|
else
|
59
59
|
m = ::Currency::Parser.default.parse(x)
|
60
60
|
end
|
61
|
-
@currency = m.currency
|
62
|
-
@time = m.time if m.time
|
63
|
-
@rep = m.rep
|
61
|
+
@currency = m.currency if m && !@currency
|
62
|
+
@time = m.time if m && m.time
|
63
|
+
@rep = m.nil?? 0 : m.rep
|
64
64
|
else
|
65
65
|
@currency = ::Currency::Currency.default unless @currency
|
66
66
|
@rep = x.Money_rep(@currency)
|
data/lib/currency/parser.rb
CHANGED
@@ -46,6 +46,8 @@ class Currency::Parser
|
|
46
46
|
|
47
47
|
|
48
48
|
def _parse(str) # :nodoc:
|
49
|
+
return nil if str.to_s.strip == ''
|
50
|
+
|
49
51
|
x = str
|
50
52
|
|
51
53
|
# Get currency.
|
@@ -70,6 +72,7 @@ class Currency::Parser
|
|
70
72
|
end
|
71
73
|
x = md.pre_match + md.post_match
|
72
74
|
end
|
75
|
+
|
73
76
|
# Default time
|
74
77
|
time ||= @time
|
75
78
|
time = Time.new if time == :now
|
@@ -108,35 +111,35 @@ class Currency::Parser
|
|
108
111
|
if md = /^([-+]?\d+)\.?$/.match(x)
|
109
112
|
# $stderr.puts "'#{self}'.parse(#{str}) => EXACT"
|
110
113
|
x = ::Currency::Money.new_rep(md[1].to_i * currency.scale, currency, @time)
|
111
|
-
|
114
|
+
|
112
115
|
# Match: fractional Currency value.
|
113
116
|
elsif md = /^([-+]?)(\d*)\.(\d+)$/.match(x)
|
114
117
|
sign = md[1]
|
115
118
|
whole = md[2]
|
116
119
|
part = md[3]
|
117
|
-
|
120
|
+
|
118
121
|
# $stderr.puts "'#{self}'.parse(#{str}) => DECIMAL (#{sign} #{whole} . #{part})"
|
119
|
-
|
122
|
+
|
120
123
|
if part.length != currency.scale
|
121
|
-
|
124
|
+
|
122
125
|
# Pad decimal places with additional '0'
|
123
126
|
while part.length < currency.scale_exp
|
124
127
|
part << '0'
|
125
128
|
end
|
126
|
-
|
129
|
+
|
127
130
|
# Truncate to Currency's decimal size.
|
128
131
|
part = part[0 ... currency.scale_exp]
|
129
|
-
|
132
|
+
|
130
133
|
# $stderr.puts " => INEXACT DECIMAL '#{whole}'"
|
131
134
|
end
|
132
|
-
|
135
|
+
|
133
136
|
# Put the string back together:
|
134
137
|
# #{sign}#{whole}#{part}
|
135
138
|
whole = sign + whole + part
|
136
139
|
# $stderr.puts " => REP = #{whole}"
|
137
|
-
|
140
|
+
|
138
141
|
x = whole.to_i
|
139
|
-
|
142
|
+
|
140
143
|
x = ::Currency::Money.new_rep(x, currency, time)
|
141
144
|
else
|
142
145
|
# $stderr.puts "'#{self}'.parse(#{str}) => ??? '#{x}'"
|
data/lib/currency.rb
CHANGED
@@ -118,13 +118,13 @@ module Currency
|
|
118
118
|
#
|
119
119
|
# See Money#new.
|
120
120
|
def self.Money(*opts)
|
121
|
+
return nil if opts.to_s.strip == ''
|
121
122
|
Money.new(*opts)
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
125
126
|
$:.unshift(File.expand_path(File.dirname(__FILE__))) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
126
127
|
|
127
|
-
require 'currency/currency_version'
|
128
128
|
require 'currency/config'
|
129
129
|
require 'currency/exception'
|
130
130
|
require 'currency/money'
|
data/spec/money_spec.rb
CHANGED
@@ -3,14 +3,33 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
3
3
|
|
4
4
|
describe Currency::Money do
|
5
5
|
|
6
|
-
|
6
|
+
before :all do
|
7
|
+
Currency::Config.configure do |config|
|
8
|
+
config.scale_exp = 6
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def zero_money
|
14
|
+
@zero_money ||= Currency::Money.new(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def negative_money
|
18
|
+
@negative_money ||= Currency::Money.new(-1.00, :USD)
|
19
|
+
end
|
20
|
+
|
21
|
+
def positive_money
|
22
|
+
@positive_money ||= Currency::Money.new(2.99, :USD)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates Monies" do
|
7
26
|
m = Currency::Money.new(1.99)
|
8
27
|
m.should be_kind_of(Currency::Money)
|
9
28
|
Currency::Currency.default.should == m.currency
|
10
29
|
:USD.should == m.currency.code
|
11
30
|
end
|
12
31
|
|
13
|
-
describe "
|
32
|
+
describe "Converts different objects to Money with the 'money' method" do
|
14
33
|
it "works with a float" do
|
15
34
|
m = 1.99.money(:USD)
|
16
35
|
m.should be_kind_of(Currency::Money)
|
@@ -38,45 +57,46 @@ describe Currency::Money do
|
|
38
57
|
:EUR.should == m.currency.code
|
39
58
|
m.rep.should == 45990000
|
40
59
|
end
|
60
|
+
|
61
|
+
describe "deals with voids" do
|
62
|
+
it "does not raise with an empty string" do
|
63
|
+
lambda{
|
64
|
+
Currency::Money.new('')
|
65
|
+
}.should_not raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it "considers the empty string to be nil " do
|
69
|
+
Currency::Money.new('').should be_nil
|
70
|
+
end
|
71
|
+
end
|
41
72
|
end
|
42
73
|
|
43
|
-
|
44
|
-
@zero_money ||= Currency::Money.new(0)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "zero" do
|
74
|
+
it "deals with zero in the least surprising way" do
|
48
75
|
zero_money.negative?.should_not == true
|
49
76
|
zero_money.zero?.should_not == nil
|
50
77
|
zero_money.positive?.should_not == true
|
51
78
|
end
|
52
79
|
|
53
|
-
|
54
|
-
@negative_money ||= Currency::Money.new(-1.00, :USD)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "negative" do
|
80
|
+
it "deals with negatives in the least surprising way" do
|
58
81
|
negative_money.negative?.should_not == nil
|
59
82
|
negative_money.zero?.should_not == true
|
60
83
|
negative_money.positive?.should_not == true
|
61
84
|
end
|
62
85
|
|
63
|
-
|
64
|
-
@positive_money ||= Currency::Money.new(2.99, :USD)
|
65
|
-
end
|
66
|
-
it "positive" do
|
86
|
+
it "deals with positive numbers in the least surprising way" do
|
67
87
|
positive_money.negative?.should_not == true
|
68
88
|
positive_money.zero?.should_not == true
|
69
89
|
positive_money.positive?.should_not == nil
|
70
90
|
end
|
71
91
|
|
72
|
-
it "
|
92
|
+
it "can do comparisons between monies" do
|
73
93
|
n = negative_money
|
74
94
|
z = zero_money
|
75
95
|
p = positive_money
|
76
96
|
|
77
|
-
|
78
|
-
|
79
|
-
|
97
|
+
negative_money.should < positive_money
|
98
|
+
(negative_money > positive_money).should_not be_true
|
99
|
+
(positive_money < negative_money).should_not be_true
|
80
100
|
(p.should > n)
|
81
101
|
(p != n).should_not == nil
|
82
102
|
|
data/spec/parser_spec.rb
CHANGED
@@ -1,105 +1,105 @@
|
|
1
1
|
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
2
2
|
# See LICENSE.txt for details.
|
3
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
4
|
|
4
|
-
|
5
|
-
require 'currency'
|
6
|
-
|
7
|
-
module Currency
|
8
|
-
|
9
|
-
class ParserTest < TestBase
|
5
|
+
describe Currency::Parser do
|
10
6
|
before do
|
11
|
-
super
|
12
7
|
@parser = ::Currency::Currency.USD.parser_or_default
|
13
8
|
end
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
describe "is great at parsing strings" do
|
11
|
+
it "can use a string that uses the thousands-separator (comma)" do
|
12
|
+
@parser.parse("1234567.89").rep.should == 123456789
|
13
|
+
@parser.parse("1,234,567.89").rep.should == 123456789
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
it "parses cents" do
|
18
|
+
@parser.parse("1234567.89").rep.should == 123456789
|
19
|
+
@parser.parse("1234567").rep.should == 123456700
|
20
|
+
@parser.parse("1234567.").rep.should == 123456700
|
21
|
+
@parser.parse("1234567.8").rep.should == 123456780
|
22
|
+
@parser.parse("1234567.891").rep.should == 123456789
|
23
|
+
@parser.parse("-1234567").rep.should == -123456700
|
24
|
+
@parser.parse("+1234567").rep.should == 123456700
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
describe "can convert the right hand side argument" do
|
29
|
+
it "converts the right hand argument to the left hand side currency if needed" do
|
30
|
+
m = "123.45 USD".money + "100 CAD"
|
31
|
+
m.should_not == nil
|
32
|
+
m.rep.should == ("123.45".money(:USD) + "100 CAD".money(:USD)).rep
|
33
|
+
end
|
34
|
+
|
35
|
+
it "uses the left hand sides currency if the right hand side argument does provide currency info" do
|
36
|
+
m = "123.45 USD".money
|
37
|
+
(m + 100).rep.should == (m + "100".money(:USD)).rep
|
38
|
+
end
|
27
39
|
end
|
28
40
|
|
41
|
+
describe "can use the inspect method as a serialization of self" do
|
42
|
+
it "can recreate a money object by using a .inspect-string" do
|
43
|
+
::Currency::Currency.default = :USD
|
44
|
+
m = ::Currency::Money("1234567.89", :CAD)
|
45
|
+
m2 = ::Currency::Money(m.inspect)
|
29
46
|
|
30
|
-
|
31
|
-
|
32
|
-
@parser.parse("1234567").rep.should == 123456700
|
33
|
-
@parser.parse("1234567.").rep.should == 123456700
|
34
|
-
@parser.parse("1234567.8").rep.should == 123456780
|
35
|
-
@parser.parse("1234567.891").rep.should == 123456789
|
36
|
-
@parser.parse("-1234567").rep.should == -123456700
|
37
|
-
@parser.parse("+1234567").rep.should == 123456700
|
38
|
-
end
|
47
|
+
m2.rep.should == m.rep
|
48
|
+
m2.currency.should == m.currency
|
39
49
|
|
50
|
+
m2.inspect.should == m.inspect
|
51
|
+
end
|
40
52
|
|
41
|
-
it "misc" do
|
42
|
-
m = "123.45 USD".money + "100 CAD".should_not == nil
|
43
|
-
(m.rep == 200.45).should_not == true
|
44
|
-
end
|
45
53
|
|
54
|
+
it "can recreate a money objectby using a .inspect-string and keep the time parameter as well" do
|
55
|
+
::Currency::Currency.default = :USD
|
56
|
+
time = Time.now.getutc
|
57
|
+
m = ::Currency::Money("1234567.89", :CAD, time)
|
58
|
+
m.time.should_not == nil
|
46
59
|
|
47
|
-
|
48
|
-
|
49
|
-
m = ::Currency::Money("1234567.89", :CAD).should_not == nil
|
50
|
-
m2 = ::Currency::Money(m.inspect).should_not == nil
|
51
|
-
m2.rep.should == m.rep
|
52
|
-
m2.currency.should == m.currency
|
53
|
-
m2.time.should == nil
|
54
|
-
m2.inspect.should == m.inspect
|
55
|
-
end
|
60
|
+
m2 = ::Currency::Money(m.inspect)
|
61
|
+
m2.time.should_not == nil
|
56
62
|
|
63
|
+
m.should_not be(m2)
|
57
64
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
m2 = ::Currency::Money(m.inspect).should_not == nil
|
64
|
-
m2.time.should_not == nil
|
65
|
-
m2.rep.should == m.rep
|
66
|
-
m2.currency.should == m.currency
|
67
|
-
m2.time.to_i.should == m.time.to_i
|
68
|
-
m2.inspect.should == m.inspect
|
65
|
+
m2.rep.should == m.rep
|
66
|
+
m2.currency.should == m.currency
|
67
|
+
m2.time.to_i.should == m.time.to_i
|
68
|
+
m2.inspect.should == m.inspect
|
69
|
+
end
|
69
70
|
end
|
70
71
|
|
72
|
+
describe "deals with time when creating money objects" do
|
73
|
+
before do
|
74
|
+
@parser = ::Currency::Parser.new
|
75
|
+
end
|
76
|
+
|
77
|
+
it "can parse even though the parser time is nil" do
|
78
|
+
@parser.time = nil
|
71
79
|
|
72
|
-
|
73
|
-
|
74
|
-
|
80
|
+
m = @parser.parse("$1234.55")
|
81
|
+
m.time.should == nil
|
82
|
+
end
|
75
83
|
|
76
|
-
m = parser.parse("$1234.55").should_not == nil
|
77
|
-
m.time.should == nil
|
78
|
-
end
|
79
84
|
|
85
|
+
it "parses money strings into money object using the parsers time" do
|
86
|
+
@parser.time = Time.now
|
80
87
|
|
81
|
-
|
82
|
-
|
83
|
-
|
88
|
+
m = @parser.parse("$1234.55")
|
89
|
+
m.time.should == @parser.time
|
90
|
+
end
|
84
91
|
|
85
|
-
m = parser.parse("$1234.55").should_not == nil
|
86
|
-
m.time.should == parser.time
|
87
|
-
end
|
88
92
|
|
93
|
+
it "when re-initializing a money object, the time is also re-initialized" do
|
94
|
+
@parser.time = :now
|
89
95
|
|
90
|
-
|
91
|
-
|
92
|
-
parser.time = :now
|
96
|
+
m = @parser.parse("$1234.55")
|
97
|
+
m1_time = m.time
|
93
98
|
|
94
|
-
|
95
|
-
|
99
|
+
m = @parser.parse("$1234.55")
|
100
|
+
m2_time = m.time
|
96
101
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
assert_not_equal m1_time, m2_time
|
102
|
+
m1_time.should_not == m2_time
|
103
|
+
end
|
101
104
|
end
|
102
105
|
end
|
103
|
-
|
104
|
-
end # module
|
105
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acvwilson-currency
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Asa Wilson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-12-01
|
12
|
+
date: 2008-12-01 08:54:17.132058 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -38,7 +38,6 @@ files:
|
|
38
38
|
- lib/currency/core_extensions.rb
|
39
39
|
- lib/currency/currency/factory.rb
|
40
40
|
- lib/currency/currency.rb
|
41
|
-
- lib/currency/currency_version.rb
|
42
41
|
- lib/currency/exception.rb
|
43
42
|
- lib/currency/exchange/rate/deriver.rb
|
44
43
|
- lib/currency/exchange/rate/source/base.rb
|