exchange 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +115 -47
- data/benchmark/benchmark.rb +49 -0
- data/changelog.rdoc +8 -1
- data/lib/exchange.rb +4 -4
- data/lib/exchange/base.rb +1 -1
- data/lib/exchange/cache.rb +2 -0
- data/lib/exchange/cache/base.rb +20 -6
- data/lib/exchange/cache/configuration.rb +24 -0
- data/lib/exchange/cache/file.rb +24 -9
- data/lib/exchange/cache/memcached.rb +3 -3
- data/lib/exchange/cache/memory.rb +89 -0
- data/lib/exchange/cache/rails.rb +1 -1
- data/lib/exchange/cache/redis.rb +4 -4
- data/lib/exchange/configurable.rb +53 -0
- data/lib/exchange/configuration.rb +32 -26
- data/lib/exchange/core_extensions.rb +3 -0
- data/lib/exchange/core_extensions/cachify.rb +25 -0
- data/lib/exchange/core_extensions/float/error_safe.rb +25 -0
- data/lib/{core_extensions → exchange/core_extensions/numeric}/conversability.rb +12 -12
- data/lib/exchange/external_api.rb +2 -1
- data/lib/exchange/external_api/base.rb +34 -9
- data/lib/exchange/external_api/call.rb +6 -8
- data/lib/exchange/external_api/configuration.rb +25 -0
- data/lib/exchange/external_api/ecb.rb +16 -25
- data/lib/exchange/external_api/json.rb +11 -1
- data/lib/exchange/external_api/open_exchange_rates.rb +65 -0
- data/lib/exchange/external_api/xavier_media.rb +7 -7
- data/lib/exchange/iso_4217.rb +32 -5
- data/lib/exchange/{currency.rb → money.rb} +112 -110
- data/lib/exchange/typecasting.rb +94 -0
- data/spec/exchange/cache/base_spec.rb +2 -2
- data/spec/exchange/cache/configuration_spec.rb +56 -0
- data/spec/exchange/cache/file_spec.rb +10 -8
- data/spec/exchange/cache/memcached_spec.rb +9 -18
- data/spec/exchange/cache/memory_spec.rb +122 -0
- data/spec/exchange/cache/no_cache_spec.rb +5 -15
- data/spec/exchange/cache/rails_spec.rb +2 -6
- data/spec/exchange/cache/redis_spec.rb +8 -18
- data/spec/exchange/configuration_spec.rb +31 -7
- data/spec/exchange/core_extensions/array/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/float/error_safe_spec.rb +49 -0
- data/spec/exchange/core_extensions/hash/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/numeric/cachify_spec.rb +26 -0
- data/spec/{core_extensions → exchange/core_extensions/numeric}/conversability_spec.rb +22 -22
- data/spec/exchange/core_extensions/string/cachify_spec.rb +59 -0
- data/spec/exchange/core_extensions/symbol/cachify_spec.rb +12 -0
- data/spec/exchange/external_api/base_spec.rb +10 -7
- data/spec/exchange/external_api/call_spec.rb +3 -0
- data/spec/exchange/external_api/configuration_spec.rb +52 -0
- data/spec/exchange/external_api/ecb_spec.rb +8 -5
- data/spec/exchange/external_api/open_exchange_rates_spec.rb +70 -0
- data/spec/exchange/external_api/xavier_media_spec.rb +8 -5
- data/spec/exchange/iso_4217_spec.rb +208 -20
- data/spec/exchange/{currency_spec.rb → money_spec.rb} +102 -82
- data/spec/exchange/typecasting_spec.rb +86 -0
- metadata +117 -71
- data/exchange-0.7.5.gem +0 -0
- data/exchange-0.7.6.gem +0 -0
- data/lib/exchange/external_api/currency_bot.rb +0 -61
- data/spec/exchange/external_api/currency_bot_spec.rb +0 -63
@@ -0,0 +1,94 @@
|
|
1
|
+
module Exchange
|
2
|
+
|
3
|
+
# Allows to access properties of an object as currencies
|
4
|
+
# The setter takes care of passing the right values to the original setter method,
|
5
|
+
# The getter takes care of instantiating a currency of the original getter method,
|
6
|
+
# This is framework agnostic. It works in ActiveRecord/Rails, Datamapper, Ohm, Your own, whatever you want
|
7
|
+
#
|
8
|
+
# @example The setter converts the currency automatically when the currency is not the one set (example in Active Record)
|
9
|
+
# class MyClass < ActiveRecord::Base
|
10
|
+
# extend Exchange::Typecasting
|
11
|
+
# money :price, :currency => lambda { |s| s.manager.currency }
|
12
|
+
#
|
13
|
+
# has_one :manager
|
14
|
+
#
|
15
|
+
# attr_accessible :price
|
16
|
+
#
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# MyClass.find(1).update_attributes :price => 1.usd
|
20
|
+
# MyClass.find(1).price #=> 0.77 EUR
|
21
|
+
#
|
22
|
+
# @example The getter sets the currency automatically to the currency set in the definition (example in Ohm)
|
23
|
+
# class MyClass < Ohm::Model
|
24
|
+
# extend Exchange::Typecasting
|
25
|
+
# reference :manager, Manager
|
26
|
+
# attribute :price
|
27
|
+
#
|
28
|
+
# money :price, :currency => :manager_currency
|
29
|
+
#
|
30
|
+
# def manager_currency
|
31
|
+
# manager.currency
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# my_instance = MyClass[0]
|
37
|
+
# my_instance.price #=> instance of exchange currency in eur
|
38
|
+
#
|
39
|
+
# manager = my_instance.manager
|
40
|
+
# managermanager.update :currency => :usd
|
41
|
+
# my_instance.price #=> instance of exchange currency in usd
|
42
|
+
#
|
43
|
+
module Typecasting
|
44
|
+
|
45
|
+
# installs a setter and a getter for the attribute you want to typecast as exchange money
|
46
|
+
|
47
|
+
def money *attributes
|
48
|
+
|
49
|
+
options = attributes.last.is_a?(Hash) ? attributes.pop : {}
|
50
|
+
|
51
|
+
attributes.each do |attribute|
|
52
|
+
|
53
|
+
define_method :"#{attribute}_with_exchange_typecasting" do
|
54
|
+
currency = evaluate_money_option(options[:currency]) if options[:currency]
|
55
|
+
raise NoCurrencyError.new("No currency is given for typecasting #{attributes.join(', ')}. Make sure a currency is present") unless currency
|
56
|
+
|
57
|
+
time = evaluate_money_option(options[:at]) if options[:at]
|
58
|
+
|
59
|
+
Exchange::Money.new(send(:"#{attribute}_without_exchange_typecasting")) do |c|
|
60
|
+
c.currency = currency
|
61
|
+
c.time = time if time
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias_method :"#{attribute}_without_exchange_typecasting", attribute.to_sym
|
65
|
+
alias_method attribute.to_sym, :"#{attribute}_with_exchange_typecasting"
|
66
|
+
|
67
|
+
define_method :"#{attribute}_with_exchange_typecasting=" do |data|
|
68
|
+
att = send(attribute)
|
69
|
+
|
70
|
+
if !data.respond_to?(:currency)
|
71
|
+
send(:"#{attribute}_without_exchange_typecasting=", data)
|
72
|
+
elsif att.currency == data.currency
|
73
|
+
send(:"#{attribute}_without_exchange_typecasting=", data.value)
|
74
|
+
elsif att.currency != data.currency
|
75
|
+
send(:"#{attribute}_without_exchange_typecasting=", data.send(:"to_#{att.currency}").value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
alias_method :"#{attribute}_without_exchange_typecasting=", :"#{attribute}="
|
79
|
+
alias_method :"#{attribute}=", :"#{attribute}_with_exchange_typecasting="
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
define_method :evaluate_money_option do |option|
|
84
|
+
option.is_a?(Proc) ? instance_eval(&option) : send(option)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Is raised when no currency is given for typecasting
|
89
|
+
#
|
90
|
+
NoCurrencyError = Class.new(ArgumentError)
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -10,7 +10,7 @@ describe "Exchange::Cache::Base" do
|
|
10
10
|
context "with a daily cache" do
|
11
11
|
it "should build a timestamped key with the class given, the yearday and the year" do
|
12
12
|
subject.send(:key, :xavier_media).should == 'exchange_xavier_media_2012_61'
|
13
|
-
subject.send(:key, :
|
13
|
+
subject.send(:key, :open_exchange_rates).should == 'exchange_open_exchange_rates_2012_61'
|
14
14
|
end
|
15
15
|
end
|
16
16
|
context "with an hourly cache" do
|
@@ -22,7 +22,7 @@ describe "Exchange::Cache::Base" do
|
|
22
22
|
end
|
23
23
|
it "should build a timestamped key with the class given, the yearday, the year and the hour" do
|
24
24
|
subject.send(:key, :xavier_media).should == 'exchange_xavier_media_2012_61_23'
|
25
|
-
subject.send(:key, :
|
25
|
+
subject.send(:key, :open_exchange_rates).should == 'exchange_open_exchange_rates_2012_61_23'
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Exchange::Cache::Configuration" do
|
4
|
+
|
5
|
+
subject { Exchange::Cache::Configuration.instance }
|
6
|
+
|
7
|
+
describe "attr_readers" do
|
8
|
+
[:subclass, :expire, :host, :port, :path].each do |reader|
|
9
|
+
it "should respond to #{reader}" do
|
10
|
+
subject.should be_respond_to(reader)
|
11
|
+
end
|
12
|
+
it "should respond to #{reader}=" do
|
13
|
+
subject.should be_respond_to(:"#{reader}=")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "subclass constantize" do
|
19
|
+
it "should automatically constantize the subclass" do
|
20
|
+
subject.subclass = :no_cache
|
21
|
+
|
22
|
+
subject.subclass.should == Exchange::Cache::NoCache
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "set" do
|
27
|
+
before(:each) do
|
28
|
+
@return = subject.set :subclass => :no_cache, :expire => :daily, :host => 'localhost', :port => 112211, :path => "PATH"
|
29
|
+
end
|
30
|
+
it "should set the options given" do
|
31
|
+
subject.subclass.should == Exchange::Cache::NoCache
|
32
|
+
subject.expire.should == :daily
|
33
|
+
subject.host.should == 'localhost'
|
34
|
+
subject.port.should == 112211
|
35
|
+
subject.path.should == 'PATH'
|
36
|
+
end
|
37
|
+
it "should return self" do
|
38
|
+
@return.should == subject
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "reset" do
|
43
|
+
before(:each) do
|
44
|
+
subject.set :subclass => :no_cache, :expire => :daily, :host => 'localhost', :port => 112211, :path => "PATH"
|
45
|
+
end
|
46
|
+
it "should restore the defaults" do
|
47
|
+
subject.reset
|
48
|
+
subject.subclass.should == Exchange::Cache::Memory
|
49
|
+
subject.expire.should == :daily
|
50
|
+
subject.host.should be_nil
|
51
|
+
subject.port.should be_nil
|
52
|
+
subject.path.should be_nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -11,11 +11,7 @@ describe "Exchange::Cache::File" do
|
|
11
11
|
}
|
12
12
|
end
|
13
13
|
after(:each) do
|
14
|
-
Exchange.configuration
|
15
|
-
c.cache = {
|
16
|
-
:subclass => :memcached
|
17
|
-
}
|
18
|
-
}
|
14
|
+
Exchange.configuration.reset
|
19
15
|
end
|
20
16
|
describe "cached" do
|
21
17
|
it "should raise an error if no block was given" do
|
@@ -26,21 +22,27 @@ describe "Exchange::Cache::File" do
|
|
26
22
|
before(:each) do
|
27
23
|
subject.should_receive(:key).with('API_CLASS', nil).and_return('KEY')
|
28
24
|
::File.should_receive(:exists?).with('STORE/PATH/KEY').and_return(true)
|
29
|
-
::File.should_receive(:read).with('STORE/PATH/KEY').and_return 'CONTENT'
|
25
|
+
::File.should_receive(:read).with('STORE/PATH/KEY').and_return 'CONTENT'.cachify
|
30
26
|
end
|
31
27
|
it "should return the file contents" do
|
32
28
|
subject.cached('API_CLASS') { 'something' }.should == 'CONTENT'
|
33
29
|
end
|
30
|
+
it "should also return plain when asked to" do
|
31
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == 'CONTENT'.cachify
|
32
|
+
end
|
34
33
|
end
|
35
|
-
context "with
|
34
|
+
context "with a monthly cache" do
|
36
35
|
before(:each) do
|
37
36
|
subject.should_receive(:key).with('API_CLASS', an_instance_of(Symbol)).and_return('KEY')
|
38
37
|
::File.should_receive(:exists?).with('STORE/PATH/KEY').and_return(true)
|
39
|
-
::File.should_receive(:read).with('STORE/PATH/KEY').and_return 'CONTENT'
|
38
|
+
::File.should_receive(:read).with('STORE/PATH/KEY').and_return 'CONTENT'.cachify
|
40
39
|
end
|
41
40
|
it "should return the file contents" do
|
42
41
|
subject.cached('API_CLASS', :cache_period => :monthly) { 'something' }.should == 'CONTENT'
|
43
42
|
end
|
43
|
+
it "should also return plain when asked to" do
|
44
|
+
subject.cached('API_CLASS', :cache_period => :monthly, :plain => true) { 'something' }.should == 'CONTENT'.cachify
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
46
48
|
context "when no file is cached yet" do
|
@@ -11,12 +11,7 @@ describe "Exchange::CacheDalli::Client" do
|
|
11
11
|
}
|
12
12
|
end
|
13
13
|
after(:each) do
|
14
|
-
Exchange.configuration
|
15
|
-
c.cache = {
|
16
|
-
:host => 'localhost',
|
17
|
-
:port => 11211
|
18
|
-
}
|
19
|
-
}
|
14
|
+
Exchange.configuration.reset
|
20
15
|
end
|
21
16
|
describe "client" do
|
22
17
|
let(:client) { mock('memcached') }
|
@@ -43,10 +38,10 @@ describe "Exchange::CacheDalli::Client" do
|
|
43
38
|
lambda { subject.cached('API_CLASS') }.should raise_error(Exchange::Cache::CachingWithoutBlockError)
|
44
39
|
end
|
45
40
|
context "when a cached result exists" do
|
46
|
-
context "when loading
|
41
|
+
context "when loading" do
|
47
42
|
before(:each) do
|
48
43
|
subject.should_receive(:key).with('API_CLASS', {}).and_return('KEY')
|
49
|
-
client.should_receive(:get).with('KEY').and_return
|
44
|
+
client.should_receive(:get).with('KEY').and_return({'RESULT' => 'YAY'}.cachify)
|
50
45
|
end
|
51
46
|
it "should return the JSON loaded result" do
|
52
47
|
subject.cached('API_CLASS') { 'something' }.should == {'RESULT' => 'YAY'}
|
@@ -57,12 +52,8 @@ describe "Exchange::CacheDalli::Client" do
|
|
57
52
|
subject.should_receive(:key).with('API_CLASS', {:plain => true}).and_return('KEY')
|
58
53
|
end
|
59
54
|
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 memcached 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"
|
55
|
+
client.should_receive(:get).with('KEY').and_return "122.0".cachify
|
56
|
+
subject.cached('API_CLASS', :plain => true) { 'something' }.should == "122.0".cachify
|
66
57
|
end
|
67
58
|
end
|
68
59
|
end
|
@@ -75,7 +66,7 @@ describe "Exchange::CacheDalli::Client" do
|
|
75
66
|
end
|
76
67
|
context "with daily cache" do
|
77
68
|
it "should call the block and set and return the result" do
|
78
|
-
client.should_receive(:set).with('KEY',
|
69
|
+
client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify, 86400).once
|
79
70
|
subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
80
71
|
end
|
81
72
|
end
|
@@ -87,7 +78,7 @@ describe "Exchange::CacheDalli::Client" do
|
|
87
78
|
Exchange.configuration.cache.expire = :daily
|
88
79
|
end
|
89
80
|
it "should call the block and set and return the result" do
|
90
|
-
client.should_receive(:set).with('KEY',
|
81
|
+
client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify, 3600).once
|
91
82
|
subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
92
83
|
end
|
93
84
|
end
|
@@ -99,7 +90,7 @@ describe "Exchange::CacheDalli::Client" do
|
|
99
90
|
end
|
100
91
|
context "with daily cache" do
|
101
92
|
it "should call the block and set and return the result" do
|
102
|
-
client.should_receive(:set).with('KEY',
|
93
|
+
client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify, 86400).once
|
103
94
|
subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
104
95
|
end
|
105
96
|
end
|
@@ -111,7 +102,7 @@ describe "Exchange::CacheDalli::Client" do
|
|
111
102
|
Exchange.configuration.cache.expire = :daily
|
112
103
|
end
|
113
104
|
it "should call the block and set and return the result" do
|
114
|
-
client.should_receive(:set).with('KEY',
|
105
|
+
client.should_receive(:set).with('KEY', {'RESULT' => 'YAY'}.cachify, 3600).once
|
115
106
|
subject.cached('API_CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
116
107
|
end
|
117
108
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Exchange::Cache::Memory" do
|
4
|
+
subject { Exchange::Cache::Memory.instance }
|
5
|
+
before(:each) do
|
6
|
+
Exchange.configuration = Exchange::Configuration.new { |c|
|
7
|
+
c.cache = { :subclass => :memory }
|
8
|
+
}
|
9
|
+
end
|
10
|
+
after(:each) do
|
11
|
+
Exchange.configuration.reset
|
12
|
+
end
|
13
|
+
describe "instance_variable_name" do
|
14
|
+
context "with a class" do
|
15
|
+
before(:each) do
|
16
|
+
@time = Time.gm(2012,10,10,12)
|
17
|
+
Time.stub! :now => @time
|
18
|
+
end
|
19
|
+
it "should yield a valid instance variable name" do
|
20
|
+
subject.send(:instance_variable_name, Exchange::ExternalAPI::Ecb, {}).should == '@exchange_externalapi_ecb_2012_284_2012_284'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
describe "clean_out_cache" do
|
25
|
+
before(:each) do
|
26
|
+
@time = Time.gm(2012,10,10,12)
|
27
|
+
Time.stub! :now => @time
|
28
|
+
subject.instance_variable_set '@exchange_externalapi_someapi_2011_284_2011_284_chfeur', 'Expired'
|
29
|
+
subject.instance_variable_set '@exchange_externalapi_someapi_2010_284_2012_284_chfeur', 'Valid1'
|
30
|
+
subject.instance_variable_set '@exchange_externalapi_ecb_2012_283_2011_283', 'Expired'
|
31
|
+
subject.instance_variable_set '@exchange_externalapi_ecb_2012_282_2012_284_chfusd', 'Valid2'
|
32
|
+
subject.instance_variable_set '@exchange_externalapi_currency_2012_284_11_2012_284_11', 'Expired'
|
33
|
+
subject.instance_variable_set '@exchange_externalapi_something_2012_284_12_2012_284_12', 'Valid3'
|
34
|
+
subject.instance_variable_set '@exchange_externalapi_something_2009_284_12_2012_284_12', 'Valid4'
|
35
|
+
subject.instance_variable_set '@exchange_externalapi_open_exchange_rates_2010_280_8_2012_284_8', 'Expired'
|
36
|
+
subject.instance_variable_set '@exchange_externalapi_xaviermedia_2012_84_12_2012_123_8', 'Expired'
|
37
|
+
end
|
38
|
+
it "should unset all expired instance variables" do
|
39
|
+
subject.send(:clean!)
|
40
|
+
subject.instance_variables.reject{|i| i.to_s == "@helper" }.map{|i| subject.instance_variable_get(i) }.compact.sort_by(&:to_s).should == %W(Valid1 Valid2 Valid3 Valid4).sort
|
41
|
+
end
|
42
|
+
end
|
43
|
+
describe "cached" do
|
44
|
+
it "should raise an error if no block was given" do
|
45
|
+
lambda { subject.cached('API_CLASS') }.should raise_error(Exchange::Cache::CachingWithoutBlockError)
|
46
|
+
end
|
47
|
+
context "when a cached result exists" do
|
48
|
+
context "when loading json" do
|
49
|
+
before(:each) do
|
50
|
+
subject.should_receive(:instance_variable_name).with('API::CLASS', {}).and_return('@KEY')
|
51
|
+
subject.should_receive(:instance_variable_get).with('@KEY').and_return('something')
|
52
|
+
end
|
53
|
+
it "should return the loaded result" do
|
54
|
+
subject.cached('API::CLASS') { 'something' }.should == 'something'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context "when loading plain" do
|
58
|
+
before(:each) do
|
59
|
+
subject.should_receive(:instance_variable_name).with('API::CLASS', {:plain => true}).and_return('@KEY')
|
60
|
+
end
|
61
|
+
it "should return a String result in the right format" do
|
62
|
+
subject.should_receive(:instance_variable_get).with('@KEY').and_return "0.122E3"
|
63
|
+
subject.cached('API::CLASS', :plain => true) { 'something' }.should == "0.122E3".cachify
|
64
|
+
end
|
65
|
+
it "should return a Hash result in the right format" do
|
66
|
+
subject.should_receive(:instance_variable_get).with('@KEY').and_return({'RESULT' => 'YAY'})
|
67
|
+
subject.cached('API::CLASS', :plain => true) { 'something' }.should == {'RESULT' => 'YAY'}.cachify
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
context "when no cached result exists" do
|
72
|
+
context "when returning nil" do
|
73
|
+
before(:each) do
|
74
|
+
subject.should_receive(:instance_variable_name).with('API::CLASS', {}).once.and_return('@KEY')
|
75
|
+
subject.should_receive(:instance_variable_get).with('@KEY').and_return(nil)
|
76
|
+
end
|
77
|
+
context "with daily cache" do
|
78
|
+
it "should call the block and set and return the result" do
|
79
|
+
subject.should_receive(:instance_variable_set).with('@KEY', {'RESULT' => 'YAY'}).once
|
80
|
+
subject.cached('API::CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
context "with hourly cache" do
|
84
|
+
before(:each) do
|
85
|
+
Exchange.configuration.cache.expire = :hourly
|
86
|
+
end
|
87
|
+
after(:each) do
|
88
|
+
Exchange.configuration.cache.expire = :daily
|
89
|
+
end
|
90
|
+
it "should call the block and set and return the result" do
|
91
|
+
subject.should_receive(:instance_variable_set).with('@KEY', {'RESULT' => 'YAY'}).once
|
92
|
+
subject.cached('API::CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
context "when returning an empty string" do
|
97
|
+
before(:each) do
|
98
|
+
subject.should_receive(:instance_variable_name).with('API::CLASS', {}).once.and_return('@KEY')
|
99
|
+
subject.should_receive(:instance_variable_get).with('@KEY').and_return('')
|
100
|
+
end
|
101
|
+
context "with daily cache" do
|
102
|
+
it "should call the block and set and return the result" do
|
103
|
+
subject.should_receive(:instance_variable_set).with('@KEY', {'RESULT' => 'YAY'}).once
|
104
|
+
subject.cached('API::CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
context "with hourly cache" do
|
108
|
+
before(:each) do
|
109
|
+
Exchange.configuration.cache.expire = :hourly
|
110
|
+
end
|
111
|
+
after(:each) do
|
112
|
+
Exchange.configuration.cache.expire = :daily
|
113
|
+
end
|
114
|
+
it "should call the block and set and return the result" do
|
115
|
+
subject.should_receive(:instance_variable_set).with('@KEY', {'RESULT' => 'YAY'}).once
|
116
|
+
subject.cached('API::CLASS') { {'RESULT' => 'YAY'} }.should == {'RESULT' => 'YAY'}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -1,26 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "Exchange::Cache::
|
4
|
-
context "with rails defined" do
|
5
|
-
class ::Rails
|
6
|
-
end
|
7
|
-
end
|
3
|
+
describe "Exchange::Cache::NoCache" do
|
8
4
|
subject { Exchange::Cache::NoCache }
|
9
|
-
before(:
|
5
|
+
before(:all) do
|
10
6
|
Exchange.configuration = Exchange::Configuration.new { |c|
|
11
7
|
c.cache = {
|
12
|
-
:
|
8
|
+
:subclass => :no_cache
|
13
9
|
}
|
14
10
|
}
|
15
11
|
end
|
16
|
-
after(:
|
17
|
-
Exchange.configuration
|
18
|
-
c.cache = {
|
19
|
-
:class => :memcached,
|
20
|
-
:host => 'localhost',
|
21
|
-
:port => 11211
|
22
|
-
}
|
23
|
-
}
|
12
|
+
after(:all) do
|
13
|
+
Exchange.configuration.reset
|
24
14
|
end
|
25
15
|
describe "cached" do
|
26
16
|
it "should directly call the block" do
|
@@ -9,16 +9,12 @@ describe "Exchange::Cache::Rails" do
|
|
9
9
|
before(:each) do
|
10
10
|
Exchange.configuration = Exchange::Configuration.new { |c|
|
11
11
|
c.cache = {
|
12
|
-
:
|
12
|
+
:subclass => :rails
|
13
13
|
}
|
14
14
|
}
|
15
15
|
end
|
16
16
|
after(:each) do
|
17
|
-
Exchange.configuration
|
18
|
-
c.cache = {
|
19
|
-
:class => :memcached
|
20
|
-
}
|
21
|
-
}
|
17
|
+
Exchange.configuration.reset
|
22
18
|
end
|
23
19
|
describe "client" do
|
24
20
|
let(:client) { mock('rails_cache') }
|