exchange 0.2.6

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 (40) hide show
  1. data/.document +5 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +17 -0
  5. data/Gemfile.lock +41 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +262 -0
  8. data/Rakefile +46 -0
  9. data/VERSION +1 -0
  10. data/exchange.gemspec +102 -0
  11. data/lib/core_extensions/conversability.rb +32 -0
  12. data/lib/exchange.rb +11 -0
  13. data/lib/exchange/cache.rb +4 -0
  14. data/lib/exchange/cache/base.rb +51 -0
  15. data/lib/exchange/cache/memcached.rb +52 -0
  16. data/lib/exchange/cache/rails.rb +45 -0
  17. data/lib/exchange/cache/redis.rb +54 -0
  18. data/lib/exchange/configuration.rb +72 -0
  19. data/lib/exchange/currency.rb +237 -0
  20. data/lib/exchange/external_api.rb +4 -0
  21. data/lib/exchange/external_api/base.rb +114 -0
  22. data/lib/exchange/external_api/call.rb +76 -0
  23. data/lib/exchange/external_api/currency_bot.rb +47 -0
  24. data/lib/exchange/external_api/xavier_media.rb +47 -0
  25. data/spec/core_extensions/conversability_spec.rb +64 -0
  26. data/spec/exchange/cache/base_spec.rb +29 -0
  27. data/spec/exchange/cache/memcached_spec.rb +72 -0
  28. data/spec/exchange/cache/rails_spec.rb +67 -0
  29. data/spec/exchange/cache/redis_spec.rb +76 -0
  30. data/spec/exchange/configuration_spec.rb +47 -0
  31. data/spec/exchange/currency_spec.rb +219 -0
  32. data/spec/exchange/external_api/base_spec.rb +31 -0
  33. data/spec/exchange/external_api/call_spec.rb +68 -0
  34. data/spec/exchange/external_api/currency_bot_spec.rb +61 -0
  35. data/spec/exchange/external_api/xavier_media_spec.rb +59 -0
  36. data/spec/spec_helper.rb +28 -0
  37. data/spec/support/api_responses/example_historic_json.json +167 -0
  38. data/spec/support/api_responses/example_json_api.json +167 -0
  39. data/spec/support/api_responses/example_xml_api.xml +156 -0
  40. metadata +191 -0
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cache::Rails" do
4
+ context "with rails defined" do
5
+ class ::Rails
6
+ end
7
+ end
8
+ subject { Exchange::Cache::Rails }
9
+ before(:each) do
10
+ Exchange::Configuration.define do |c|
11
+ c.cache = :rails
12
+ end
13
+ end
14
+ after(:each) do
15
+ Exchange::Configuration.define do |c|
16
+ c.cache = :memcached
17
+ end
18
+ end
19
+ describe "client" do
20
+ let(:client) { mock('rails_cache') }
21
+ it "should set up a client on the specified host and port for the cache" do
22
+ ::Rails.should_receive(:cache).and_return(client)
23
+ subject.client.should == client
24
+ end
25
+ end
26
+ describe "cached" do
27
+ context "when a result is returned" do
28
+ let(:client) { mock('rails_cache') }
29
+ context "with a daily cache" do
30
+ before(:each) do
31
+ subject.should_receive(:key).with('API_CLASS', nil).and_return('KEY')
32
+ ::Rails.should_receive(:cache).and_return(client)
33
+ client.should_receive(:fetch).with('KEY', :expires_in => 86400).and_return "{\"RESULT\":\"YAY\"}"
34
+ end
35
+ it "should return the JSON loaded result" do
36
+ subject.cached('API_CLASS') { 'something' }.should == "{\"RESULT\":\"YAY\"}"
37
+ end
38
+ end
39
+ context "with an hourly cache" do
40
+ before(:each) do
41
+ Exchange::Configuration.update = :hourly
42
+ subject.should_receive(:key).with('API_CLASS', nil).and_return('KEY')
43
+ ::Rails.should_receive(:cache).and_return(client)
44
+ client.should_receive(:fetch).with('KEY', :expires_in => 3600).and_return "{\"RESULT\":\"YAY\"}"
45
+ end
46
+ after(:each) do
47
+ Exchange::Configuration.update = :daily
48
+ end
49
+ it "should return the JSON loaded result" do
50
+ subject.cached('API_CLASS') { 'something' }.should == "{\"RESULT\":\"YAY\"}"
51
+ end
52
+ end
53
+ end
54
+ context "when no result is returned" do
55
+ let(:client) { mock('rails_cache') }
56
+ before(:each) do
57
+ subject.should_receive(:key).with('API_CLASS', nil).at_most(3).times.and_return('KEY')
58
+ ::Rails.should_receive(:cache).twice.and_return(client)
59
+ client.should_receive(:fetch).with('KEY', an_instance_of(Hash)).and_return nil
60
+ client.should_receive(:delete).with('KEY').once
61
+ end
62
+ it "should call the block and delete the key to avoid empty caches" do
63
+ subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should be_nil
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Cache::Redis" do
4
+ subject { Exchange::Cache::Redis }
5
+ before(:each) do
6
+ Exchange::Configuration.define do |c|
7
+ c.cache = :redis
8
+ c.cache_host = 'HOST'
9
+ c.cache_port = 'PORT'
10
+ end
11
+ end
12
+ after(:each) do
13
+ Exchange::Configuration.define do |c|
14
+ c.cache = :memcached
15
+ c.cache_host = 'localhost'
16
+ c.cache_port = 11211
17
+ end
18
+ end
19
+ describe "client" do
20
+ let(:client) { mock('redis') }
21
+ after(:each) do
22
+ subject.send(:remove_class_variable, "@@client")
23
+ end
24
+ it "should set up a client on the specified host and port for the cache" do
25
+ ::Redis.should_receive(:new).with(:host => 'HOST', :port => 'PORT').and_return(client)
26
+ subject.client.should == client
27
+ end
28
+ end
29
+ describe "cached" do
30
+ context "when a cached result exists" do
31
+ let(:client) { mock('redis') }
32
+ before(:each) do
33
+ subject.should_receive(:key).with('API_CLASS', nil).and_return('KEY')
34
+ ::Redis.should_receive(:new).with(:host => 'HOST', :port => 'PORT').and_return(client)
35
+ client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
36
+ end
37
+ after(:each) do
38
+ subject.send(:remove_class_variable, "@@client")
39
+ end
40
+ it "should return the JSON loaded result" do
41
+ subject.cached('API_CLASS') { 'something' }.should == {'RESULT' => 'YAY'}
42
+ end
43
+ end
44
+ context "when no cached result exists" do
45
+ let(:client) { mock('redis') }
46
+ before(:each) do
47
+ subject.should_receive(:key).with('API_CLASS', nil).at_most(3).times.and_return('KEY')
48
+ ::Redis.should_receive(:new).with(:host => 'HOST', :port => 'PORT').and_return(client)
49
+ client.should_receive(:get).with('KEY').and_return nil
50
+ end
51
+ after(:each) do
52
+ subject.send(:remove_class_variable, "@@client")
53
+ end
54
+ context "with daily cache" do
55
+ it "should call the block and set and return the result" do
56
+ client.should_receive(:set).with('KEY', "{\"RESULT\":\"YAY\"}").once
57
+ client.should_receive(:expire).with('KEY', 86400).once
58
+ subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
59
+ end
60
+ end
61
+ context "with hourly cache" do
62
+ before(:each) do
63
+ Exchange::Configuration.update = :hourly
64
+ end
65
+ after(:each) do
66
+ Exchange::Configuration.update = :daily
67
+ end
68
+ it "should call the block and set and return the result" do
69
+ client.should_receive(:set).with('KEY', "{\"RESULT\":\"YAY\"}").once
70
+ client.should_receive(:expire).with('KEY', 3600).once
71
+ subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Configuration" do
4
+ let(:subject) { Exchange::Configuration }
5
+ it "should have a standard configuration" do
6
+ subject.api.should == :currency_bot
7
+ subject.api_class.should == Exchange::ExternalAPI::CurrencyBot
8
+ subject.cache.should == :memcached
9
+ subject.cache_class.should == Exchange::Cache::Memcached
10
+ subject.cache_host.should == 'localhost'
11
+ subject.cache_port.should == 11211
12
+ subject.retries.should == 5
13
+ end
14
+ it "should respond to all configuration getters and setters" do
15
+ [:api, :retries, :allow_mixed_operations, :cache, :cache_host, :cache_port, :update].each do |k|
16
+ subject.should be_respond_to(k)
17
+ subject.should be_respond_to(:"#{k}=")
18
+ end
19
+ end
20
+ it "should allow to be defined with a block" do
21
+ subject.define do |c|
22
+ c.api = :xavier_media
23
+ c.cache = :redis
24
+ c.retries = 60
25
+ end
26
+ subject.api.should == :xavier_media
27
+ subject.api_class.should == Exchange::ExternalAPI::XavierMedia
28
+ subject.cache.should == :redis
29
+ subject.cache_class.should == Exchange::Cache::Redis
30
+ subject.retries.should == 60
31
+ end
32
+ it "should allow to be set directly" do
33
+ subject.api = :paypal
34
+ subject.cache = :yml
35
+ subject.retries = 1
36
+ subject.api.should == :paypal
37
+ subject.cache.should == :yml
38
+ subject.retries.should == 1
39
+ end
40
+ after(:all) do
41
+ subject.api = :currency_bot
42
+ subject.cache = :memcached
43
+ subject.cache_host = 'localhost'
44
+ subject.cache_port = 11211
45
+ subject.retries = 5
46
+ end
47
+ end
@@ -0,0 +1,219 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::Currency" do
4
+ subject { Exchange::Currency.new(40, :usd) }
5
+ before(:all) do
6
+ Exchange::Configuration.define do |c|
7
+ c.api = :currency_bot
8
+ c.cache = false
9
+ end
10
+ end
11
+ after(:all) do
12
+ Exchange::Configuration.cache = :memcached
13
+ end
14
+ it "should initialize with a number and a currency" do
15
+ subject.value.should == 40
16
+ subject.currency.should == :usd
17
+ end
18
+ describe "convert_to" do
19
+ it "should be able to convert itself to other currencies" do
20
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 3)
21
+ subject.convert_to(:chf).value.should == 36.5
22
+ subject.convert_to(:chf).currency.should == :chf
23
+ subject.convert_to(:chf).should be_kind_of Exchange::Currency
24
+ end
25
+ end
26
+ describe "operations" do
27
+ describe "+ other" do
28
+ it "should be able to add an integer" do
29
+ (subject + 40).value.should == 80
30
+ end
31
+ it "should be able to add a float" do
32
+ (subject + 40.5).value.should == 80.5
33
+ end
34
+ it "should be able to add another currency value" do
35
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
36
+ (subject + Exchange::Currency.new(30, :chf)).value.should == 72.87
37
+ (subject + Exchange::Currency.new(30, :sek)).currency.should == :usd
38
+ end
39
+ it "should raise when currencies get mixed and the configuration does not allow it" do
40
+ Exchange::Configuration.allow_mixed_operations = false
41
+ lambda { subject + Exchange::Currency.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
42
+ Exchange::Configuration.allow_mixed_operations = true
43
+ end
44
+ it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
45
+ Exchange::Configuration.allow_mixed_operations = false
46
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
47
+ lambda { subject + Exchange::Currency.new(30, :usd) }.should_not raise_error
48
+ Exchange::Configuration.allow_mixed_operations = true
49
+ end
50
+ end
51
+ describe "- other" do
52
+ it "should be able to subtract an integer" do
53
+ (subject + 40).value.should == 80
54
+ end
55
+ it "should be able to subtract a float" do
56
+ (subject + 40.5).value.should == 80.5
57
+ end
58
+ it "should be able to subtract another currency value" do
59
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
60
+ (subject + Exchange::Currency.new(10, :chf)).value.should == 50.96
61
+ (subject + Exchange::Currency.new(23.3, :eur)).currency.should == :usd
62
+ end
63
+ it "should raise when currencies get mixed and the configuration does not allow it" do
64
+ Exchange::Configuration.allow_mixed_operations = false
65
+ lambda { subject - Exchange::Currency.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
66
+ Exchange::Configuration.allow_mixed_operations = true
67
+ end
68
+ it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
69
+ Exchange::Configuration.allow_mixed_operations = false
70
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
71
+ lambda { subject - Exchange::Currency.new(30, :usd) }.should_not raise_error
72
+ Exchange::Configuration.allow_mixed_operations = true
73
+ end
74
+ end
75
+ describe "* other" do
76
+ it "should be able to multiply by an integer" do
77
+ (subject * 40).value.should == 1600
78
+ end
79
+ it "should be able to multiply a float" do
80
+ (subject * 40.5).value.should == 1620
81
+ end
82
+ it "should be able to multiply by another currency value" do
83
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
84
+ (((subject * Exchange::Currency.new(10, :chf)).value * 10000.0).round.to_f / 10000.0).should == 438.4
85
+ (subject * Exchange::Currency.new(23.3, :eur)).currency.should == :usd
86
+ end
87
+ it "should raise when currencies get mixed and the configuration does not allow it" do
88
+ Exchange::Configuration.allow_mixed_operations = false
89
+ lambda { subject * Exchange::Currency.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
90
+ Exchange::Configuration.allow_mixed_operations = true
91
+ end
92
+ it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
93
+ Exchange::Configuration.allow_mixed_operations = false
94
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
95
+ lambda { subject * Exchange::Currency.new(30, :usd) }.should_not raise_error
96
+ Exchange::Configuration.allow_mixed_operations = true
97
+ end
98
+ end
99
+ describe "/ other" do
100
+ it "should be able to multiply by an integer" do
101
+ (subject / 40).value.should == 1
102
+ end
103
+ it "should be able to multiply a float" do
104
+ (((subject / 40.5).value * 10000.0).round.to_f / 10000.0).should == 0.9877
105
+ end
106
+ it "should be able to multiply by another currency value" do
107
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
108
+ (((subject / Exchange::Currency.new(10, :chf)).value * 10000.0).round.to_f / 10000.0).should == 3.6496
109
+ (subject / Exchange::Currency.new(23.3, :eur)).currency.should == :usd
110
+ end
111
+ it "should raise when currencies get mixed and the configuration does not allow it" do
112
+ Exchange::Configuration.allow_mixed_operations = false
113
+ lambda { subject / Exchange::Currency.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
114
+ Exchange::Configuration.allow_mixed_operations = true
115
+ end
116
+ it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
117
+ Exchange::Configuration.allow_mixed_operations = false
118
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
119
+ lambda { subject / Exchange::Currency.new(30, :usd) }.should_not raise_error
120
+ Exchange::Configuration.allow_mixed_operations = true
121
+ end
122
+ end
123
+ describe "comparison" do
124
+ subject { Exchange::Currency.new(40.123, :usd) }
125
+ let(:comp1) { Exchange::Currency.new(40.123, :usd) }
126
+ let(:comp2) { Exchange::Currency.new(40, :usd) }
127
+ let(:comp3) { Exchange::Currency.new(50, :eur) }
128
+ let(:comp4) { Exchange::Currency.new(45, :eur) }
129
+ let(:comp5) { Exchange::Currency.new(66.1, :usd) }
130
+ let(:comp6) { Exchange::Currency.new(66.1, :usd, :at => Time.gm(2011,1,1)) }
131
+ before(:each) do
132
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 2)
133
+ end
134
+ context "with identical currencies" do
135
+ it "should be true if the currency and the value is the same" do
136
+ (subject == comp1).should be_true
137
+ end
138
+ it "should be false if the value is different" do
139
+ (subject == comp2).should be_false
140
+ end
141
+ end
142
+ context "with different currencies" do
143
+ it "should be true if the converted value is the same" do
144
+ (comp3 == comp5).should be_true
145
+ end
146
+ it "should be false if the converted value is different" do
147
+ (subject == comp4).should be_false
148
+ end
149
+ it "should be false if the currency is defined historic and the converted value is different" do
150
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/historical/2011-01-01.json", fixture('api_responses/example_historic_json.json'), 2)
151
+ (comp3 == comp6).should be_false
152
+ end
153
+ end
154
+ end
155
+ describe "sorting" do
156
+ subject { Exchange::Currency.new(40.123, :usd) }
157
+ let(:comp1) { Exchange::Currency.new(40.123, :usd) }
158
+ let(:comp2) { Exchange::Currency.new(40, :usd) }
159
+ let(:comp3) { Exchange::Currency.new(50, :eur) }
160
+ let(:comp4) { Exchange::Currency.new(45, :eur) }
161
+ before(:each) do
162
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 6)
163
+ end
164
+ it "should sort and by doing conversions" do
165
+ [subject, comp1, comp2, comp3, comp4].sort.should == [comp2, subject, comp1, comp4, comp3]
166
+ end
167
+ end
168
+ describe "round" do
169
+ subject { Exchange::Currency.new(40.123, :usd) }
170
+ it "should apply it to its number" do
171
+ subject.round.value.should == 40
172
+ subject.round.currency.should == :usd
173
+ subject.round.should be_kind_of Exchange::Currency
174
+ end
175
+ end
176
+ describe "ceil" do
177
+ subject { Exchange::Currency.new(40.123, :usd) }
178
+ it "should apply it to its number" do
179
+ subject.ceil.value.should == 41
180
+ subject.ceil.currency.should == :usd
181
+ subject.ceil.should be_kind_of Exchange::Currency
182
+ end
183
+ end
184
+ describe "floor" do
185
+ subject { Exchange::Currency.new(40.723, :usd) }
186
+ it "should apply it to its number" do
187
+ subject.floor.value.should == 40
188
+ subject.floor.currency.should == :usd
189
+ subject.floor.should be_kind_of Exchange::Currency
190
+ end
191
+ end
192
+ end
193
+ describe "methods via method missing" do
194
+ it "should be able to convert via to_currency to other currencies" do
195
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json", fixture('api_responses/example_json_api.json'), 6)
196
+ {'chf' => 36.5, 'usd' => 40.0, 'dkk' => 225.12, 'sek' => 269.85, 'nok' => 232.06, 'rub' => 1205.24}.each do |currency, value|
197
+ c = subject.send(:"to_#{currency}")
198
+ c.value.should == value
199
+ c.currency.should == currency
200
+ end
201
+ end
202
+ it "should be able to convert via to_currency to other currencies and use historic data" do
203
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/historical/2011-10-09.json", fixture('api_responses/example_json_api.json'), 6)
204
+ {'chf' => 36.5, 'usd' => 40.0, 'dkk' => 225.12, 'sek' => 269.85, 'nok' => 232.06, 'rub' => 1205.24}.each do |currency, value|
205
+ c = subject.send(:"to_#{currency}", :at => Time.gm(2011,10,9))
206
+ c.value.should == value
207
+ c.currency.should == currency
208
+ end
209
+ end
210
+ it "should use the own time if defined as historic to convert" do
211
+ mock_api("https://raw.github.com/currencybot/open-exchange-rates/master/historical/2011-01-01.json", fixture('api_responses/example_json_api.json'), 2)
212
+ 5.eur(:at => Time.gm(2011,1,1)).to_usd.value.should == 5.eur.to_usd(:at => Time.gm(2011,1,1)).value
213
+ end
214
+ it "should pass on methods it does not understand to its number" do
215
+ subject.to_f.should == 40
216
+ lambda { subject.to_hell }.should raise_error(NoMethodError)
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::ExternalAPI::Base" do
4
+ subject { Exchange::ExternalAPI::Base.new }
5
+ before(:each) do
6
+ subject.instance_variable_set("@rates", {'EUR' => 3.45, 'CHF' => 5.565})
7
+ subject.instance_variable_set("@base", 'usd')
8
+ end
9
+ describe "rate" do
10
+ it "should put out an exchange rate for the two currencies" do
11
+ subject.should_receive(:update).once
12
+ ((subject.rate('eur', 'chf') * 10000).round.to_f / 10000).should == 1.613
13
+ end
14
+ it "should put out an exchange rate for the two currencies and pass on opts" do
15
+ time = Time.now
16
+ subject.should_receive(:update).with(:at => time).once
17
+ ((subject.rate('eur', 'chf', :at => time) * 10000).round.to_f / 10000).should == 1.613
18
+ end
19
+ end
20
+ describe "convert" do
21
+ it "should convert according to the given rates" do
22
+ subject.should_receive(:update).once
23
+ subject.convert(80,'chf','eur').should == 49.6
24
+ end
25
+ it "should convert according to the given rates and pass opts" do
26
+ time = Time.now
27
+ subject.should_receive(:update).with(:at => time).once
28
+ subject.convert(80,'chf','eur', :at => time).should == 49.6
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Exchange::ExternalAPI::Call" do
4
+ before(:all) do
5
+ Exchange::Configuration.cache = false
6
+ end
7
+ describe "initialization" do
8
+ context "with a json api" do
9
+ before(:each) do
10
+ mock_api('JSON_API', fixture('api_responses/example_json_api.json'))
11
+ end
12
+ it "should call the api and yield a block with the result" do
13
+ Exchange::ExternalAPI::Call.new('JSON_API') do |result|
14
+ result.should == JSON.load(fixture('api_responses/example_json_api.json'))
15
+ end
16
+ end
17
+ #context "with http errors" do
18
+ #let(:opened_uri) { mock('uri', :read => fixture('api_responses/example_xml_api.xml'))}
19
+ # it "should recall as many times as specified in the options" do
20
+ # URI.should_receive(:parse).with('JSON_API').and_return(uri_mock)
21
+ # Exchange::ExternalAPI::Call.new('JSON_API') do |result|
22
+ # result.should == JSON.load(fixture('api_responses/example_json_api.json'))
23
+ # end
24
+ # end
25
+ # it "should raise errors if the maximum call repetition is reached" do
26
+ # URI.stub_chain :parse, :open, :read => OpenURI::HTTPError.new
27
+ # uri_mock.should_receive(:open).at_most(5).times.and_raise(OpenURI::HTTPError)
28
+ # lambda { Exchange::ExternalAPI::Call.new('JSON_API') }.should raise_error(Exchange::ExternalAPI::APIError)
29
+ # end
30
+ #end
31
+ context "with socket errors" do
32
+ it "should raise an error immediately" do
33
+ @uri_mock.should_receive(:open).at_most(5).times.and_raise(SocketError)
34
+ lambda { Exchange::ExternalAPI::Call.new('JSON_API') }.should raise_error(Exchange::ExternalAPI::APIError)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ context "with an xml api" do
40
+ before(:each) do
41
+ mock_api('XML_API', fixture('api_responses/example_xml_api.xml'))
42
+ end
43
+ it "should call the api and yield a block with the result" do
44
+ Exchange::ExternalAPI::Call.new('XML_API', :format => :xml) do |result|
45
+ result.to_s.should == Nokogiri.parse(fixture('api_responses/example_xml_api.xml')).to_s
46
+ end
47
+ end
48
+ # context "with http errors" do
49
+ # let(:error_mock) { mock('opened_uri') }
50
+ # it "should recall as many times as specified in the options" do
51
+ # URI.stub! :parse => OpenURI::HTTPError.new
52
+ # Exchange::ExternalAPI::Call.new('XML_API', :format => :xml) do |result|
53
+ # result.to_s.should == Nokogiri.parse(fixture('api_responses/example_xml_api.xml')).to_s
54
+ # end
55
+ # end
56
+ # it "should raise errors if the maximum call repetition is reached" do
57
+ # URI.stub! :parse => OpenURI::HTTPError.new
58
+ # lambda { Exchange::ExternalAPI::Call.new('XML_API', :format => :xml) }.should raise_error(Exchange::ExternalAPI::APIError)
59
+ # end
60
+ # end
61
+ context "with socket errors" do
62
+ it "should raise an error immediately" do
63
+ @uri_mock.should_receive(:open).once.and_raise(SocketError)
64
+ lambda { Exchange::ExternalAPI::Call.new('XML_API', :format => :xml) }.should raise_error(Exchange::ExternalAPI::APIError)
65
+ end
66
+ end
67
+ end
68
+ end