exchange 0.8.0 → 0.9.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.
Files changed (63) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -1
  3. data/Gemfile.lock +3 -3
  4. data/README.rdoc +115 -47
  5. data/benchmark/benchmark.rb +49 -0
  6. data/changelog.rdoc +8 -1
  7. data/lib/exchange.rb +4 -4
  8. data/lib/exchange/base.rb +1 -1
  9. data/lib/exchange/cache.rb +2 -0
  10. data/lib/exchange/cache/base.rb +20 -6
  11. data/lib/exchange/cache/configuration.rb +24 -0
  12. data/lib/exchange/cache/file.rb +24 -9
  13. data/lib/exchange/cache/memcached.rb +3 -3
  14. data/lib/exchange/cache/memory.rb +89 -0
  15. data/lib/exchange/cache/rails.rb +1 -1
  16. data/lib/exchange/cache/redis.rb +4 -4
  17. data/lib/exchange/configurable.rb +53 -0
  18. data/lib/exchange/configuration.rb +32 -26
  19. data/lib/exchange/core_extensions.rb +3 -0
  20. data/lib/exchange/core_extensions/cachify.rb +25 -0
  21. data/lib/exchange/core_extensions/float/error_safe.rb +25 -0
  22. data/lib/{core_extensions → exchange/core_extensions/numeric}/conversability.rb +12 -12
  23. data/lib/exchange/external_api.rb +2 -1
  24. data/lib/exchange/external_api/base.rb +34 -9
  25. data/lib/exchange/external_api/call.rb +6 -8
  26. data/lib/exchange/external_api/configuration.rb +25 -0
  27. data/lib/exchange/external_api/ecb.rb +16 -25
  28. data/lib/exchange/external_api/json.rb +11 -1
  29. data/lib/exchange/external_api/open_exchange_rates.rb +65 -0
  30. data/lib/exchange/external_api/xavier_media.rb +7 -7
  31. data/lib/exchange/iso_4217.rb +32 -5
  32. data/lib/exchange/{currency.rb → money.rb} +112 -110
  33. data/lib/exchange/typecasting.rb +94 -0
  34. data/spec/exchange/cache/base_spec.rb +2 -2
  35. data/spec/exchange/cache/configuration_spec.rb +56 -0
  36. data/spec/exchange/cache/file_spec.rb +10 -8
  37. data/spec/exchange/cache/memcached_spec.rb +9 -18
  38. data/spec/exchange/cache/memory_spec.rb +122 -0
  39. data/spec/exchange/cache/no_cache_spec.rb +5 -15
  40. data/spec/exchange/cache/rails_spec.rb +2 -6
  41. data/spec/exchange/cache/redis_spec.rb +8 -18
  42. data/spec/exchange/configuration_spec.rb +31 -7
  43. data/spec/exchange/core_extensions/array/cachify_spec.rb +12 -0
  44. data/spec/exchange/core_extensions/float/error_safe_spec.rb +49 -0
  45. data/spec/exchange/core_extensions/hash/cachify_spec.rb +12 -0
  46. data/spec/exchange/core_extensions/numeric/cachify_spec.rb +26 -0
  47. data/spec/{core_extensions → exchange/core_extensions/numeric}/conversability_spec.rb +22 -22
  48. data/spec/exchange/core_extensions/string/cachify_spec.rb +59 -0
  49. data/spec/exchange/core_extensions/symbol/cachify_spec.rb +12 -0
  50. data/spec/exchange/external_api/base_spec.rb +10 -7
  51. data/spec/exchange/external_api/call_spec.rb +3 -0
  52. data/spec/exchange/external_api/configuration_spec.rb +52 -0
  53. data/spec/exchange/external_api/ecb_spec.rb +8 -5
  54. data/spec/exchange/external_api/open_exchange_rates_spec.rb +70 -0
  55. data/spec/exchange/external_api/xavier_media_spec.rb +8 -5
  56. data/spec/exchange/iso_4217_spec.rb +208 -20
  57. data/spec/exchange/{currency_spec.rb → money_spec.rb} +102 -82
  58. data/spec/exchange/typecasting_spec.rb +86 -0
  59. metadata +117 -71
  60. data/exchange-0.7.5.gem +0 -0
  61. data/exchange-0.7.6.gem +0 -0
  62. data/lib/exchange/external_api/currency_bot.rb +0 -61
  63. data/spec/exchange/external_api/currency_bot_spec.rb +0 -63
@@ -6,20 +6,14 @@ describe "Exchange::Cache::Redis" do
6
6
  before(:each) do
7
7
  Exchange.configuration = Exchange::Configuration.new do |c|
8
8
  c.cache = {
9
- :class => :redis,
9
+ :subclass => :redis,
10
10
  :host => 'HOST',
11
11
  :port => 'PORT'
12
12
  }
13
13
  end
14
14
  end
15
15
  after(:each) do
16
- Exchange.configuration = Exchange::Configuration.new do |c|
17
- c.cache = {
18
- :class => :memcached,
19
- :host => 'localhost',
20
- :port => 11211
21
- }
22
- end
16
+ Exchange.configuration.reset
23
17
  end
24
18
  describe "client" do
25
19
  let(:client) { mock('redis') }
@@ -43,10 +37,10 @@ describe "Exchange::Cache::Redis" do
43
37
  lambda { subject.cached('API_CLASS') }.should raise_error(Exchange::Cache::CachingWithoutBlockError)
44
38
  end
45
39
  context "when a cached result exists" do
46
- context "when loading json" do
40
+ context "when loading" do
47
41
  before(:each) do
48
42
  subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
49
- client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
43
+ client.should_receive(:get).with('KEY').and_return({'RESULT' => 'YAY'}.cachify)
50
44
  end
51
45
  it "should return the JSON loaded result" do
52
46
  subject.cached('API_CLASS') { 'something' }.should == {'RESULT' => 'YAY'}
@@ -57,12 +51,8 @@ describe "Exchange::Cache::Redis" do
57
51
  subject.should_receive(:key).with('API_CLASS', {:plain => true}).and_return('KEY')
58
52
  end
59
53
  it "should return a String result in the right format" do
60
- client.should_receive(:get).with('KEY').and_return "122.0"
61
- subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
62
- end
63
- it "should also return a String result in the right format when redis adds quotes and spaces" do
64
- client.should_receive(:get).with('KEY').and_return "\"122.0\" "
65
- subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
54
+ client.should_receive(:get).with('KEY').and_return("122.0".cachify)
55
+ subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0".cachify
66
56
  end
67
57
  end
68
58
  end
@@ -73,7 +63,7 @@ describe "Exchange::Cache::Redis" do
73
63
  end
74
64
  context "with daily cache" do
75
65
  it "should call the block and set and return the result" do
76
- client.should_receive(:set).with('KEY', "{\"RESULT\":\"YAY\"}").once
66
+ client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify).once
77
67
  client.should_receive(:expire).with('KEY', 86400).once
78
68
  subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
79
69
  end
@@ -86,7 +76,7 @@ describe "Exchange::Cache::Redis" do
86
76
  Exchange.configuration.cache.expire = :daily
87
77
  end
88
78
  it "should call the block and set and return the result" do
89
- client.should_receive(:set).with('KEY', "{\"RESULT\":\"YAY\"}").once
79
+ client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify).once
90
80
  client.should_receive(:expire).with('KEY', 3600).once
91
81
  subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
92
82
  end
@@ -5,9 +5,9 @@ describe "Exchange::Configuration" do
5
5
  it "should have a standard configuration" do
6
6
  subject.api.retries.should == 5
7
7
  subject.api.subclass.should == Exchange::ExternalAPI::XavierMedia
8
- subject.cache.subclass.should == Exchange::Cache::Memcached
9
- subject.cache.host.should == 'localhost'
10
- subject.cache.port.should == 11211
8
+ subject.cache.subclass.should == Exchange::Cache::Memory
9
+ subject.cache.host.should be_nil
10
+ subject.cache.port.should be_nil
11
11
  subject.cache.expire.should == :daily
12
12
  end
13
13
  it "should respond to all configuration getters and setters" do
@@ -46,10 +46,34 @@ describe "Exchange::Configuration" do
46
46
  subject.api.subclass.should == Exchange::ExternalAPI::Ecb
47
47
  subject.api.retries.should == 1
48
48
  end
49
- after(:all) do
50
- subject.api = {
51
- :subclass => :currency_bot,
52
- :retries => 5
49
+ describe "reset" do
50
+ Exchange.configuration = Exchange::Configuration.new {|c|
51
+ c.api = {
52
+ :subclass => :open_exchange_rates,
53
+ :retries => 60,
54
+ :app_id => '234u230482348023'
55
+ }
56
+ c.cache = {
57
+ :subclass => :redis,
58
+ :host => 'localhost',
59
+ :port => 112211,
60
+ :path => 'PATH'
61
+ }
62
+ c.allow_mixed_operations = false
53
63
  }
64
+ it "should restore the defaults" do
65
+ subject.reset
66
+ subject.api.subclass.should == Exchange::ExternalAPI::XavierMedia
67
+ subject.api.retries.should == 5
68
+ subject.api.app_id.should be_nil
69
+ subject.cache.subclass.should == Exchange::Cache::Memory
70
+ subject.cache.host.should be_nil
71
+ subject.cache.port.should be_nil
72
+ subject.cache.path.should be_nil
73
+ subject.allow_mixed_operations.should be_true
74
+ end
75
+ end
76
+ after(:all) do
77
+ Exchange.configuration.reset
54
78
  end
55
79
  end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cachify" do
4
+
5
+ describe "cachify" do
6
+ subject { ["hello", 23, :world ] }
7
+ it "should marshal dump" do
8
+ subject.cachify.should == Marshal.dump(subject)
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::ErrorSafe" do
4
+ before(:all) do
5
+ Exchange.configuration = Exchange::Configuration.new { |c| c.cache = { :subclass => :no_cache } }
6
+ end
7
+ before(:each) do
8
+ @time = Time.gm(2012,8,27)
9
+ Time.stub! :now => @time
10
+ end
11
+ after(:all) do
12
+ Exchange.configuration.reset
13
+ end
14
+
15
+ describe "money safe calculation" do
16
+ describe "*" do
17
+ it "should calculate correctly with exchange money" do
18
+ (0.29 * 50.usd).round.should == 15
19
+ end
20
+ it "should not touch other operations" do
21
+ (0.29 * 50).round.should == 14
22
+ end
23
+ end
24
+ describe "/" do
25
+ it "should calculate correctly with exchange money" do
26
+ (((1829.82 / 12.usd) * 100).round.to_f / 100).to_f.should == 152.49
27
+ end
28
+ it "should not touch other operations" do
29
+ (((1829.82 / 12) * 100).round.to_f / 100).should == 152.48
30
+ end
31
+ end
32
+ describe "+" do
33
+ it "should calculate correctly with exchange money" do
34
+ (1.0e+25 + BigDecimal.new("9999999999999999900000000").usd).round.to_f.should == 2.0e+25
35
+ end
36
+ it "should not touch other operations" do
37
+ (1.0e+25 + BigDecimal.new("9999999999999999900000000")).round.should == 20000000000000001811939328
38
+ end
39
+ end
40
+ describe "-" do
41
+ it "should calculate correctly with exchange money" do
42
+ (1.0e+25 - BigDecimal.new("9999999999999999900000000").usd).round.should == 100000000
43
+ end
44
+ it "should not touch other operations" do
45
+ (1.0e+25 - BigDecimal.new("9999999999999999900000000")).should == 0
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cachify" do
4
+
5
+ describe "cachify" do
6
+ subject { { :bla => 'bli', "BLU" => [2,3] } }
7
+ it "should marshal dump" do
8
+ subject.cachify.should == Marshal.dump(subject)
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cachify" do
4
+
5
+ describe "cachify" do
6
+ context "with a big decimal" do
7
+ subject { BigDecimal.new("5") }
8
+ it "should marshal dump" do
9
+ subject.cachify.should == Marshal.dump(subject)
10
+ end
11
+ end
12
+ context "with a float" do
13
+ subject { 0.4545 }
14
+ it "should marshal dump" do
15
+ subject.cachify.should == Marshal.dump(subject)
16
+ end
17
+ end
18
+ context "with an integer" do
19
+ subject { 45 }
20
+ it "should marshal dump" do
21
+ subject.cachify.should == Marshal.dump(subject)
22
+ end
23
+ end
24
+ end
25
+
26
+ end
@@ -9,35 +9,35 @@ describe "Exchange::Conversability" do
9
9
  Time.stub! :now => @time
10
10
  end
11
11
  after(:all) do
12
- Exchange::configuration = Exchange::Configuration.new { |c| c.cache = { :subclass => :memcached } }
12
+ Exchange.configuration.reset
13
13
  end
14
14
  it "should define all currencies on Fixnum, Float and BigDecimal" do
15
15
  Exchange::ISO4217.definitions.keys.each do |c|
16
- 1.should be_respond_to(c.downcase.to_sym)
17
- 1.1.should be_respond_to(c.downcase.to_sym)
18
- BigDecimal.new("1").should be_respond_to(c.downcase.to_sym)
16
+ 1.should be_respond_to(c.to_s.downcase.to_sym)
17
+ 1.1.should be_respond_to(c.to_s.downcase.to_sym)
18
+ BigDecimal.new("1").should be_respond_to(c.to_s.downcase.to_sym)
19
19
  end
20
20
  end
21
21
  context "with a fixnum" do
22
22
  it "should allow to convert to a currency" do
23
- 3.eur.should be_kind_of Exchange::Currency
23
+ 3.eur.should be_kind_of Exchange::Money
24
24
  3.eur.value.should == 3
25
25
  end
26
26
  it "should allow to convert to a curreny with a negative number" do
27
- -3.eur.should be_kind_of Exchange::Currency
27
+ -3.eur.should be_kind_of Exchange::Money
28
28
  -3.eur.value.should == -3
29
29
  end
30
30
  it "should allow to do full conversions" do
31
31
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
32
- 3.eur.to_chf.should be_kind_of Exchange::Currency
32
+ 3.eur.to_chf.should be_kind_of Exchange::Money
33
33
  3.eur.to_chf.value.round(2).should == 3.68
34
- 3.eur.to_chf.currency.should == 'chf'
34
+ 3.eur.to_chf.currency.should == :chf
35
35
  end
36
36
  it "should allow to do full conversions with negative numbers" do
37
37
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
38
- -3.eur.to_chf.should be_kind_of Exchange::Currency
38
+ -3.eur.to_chf.should be_kind_of Exchange::Money
39
39
  -3.eur.to_chf.value.round(2).should == -3.68
40
- -3.eur.to_chf.currency.should == 'chf'
40
+ -3.eur.to_chf.currency.should == :chf
41
41
  end
42
42
  it "should allow to define a historic time in which the currency should be interpreted" do
43
43
  3.chf(:at => Time.gm(2010,1,1)).time.yday.should == 1
@@ -47,24 +47,24 @@ describe "Exchange::Conversability" do
47
47
  end
48
48
  context "with a float" do
49
49
  it "should allow to convert to a currency" do
50
- 3.25.eur.should be_kind_of Exchange::Currency
50
+ 3.25.eur.should be_kind_of Exchange::Money
51
51
  3.25.eur.value.round(2).should == 3.25
52
52
  end
53
53
  it "should allow to convert to a curreny with a negative number" do
54
- -3.25.eur.should be_kind_of Exchange::Currency
54
+ -3.25.eur.should be_kind_of Exchange::Money
55
55
  -3.25.eur.value.round(2).should == -3.25
56
56
  end
57
57
  it "should allow to do full conversions" do
58
58
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
59
- 3.25.eur.to_chf.should be_kind_of Exchange::Currency
59
+ 3.25.eur.to_chf.should be_kind_of Exchange::Money
60
60
  3.25.eur.to_chf.value.round(2).should == 3.99
61
- 3.25.eur.to_chf.currency.should == 'chf'
61
+ 3.25.eur.to_chf.currency.should == :chf
62
62
  end
63
63
  it "should allow to do full conversions with negative numbers" do
64
64
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
65
- -3.25.eur.to_chf.should be_kind_of Exchange::Currency
65
+ -3.25.eur.to_chf.should be_kind_of Exchange::Money
66
66
  -3.25.eur.to_chf.value.round(2).should == -3.99
67
- -3.25.eur.to_chf.currency.should == 'chf'
67
+ -3.25.eur.to_chf.currency.should == :chf
68
68
  end
69
69
  it "should allow to define a historic time in which the currency should be interpreted" do
70
70
  3.25.chf(:at => Time.gm(2010,1,1)).time.yday.should == 1
@@ -74,24 +74,24 @@ describe "Exchange::Conversability" do
74
74
  end
75
75
  context "with a big decimal" do
76
76
  it "should allow to convert to a currency" do
77
- BigDecimal.new("3.25").eur.should be_kind_of Exchange::Currency
77
+ BigDecimal.new("3.25").eur.should be_kind_of Exchange::Money
78
78
  BigDecimal.new("3.25").eur.value.round(2).should == 3.25
79
79
  end
80
80
  it "should allow to convert to a curreny with a negative number" do
81
- BigDecimal.new("-3.25").eur.should be_kind_of Exchange::Currency
81
+ BigDecimal.new("-3.25").eur.should be_kind_of Exchange::Money
82
82
  BigDecimal.new("-3.25").eur.value.round(2).should == -3.25
83
83
  end
84
84
  it "should allow to do full conversions" do
85
85
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
86
- BigDecimal.new("3.25").eur.to_chf.should be_kind_of Exchange::Currency
86
+ BigDecimal.new("3.25").eur.to_chf.should be_kind_of Exchange::Money
87
87
  BigDecimal.new("3.25").eur.to_chf.value.round(2).should == 3.99
88
- BigDecimal.new("3.25").eur.to_chf.currency.should == 'chf'
88
+ BigDecimal.new("3.25").eur.to_chf.currency.should == :chf
89
89
  end
90
90
  it "should allow to do full conversions with negative numbers" do
91
91
  mock_api("http://api.finance.xaviermedia.com/api/2012/08/27.xml", fixture('api_responses/example_xml_api.xml'), 3)
92
- BigDecimal.new("-3.25").eur.to_chf.should be_kind_of Exchange::Currency
92
+ BigDecimal.new("-3.25").eur.to_chf.should be_kind_of Exchange::Money
93
93
  BigDecimal.new("-3.25").eur.to_chf.value.round(2).should == -3.99
94
- BigDecimal.new("-3.25").eur.to_chf.currency.should == 'chf'
94
+ BigDecimal.new("-3.25").eur.to_chf.currency.should == :chf
95
95
  end
96
96
  it "should allow to define a historic time in which the currency should be interpreted" do
97
97
  BigDecimal.new("3.25").chf(:at => Time.gm(2010,1,1)).time.yday.should == 1
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cachify" do
4
+
5
+ describe "cachify" do
6
+ subject { "bla" }
7
+ it "should marshal dump" do
8
+ subject.cachify.should == Marshal.dump(subject)
9
+ end
10
+ end
11
+
12
+ describe "decachify" do
13
+ context "with a string" do
14
+ subject { "blu" }
15
+ it "should work" do
16
+ subject.cachify.decachify.should == subject
17
+ end
18
+ end
19
+ context "with a hash" do
20
+ subject { {:bla => "blu", "bli" => :blo, nil => [5,6]} }
21
+ it "should work" do
22
+ subject.cachify.decachify.should == subject
23
+ end
24
+ end
25
+ context "with a symbol" do
26
+ subject { :blu }
27
+ it "should work" do
28
+ subject.cachify.decachify.should == subject
29
+ end
30
+ end
31
+ context "with an array" do
32
+ subject { [2, 2.3, "blu", :bli, BigDecimal.new("3.345345")] }
33
+ it "should work" do
34
+ subject.cachify.decachify.should == subject
35
+ end
36
+ end
37
+ context "with numeric" do
38
+ context "big decimal" do
39
+ subject { BigDecimal.new("33.3333333", 3) }
40
+ it "should work" do
41
+ subject.cachify.decachify.should == subject
42
+ end
43
+ end
44
+ context "integer" do
45
+ subject { 33 }
46
+ it "should work" do
47
+ subject.cachify.decachify.should == subject
48
+ end
49
+ end
50
+ context "float" do
51
+ subject { 33.33333333 }
52
+ it "should work" do
53
+ subject.cachify.decachify.should == subject
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cachify" do
4
+
5
+ describe "cachify" do
6
+ subject { :blu }
7
+ it "should marshal dump" do
8
+ subject.cachify.should == Marshal.dump(subject)
9
+ end
10
+ end
11
+
12
+ end
@@ -2,35 +2,38 @@ require 'spec_helper'
2
2
 
3
3
  describe "Exchange::ExternalAPI::Base" do
4
4
  subject { Exchange::ExternalAPI::Base.new }
5
- before(:each) do
5
+ before(:all) do
6
6
  Exchange.configuration = Exchange::Configuration.new{|c|
7
7
  c.cache = {:subclass => :no_cache}
8
8
  }
9
9
  end
10
+ after(:all) do
11
+ Exchange.configuration.reset
12
+ end
10
13
  before(:each) do
11
- subject.instance_variable_set("@rates", {'EUR' => BigDecimal.new("3.45"), 'CHF' => BigDecimal.new("5.565")})
12
- subject.instance_variable_set("@base", 'usd')
14
+ subject.instance_variable_set("@rates", {:eur => BigDecimal.new("3.45"), :chf => BigDecimal.new("5.565")})
15
+ subject.instance_variable_set("@base", :usd)
13
16
  end
14
17
  describe "rate" do
15
18
  it "should put out an exchange rate for the two currencies" do
16
19
  subject.should_receive(:update).once
17
- subject.rate('eur', 'chf').round(3).should == 1.613
20
+ subject.rate(:eur, :chf).round(3).should == 1.613
18
21
  end
19
22
  it "should put out an exchange rate for the two currencies and pass on opts" do
20
23
  time = Time.now
21
24
  subject.should_receive(:update).with(:at => time).once
22
- subject.rate('eur', 'chf', :at => time).round(3).should == 1.613
25
+ subject.rate(:eur, :chf, :at => time).round(3).should == 1.613
23
26
  end
24
27
  end
25
28
  describe "convert" do
26
29
  it "should convert according to the given rates" do
27
30
  subject.should_receive(:update).once
28
- subject.convert(80,'chf','eur').round(2).should == 49.6
31
+ subject.convert(80,:chf, :eur).round(2).should == 49.6
29
32
  end
30
33
  it "should convert according to the given rates and pass opts" do
31
34
  time = Time.now
32
35
  subject.should_receive(:update).with(:at => time).once
33
- subject.convert(80,'chf','eur', :at => time).round(2).should == 49.6
36
+ subject.convert(80,:chf, :eur, :at => time).round(2).should == 49.6
34
37
  end
35
38
  end
36
39
  end