acvwilson-acvwilson-currency 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/currency.gemspec +5 -5
- data/lib/currency.rb +2 -2
- data/lib/currency/config.rb +26 -24
- data/lib/currency/core_extensions.rb +0 -15
- data/lib/currency/currency.rb +3 -6
- data/lib/currency/currency/factory.rb +14 -4
- data/lib/currency/exchange.rb +0 -2
- data/lib/currency/exchange/rate/source/base.rb +2 -2
- data/lib/currency/exchange/rate/source/federal_reserve.rb +3 -12
- data/lib/currency/exchange/rate/source/provider.rb +7 -10
- data/lib/currency/formatter.rb +9 -1
- data/lib/currency/money.rb +4 -7
- data/spec/ar_column_spec.rb +36 -49
- data/spec/ar_simple_spec.rb +9 -17
- data/spec/ar_spec_helper.rb +127 -0
- data/spec/config_spec.rb +44 -3
- data/spec/federal_reserve_spec.rb +55 -59
- data/spec/historical_writer_spec.rb +74 -140
- data/spec/macro_spec.rb +8 -8
- data/spec/money_spec.rb +1 -1
- data/spec/new_york_fed_spec.rb +11 -11
- data/spec/parser_spec.rb +14 -14
- data/spec/spec_helper.rb +6 -6
- data/spec/timed_cache_spec.rb +23 -23
- metadata +4 -5
- data/spec/ar_base_spec.rb +0 -140
- data/spec/ar_core_spec.rb +0 -64
data/spec/ar_column_spec.rb
CHANGED
@@ -1,69 +1,56 @@
|
|
1
|
-
|
2
|
-
# See LICENSE.txt for details.
|
1
|
+
require File.dirname(__FILE__) + '/ar_spec_helper'
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
##################################################
|
4
|
+
# Basic CurrenyTest AR::B class
|
5
|
+
#
|
6
6
|
|
7
|
-
|
8
|
-
require 'active_record'
|
9
|
-
require 'active_record/migration'
|
10
|
-
require 'currency/active_record'
|
7
|
+
# TODO: Move elsewhere, combine with other AR tests
|
11
8
|
|
12
|
-
|
9
|
+
TABLE_NAME = 'currency_column_test'
|
13
10
|
|
14
|
-
class
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
TABLE_NAME = 'currency_column_test'
|
21
|
-
|
22
|
-
class CurrencyColumnTestMigration < AR_M
|
23
|
-
def self.up
|
24
|
-
create_table TABLE_NAME.intern do |t|
|
25
|
-
t.column :name, :string
|
26
|
-
t.column :amount, :integer # Money
|
27
|
-
t.column :amount_currency, :string, :size => 3 # Money.currency.code
|
28
|
-
end
|
11
|
+
class CurrencyColumnTestMigration < AR_M
|
12
|
+
def self.up
|
13
|
+
create_table TABLE_NAME.intern do |t|
|
14
|
+
t.column :name, :string
|
15
|
+
t.column :amount, :integer # Money
|
16
|
+
t.column :amount_currency, :string, :size => 3 # Money.currency.code
|
29
17
|
end
|
18
|
+
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
20
|
+
def self.down
|
21
|
+
drop_table TABLE_NAME.intern
|
34
22
|
end
|
23
|
+
end
|
35
24
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
25
|
+
class CurrencyColumnTest < AR_B
|
26
|
+
set_table_name TABLE_NAME
|
27
|
+
attr_money :amount, :currency_column => true
|
28
|
+
end
|
40
29
|
|
41
|
-
|
30
|
+
##################################################
|
42
31
|
|
43
|
-
|
32
|
+
describe "ActiveRecord macros" do
|
33
|
+
before(:all) do
|
34
|
+
AR_B.establish_connection(database_spec)
|
44
35
|
@currency_test_migration ||= CurrencyColumnTestMigration
|
45
36
|
@currency_test ||= CurrencyColumnTest
|
46
|
-
|
37
|
+
schema_down
|
38
|
+
schema_up
|
47
39
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
40
|
+
|
41
|
+
after(:all) do
|
42
|
+
schema_down
|
51
43
|
end
|
52
44
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
it "field" do
|
45
|
+
it "can store and retrieve money values from a DB and automagically transfomr them to Money" do
|
57
46
|
insert_records
|
58
47
|
|
59
|
-
usd = @currency_test.find(@usd.id)
|
60
|
-
|
48
|
+
usd = @currency_test.find(@usd.id)
|
49
|
+
usd.should == @usd
|
50
|
+
usd.object_id.should_not == @usd.object_id # not same object
|
61
51
|
|
62
|
-
cad = @currency_test.find(@cad.id)
|
63
|
-
|
52
|
+
cad = @currency_test.find(@cad.id)
|
53
|
+
cad.should == @cad
|
54
|
+
cad.object_id.should_not == @cad.object_id # not same object
|
64
55
|
end
|
65
|
-
|
66
56
|
end
|
67
|
-
|
68
|
-
end # module
|
69
|
-
|
data/spec/ar_simple_spec.rb
CHANGED
@@ -1,31 +1,23 @@
|
|
1
1
|
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
2
|
+
# Copyright (C) 2008 Asa Wilson <acvwilson(at)gmail.com>
|
2
3
|
# See LICENSE.txt for details.
|
3
4
|
|
4
|
-
require '
|
5
|
-
require 'currency'
|
6
|
-
|
7
|
-
require 'rubygems'
|
8
|
-
require 'active_record'
|
9
|
-
require 'active_record/migration'
|
10
|
-
require 'currency/active_record'
|
11
|
-
|
12
|
-
module Currency
|
13
|
-
|
14
|
-
class ArSimpleTest < ArTestCore
|
5
|
+
require File.dirname(__FILE__) + '/ar_spec_helper'
|
15
6
|
|
7
|
+
describe Currency::ActiveRecord do
|
16
8
|
it "simple" do
|
9
|
+
# TODO: move insert_records into a before block?
|
17
10
|
insert_records
|
18
11
|
|
19
|
-
usd = @currency_test.find(@usd.id)
|
12
|
+
usd = @currency_test.find(@usd.id)
|
13
|
+
usd.should_not be_nil
|
20
14
|
assert_equal_currency usd, @usd
|
21
15
|
|
22
|
-
cad = @currency_test.find(@cad.id)
|
16
|
+
cad = @currency_test.find(@cad.id)
|
17
|
+
cad.should_not == nil
|
23
18
|
assert_equal_money cad, @cad
|
24
19
|
|
25
|
-
|
20
|
+
cad.amount.currency.code.should == :USD
|
26
21
|
end
|
27
|
-
|
28
22
|
end
|
29
23
|
|
30
|
-
end # module
|
31
|
-
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
2
|
+
# Copyright (C) 2008 Asa Wilson <acvwilson(at)gmail.com>
|
3
|
+
# See LICENSE.txt for details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
6
|
+
|
7
|
+
require 'active_record'
|
8
|
+
require 'active_record/migration'
|
9
|
+
require File.dirname(__FILE__) + '/../lib/currency/active_record'
|
10
|
+
|
11
|
+
AR_M = ActiveRecord::Migration
|
12
|
+
AR_B = ActiveRecord::Base
|
13
|
+
|
14
|
+
def ar_setup
|
15
|
+
AR_B.establish_connection(database_spec)
|
16
|
+
|
17
|
+
# Subclasses can override this.
|
18
|
+
@currency_test_migration ||= nil
|
19
|
+
@currency_test ||= nil
|
20
|
+
|
21
|
+
# schema_down
|
22
|
+
|
23
|
+
schema_up
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# DB Connection info
|
28
|
+
def database_spec
|
29
|
+
# TODO: Get from ../config/database.yml:test
|
30
|
+
# Create test database on:
|
31
|
+
|
32
|
+
# MYSQL:
|
33
|
+
#
|
34
|
+
# sudo mysqladmin create test;
|
35
|
+
# sudo mysql
|
36
|
+
# grant all on test.* to test@localhost identified by 'test';
|
37
|
+
# flush privileges;
|
38
|
+
|
39
|
+
# POSTGRES:
|
40
|
+
#
|
41
|
+
# CREATE USER test PASSWORD 'test';
|
42
|
+
# CREATE DATABASE test WITH OWNER = test;
|
43
|
+
#
|
44
|
+
|
45
|
+
# @database_spec = {
|
46
|
+
# :adapter => ENV['TEST_DB_ADAPTER'] || 'mysql',
|
47
|
+
# :host => ENV['TEST_DB_HOST'] || 'localhost',
|
48
|
+
# :username => ENV['TEST_DB_USER'] || 'test',
|
49
|
+
# :password => ENV['TEST_DB_PASS'] || 'test',
|
50
|
+
# :database => ENV['TEST_DB_TEST'] || 'test'
|
51
|
+
# }
|
52
|
+
|
53
|
+
@database_spec = {
|
54
|
+
:adapter => ENV['TEST_DB_ADAPTER'] || 'mysql',
|
55
|
+
:host => ENV['TEST_DB_HOST'] || 'localhost',
|
56
|
+
:username => ENV['TEST_DB_USER'] || 'root',
|
57
|
+
:password => ENV['TEST_DB_PASS'] || '',
|
58
|
+
:database => ENV['TEST_DB_TEST'] || 'currency_gem_test'
|
59
|
+
}
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Run AR migrations UP
|
64
|
+
def schema_up
|
65
|
+
return unless @currency_test_migration
|
66
|
+
begin
|
67
|
+
@currency_test_migration.migrate(:up)
|
68
|
+
rescue Object =>e
|
69
|
+
$stderr.puts "Warning: #{e}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# Run AR migrations DOWN
|
75
|
+
def schema_down
|
76
|
+
return unless @currency_test_migration
|
77
|
+
begin
|
78
|
+
@currency_test_migration.migrate(:down)
|
79
|
+
rescue Object => e
|
80
|
+
$stderr.puts "Warning: #{e}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Scaffold: insert stuff into DB so we can test AR integration
|
85
|
+
def insert_records
|
86
|
+
delete_records
|
87
|
+
|
88
|
+
@currency_test.reset_column_information
|
89
|
+
|
90
|
+
@usd = @currency_test.new(:name => '#1: USD', :amount => Currency::Money.new("12.34", :USD))
|
91
|
+
@usd.save
|
92
|
+
|
93
|
+
@cad = @currency_test.new(:name => '#2: CAD', :amount => Currency::Money.new("56.78", :CAD))
|
94
|
+
@cad.save
|
95
|
+
end
|
96
|
+
|
97
|
+
def delete_records
|
98
|
+
@currency_test.destroy_all
|
99
|
+
end
|
100
|
+
|
101
|
+
##################################################
|
102
|
+
|
103
|
+
# TODO: need this?
|
104
|
+
def assert_equal_money(a,b)
|
105
|
+
a.should_not be_nil
|
106
|
+
b.should_not be_nil
|
107
|
+
# Make sure a and b are not the same object.
|
108
|
+
b.object_id.should_not == a.object_id
|
109
|
+
b.id.should == a.id
|
110
|
+
a.amount.should_not == nil
|
111
|
+
a.amount.should be_kind_of(Currency::Money)
|
112
|
+
b.amount.should_not == nil
|
113
|
+
b.amount.should be_kind_of(Currency::Money)
|
114
|
+
# Make sure that what gets stored in the database comes back out
|
115
|
+
# when converted back to the original currency.
|
116
|
+
b.amount.rep.should == a.amount.convert(b.amount.currency).rep
|
117
|
+
end
|
118
|
+
|
119
|
+
# TODO: need this?
|
120
|
+
def assert_equal_currency(a,b)
|
121
|
+
assert_equal_money a, b
|
122
|
+
|
123
|
+
b.amount.rep.should == a.amount.rep
|
124
|
+
b.amount.currency.should == a.amount.currency
|
125
|
+
b.amount.currency.code.should == a.amount.currency.code
|
126
|
+
|
127
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -22,8 +22,49 @@ describe Currency::Config do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
25
|
+
|
26
|
+
describe "the scale expression is configurable" do
|
27
|
+
before(:all) do
|
28
|
+
@config = Currency::Config.new
|
29
|
+
end
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
Currency::Config.current = nil
|
33
|
+
Currency::Config.send(:class_variable_set, "@@default", nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a scale_exp setter" do
|
37
|
+
Currency::Config.current.should respond_to(:scale_exp=)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has a 'scale' reader" do
|
41
|
+
Currency::Config.current.should respond_to(:scale)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "uses the scale reader from the config when creating new Money object" do
|
45
|
+
Currency::Config.should_receive(:current).and_return(@config)
|
46
|
+
@config.should_receive(:scale).and_return(100)
|
47
|
+
10.money
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can be configured using a block" do
|
51
|
+
Currency::Config.configure do |config|
|
52
|
+
config.scale_exp = 6
|
53
|
+
end
|
25
54
|
|
26
|
-
|
27
|
-
|
28
|
-
|
55
|
+
10.money.currency.scale_exp.should == 6
|
56
|
+
|
57
|
+
Currency::Config.configure do |config|
|
58
|
+
config.scale_exp = 4
|
59
|
+
end
|
60
|
+
10.money.currency.scale_exp.should == 4
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can be configured using straight setters" do
|
64
|
+
10.money(:USD).currency.scale_exp.should == 2
|
65
|
+
Currency::Config.current.scale_exp = 6
|
66
|
+
10.money(:USD).currency.scale_exp.should == 6
|
67
|
+
end
|
68
|
+
end
|
29
69
|
|
70
|
+
end
|
@@ -1,75 +1,71 @@
|
|
1
1
|
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
2
2
|
# See LICENSE.txt for details.
|
3
3
|
|
4
|
-
require '
|
4
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
5
|
+
require File.dirname(__FILE__) + '/../lib/currency/exchange/rate/source/federal_reserve'
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
# Uncomment to avoid hitting the FED for every testrun
|
8
|
+
Currency::Exchange::Rate::Source::FederalReserve.class_eval do
|
9
|
+
def get_page_content
|
10
|
+
%Q{
|
8
11
|
|
9
|
-
|
12
|
+
SPOT EXCHANGE RATE - DISNEYLAND
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
------------------------------
|
15
|
+
14-Nov-08 1.1
|
16
|
+
}
|
14
17
|
end
|
18
|
+
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
# New York Fed rates are not available on Saturday and Sunday.
|
20
|
+
include Currency
|
21
|
+
describe "FederalReserve" do
|
20
22
|
def available?
|
21
|
-
|
22
|
-
|
23
|
-
STDERR.puts "Warning: FederalReserve unavailable on Saturday and Sunday, skipping tests." unless
|
23
|
+
unless @available
|
24
|
+
@available = @source.available?
|
25
|
+
STDERR.puts "Warning: FederalReserve unavailable on Saturday and Sunday, skipping tests." unless @available
|
24
26
|
end
|
25
|
-
|
27
|
+
@available
|
26
28
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
deriver
|
29
|
+
|
30
|
+
# Called by the before(:all) in spec_helper
|
31
|
+
# Overriding here to force FederalReserve Exchange.
|
32
|
+
# TODO: when refactoring the whole spec to test only specific FedralReserve Stuff, make sure this one goes away
|
33
|
+
def get_rate_source(source = nil)
|
34
|
+
@source ||= Exchange::Rate::Source::FederalReserve.new(:verbose => false)
|
35
|
+
@deriver ||= Exchange::Rate::Deriver.new(:source => @source, :verbose => @source.verbose)
|
34
36
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
it "usd cad" do
|
39
|
-
return unless available?
|
40
|
-
|
41
|
-
# yesterday = Time.now.to_date - 1
|
42
|
-
|
43
|
-
rates = Exchange::Rate::Source.default.source.raw_rates.should.not == nil
|
44
|
-
#assert_not_nil rates[:USD]
|
45
|
-
#assert_not_nil usd_cad = rates[:USD][:CAD]
|
46
|
-
|
47
|
-
usd = Money.new(123.45, :USD).should.not == nil
|
48
|
-
cad = usd.convert(:CAD).should.not == nil
|
49
|
-
|
50
|
-
# assert_kind_of Numeric, m = (cad.to_f / usd.to_f)
|
51
|
-
# $stderr.puts "m = #{m}"
|
52
|
-
# assert_equal_float usd_cad, m, 0.001
|
37
|
+
|
38
|
+
def get_rates
|
39
|
+
@rates ||= @source.raw_rates
|
53
40
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#assert_kind_of Numeric, m = (eur.to_f / cad.to_f)
|
68
|
-
# $stderr.puts "m = #{m}"
|
69
|
-
#assert_equal_float (1.0 / usd_cad) * usd_eur, m, 0.001
|
41
|
+
|
42
|
+
before(:all) do
|
43
|
+
get_rate_source
|
44
|
+
get_rates
|
45
|
+
end
|
46
|
+
|
47
|
+
before(:each) do
|
48
|
+
get_rate_source
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can retrieve rates from the FED" do
|
52
|
+
@rates.should_not be_nil
|
70
53
|
end
|
71
54
|
|
72
|
-
|
73
|
-
|
74
|
-
end # module
|
55
|
+
it "can convert from USD to CAD" do
|
56
|
+
usd = Money.new(123.45, :USD)
|
75
57
|
|
58
|
+
cad = usd.convert(:CAD)
|
59
|
+
cad.should_not be_nil
|
60
|
+
cad.to_f.should be_kind_of(Numeric)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can do conversions from AUD to USD to JPY" do
|
64
|
+
aud = Money.new(123.45, :AUD)
|
65
|
+
usd = aud.convert(:USD)
|
66
|
+
jpy = usd.convert(:JPY)
|
67
|
+
jpy.should_not be_nil
|
68
|
+
jpy.to_f.should be_kind_of(Numeric)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|