exchange 0.11.0 → 0.12.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/.travis.yml +1 -6
- data/README.rdoc +1 -1
- data/html.html +1 -0
- data/iso4217.yml +418 -256
- data/iso4217_country_map.yml +493 -0
- data/lib/exchange.rb +1 -1
- data/lib/exchange/base.rb +1 -1
- data/lib/exchange/cache/configuration.rb +32 -1
- data/lib/exchange/cache/memcached.rb +8 -0
- data/lib/exchange/cache/redis.rb +9 -1
- data/lib/exchange/configurable.rb +6 -1
- data/lib/exchange/core_extensions/float/error_safe.rb +1 -1
- data/lib/exchange/core_extensions/numeric/conversability.rb +1 -5
- data/lib/exchange/{iso_4217.rb → iso.rb} +71 -30
- data/lib/exchange/money.rb +12 -7
- data/lib/exchange/typecasting.rb +5 -5
- data/spec/exchange/cache/configuration_spec.rb +38 -0
- data/spec/exchange/cache/memcached_spec.rb +10 -0
- data/spec/exchange/core_extensions/numeric/conversability_spec.rb +3 -3
- data/spec/exchange/iso_spec.rb +795 -0
- data/spec/exchange/money_spec.rb +32 -13
- metadata +77 -93
- data/spec/exchange/iso_4217_spec.rb +0 -233
data/lib/exchange.rb
CHANGED
data/lib/exchange/base.rb
CHANGED
@@ -8,8 +8,33 @@ module Exchange
|
|
8
8
|
#
|
9
9
|
class Configuration < Exchange::Configurable
|
10
10
|
attr_accessor :expire, :host, :port, :path
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def wipe_client_before_setting *setters
|
15
|
+
|
16
|
+
setters.each do |setter|
|
17
|
+
define_method :"#{setter}_with_client_wipe=" do |data|
|
18
|
+
wipe_subclass_client!
|
19
|
+
send(:"#{setter}_without_client_wipe=", data)
|
20
|
+
end
|
21
|
+
alias_method :"#{setter}_without_client_wipe=", :"#{setter}="
|
22
|
+
alias_method :"#{setter}=", :"#{setter}_with_client_wipe="
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
11
28
|
|
12
29
|
def_delegators :instance, :expire, :expire=, :host, :host=, :port, :port=, :path, :path=
|
30
|
+
wipe_client_before_setting :host, :port
|
31
|
+
|
32
|
+
# Overrides the parent class method to wipe the client before setting
|
33
|
+
#
|
34
|
+
def set hash
|
35
|
+
wipe_subclass_client!
|
36
|
+
super
|
37
|
+
end
|
13
38
|
|
14
39
|
def parent_module
|
15
40
|
Cache
|
@@ -18,7 +43,13 @@ module Exchange
|
|
18
43
|
def key
|
19
44
|
:cache
|
20
45
|
end
|
21
|
-
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def wipe_subclass_client!
|
50
|
+
subclass.wipe_client! if subclass && subclass.respond_to?(:wipe_client!)
|
51
|
+
end
|
52
|
+
|
22
53
|
end
|
23
54
|
end
|
24
55
|
end
|
@@ -14,6 +14,8 @@ module Exchange
|
|
14
14
|
#
|
15
15
|
class Memcached < Base
|
16
16
|
|
17
|
+
def_delegators :instance, :client, :wipe_client!
|
18
|
+
|
17
19
|
# instantiates a memcached client and memoizes it in a class variable.
|
18
20
|
# Use this client to access memcached data. For further explanation of use visit the memcached gem documentation
|
19
21
|
# @example
|
@@ -25,6 +27,12 @@ module Exchange
|
|
25
27
|
@client ||= Dalli::Client.new("#{config.host}:#{config.port}")
|
26
28
|
end
|
27
29
|
|
30
|
+
# Wipe the client instance variable
|
31
|
+
#
|
32
|
+
def wipe_client!
|
33
|
+
@client = nil
|
34
|
+
end
|
35
|
+
|
28
36
|
# returns either cached data from the memcached client or calls the block and caches it in memcached.
|
29
37
|
# This method has to be the same in all the cache classes in order for the configuration binding to work
|
30
38
|
# @param [Exchange::ExternalAPI::Subclass] api The API class the data has to be stored for
|
data/lib/exchange/cache/redis.rb
CHANGED
@@ -12,7 +12,9 @@ module Exchange
|
|
12
12
|
# c.cache_port = 'Your redis port (an Integer)'
|
13
13
|
# end
|
14
14
|
class Redis < Base
|
15
|
-
|
15
|
+
|
16
|
+
def_delegators :instance, :client, :wipe_client!
|
17
|
+
|
16
18
|
# instantiates a redis client and memoizes it in a class variable.
|
17
19
|
# Use this client to access redis data. For further explanation of use visit the redis gem documentation
|
18
20
|
# @example
|
@@ -24,6 +26,12 @@ module Exchange
|
|
24
26
|
@client ||= ::Redis.new(:host => config.host, :port => config.port)
|
25
27
|
end
|
26
28
|
|
29
|
+
# Wipe the client instance variable
|
30
|
+
#
|
31
|
+
def wipe_client!
|
32
|
+
@client = nil
|
33
|
+
end
|
34
|
+
|
27
35
|
# returns either cached data from the redis client or calls the block and caches it in redis.
|
28
36
|
# This method has to be the same in all the cache classes in order for the configuration binding to work
|
29
37
|
# @param [Exchange::ExternalAPI::Subclass] api The API class the data has to be stored for
|
@@ -12,12 +12,15 @@ module Exchange
|
|
12
12
|
def_delegators :instance, :subclass, :subclass=, :set
|
13
13
|
|
14
14
|
def subclass_with_constantize
|
15
|
-
self.subclass = parent_module.const_get camelize(self.subclass_without_constantize) unless self.subclass_without_constantize.is_a?(Class)
|
15
|
+
self.subclass = parent_module.const_get camelize(self.subclass_without_constantize) unless !self.subclass_without_constantize || self.subclass_without_constantize.is_a?(Class)
|
16
16
|
subclass_without_constantize
|
17
17
|
end
|
18
18
|
alias_method :subclass_without_constantize, :subclass
|
19
19
|
alias_method :subclass, :subclass_with_constantize
|
20
20
|
|
21
|
+
# Set a configuration via a hash of options
|
22
|
+
# @params [Hash] hash The hash of options to set the configuration to
|
23
|
+
#
|
21
24
|
def set hash
|
22
25
|
hash.each_pair do |k,v|
|
23
26
|
self.send(:"#{k}=", v)
|
@@ -26,6 +29,8 @@ module Exchange
|
|
26
29
|
self
|
27
30
|
end
|
28
31
|
|
32
|
+
# Reset the configuration to a set of defaults
|
33
|
+
#
|
29
34
|
def reset
|
30
35
|
set Exchange::Configuration::DEFAULTS[key]
|
31
36
|
end
|
@@ -19,7 +19,7 @@ module Exchange
|
|
19
19
|
def self.prevent_errors_with_exchange_for base, meth
|
20
20
|
base.send(:define_method, :"#{meth}without_errors", lambda { |other|
|
21
21
|
if other.is_a?(Exchange::Money)
|
22
|
-
BigDecimal.new(self.to_s).send(meth, other).to_f
|
22
|
+
BigDecimal.new(self.to_s).send(meth, other.value).to_f
|
23
23
|
else
|
24
24
|
send(:"#{meth}with_errors", other)
|
25
25
|
end
|
@@ -29,11 +29,7 @@ module Exchange
|
|
29
29
|
# @version 0.10
|
30
30
|
#
|
31
31
|
def in currency, options={}
|
32
|
-
|
33
|
-
Money.new(self, currency, options)
|
34
|
-
else
|
35
|
-
raise Exchange::NoCurrencyError.new("#{currency} is not a currency")
|
36
|
-
end
|
32
|
+
Money.new(self, currency, options)
|
37
33
|
end
|
38
34
|
end
|
39
35
|
end
|
@@ -10,7 +10,7 @@ module Exchange
|
|
10
10
|
# @since 0.3
|
11
11
|
# @author Beat Richartz
|
12
12
|
#
|
13
|
-
class
|
13
|
+
class ISO
|
14
14
|
include Singleton
|
15
15
|
extend SingleForwardable
|
16
16
|
|
@@ -24,38 +24,34 @@ module Exchange
|
|
24
24
|
self.class_eval <<-EOV
|
25
25
|
def #{op}(amount, currency, precision=nil)
|
26
26
|
minor = definitions[currency][:minor_unit]
|
27
|
-
(amount.is_a?(BigDecimal) ? amount : BigDecimal.new(amount.to_s,
|
27
|
+
(amount.is_a?(BigDecimal) ? amount : BigDecimal.new(amount.to_s, precision_for(amount, currency))).#{op}(precision || minor)
|
28
28
|
end
|
29
29
|
EOV
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
33
33
|
|
34
|
-
# The ISO 4217 that have to be loaded.
|
34
|
+
# The ISO 4217 that have to be loaded. Use this method to get to the definitions
|
35
35
|
# They are static, so they can be stored in a class variable without many worries
|
36
|
-
# @return [Hash] The
|
36
|
+
# @return [Hash] The iso4217 Definitions with the currency code as keys
|
37
37
|
#
|
38
38
|
def definitions
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@definitions[k.downcase.to_sym] = v
|
49
|
-
end
|
50
|
-
|
51
|
-
@definitions
|
39
|
+
@definitions ||= symbolize_keys(YAML.load_file(File.join(ROOT_PATH, 'iso4217.yml')))
|
40
|
+
end
|
41
|
+
|
42
|
+
# A map of country abbreviations to currency codes. Makes an instantiation of currency codes via a country code
|
43
|
+
# possible
|
44
|
+
# @return [Hash] The ISO3166 (1 and 2) country codes matched to a currency
|
45
|
+
#
|
46
|
+
def country_map
|
47
|
+
@country_map ||= symbolize_keys(YAML.load_file(File.join(ROOT_PATH, 'iso4217_country_map.yml')))
|
52
48
|
end
|
53
49
|
|
54
50
|
# All currencies defined by ISO 4217 as an array of symbols for inclusion testing
|
55
51
|
# @return [Array] An Array of currency symbols
|
56
52
|
#
|
57
53
|
def currencies
|
58
|
-
@currencies ||= definitions.keys.
|
54
|
+
@currencies ||= definitions.keys.sort_by(&:to_s)
|
59
55
|
end
|
60
56
|
|
61
57
|
# Check if a currency is defined by ISO 4217 standards
|
@@ -63,7 +59,15 @@ module Exchange
|
|
63
59
|
# @return [Boolean] true if the symbol matches a currency, false if not
|
64
60
|
#
|
65
61
|
def defines? currency
|
66
|
-
currencies.include? currency
|
62
|
+
currencies.include?(country_map[currency] ? country_map[currency] : currency)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Asserts a given argument is a currency. Tries to match with a country code if the argument is not a currency
|
66
|
+
# @param [Symbol, String] arg The argument to assert
|
67
|
+
# @return [Symbol] The matching currency as a symbol
|
68
|
+
#
|
69
|
+
def assert_currency! arg
|
70
|
+
defines?(arg) ? (country_map[arg] || arg) : raise(Exchange::NoCurrencyError.new("#{arg} is not a currency nor a country code matchable to a currency"))
|
67
71
|
end
|
68
72
|
|
69
73
|
# Use this to instantiate a currency amount. For one, it is important that we use BigDecimal here so nothing gets lost because
|
@@ -72,10 +76,15 @@ module Exchange
|
|
72
76
|
# @param [String, Symbol] currency The currency you want to instantiate the money in
|
73
77
|
# @return [BigDecimal] The instantiated currency
|
74
78
|
# @example instantiate a currency from a string
|
75
|
-
# Exchange::
|
79
|
+
# Exchange::ISO.instantiate("4523", "usd") #=> #<Bigdecimal 4523.00>
|
80
|
+
# @note Reinstantiation is not needed in case the amount is already a big decimal. In this case, the maximum precision is already given.
|
76
81
|
#
|
77
82
|
def instantiate(amount, currency)
|
78
|
-
|
83
|
+
if amount.is_a?(BigDecimal)
|
84
|
+
amount
|
85
|
+
else
|
86
|
+
BigDecimal.new(amount.to_s, precision_for(amount, currency))
|
87
|
+
end
|
79
88
|
end
|
80
89
|
|
81
90
|
# Converts the currency to a string in ISO 4217 standardized format, either with or without the currency. This leaves you
|
@@ -86,17 +95,18 @@ module Exchange
|
|
86
95
|
# @option opts [Boolean] :amount_only Whether you want to have the currency in the string or not
|
87
96
|
# @return [String] The formatted string
|
88
97
|
# @example Convert a currency to a string
|
89
|
-
# Exchange::
|
98
|
+
# Exchange::ISO.stringify(49.567, :usd) #=> "USD 49.57"
|
90
99
|
# @example Convert a currency without minor to a string
|
91
|
-
# Exchange::
|
100
|
+
# Exchange::ISO.stringif(45, :jpy) #=> "JPY 45"
|
92
101
|
# @example Convert a currency with a three decimal minor to a string
|
93
|
-
# Exchange::
|
102
|
+
# Exchange::ISO.stringif(34.34, :omr) #=> "OMR 34.340"
|
94
103
|
# @example Convert a currency to a string without the currency
|
95
|
-
# Exchange::
|
104
|
+
# Exchange::ISO.stringif(34.34, :omr, :amount_only => true) #=> "34.340"
|
96
105
|
#
|
97
106
|
def stringify(amount, currency, opts={})
|
98
107
|
format = "%.#{definitions[currency][:minor_unit]}f"
|
99
|
-
|
108
|
+
pre = [opts[:amount_only] && '', opts[:symbol] && (definitions[currency][:symbol] || currency.to_s.upcase), currency.to_s.upcase + ' '].detect{|a| a.is_a?(String)}
|
109
|
+
"#{pre}#{format % amount}"
|
100
110
|
end
|
101
111
|
|
102
112
|
# Use this to round a currency amount. This allows us to round exactly to the number of minors the currency has in the
|
@@ -104,7 +114,7 @@ module Exchange
|
|
104
114
|
# @param [BigDecimal, Fixed, Float, String] amount The amount of money you want to round
|
105
115
|
# @param [String, Symbol] currency The currency you want to round the money in
|
106
116
|
# @example Round a currency with 2 minors
|
107
|
-
# Exchange::
|
117
|
+
# Exchange::ISO.round("4523.456", "usd") #=> #<Bigdecimal 4523.46>
|
108
118
|
|
109
119
|
install_operation :round
|
110
120
|
|
@@ -113,7 +123,7 @@ module Exchange
|
|
113
123
|
# @param [BigDecimal, Fixed, Float, String] amount The amount of money you want to ceil
|
114
124
|
# @param [String, Symbol] currency The currency you want to ceil the money in
|
115
125
|
# @example Ceil a currency with 2 minors
|
116
|
-
# Exchange::
|
126
|
+
# Exchange::ISO.ceil("4523.456", "usd") #=> #<Bigdecimal 4523.46>
|
117
127
|
|
118
128
|
install_operation :ceil
|
119
129
|
|
@@ -122,13 +132,44 @@ module Exchange
|
|
122
132
|
# @param [BigDecimal, Fixed, Float, String] amount The amount of money you want to floor
|
123
133
|
# @param [String, Symbol] currency The currency you want to floor the money in
|
124
134
|
# @example Floor a currency with 2 minors
|
125
|
-
# Exchange::
|
135
|
+
# Exchange::ISO.floor("4523.456", "usd") #=> #<Bigdecimal 4523.46>
|
126
136
|
|
127
137
|
install_operation :floor
|
128
138
|
|
129
139
|
# Forwards the assure_time method to the instance using singleforwardable
|
130
140
|
#
|
131
|
-
def_delegators :instance, :definitions, :instantiate, :stringify, :round, :ceil, :floor, :currencies, :defines
|
141
|
+
def_delegators :instance, :definitions, :instantiate, :stringify, :round, :ceil, :floor, :currencies, :country_map, :defines?, :assert_currency!
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
# symbolizes keys and returns a new hash
|
146
|
+
#
|
147
|
+
def symbolize_keys hsh
|
148
|
+
new_hsh = Hash.new
|
149
|
+
|
150
|
+
hsh.each_pair do |k,v|
|
151
|
+
if v.is_a?(Hash)
|
152
|
+
v.keys.each do |key|
|
153
|
+
v[key.to_sym] = v.delete(key)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
new_hsh[k.downcase.to_sym] = v
|
158
|
+
end
|
159
|
+
|
160
|
+
new_hsh
|
161
|
+
end
|
162
|
+
|
163
|
+
# get a precision for a specified amount and a specified currency
|
164
|
+
# @params [Float, Integer] amount The amount to get the precision for
|
165
|
+
# @params [Symbol] currency the currency to get the precision for
|
166
|
+
#
|
167
|
+
def precision_for amount, currency
|
168
|
+
defined_minor_precision = definitions[currency][:minor_unit]
|
169
|
+
given_major_precision, given_minor_precision = amount.to_s.match(/^-?(\d*)\.?(\d*)$/).to_a[1..2].map(&:size)
|
170
|
+
|
171
|
+
given_major_precision + [defined_minor_precision, given_minor_precision].max
|
172
|
+
end
|
132
173
|
|
133
174
|
end
|
134
175
|
end
|
data/lib/exchange/money.rb
CHANGED
@@ -48,14 +48,16 @@ module Exchange
|
|
48
48
|
# Exchange::Money.new(40, :usd).to(:eur, :at => Time.gm(2012,9,1))
|
49
49
|
# #=> #<Exchange::Money @number=37.0 @currency=:usd @time=#<Time> @from=#<Exchange::Money @number=40.0 @currency=:usd>>
|
50
50
|
#
|
51
|
-
def initialize value, currency_arg=nil, opts={}, &block
|
51
|
+
def initialize value, currency_arg=nil, opts={}, &block
|
52
|
+
currency_arg = ISO.assert_currency!(currency_arg) if currency_arg
|
53
|
+
|
52
54
|
@from = opts[:from]
|
53
55
|
@api = Exchange.configuration.api.subclass
|
54
56
|
|
55
57
|
yield(self) if block_given?
|
56
58
|
|
57
59
|
self.time = Helper.assure_time(time || opts[:at], :default => :now)
|
58
|
-
self.value =
|
60
|
+
self.value = ISO.instantiate(value, currency || currency_arg)
|
59
61
|
self.currency = currency || currency_arg
|
60
62
|
end
|
61
63
|
|
@@ -81,6 +83,8 @@ module Exchange
|
|
81
83
|
# Exchange::Money.new(40,:nok).to(:sek, :at => Time.gm(2012,2,2))
|
82
84
|
#
|
83
85
|
def to other, options={}
|
86
|
+
other = ISO.assert_currency!(other)
|
87
|
+
|
84
88
|
if api_supports_currency?(other)
|
85
89
|
opts = { :at => time, :from => self }.merge(options)
|
86
90
|
Money.new(api.new.convert(value, currency, other, opts), other, opts)
|
@@ -88,6 +92,7 @@ module Exchange
|
|
88
92
|
raise_no_rate_error(other)
|
89
93
|
end
|
90
94
|
end
|
95
|
+
alias :in :to
|
91
96
|
|
92
97
|
class << self
|
93
98
|
|
@@ -98,7 +103,7 @@ module Exchange
|
|
98
103
|
#
|
99
104
|
def install_operation op
|
100
105
|
define_method op do |*precision|
|
101
|
-
Exchange::Money.new(
|
106
|
+
Exchange::Money.new(ISO.send(op, self.value, self.currency, precision.first), currency, :at => time, :from => self)
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
@@ -110,7 +115,7 @@ module Exchange
|
|
110
115
|
self.class_eval <<-EOV
|
111
116
|
def #{op}(other)
|
112
117
|
test_for_currency_mix_error(other)
|
113
|
-
new_value = value #{op} (other.kind_of?(Money) ? other.to(self.currency, :at => other.time) : BigDecimal.new(other.to_s))
|
118
|
+
new_value = value #{op} (other.kind_of?(Money) ? other.to(self.currency, :at => other.time).value : BigDecimal.new(other.to_s))
|
114
119
|
Exchange::Money.new(new_value, currency, :at => time, :from => self)
|
115
120
|
end
|
116
121
|
EOV
|
@@ -292,12 +297,12 @@ module Exchange
|
|
292
297
|
# @example Convert a currency with a three decimal minor to a string
|
293
298
|
# Exchange::Money.new(34.34, :omr).to_s #=> "OMR 34.340"
|
294
299
|
# @example Convert a currency to a string without the currency
|
295
|
-
# Exchange::
|
300
|
+
# Exchange::ISO.stringif(34.34, :omr).to_s(:iso) #=> "34.340"
|
296
301
|
#
|
297
302
|
def to_s format=:currency
|
298
303
|
[
|
299
|
-
format == :currency &&
|
300
|
-
format == :amount &&
|
304
|
+
format == :currency && ISO.stringify(value, currency),
|
305
|
+
format == :amount && ISO.stringify(value, currency, :amount_only => true)
|
301
306
|
].detect{|l| l.is_a?(String) }
|
302
307
|
end
|
303
308
|
|
data/lib/exchange/typecasting.rb
CHANGED
@@ -77,13 +77,13 @@ module Exchange
|
|
77
77
|
att = send(attribute)
|
78
78
|
attribute_setter = :"#{attribute}_without_exchange_typecasting="
|
79
79
|
|
80
|
-
if !data.respond_to?(:currency)
|
81
|
-
|
80
|
+
send(attribute_setter, if !data.respond_to?(:currency)
|
81
|
+
data
|
82
82
|
elsif att.currency == data.currency
|
83
|
-
|
83
|
+
data.value
|
84
84
|
elsif att.currency != data.currency
|
85
|
-
|
86
|
-
end
|
85
|
+
data.to(att.currency).value
|
86
|
+
end)
|
87
87
|
end
|
88
88
|
exchange_typecasting_alias_method_chain attribute, '='
|
89
89
|
end
|
@@ -39,6 +39,44 @@ describe "Exchange::Cache::Configuration" do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
describe "setting and wiping the client" do
|
43
|
+
context "with a wipeable client" do
|
44
|
+
before(:each) do
|
45
|
+
subject.subclass = :memcached
|
46
|
+
subject.host = '127.0.0.1'
|
47
|
+
subject.port = 11211
|
48
|
+
end
|
49
|
+
after(:each) do
|
50
|
+
subject.subclass = :no_cache
|
51
|
+
end
|
52
|
+
it "should do so for the host" do
|
53
|
+
subject.subclass.client.should_not be_nil
|
54
|
+
subject.subclass.instance.instance_variable_get("@client").should_not be_nil
|
55
|
+
subject.host = 'new'
|
56
|
+
subject.subclass.instance.instance_variable_get("@client").should be_nil
|
57
|
+
end
|
58
|
+
it "should do so for the port" do
|
59
|
+
subject.subclass.client.should_not be_nil
|
60
|
+
subject.subclass.instance.instance_variable_get("@client").should_not be_nil
|
61
|
+
subject.port = 112
|
62
|
+
subject.subclass.instance.instance_variable_get("@client").should be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
context "without a wipeable client" do
|
66
|
+
before(:each) do
|
67
|
+
subject.subclass = :memory
|
68
|
+
end
|
69
|
+
it "should not fail for the host" do
|
70
|
+
subject.host = 'new'
|
71
|
+
subject.host.should == 'new'
|
72
|
+
end
|
73
|
+
it "should not fail for the port" do
|
74
|
+
subject.port = 11
|
75
|
+
subject.port.should == 11
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
42
80
|
describe "reset" do
|
43
81
|
before(:each) do
|
44
82
|
subject.set :subclass => :no_cache, :expire => :daily, :host => 'localhost', :port => 112211, :path => "PATH"
|