exchange 0.4.1 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/exchange.gemspec +2 -2
- data/lib/exchange.rb +1 -1
- data/lib/exchange/cache/memcached.rb +2 -2
- data/lib/exchange/cache/redis.rb +1 -1
- data/lib/exchange/external_api/base.rb +1 -1
- data/lib/exchange/external_api/call.rb +1 -1
- data/lib/exchange/external_api/ecb.rb +3 -3
- data/spec/exchange/cache/memcached_spec.rb +21 -4
- data/spec/exchange/cache/redis_spec.rb +21 -4
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
data/exchange.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "exchange"
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Beat Richartz"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-06-10"
|
13
13
|
s.description = "The Exchange Gem gives you easy access to currency functions directly on your Numbers. Imagine a conversion as easy as \n 1.eur.to_usd\n or even better \n 1.eur.to_usd(:at => Time.now - 84600)\n which gets you an exchange at the rates of yesterday."
|
14
14
|
s.email = "exchange_gem@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/exchange.rb
CHANGED
@@ -32,10 +32,10 @@ module Exchange
|
|
32
32
|
# @yield [] This method takes a mandatory block with an arity of 0 and calls it if no cached result is available
|
33
33
|
# @raise [CachingWithoutBlockError] an Argument Error when no mandatory block has been given
|
34
34
|
|
35
|
-
def cached api, opts={}, &block
|
35
|
+
def cached api, opts={}, &block
|
36
36
|
raise CachingWithoutBlockError.new('Caching needs a block') unless block_given?
|
37
37
|
begin
|
38
|
-
result = opts[:plain] ? client.get(key(api, opts)) : JSON.load(client.get(key(api, opts)))
|
38
|
+
result = opts[:plain] ? client.get(key(api, opts)).gsub(/["\s+]/, '') : JSON.load(client.get(key(api, opts)))
|
39
39
|
rescue ::Memcached::NotFound
|
40
40
|
result = block.call
|
41
41
|
if result && !result.to_s.empty?
|
data/lib/exchange/cache/redis.rb
CHANGED
@@ -36,7 +36,7 @@ module Exchange
|
|
36
36
|
raise CachingWithoutBlockError.new('Caching needs a block') unless block_given?
|
37
37
|
|
38
38
|
if result = client.get(key(api, opts))
|
39
|
-
result = opts[:plain] ? result : JSON.load(result)
|
39
|
+
result = opts[:plain] ? result.gsub(/["\s+]/, '') : JSON.load(result)
|
40
40
|
else
|
41
41
|
result = block.call
|
42
42
|
if result && !result.to_s.empty?
|
@@ -77,7 +77,7 @@ module Exchange
|
|
77
77
|
# Exchange::ExternalAPI::Base.new.rate(:usd, :eur, :at => Time.gm(3,23,2009))
|
78
78
|
# #=> 1.232231231
|
79
79
|
def rate(from, to, opts={})
|
80
|
-
rate = Configuration.cache_class.cached(Exchange::Configuration.api, opts.merge(:key_for => [from, to], :plain => true)) do
|
80
|
+
rate = Exchange::Configuration.cache_class.cached(Exchange::Configuration.api, opts.merge(:key_for => [from, to], :plain => true)) do
|
81
81
|
update(opts)
|
82
82
|
rate_from = self.rates[to.to_s.upcase]
|
83
83
|
rate_to = self.rates[from.to_s.upcase]
|
@@ -31,7 +31,7 @@ module Exchange
|
|
31
31
|
# # Do something with that result
|
32
32
|
|
33
33
|
def initialize url, options={}, &block
|
34
|
-
result = Configuration.cache_class(options).cached(options[:api] || Configuration.api, options) do
|
34
|
+
result = Exchange::Configuration.cache_class(options).cached(options[:api] || Exchange::Configuration.api, options) do
|
35
35
|
load_url(url, options[:retries] || Exchange::Configuration.retries, options[:retry_with])
|
36
36
|
end
|
37
37
|
|
@@ -28,12 +28,12 @@ module Exchange
|
|
28
28
|
api_url = api_url(time)
|
29
29
|
times = Exchange::Configuration.retries.times.map{ |i| time - 86400 * (i+1) }
|
30
30
|
|
31
|
-
Kernel.warn "WARNING: Using the ECB API without caching can be very, very slow." unless Configuration.cache
|
31
|
+
Kernel.warn "WARNING: Using the ECB API without caching can be very, very slow." unless Exchange::Configuration.cache
|
32
32
|
|
33
|
-
Configuration.cache_class.cached(self.class, :at => time) do
|
33
|
+
Exchange::Configuration.cache_class.cached(self.class, :at => time) do
|
34
34
|
Call.new(api_url, :format => :xml, :at => time, :cache => :file, :cache_period => time >= Time.now - 90 * 86400 ? :daily : :monthly) do |result|
|
35
35
|
t = time
|
36
|
-
|
36
|
+
|
37
37
|
while (r = result.css("Cube[time=\"#{t.strftime("%Y-%m-%d")}\"]")).empty? && !times.empty?
|
38
38
|
t = times.shift
|
39
39
|
end
|
@@ -31,15 +31,32 @@ describe "Exchange::Cache::Memcached" do
|
|
31
31
|
context "when a cached result exists" do
|
32
32
|
let(:client) { mock('memcached') }
|
33
33
|
before(:each) do
|
34
|
-
subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
|
35
34
|
::Memcached.should_receive(:new).with("HOST:PORT").and_return(client)
|
36
|
-
client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
|
37
35
|
end
|
38
36
|
after(:each) do
|
39
37
|
subject.send(:remove_class_variable, "@@client")
|
40
38
|
end
|
41
|
-
|
42
|
-
|
39
|
+
context "when loading json" do
|
40
|
+
before(:each) do
|
41
|
+
subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
|
42
|
+
client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
|
43
|
+
end
|
44
|
+
it "should return the JSON loaded result" do
|
45
|
+
subject.cached('API_CLASS') { 'something' }.should == {'RESULT' => 'YAY'}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context "when loading plain" do
|
49
|
+
before(:each) do
|
50
|
+
subject.should_receive(:key).with('API_CLASS', {:plain => true}).and_return('KEY')
|
51
|
+
end
|
52
|
+
it "should return a String result in the right format" do
|
53
|
+
client.should_receive(:get).with('KEY').and_return "122.0"
|
54
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
|
55
|
+
end
|
56
|
+
it "should also return a String result in the right format when memcached adds quotes and spaces" do
|
57
|
+
client.should_receive(:get).with('KEY').and_return "\"122.0\" "
|
58
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
|
59
|
+
end
|
43
60
|
end
|
44
61
|
end
|
45
62
|
context "when no cached result exists" do
|
@@ -33,15 +33,32 @@ describe "Exchange::Cache::Redis" do
|
|
33
33
|
context "when a cached result exists" do
|
34
34
|
let(:client) { mock('redis') }
|
35
35
|
before(:each) do
|
36
|
-
subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
|
37
36
|
::Redis.should_receive(:new).with(:host => 'HOST', :port => 'PORT').and_return(client)
|
38
|
-
client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
|
39
37
|
end
|
40
38
|
after(:each) do
|
41
39
|
subject.send(:remove_class_variable, "@@client")
|
42
40
|
end
|
43
|
-
|
44
|
-
|
41
|
+
context "when loading json" do
|
42
|
+
before(:each) do
|
43
|
+
subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
|
44
|
+
client.should_receive(:get).with('KEY').and_return "{\"RESULT\":\"YAY\"}"
|
45
|
+
end
|
46
|
+
it "should return the JSON loaded result" do
|
47
|
+
subject.cached('API_CLASS') { 'something' }.should == {'RESULT' => 'YAY'}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context "when loading plain" do
|
51
|
+
before(:each) do
|
52
|
+
subject.should_receive(:key).with('API_CLASS', {:plain => true}).and_return('KEY')
|
53
|
+
end
|
54
|
+
it "should return a String result in the right format" do
|
55
|
+
client.should_receive(:get).with('KEY').and_return "122.0"
|
56
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
|
57
|
+
end
|
58
|
+
it "should also return a String result in the right format when redis adds quotes and spaces" do
|
59
|
+
client.should_receive(:get).with('KEY').and_return "\"122.0\" "
|
60
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0"
|
61
|
+
end
|
45
62
|
end
|
46
63
|
end
|
47
64
|
context "when no cached result exists" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exchange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -235,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
235
|
version: '0'
|
236
236
|
segments:
|
237
237
|
- 0
|
238
|
-
hash: -
|
238
|
+
hash: -2237646329564279677
|
239
239
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
240
240
|
none: false
|
241
241
|
requirements:
|