cleanconscience-currency 0.7.0.11
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/COPYING.txt +339 -0
- data/ChangeLog +8 -0
- data/LICENSE.txt +65 -0
- data/Manifest.txt +57 -0
- data/README.txt +51 -0
- data/Releases.txt +155 -0
- data/TODO.txt +9 -0
- data/currency.gemspec +18 -0
- data/examples/ex1.rb +13 -0
- data/examples/xe1.rb +20 -0
- data/lib/currency.rb +143 -0
- data/lib/currency/active_record.rb +304 -0
- data/lib/currency/config.rb +93 -0
- data/lib/currency/core_extensions.rb +33 -0
- data/lib/currency/currency.rb +172 -0
- data/lib/currency/currency/factory.rb +131 -0
- data/lib/currency/exception.rb +119 -0
- data/lib/currency/exchange.rb +48 -0
- data/lib/currency/exchange/rate.rb +214 -0
- data/lib/currency/exchange/rate/deriver.rb +157 -0
- data/lib/currency/exchange/rate/source.rb +89 -0
- data/lib/currency/exchange/rate/source/base.rb +166 -0
- data/lib/currency/exchange/rate/source/failover.rb +63 -0
- data/lib/currency/exchange/rate/source/federal_reserve.rb +151 -0
- data/lib/currency/exchange/rate/source/historical.rb +79 -0
- data/lib/currency/exchange/rate/source/historical/rate.rb +185 -0
- data/lib/currency/exchange/rate/source/historical/rate_loader.rb +186 -0
- data/lib/currency/exchange/rate/source/historical/writer.rb +220 -0
- data/lib/currency/exchange/rate/source/new_york_fed.rb +127 -0
- data/lib/currency/exchange/rate/source/provider.rb +117 -0
- data/lib/currency/exchange/rate/source/test.rb +50 -0
- data/lib/currency/exchange/rate/source/the_financials.rb +191 -0
- data/lib/currency/exchange/rate/source/timed_cache.rb +198 -0
- data/lib/currency/exchange/rate/source/xe.rb +152 -0
- data/lib/currency/exchange/time_quantitizer.rb +111 -0
- data/lib/currency/formatter.rb +308 -0
- data/lib/currency/macro.rb +321 -0
- data/lib/currency/money.rb +293 -0
- data/lib/currency/money_helper.rb +13 -0
- data/lib/currency/parser.rb +196 -0
- data/spec/ar_simple_spec.rb +80 -0
- data/spec/ar_spec_helper.rb +164 -0
- data/spec/config_spec.rb +70 -0
- data/spec/federal_reserve_spec.rb +71 -0
- data/spec/formatter_spec.rb +72 -0
- data/spec/historical_writer_spec.rb +121 -0
- data/spec/macro_spec.rb +109 -0
- data/spec/money_spec.rb +367 -0
- data/spec/new_york_fed_spec.rb +73 -0
- data/spec/parser_spec.rb +105 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/time_quantitizer_spec.rb +115 -0
- data/spec/timed_cache_spec.rb +95 -0
- data/spec/xe_spec.rb +50 -0
- metadata +116 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
|
2
|
+
# See LICENSE.txt for details.
|
|
3
|
+
require File.dirname(__FILE__) + '/ar_spec_helper'
|
|
4
|
+
|
|
5
|
+
require File.dirname(__FILE__) + '/../lib/currency/exchange/rate/source/historical'
|
|
6
|
+
require File.dirname(__FILE__) + '/../lib/currency/exchange/rate/source/historical/writer'
|
|
7
|
+
require File.dirname(__FILE__) + '/../lib/currency/exchange/rate/source/xe'
|
|
8
|
+
require File.dirname(__FILE__) + '/../lib/currency/exchange/rate/source/new_york_fed'
|
|
9
|
+
|
|
10
|
+
include Currency
|
|
11
|
+
RATE_CLASS = Exchange::Rate::Source::Historical::Rate
|
|
12
|
+
TABLE_NAME = RATE_CLASS.table_name
|
|
13
|
+
|
|
14
|
+
class HistoricalRateMigration < ActiveRecord::Migration
|
|
15
|
+
def self.up
|
|
16
|
+
RATE_CLASS.__create_table(self)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.down
|
|
20
|
+
drop_table TABLE_NAME.to_sym
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "HistoricalWriter" do
|
|
25
|
+
before(:all) do
|
|
26
|
+
ActiveRecord::Base.establish_connection(database_spec)
|
|
27
|
+
@currency_test_migration ||= HistoricalRateMigration
|
|
28
|
+
schema_down
|
|
29
|
+
schema_up
|
|
30
|
+
@xe_src = Exchange::Rate::Source::Xe.new
|
|
31
|
+
@fed_src = Exchange::Rate::Source::NewYorkFed.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
after(:all) do
|
|
35
|
+
schema_down
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def setup_writer(source)
|
|
39
|
+
writer = Exchange::Rate::Source::Historical::Writer.new
|
|
40
|
+
writer.time_quantitizer = :current
|
|
41
|
+
writer.required_currencies = [ :USD, :GBP, :EUR, :CAD ]
|
|
42
|
+
writer.base_currencies = [ :USD ]
|
|
43
|
+
writer.preferred_currencies = writer.required_currencies
|
|
44
|
+
writer.reciprocal_rates = true
|
|
45
|
+
writer.all_rates = true
|
|
46
|
+
writer.identity_rates = false
|
|
47
|
+
writer.source = source
|
|
48
|
+
writer
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "can read, parse and write XE data" do
|
|
52
|
+
writer = setup_writer(@xe_src)
|
|
53
|
+
rates = writer.write_rates
|
|
54
|
+
rates.size.should == 12
|
|
55
|
+
assert_h_rates(rates, writer)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "can read, parse and write NewYorkFed data (will fail on weekends)" do
|
|
59
|
+
if @fed_src.available?
|
|
60
|
+
writer = setup_writer(@fed_src)
|
|
61
|
+
rates = writer.write_rates
|
|
62
|
+
rates.size.should == 12
|
|
63
|
+
assert_h_rates(rates, writer)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def assert_h_rates(rates, writer = nil)
|
|
68
|
+
hr0 = rates[0]
|
|
69
|
+
hr0.should_not be_nil
|
|
70
|
+
rates.each do | hr |
|
|
71
|
+
found_hr = nil
|
|
72
|
+
begin
|
|
73
|
+
found_hr = hr.find_matching_this(:first)
|
|
74
|
+
found_hr.should_not be_nil
|
|
75
|
+
rescue Object => err
|
|
76
|
+
raise "#{hr.inspect}: #{err}:\n#{err.backtrace.inspect}"
|
|
77
|
+
end
|
|
78
|
+
assert_equal_rate(hr, found_hr)
|
|
79
|
+
assert_rate_defaults(hr, writer)
|
|
80
|
+
|
|
81
|
+
hr.instance_eval do
|
|
82
|
+
date.should == hr0.date
|
|
83
|
+
date_0.should == hr0.date_0
|
|
84
|
+
date_1.should == hr0.date_1
|
|
85
|
+
source.should == hr0.source
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def assert_equal_rate(hr0, hr)
|
|
91
|
+
tollerance = 0.00001
|
|
92
|
+
hr.c1.to_s.should == hr0.c1.to_s
|
|
93
|
+
hr.c2.to_s.should == hr0.c2.to_s
|
|
94
|
+
hr.source.should == hr0.source
|
|
95
|
+
|
|
96
|
+
hr0.rate.should be_close(hr.rate, tollerance)
|
|
97
|
+
hr0.rate_avg.should be_close(hr.rate_avg, tollerance)
|
|
98
|
+
hr0.rate_samples.should == hr.rate_samples.should
|
|
99
|
+
|
|
100
|
+
hr0.rate_lo.should be_close(hr.rate_lo, tollerance)
|
|
101
|
+
hr0.rate_hi.should be_close(hr.rate_hi, tollerance)
|
|
102
|
+
hr0.rate_date_0.should be_close(hr.rate_date_0, tollerance)
|
|
103
|
+
hr0.rate_date_1.should be_close(hr.rate_date_1, tollerance)
|
|
104
|
+
|
|
105
|
+
hr0.date.should == hr.date
|
|
106
|
+
hr0.date_0.should == hr.date_0
|
|
107
|
+
hr0.date_1.should == hr.date_1
|
|
108
|
+
hr0.derived.should == hr.derived
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def assert_rate_defaults(hr, writer)
|
|
112
|
+
hr.source.should == writer.source.name
|
|
113
|
+
hr.rate_avg.should == hr.rate
|
|
114
|
+
hr.rate_samples.should == 1
|
|
115
|
+
hr.rate_lo.should == hr.rate
|
|
116
|
+
hr.rate_hi.should == hr.rate
|
|
117
|
+
hr.rate_date_0.should == hr.rate
|
|
118
|
+
hr.rate_date_1.should == hr.rate
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
data/spec/macro_spec.rb
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
|
2
|
+
# See LICENSE.txt for details.
|
|
3
|
+
|
|
4
|
+
require 'test/test_base'
|
|
5
|
+
require 'currency'
|
|
6
|
+
require 'currency/macro'
|
|
7
|
+
|
|
8
|
+
module Currency
|
|
9
|
+
|
|
10
|
+
class MacroTest < TestBase
|
|
11
|
+
class Record
|
|
12
|
+
include ::Currency::Macro
|
|
13
|
+
|
|
14
|
+
attr_accessor :date
|
|
15
|
+
attr_accessor :gross
|
|
16
|
+
attr_accessor :tax
|
|
17
|
+
attr_accessor :net
|
|
18
|
+
attr_accessor :currency
|
|
19
|
+
|
|
20
|
+
attr_money :gross_money, :value => :gross, :time => :date, :currency => :currency
|
|
21
|
+
attr_money :tax_money, :value => :tax, :time => :date, :currency => :currency
|
|
22
|
+
attr_money :net_money, :value => :net, :time => :date, :currency => :currency
|
|
23
|
+
|
|
24
|
+
def initialize
|
|
25
|
+
self.date = Time.now
|
|
26
|
+
self.currency = :USD
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def compute_net
|
|
30
|
+
self.net = self.gross - self.tax
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def compute_net_money
|
|
34
|
+
self.net_money = self.gross_money - self.tax_money
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
before do
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
############################################
|
|
44
|
+
# Tests
|
|
45
|
+
#
|
|
46
|
+
|
|
47
|
+
it "read money" do
|
|
48
|
+
assert_kind_of Record, r = Record.new
|
|
49
|
+
r.gross = 10.00.should_not == nil
|
|
50
|
+
r.gross.should == r.gross_money.to_f
|
|
51
|
+
r.currency.should == r.gross_money.currency.code
|
|
52
|
+
r.date.should == r.gross_money.time
|
|
53
|
+
|
|
54
|
+
r
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
it "write money rep" do
|
|
59
|
+
assert_kind_of Record, r = Record.new
|
|
60
|
+
r.gross_money = 10.00.should_not == nil
|
|
61
|
+
r.gross.should == r.gross_money.to_f
|
|
62
|
+
r.currency.should == r.gross_money.currency.code
|
|
63
|
+
r.date.should == r.gross_money.time
|
|
64
|
+
|
|
65
|
+
r
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
it "money cache" do
|
|
70
|
+
r = test_read_money
|
|
71
|
+
|
|
72
|
+
r_gross = r.gross.should_not == nil
|
|
73
|
+
r_gross.object_id.should == r.gross.object_id
|
|
74
|
+
|
|
75
|
+
# Cache flush
|
|
76
|
+
r.gross = 12.00.should_not == nil
|
|
77
|
+
r.gross.should == r.gross_money.to_f
|
|
78
|
+
r_gross.object_id != r.gross.object_id.should_not == nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
it "currency" do
|
|
83
|
+
r = test_read_money
|
|
84
|
+
|
|
85
|
+
r.gross_money.currency.should_not == nil
|
|
86
|
+
r.currency.should == r.gross_money.currency.code
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
it "compute" do
|
|
92
|
+
assert_kind_of Record, r = Record.new
|
|
93
|
+
r.gross = 10.00.should_not == nil
|
|
94
|
+
r.tax = 1.50.should_not == nil
|
|
95
|
+
r.compute_net
|
|
96
|
+
|
|
97
|
+
r.net.should == 8.50
|
|
98
|
+
r.net_money.to_f.should == r.net
|
|
99
|
+
|
|
100
|
+
r.compute_net_money
|
|
101
|
+
|
|
102
|
+
r.net.should == 8.50
|
|
103
|
+
r.net_money.to_f.should == r.net
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end # class
|
|
107
|
+
|
|
108
|
+
end # module
|
|
109
|
+
|
data/spec/money_spec.rb
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
# require File.dirname(__FILE__) + '/../lib/currency/formatter'
|
|
3
|
+
|
|
4
|
+
describe Currency::Money do
|
|
5
|
+
|
|
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
|
|
26
|
+
m = Currency::Money.new(1.99)
|
|
27
|
+
m.should be_kind_of(Currency::Money)
|
|
28
|
+
Currency::Currency.default.should == m.currency
|
|
29
|
+
:USD.should == m.currency.code
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "Converts different objects to Money with the 'money' method" do
|
|
33
|
+
it "works with a float" do
|
|
34
|
+
m = 1.99.money(:USD)
|
|
35
|
+
m.should be_kind_of(Currency::Money)
|
|
36
|
+
:USD.should == m.currency.code
|
|
37
|
+
m.rep.should == 1990000
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "works with a FixNum" do
|
|
41
|
+
m = 199.money(:CAD)
|
|
42
|
+
m.should be_kind_of(Currency::Money)
|
|
43
|
+
:CAD.should == m.currency.code
|
|
44
|
+
m.rep.should == 199000000
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "works with a string" do
|
|
48
|
+
m = "13.98".money(:CAD)
|
|
49
|
+
m.should be_kind_of(Currency::Money)
|
|
50
|
+
:CAD.should == m.currency.code
|
|
51
|
+
m.rep.should == 13980000
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "works with a string again" do
|
|
55
|
+
m = "45.99".money(:EUR)
|
|
56
|
+
m.should be_kind_of(Currency::Money)
|
|
57
|
+
:EUR.should == m.currency.code
|
|
58
|
+
m.rep.should == 45990000
|
|
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
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "deals with zero in the least surprising way" do
|
|
75
|
+
zero_money.negative?.should_not == true
|
|
76
|
+
zero_money.zero?.should_not == nil
|
|
77
|
+
zero_money.positive?.should_not == true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "deals with negatives in the least surprising way" do
|
|
81
|
+
negative_money.negative?.should_not == nil
|
|
82
|
+
negative_money.zero?.should_not == true
|
|
83
|
+
negative_money.positive?.should_not == true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "deals with positive numbers in the least surprising way" do
|
|
87
|
+
positive_money.negative?.should_not == true
|
|
88
|
+
positive_money.zero?.should_not == true
|
|
89
|
+
positive_money.positive?.should_not == nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "can do comparisons between monies" do
|
|
93
|
+
n = negative_money
|
|
94
|
+
z = zero_money
|
|
95
|
+
p = positive_money
|
|
96
|
+
|
|
97
|
+
negative_money.should < positive_money
|
|
98
|
+
(negative_money > positive_money).should_not be_true
|
|
99
|
+
(positive_money < negative_money).should_not be_true
|
|
100
|
+
(p.should > n)
|
|
101
|
+
(p != n).should_not == nil
|
|
102
|
+
|
|
103
|
+
(z.should <= z)
|
|
104
|
+
(z.should >= z)
|
|
105
|
+
|
|
106
|
+
(z.should <= p)
|
|
107
|
+
(n.should <= z)
|
|
108
|
+
(z.should >= n)
|
|
109
|
+
|
|
110
|
+
n.should == n
|
|
111
|
+
p.should == p
|
|
112
|
+
|
|
113
|
+
z.should == zero_money
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "compare" do
|
|
117
|
+
n = negative_money
|
|
118
|
+
z = zero_money
|
|
119
|
+
p = positive_money
|
|
120
|
+
|
|
121
|
+
(n <=> p).should == -1
|
|
122
|
+
(p <=> n).should == 1
|
|
123
|
+
(p <=> z).should == 1
|
|
124
|
+
|
|
125
|
+
(n <=> n).should == 0
|
|
126
|
+
(z <=> z).should == 0
|
|
127
|
+
(p <=> p).should == 0
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "rep" do
|
|
131
|
+
m = Currency::Money.new(123, :USD)
|
|
132
|
+
m.should_not == nil
|
|
133
|
+
m.rep.should == 123000000
|
|
134
|
+
|
|
135
|
+
m = Currency::Money.new(123.45, :USD)
|
|
136
|
+
m.should_not == nil
|
|
137
|
+
m.rep.should == 123450000
|
|
138
|
+
|
|
139
|
+
m = Currency::Money.new("123.456", :USD)
|
|
140
|
+
m.should_not == nil
|
|
141
|
+
m.rep.should == 123456000
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "convert" do
|
|
145
|
+
m = Currency::Money.new("123.456", :USD)
|
|
146
|
+
m.should_not == nil
|
|
147
|
+
m.rep.should == 123456000
|
|
148
|
+
|
|
149
|
+
m.to_i.should == 123
|
|
150
|
+
m.to_f.should == 123.456
|
|
151
|
+
m.to_s.should == "$123.456000"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "eql" do
|
|
155
|
+
usd1 = Currency::Money.new(123, :USD)
|
|
156
|
+
usd1.should_not == nil
|
|
157
|
+
usd2 = Currency::Money.new("123", :USD)
|
|
158
|
+
usd2.should_not == nil
|
|
159
|
+
|
|
160
|
+
usd1.currency.code.should == :USD
|
|
161
|
+
usd2.currency.code.should == :USD
|
|
162
|
+
|
|
163
|
+
usd2.rep.should == usd1.rep
|
|
164
|
+
|
|
165
|
+
usd1.should == usd2
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "not eql" do
|
|
170
|
+
|
|
171
|
+
usd1 = Currency::Money.new(123, :USD)
|
|
172
|
+
usd1.should_not == nil
|
|
173
|
+
usd2 = Currency::Money.new("123.01", :USD)
|
|
174
|
+
usd2.should_not == nil
|
|
175
|
+
|
|
176
|
+
usd1.currency.code.should == :USD
|
|
177
|
+
usd2.currency.code.should == :USD
|
|
178
|
+
|
|
179
|
+
usd2.rep.should_not == usd1.rep
|
|
180
|
+
|
|
181
|
+
(usd1 != usd2).should_not == nil
|
|
182
|
+
|
|
183
|
+
################
|
|
184
|
+
# currency !=
|
|
185
|
+
# rep ==
|
|
186
|
+
|
|
187
|
+
usd = Currency::Money.new(123, :USD)
|
|
188
|
+
usd.should_not == nil
|
|
189
|
+
cad = Currency::Money.new(123, :CAD)
|
|
190
|
+
cad.should_not == nil
|
|
191
|
+
|
|
192
|
+
usd.currency.code.should == :USD
|
|
193
|
+
cad.currency.code.should == :CAD
|
|
194
|
+
|
|
195
|
+
cad.rep.should == usd.rep
|
|
196
|
+
(usd.currency != cad.currency).should_not == nil
|
|
197
|
+
|
|
198
|
+
(usd != cad).should_not == nil
|
|
199
|
+
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "operations" do
|
|
203
|
+
before(:each) do
|
|
204
|
+
@usd = Currency::Money.new(123.45, :USD)
|
|
205
|
+
@cad = Currency::Money.new(123.45, :CAD)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should work" do
|
|
209
|
+
@usd.should_not == nil
|
|
210
|
+
@cad.should_not == nil
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "handle negative money" do
|
|
214
|
+
# - Currency::Money => Currency::Money
|
|
215
|
+
(- @usd).rep.should == -123450000
|
|
216
|
+
(- @usd).currency.code.should == :USD
|
|
217
|
+
|
|
218
|
+
(- @cad).rep.should == -123450000
|
|
219
|
+
(- @cad).currency.code.should == :CAD
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "should add monies of the same currency" do
|
|
223
|
+
m = (@usd + @usd)
|
|
224
|
+
m.should be_kind_of(Currency::Money)
|
|
225
|
+
m.rep.should == 246900000
|
|
226
|
+
m.currency.code.should == :USD
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it "should add monies of different currencies and return USD" do
|
|
230
|
+
m = (@usd + @cad)
|
|
231
|
+
m.should be_kind_of(Currency::Money)
|
|
232
|
+
m.rep.should == 228890724
|
|
233
|
+
m.currency.code.should == :USD
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "should add monies of different currencies and return CAD" do
|
|
237
|
+
m = (@cad + @usd)
|
|
238
|
+
m.should be_kind_of(Currency::Money)
|
|
239
|
+
m.rep.should == 267985260
|
|
240
|
+
m.currency.code.should == :CAD
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it "should subtract monies of the same currency" do
|
|
244
|
+
m = (@usd - @usd)
|
|
245
|
+
m.should be_kind_of(Currency::Money)
|
|
246
|
+
m.rep.should == 0
|
|
247
|
+
m.currency.code.should == :USD
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should subtract monies of different currencies and return USD" do
|
|
251
|
+
m = (@usd - @cad)
|
|
252
|
+
m.should be_kind_of(Currency::Money)
|
|
253
|
+
m.rep.should == 18009276
|
|
254
|
+
m.currency.code.should == :USD
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it "should subtract monies of different currencies and return CAD" do
|
|
258
|
+
m = (@cad - @usd)
|
|
259
|
+
m.should be_kind_of(Currency::Money)
|
|
260
|
+
m.rep.should == -21085260
|
|
261
|
+
m.currency.code.should == :CAD
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "should multiply by numerics and return money" do
|
|
265
|
+
m = (@usd * 0.5)
|
|
266
|
+
m.should be_kind_of(Currency::Money)
|
|
267
|
+
m.rep.should == 61725000
|
|
268
|
+
m.currency.code.should == :USD
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it "should divide by numerics and return money" do
|
|
272
|
+
m = @usd / 3
|
|
273
|
+
m.should be_kind_of(Currency::Money)
|
|
274
|
+
m.rep.should == 41150000
|
|
275
|
+
m.currency.code.should == :USD
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it "should divide by monies of the same currency and return numeric" do
|
|
279
|
+
m = @usd / Currency::Money.new("41.15", :USD)
|
|
280
|
+
m.should be_kind_of(Numeric)
|
|
281
|
+
m.should be_close(3.0, 1.0e-8)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "should divide by monies of different currencies and return numeric" do
|
|
285
|
+
m = (@usd / @cad)
|
|
286
|
+
m.should be_kind_of(Numeric)
|
|
287
|
+
m.should be_close(Currency::Exchange::Rate::Source::Test.USD_CAD, 0.0001)
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "pivot conversions" do
|
|
292
|
+
# Using default get_rate
|
|
293
|
+
cad = Currency::Money.new(123.45, :CAD)
|
|
294
|
+
cad.should_not == nil
|
|
295
|
+
eur = cad.convert(:EUR)
|
|
296
|
+
eur.should_not == nil
|
|
297
|
+
m = (eur.to_f / cad.to_f)
|
|
298
|
+
m.should be_kind_of(Numeric)
|
|
299
|
+
m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_CAD) * Currency::Exchange::Rate::Source::Test.USD_EUR
|
|
300
|
+
m.should be_close(m_expected, 0.001)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
gbp = Currency::Money.new(123.45, :GBP)
|
|
304
|
+
gbp.should_not == nil
|
|
305
|
+
eur = gbp.convert(:EUR)
|
|
306
|
+
eur.should_not == nil
|
|
307
|
+
m = (eur.to_f / gbp.to_f)
|
|
308
|
+
m.should be_kind_of(Numeric)
|
|
309
|
+
m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_GBP) * Currency::Exchange::Rate::Source::Test.USD_EUR
|
|
310
|
+
m.should be_close(m_expected, 0.001)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
it "invalid currency code" do
|
|
315
|
+
lambda {Currency::Money.new(123, :asdf)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
|
|
316
|
+
lambda {Currency::Money.new(123, 5)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
it "time default" do
|
|
321
|
+
Currency::Money.default_time = nil
|
|
322
|
+
|
|
323
|
+
usd = Currency::Money.new(123.45, :USD)
|
|
324
|
+
usd.should_not == nil
|
|
325
|
+
usd.time.should == nil
|
|
326
|
+
|
|
327
|
+
Currency::Money.default_time = Time.now
|
|
328
|
+
usd = Currency::Money.new(123.45, :USD)
|
|
329
|
+
usd.should_not == nil
|
|
330
|
+
Currency::Money.default_time.should == usd.time
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
it "time now" do
|
|
335
|
+
Currency::Money.default_time = :now
|
|
336
|
+
|
|
337
|
+
usd = Currency::Money.new(123.45, :USD)
|
|
338
|
+
usd.should_not == nil
|
|
339
|
+
usd.time.should_not == nil
|
|
340
|
+
|
|
341
|
+
sleep 1
|
|
342
|
+
|
|
343
|
+
usd2 = Currency::Money.new(123.45, :USD)
|
|
344
|
+
usd2.should_not == nil
|
|
345
|
+
usd2.time.should_not == nil
|
|
346
|
+
(usd.time != usd2.time).should_not == nil
|
|
347
|
+
|
|
348
|
+
Currency::Money.default_time = nil
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
it "time fixed" do
|
|
353
|
+
Currency::Money.default_time = Time.new
|
|
354
|
+
|
|
355
|
+
usd = Currency::Money.new(123.45, :USD)
|
|
356
|
+
usd.should_not == nil
|
|
357
|
+
usd.time.should_not == nil
|
|
358
|
+
|
|
359
|
+
sleep 1
|
|
360
|
+
|
|
361
|
+
usd2 = Currency::Money.new(123.45, :USD)
|
|
362
|
+
usd2.should_not == nil
|
|
363
|
+
usd2.time.should_not == nil
|
|
364
|
+
usd.time.should == usd2.time
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|