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.
- 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') }
|