cachy 0.3.1 → 0.4.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/lib/cachy.rb +2 -2
- data/lib/cachy/memcached_wrapper.rb +4 -0
- data/lib/cachy/version.rb +1 -1
- metadata +37 -40
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -5
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -30
- data/Rakefile +0 -7
- data/Readme.md +0 -124
- data/cachy.gemspec +0 -13
- data/spec/cachy/memcache_timeout_protection_spec.rb +0 -50
- data/spec/cachy/memcached_wrapper_spec.rb +0 -37
- data/spec/cachy/moneta_wrapper_spec.rb +0 -59
- data/spec/cachy/redis_wrapper_spec.rb +0 -69
- data/spec/cachy_spec.rb +0 -405
- data/spec/mem_cache.rb +0 -35
- data/spec/spec_helper.rb +0 -3
- data/spec/test_cache.rb +0 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d154547cc7dcbf3e251e975ec0ccfcc19edc41ff
|
4
|
+
data.tar.gz: 7f14b01d7247b0e8c32e06956673345eb614dea1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7d338aa171c655806b9030383c917e0a87c3b2ce88ad8c724663a69681af7cc30d103c08a7ecc099fcd6d83f74965b05a61b080883086bd2e77a58646780b5e
|
7
|
+
data.tar.gz: 32ffcf0aa8176344a1c5fe3db890cbf01d83eea63a95e5f175ed6e15b9b726d1fc0d8a204a4d8cc29d74ebe5b6b44b42739f346d177895442d66e998ba30250b
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
Binary file
|
data/lib/cachy.rb
CHANGED
@@ -159,10 +159,10 @@ module Cachy
|
|
159
159
|
elsif cache.class.to_s == 'Redis'
|
160
160
|
require 'cachy/redis_wrapper'
|
161
161
|
RedisWrapper.new(cache)
|
162
|
-
elsif cache.respond_to?
|
162
|
+
elsif cache.respond_to? :get and cache.respond_to? :set
|
163
163
|
require 'cachy/memcached_wrapper'
|
164
164
|
MemcachedWrapper.new(cache)
|
165
|
-
elsif cache.respond_to?
|
165
|
+
elsif cache.respond_to? :[] and cache.respond_to? :store
|
166
166
|
require 'cachy/moneta_wrapper'
|
167
167
|
MonetaWrapper.new(cache)
|
168
168
|
else
|
data/lib/cachy/version.rb
CHANGED
metadata
CHANGED
@@ -1,44 +1,56 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cachy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.3.1
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Michael Grosser
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
|
14
|
+
YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
|
15
|
+
MB4XDTEzMDIwMzE4MTMxMVoXDTE0MDIwMzE4MTMxMVowPzEQMA4GA1UEAwwHbWlj
|
16
|
+
aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
|
17
|
+
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
|
18
|
+
MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
|
19
|
+
cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
|
20
|
+
6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
|
21
|
+
h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
|
22
|
+
FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
|
23
|
+
/88CAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUsiNnXHtKeMYYcr4yJVmQ
|
24
|
+
WONL+IwwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAlyN7kKo/NQCQ0
|
25
|
+
AOzZLZ3WAePvStkCFIJ53tsv5Kyo4pMAllv+BgPzzBt7qi605mFSL6zBd9uLou+W
|
26
|
+
Co3s48p1dy7CjjAfVQdmVNHF3MwXtfC2OEyvSQPi4xKR8iba8wa3xp9LVo1PuLpw
|
27
|
+
/6DsrChWw74HfsJN6qJOK684hJeT8lBYAUfiC3wD0owoPSg+XtyAAddisR+KV5Y1
|
28
|
+
NmVHuLtQcNTZy+gRht3ahJRMuC6QyLmkTsf+6MaenwAMkAgHdswGsJztOnNnBa3F
|
29
|
+
y0kCSWmK6D+x/SbfS6r7Ke07MRqziJdB9GuE1+0cIRuFh8EQ+LN6HXCKM5pon/GU
|
30
|
+
ycwMXfl0
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2013-09-09 00:00:00.000000000 Z
|
13
33
|
dependencies:
|
14
34
|
- !ruby/object:Gem::Dependency
|
15
|
-
|
35
|
+
name: mini_memory_store
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
16
37
|
requirements:
|
17
|
-
- -
|
38
|
+
- - '>='
|
18
39
|
- !ruby/object:Gem::Version
|
19
40
|
version: '0'
|
20
|
-
|
41
|
+
type: :runtime
|
21
42
|
prerelease: false
|
22
|
-
|
23
|
-
requirement: !ruby/object:Gem::Requirement
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
44
|
requirements:
|
25
|
-
- -
|
45
|
+
- - '>='
|
26
46
|
- !ruby/object:Gem::Version
|
27
47
|
version: '0'
|
28
|
-
none: false
|
29
|
-
type: :runtime
|
30
48
|
description:
|
31
49
|
email: michael@grosser.it
|
32
50
|
executables: []
|
33
51
|
extensions: []
|
34
52
|
extra_rdoc_files: []
|
35
53
|
files:
|
36
|
-
- .travis.yml
|
37
|
-
- Gemfile
|
38
|
-
- Gemfile.lock
|
39
|
-
- Rakefile
|
40
|
-
- Readme.md
|
41
|
-
- cachy.gemspec
|
42
54
|
- lib/cachy.rb
|
43
55
|
- lib/cachy/memcache_timeout_protection.rb
|
44
56
|
- lib/cachy/memcached_wrapper.rb
|
@@ -46,43 +58,28 @@ files:
|
|
46
58
|
- lib/cachy/redis_wrapper.rb
|
47
59
|
- lib/cachy/version.rb
|
48
60
|
- lib/cachy/wrapper.rb
|
49
|
-
|
50
|
-
- spec/cachy/memcached_wrapper_spec.rb
|
51
|
-
- spec/cachy/moneta_wrapper_spec.rb
|
52
|
-
- spec/cachy/redis_wrapper_spec.rb
|
53
|
-
- spec/cachy_spec.rb
|
54
|
-
- spec/mem_cache.rb
|
55
|
-
- spec/spec_helper.rb
|
56
|
-
- spec/test_cache.rb
|
57
|
-
homepage: http://github.com/grosser/cachy
|
61
|
+
homepage: https://github.com/grosser/cachy
|
58
62
|
licenses:
|
59
63
|
- MIT
|
64
|
+
metadata: {}
|
60
65
|
post_install_message:
|
61
66
|
rdoc_options: []
|
62
67
|
require_paths:
|
63
68
|
- lib
|
64
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
70
|
requirements:
|
66
|
-
- -
|
71
|
+
- - '>='
|
67
72
|
- !ruby/object:Gem::Version
|
68
73
|
version: '0'
|
69
|
-
segments:
|
70
|
-
- 0
|
71
|
-
hash: 966047757035435948
|
72
|
-
none: false
|
73
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
75
|
requirements:
|
75
|
-
- -
|
76
|
+
- - '>='
|
76
77
|
- !ruby/object:Gem::Version
|
77
78
|
version: '0'
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
hash: 966047757035435948
|
81
|
-
none: false
|
82
79
|
requirements: []
|
83
80
|
rubyforge_project:
|
84
|
-
rubygems_version:
|
81
|
+
rubygems_version: 2.0.6
|
85
82
|
signing_key:
|
86
|
-
specification_version:
|
87
|
-
summary:
|
83
|
+
specification_version: 4
|
84
|
+
summary: See which gems depend on your gems
|
88
85
|
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
cachy (0.3.1)
|
5
|
-
mini_memory_store
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: http://rubygems.org/
|
9
|
-
specs:
|
10
|
-
bump (0.3.8)
|
11
|
-
diff-lcs (1.1.3)
|
12
|
-
mini_memory_store (0.1.0)
|
13
|
-
rake (10.0.3)
|
14
|
-
rspec (2.12.0)
|
15
|
-
rspec-core (~> 2.12.0)
|
16
|
-
rspec-expectations (~> 2.12.0)
|
17
|
-
rspec-mocks (~> 2.12.0)
|
18
|
-
rspec-core (2.12.2)
|
19
|
-
rspec-expectations (2.12.1)
|
20
|
-
diff-lcs (~> 1.1.3)
|
21
|
-
rspec-mocks (2.12.1)
|
22
|
-
|
23
|
-
PLATFORMS
|
24
|
-
ruby
|
25
|
-
|
26
|
-
DEPENDENCIES
|
27
|
-
bump
|
28
|
-
cachy!
|
29
|
-
rake
|
30
|
-
rspec (~> 2)
|
data/Rakefile
DELETED
data/Readme.md
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
Caching library to simplify and organize caching.
|
2
|
-
|
3
|
-
- I18n (seperate caches by locale / expires all locales)
|
4
|
-
- Generation based (your able expire all caches of one type)
|
5
|
-
- Simultanouse caching (handle multiple processes trying to write same expensive cache at once)
|
6
|
-
- Dependent caches (x caches result of cache z+y -> z changes -> x changes)
|
7
|
-
- Hashed keys (optional -> short/unreadable)
|
8
|
-
- Global cache_version (expire everything Cachy cached, but not e.g. sessions)
|
9
|
-
- ...
|
10
|
-
- works out of the box with Rails
|
11
|
-
- works with pure Memcache, Redis and [Moneta](http://github.com/wycats/moneta/tree/master)(-> Tokyo Cabinet / CouchDB / S3 / Berkeley DB / DataMapper / Memory store)
|
12
|
-
|
13
|
-
Install
|
14
|
-
=======
|
15
|
-
As Gem: ` sudo gem install cachy `
|
16
|
-
Or as Rails plugin: ` script/plugins install git://github.com/grosser/cachy.git `
|
17
|
-
|
18
|
-
Usage
|
19
|
-
=====
|
20
|
-
###Cachy.cache
|
21
|
-
result = Cachy.cache(:a_key){ expensive() }
|
22
|
-
result = Cachy.cache(:a_key, :expires_in => 1.minute){ expensive() }
|
23
|
-
result = Cachy.cache(:a_key, 'something else', Date.today.day){ expensive() }
|
24
|
-
|
25
|
-
####Cache expensive operation that is run many times by many processes
|
26
|
-
Example: at application startup 20 processes try to set the same cache -> 20 heavy database requests -> database timeout -> cache still empty -> ... -> death
|
27
|
-
|
28
|
-
# 19 Processes get [], 1 makes the request -- when cached all get the same result
|
29
|
-
result = Cachy.cache(:a_key, :while_running=>[]){ block_db_for_5_seconds }
|
30
|
-
|
31
|
-
|
32
|
-
####Seperate version for each key
|
33
|
-
Expire all all caches of one kind when code inside the cache has been updated
|
34
|
-
|
35
|
-
100.times{ Cachy.cache(:a_key, rand(100000) ){ expensive() } }
|
36
|
-
Cachy.increment_key(:a_key) --> everything expired
|
37
|
-
|
38
|
-
|
39
|
-
####Uses I18n.locale if available
|
40
|
-
Cachy.cache(:a_key){ 'English' }
|
41
|
-
I18n.locale = :de
|
42
|
-
Cachy.cache(:a_key){ 'German' } != 'English'
|
43
|
-
|
44
|
-
####Explicitly not use I18n.locale
|
45
|
-
Cachy.cache(:a_key, :witout_locale=>true){ 'English' }
|
46
|
-
I18n.locale = :de
|
47
|
-
Cachy.cache(:a_key, :witout_locale=>true){ 'German' } == 'English'
|
48
|
-
|
49
|
-
####Caching results of other caches
|
50
|
-
When inner cache is expired outer cache would normally still shows old results.<br/>
|
51
|
-
--> expire outer cache when inner cache is expired.
|
52
|
-
|
53
|
-
a = Cachy.cache(:a, :expires_in=>1.day){ expensive() }
|
54
|
-
b = Cachy.cache(:b, :expires_in=>1.week){ expensive_2() }
|
55
|
-
Cachy.cache(:surrounding, :expires_in=>5.hours, :keys=>[:a, :b]){ a + b * c }
|
56
|
-
Cachy.increment_key(:b) --> expires :b and :surrounding
|
57
|
-
|
58
|
-
####Hashing keys
|
59
|
-
In case they get to long for your caching backend, makes them short but unreadable.
|
60
|
-
|
61
|
-
Cachy.hash_keys = true # global
|
62
|
-
Cachy.cache(:a_key, :hash_key=>true){ expensive } # per call
|
63
|
-
|
64
|
-
#### Uses .cache_key when available
|
65
|
-
E.g. ActiveRecord objects are stored in the key with their updated_at timestamp.<br/>
|
66
|
-
When they are updated the cache is automatically expired.
|
67
|
-
|
68
|
-
Cachy.cache(:my_key, User.first){ expensive }
|
69
|
-
|
70
|
-
#### Uses CACHE_VERSION if defined
|
71
|
-
Use a global `CACHE_VERSION=1` so that all caches can be expired when something big changes.
|
72
|
-
The cache server does not need to be restarted and session data(Rails) is saved.
|
73
|
-
|
74
|
-
#### Does not cache nil
|
75
|
-
If you want to cache a falsy result, use false (same goes for :while_running)
|
76
|
-
Cachy.cache(:x){ expensive || false }
|
77
|
-
Cachy.cache(:x, :while_running=>false){ expensive }
|
78
|
-
|
79
|
-
###Cachy.cache_if
|
80
|
-
Only caches if condition is fulfilled
|
81
|
-
Cachy.cache_if(condition, :foo, 'bar', :expires_in => 1.minute){do_something}
|
82
|
-
|
83
|
-
###Cachy.expire / .expire_view
|
84
|
-
Expires all locales of a key
|
85
|
-
Cachy.locales = [:de, :en] # by default filled with I18n.available_locales
|
86
|
-
Cachy.expire(:my_key) -> expires for :de, :en and no-locale
|
87
|
-
|
88
|
-
#expire "views/#{key}" (counterpart for Rails-view-caching)
|
89
|
-
Cachy.expire_view(:my_key)
|
90
|
-
Cachy.expire(:my_key, :prefix=>'views/')
|
91
|
-
|
92
|
-
###Cachy.key
|
93
|
-
Use to cache e.g. Erb output
|
94
|
-
<% cache Cachy.key(:a_key), :expires_in=>1.hour do %>
|
95
|
-
More html ...
|
96
|
-
<% end %>
|
97
|
-
|
98
|
-
###Cachy.cache_store
|
99
|
-
No ActionController::Base.cache_store ?<br/>
|
100
|
-
Give me something that responds to read/write(Rails style) or []/store([Moneta](http://github.com/wycats/moneta/tree/master)) or get/set(Memcached)
|
101
|
-
Cachy.cache_store = some_cache
|
102
|
-
|
103
|
-
###Cachy.locales
|
104
|
-
No I18n.available_locales ?
|
105
|
-
Cachy.locales = [:de, :en, :fr]
|
106
|
-
|
107
|
-
### Memcache timeout protection
|
108
|
-
If Memcache timeouts keep killing your pages -> [catch MemCache timeouts](http://github.com/grosser/cachy/blob/master/lib/cachy/memcache_timeout_protection)
|
109
|
-
|
110
|
-
TODO
|
111
|
-
====
|
112
|
-
- optionally store dependent keys (:keys=>xxx), so that they can be setup up once and do not need to be remembered
|
113
|
-
|
114
|
-
Authors
|
115
|
-
=======
|
116
|
-
|
117
|
-
###Contributors
|
118
|
-
- [mindreframer](http://www.simplewebapp.de/roman)
|
119
|
-
|
120
|
-
[Michael Grosser](http://grosser.it)<br/>
|
121
|
-
michael@grosser.it<br/>
|
122
|
-
License: MIT<br/>
|
123
|
-
[](http://travis-ci.org/grosser/cachy)
|
124
|
-
|
data/cachy.gemspec
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
2
|
-
name = "cachy"
|
3
|
-
require "#{name}/version"
|
4
|
-
|
5
|
-
Gem::Specification.new name, Cachy::VERSION do |s|
|
6
|
-
s.summary = "Caching library for projects that have many processes or many caches"
|
7
|
-
s.authors = ["Michael Grosser"]
|
8
|
-
s.email = "michael@grosser.it"
|
9
|
-
s.homepage = "http://github.com/grosser/#{name}"
|
10
|
-
s.files = `git ls-files`.split("\n")
|
11
|
-
s.license = "MIT"
|
12
|
-
s.add_runtime_dependency "mini_memory_store"
|
13
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require './spec/mem_cache'
|
3
|
-
require 'cachy/memcache_timeout_protection'
|
4
|
-
|
5
|
-
describe "MemCache timeout protection" do
|
6
|
-
before do
|
7
|
-
MemCache.read_error_callback = nil
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:cache){ MemCache.new }
|
11
|
-
|
12
|
-
def simulate_timeout
|
13
|
-
cache.stub!(:stubable_cache_get).and_raise('IO timeout')
|
14
|
-
end
|
15
|
-
|
16
|
-
it "has no errors by default" do
|
17
|
-
cache.read_error_occurred.should == nil
|
18
|
-
end
|
19
|
-
|
20
|
-
it "catches timeout errors" do
|
21
|
-
MemCache.read_error_callback = lambda{|x|}
|
22
|
-
simulate_timeout
|
23
|
-
cache.get('x').should == nil
|
24
|
-
cache.read_error_occurred.should == true
|
25
|
-
end
|
26
|
-
|
27
|
-
it "resets error_occurred to false after successful get" do
|
28
|
-
MemCache.read_error_callback = lambda{|x|}
|
29
|
-
simulate_timeout
|
30
|
-
cache.get('x').should == nil
|
31
|
-
cache.stub!(:stubable_cache_get).and_return 1
|
32
|
-
cache.get('x').should == 1
|
33
|
-
cache.read_error_occurred.should == false
|
34
|
-
end
|
35
|
-
|
36
|
-
it "raises if no callback is given" do
|
37
|
-
simulate_timeout
|
38
|
-
lambda{
|
39
|
-
cache.get('x').should == nil
|
40
|
-
}.should raise_error
|
41
|
-
cache.read_error_occurred.should == true
|
42
|
-
end
|
43
|
-
|
44
|
-
it "calls the callback" do
|
45
|
-
MemCache.read_error_callback = lambda{|x| 1 }
|
46
|
-
simulate_timeout
|
47
|
-
cache.get('x').should == 1
|
48
|
-
cache.read_error_occurred.should == true
|
49
|
-
end
|
50
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require './spec/mem_cache'
|
3
|
-
|
4
|
-
describe "Cachy::MemcachedWrapper" do
|
5
|
-
before :all do
|
6
|
-
@cache = MemCache.new
|
7
|
-
Cachy.cache_store = @cache
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
@cache.clear
|
12
|
-
end
|
13
|
-
|
14
|
-
it "is wrapped" do
|
15
|
-
Cachy.cache_store.class.should == Cachy::MemcachedWrapper
|
16
|
-
end
|
17
|
-
|
18
|
-
it "can cache" do
|
19
|
-
Cachy.cache(:x){ 'SUCCESS' }
|
20
|
-
Cachy.cache(:x){ 'FAIL' }.should == 'SUCCESS'
|
21
|
-
end
|
22
|
-
|
23
|
-
it "can cache without expires" do
|
24
|
-
@cache.should_receive(:set).with('x_v1', 'SUCCESS', 0)
|
25
|
-
Cachy.cache(:x){ 'SUCCESS' }
|
26
|
-
end
|
27
|
-
|
28
|
-
it "can cache with expires" do
|
29
|
-
@cache.should_receive(:set).with('x_v1', 'SUCCESS', 1)
|
30
|
-
Cachy.cache(:x, :expires_in=>1){ 'SUCCESS' }
|
31
|
-
end
|
32
|
-
|
33
|
-
it "can expire" do
|
34
|
-
@cache.should_receive(:delete).with('x_v1')
|
35
|
-
Cachy.expire(:x)
|
36
|
-
end
|
37
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class TestMoneta
|
4
|
-
def initialize
|
5
|
-
@wrapped = {}
|
6
|
-
end
|
7
|
-
|
8
|
-
def store(key, object, options={})
|
9
|
-
raise 'nope!' if options[:expires_in] and not options[:expires_in].is_a? Numeric
|
10
|
-
@wrapped[key] = object
|
11
|
-
end
|
12
|
-
|
13
|
-
def [](x)
|
14
|
-
@wrapped[x]
|
15
|
-
end
|
16
|
-
|
17
|
-
def clear
|
18
|
-
@wrapped.clear
|
19
|
-
end
|
20
|
-
|
21
|
-
def delete(key)
|
22
|
-
@wrapped.delete(key)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "Cachy::MonetaWrapper" do
|
27
|
-
before :all do
|
28
|
-
@cache = TestMoneta.new
|
29
|
-
Cachy.cache_store = @cache
|
30
|
-
end
|
31
|
-
|
32
|
-
before do
|
33
|
-
@cache.clear
|
34
|
-
end
|
35
|
-
|
36
|
-
it "is wrapped" do
|
37
|
-
Cachy.cache_store.class.should == Cachy::MonetaWrapper
|
38
|
-
end
|
39
|
-
|
40
|
-
it "can cache" do
|
41
|
-
Cachy.cache(:x){ 'SUCCESS' }
|
42
|
-
Cachy.cache(:x){ 'FAIL' }.should == 'SUCCESS'
|
43
|
-
end
|
44
|
-
|
45
|
-
it "can cache without expires" do
|
46
|
-
@cache.should_receive(:store).with('x_v1', 'SUCCESS', {})
|
47
|
-
Cachy.cache(:x){ 'SUCCESS' }
|
48
|
-
end
|
49
|
-
|
50
|
-
it "can cache with expires" do
|
51
|
-
@cache.should_receive(:store).with('x_v1', 'SUCCESS', :expires_in=>1)
|
52
|
-
Cachy.cache(:x, :expires_in=>1){ 'SUCCESS' }
|
53
|
-
end
|
54
|
-
|
55
|
-
it "can expire" do
|
56
|
-
@cache.should_receive(:delete).with('x_v1')
|
57
|
-
Cachy.expire(:x)
|
58
|
-
end
|
59
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class TestRedis
|
4
|
-
def self.to_s
|
5
|
-
'Redis'
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@wrapped = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def set(key, object)
|
13
|
-
@wrapped[key] = object
|
14
|
-
end
|
15
|
-
|
16
|
-
def expire(key, seconds)
|
17
|
-
end
|
18
|
-
|
19
|
-
def [](x)
|
20
|
-
@wrapped[x]
|
21
|
-
end
|
22
|
-
|
23
|
-
def clear
|
24
|
-
@wrapped.clear
|
25
|
-
end
|
26
|
-
|
27
|
-
def del(key)
|
28
|
-
@wrapped.delete(key)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "Cachy::RedisWrapper" do
|
33
|
-
let(:yaml_ending) { RUBY_VERSION > '1.9' ? "\n...\n" : "\n" }
|
34
|
-
|
35
|
-
before :all do
|
36
|
-
@cache = TestRedis.new
|
37
|
-
Cachy.cache_store = @cache
|
38
|
-
end
|
39
|
-
|
40
|
-
before do
|
41
|
-
@cache.clear
|
42
|
-
end
|
43
|
-
|
44
|
-
it "is wrapped" do
|
45
|
-
Cachy.cache_store.class.should == Cachy::RedisWrapper
|
46
|
-
end
|
47
|
-
|
48
|
-
it "can cache" do
|
49
|
-
Cachy.cache(:x){ 'SUCCESS' }
|
50
|
-
Cachy.cache(:x){ 'FAIL' }.should == 'SUCCESS'
|
51
|
-
end
|
52
|
-
|
53
|
-
it "can cache without expires" do
|
54
|
-
@cache.should_receive(:set).with('x_v1', "--- SUCCESS#{yaml_ending}")
|
55
|
-
@cache.should_not_receive(:expire)
|
56
|
-
Cachy.cache(:x){ 'SUCCESS' }.should == 'SUCCESS'
|
57
|
-
end
|
58
|
-
|
59
|
-
it "can cache with expires" do
|
60
|
-
@cache.should_receive(:set).with('x_v1', "--- SUCCESS#{yaml_ending}")
|
61
|
-
@cache.should_receive(:expire).with('x_v1', 1)
|
62
|
-
Cachy.cache(:x, :expires_in=>1){ 'SUCCESS' }.should == 'SUCCESS'
|
63
|
-
end
|
64
|
-
|
65
|
-
it "can expire" do
|
66
|
-
@cache.should_receive(:del).with('x_v1')
|
67
|
-
Cachy.expire(:x)
|
68
|
-
end
|
69
|
-
end
|
data/spec/cachy_spec.rb
DELETED
@@ -1,405 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Cachy do
|
4
|
-
|
5
|
-
def reset_cachy!
|
6
|
-
Cachy.prefix = nil
|
7
|
-
Cachy.hash_keys = false
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
@cache = TestCache.new
|
12
|
-
Cachy.cache_store = @cache
|
13
|
-
@cache.write(Cachy::HEALTH_CHECK_KEY, 'yes')
|
14
|
-
Cachy.send(:class_variable_set, '@@cache_error', false)
|
15
|
-
Cachy.send(:memory_store).clear
|
16
|
-
end
|
17
|
-
|
18
|
-
after do
|
19
|
-
reset_cachy!
|
20
|
-
end
|
21
|
-
|
22
|
-
describe :cache do
|
23
|
-
it "caches" do
|
24
|
-
Cachy.cache(:my_key){ "X" }.should == "X"
|
25
|
-
Cachy.cache(:my_key){ "ABC" }.should == "X"
|
26
|
-
end
|
27
|
-
|
28
|
-
it "expires" do
|
29
|
-
Cachy.cache(:his_key, :expires_in=> -100){ 'X' }.should == 'X'
|
30
|
-
Cachy.cache(:his_key, :expires_in=> -100){ 'X' }.should == 'X'
|
31
|
-
end
|
32
|
-
|
33
|
-
it "sets cache to intermediate value while running expensive query" do
|
34
|
-
Cachy.cache(:my_key, :while_running=>'A') do
|
35
|
-
Cachy.cache(:my_key){ 'X' }.should == 'A'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it "can set while_running to false" do
|
40
|
-
Cachy.cache(:my_key, :while_running=>false) do
|
41
|
-
Cachy.cache(:my_key){ 'X' }.should == false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it "can not set while_running to nil" do
|
46
|
-
Cachy.should_receive(:warn)
|
47
|
-
Cachy.cache(:my_key, :while_running=>nil) do
|
48
|
-
Cachy.cache(:my_key){ 'X' }.should == "X"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
it "can cache false" do
|
53
|
-
Cachy.cache(:x){ false }.should == false
|
54
|
-
Cachy.cache(:x){ true }.should == false
|
55
|
-
end
|
56
|
-
|
57
|
-
it "does not cache nil" do
|
58
|
-
Cachy.cache(:x){ nil }.should == nil
|
59
|
-
Cachy.cache(:x){ true }.should == true
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe :cache_if do
|
64
|
-
it "should not call the cache command if condition is wrong" do
|
65
|
-
Cachy.should_not_receive(:cache)
|
66
|
-
Cachy.cache_if(false, :x) do
|
67
|
-
"asd"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should call cache command if condition is true" do
|
72
|
-
Cachy.should_receive(:cache)
|
73
|
-
Cachy.cache_if(true, :x) do
|
74
|
-
"asd"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should pass params correctly" do
|
79
|
-
Cachy.should_receive(:cache).with(:x, {:y => 1}, :expires_in => 3)
|
80
|
-
Cachy.cache_if(true, :x, {:y => 1}, :expires_in => 3) do
|
81
|
-
"asd"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe :get do
|
87
|
-
it "gets back an object" do
|
88
|
-
Cachy.cache(:foo){'xxx'}
|
89
|
-
Cachy.get(:foo).should == 'xxx'
|
90
|
-
end
|
91
|
-
|
92
|
-
it "gets complex key" do
|
93
|
-
Cachy.cache(:foo, 1){'xxx'}
|
94
|
-
Cachy.get(:foo).should == nil
|
95
|
-
Cachy.get(:foo, 1).should == 'xxx'
|
96
|
-
end
|
97
|
-
|
98
|
-
it "gets back nil" do
|
99
|
-
Cachy.get(:bar).should == nil
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe :expire do
|
104
|
-
it "expires the cache for all languages" do
|
105
|
-
Cachy.cache(:my_key){ "without_locale" }
|
106
|
-
|
107
|
-
locales = [:de, :en, :fr]
|
108
|
-
locales.each do |l|
|
109
|
-
Cachy.stub!(:locale).and_return l
|
110
|
-
Cachy.cache(:my_key){ l }
|
111
|
-
end
|
112
|
-
|
113
|
-
@cache.keys.select{|k| k=~ /my_key/}.size.should == 4
|
114
|
-
Cachy.stub!(:locales).and_return locales
|
115
|
-
Cachy.expire(:my_key)
|
116
|
-
@cache.keys.select{|k| k=~ /my_key/}.size.should == 0
|
117
|
-
end
|
118
|
-
|
119
|
-
it "does not expire other keys" do
|
120
|
-
Cachy.cache(:another_key){ 'X' }
|
121
|
-
Cachy.cache(:my_key){ 'X' }
|
122
|
-
Cachy.cache(:yet_another_key){ 'X' }
|
123
|
-
Cachy.expire :my_key
|
124
|
-
@cache.keys.should include("another_key_v1")
|
125
|
-
@cache.keys.should include("yet_another_key_v1")
|
126
|
-
end
|
127
|
-
|
128
|
-
it "expires the cache when no available_locales are set" do
|
129
|
-
Cachy.cache(:another_key){ "X" }
|
130
|
-
Cachy.cache(:my_key){ "X" }
|
131
|
-
|
132
|
-
@cache.keys.select{|k| k=~ /my_key/}.size.should == 1
|
133
|
-
Cachy.expire(:my_key)
|
134
|
-
@cache.keys.select{|k| k=~ /my_key/}.size.should == 0
|
135
|
-
end
|
136
|
-
|
137
|
-
it "expires the cache with prefix" do
|
138
|
-
key = 'views/my_key_v1'
|
139
|
-
@cache.write(key, 'x')
|
140
|
-
@cache.read(key).should_not == nil
|
141
|
-
Cachy.expire(:my_key, :prefix=>'views/')
|
142
|
-
@cache.read(key).should == nil
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe :expire_view do
|
147
|
-
it "expires the cache with prefix" do
|
148
|
-
key = 'views/my_key_v1'
|
149
|
-
@cache.write(key, 'x')
|
150
|
-
@cache.read(key).should_not == nil
|
151
|
-
Cachy.expire_view(:my_key)
|
152
|
-
@cache.read(key).should == nil
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
describe :key do
|
157
|
-
it "builds based on cache_key" do
|
158
|
-
user = mock(:cache_key=>'XXX',:something_else=>'YYY')
|
159
|
-
Cachy.key(:my_key, 1, user, "abc").should == 'my_key_1_XXX_abc_v1'
|
160
|
-
end
|
161
|
-
|
162
|
-
it "adds current_language" do
|
163
|
-
Cachy.stub!(:locale).and_return :de
|
164
|
-
Cachy.key(:x).should == "x_v1_de"
|
165
|
-
end
|
166
|
-
|
167
|
-
it "raises on unknown options" do
|
168
|
-
lambda{Cachy.key(:x, :asdasd=>'asd')}.should raise_error
|
169
|
-
end
|
170
|
-
|
171
|
-
it "gets the locale from I18n" do
|
172
|
-
# a bit weird but just module I18n does not work with 1.9.1
|
173
|
-
i18n = Module.new
|
174
|
-
i18n.class_eval do
|
175
|
-
def self.locale
|
176
|
-
:de
|
177
|
-
end
|
178
|
-
end
|
179
|
-
Object.const_set :I18n, i18n
|
180
|
-
|
181
|
-
key = Cachy.key(:x)
|
182
|
-
Object.send :remove_const, :I18n #cleanup
|
183
|
-
key.should == "x_v1_de"
|
184
|
-
end
|
185
|
-
|
186
|
-
describe :prefix do
|
187
|
-
it "uses prefix, if set with Cachy.prefix = ..." do
|
188
|
-
user = mock(:cache_key=>'XXX',:something_else=>'YYY')
|
189
|
-
Cachy.prefix = "cachy_"
|
190
|
-
Cachy.key(:my_key, 1, user, "abc").should == 'cachy_my_key_1_XXX_abc_v1'
|
191
|
-
end
|
192
|
-
|
193
|
-
it "can be overridden by :prefix => ... option" do
|
194
|
-
user = mock(:cache_key=>'XXX',:something_else=>'YYY')
|
195
|
-
Cachy.prefix = "cachy_"
|
196
|
-
Cachy.key(:my_key, 1, user, "abc", :prefix => "special_prefix_").should_not == 'cachy_my_key_1_XXX_abc_v1'
|
197
|
-
Cachy.key(:my_key, 1, user, "abc", :prefix => "special_prefix_").should == 'special_prefix_my_key_1_XXX_abc_v1'
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
describe "with :hash_key" do
|
202
|
-
before do
|
203
|
-
@hash = '3b2b8f418849bc73071375529f8515be'
|
204
|
-
end
|
205
|
-
|
206
|
-
it "hashed the key to a stable value" do
|
207
|
-
Cachy.key(:xxx, :hash_key=>true).should == @hash
|
208
|
-
end
|
209
|
-
|
210
|
-
it "changes when key changes" do
|
211
|
-
Cachy.key(:xxx, :hash_key=>true).should_not == Cachy.key(:yyy, :hash_key=>true)
|
212
|
-
end
|
213
|
-
|
214
|
-
it "changes when arguments change" do
|
215
|
-
Cachy.key(:xxx, :hash_key=>true).should_not == Cachy.key(:xxx, 1, :hash_key=>true)
|
216
|
-
end
|
217
|
-
|
218
|
-
it "can be triggered by Cachy.hash_keys" do
|
219
|
-
Cachy.hash_keys = true
|
220
|
-
Cachy.key(:xxx).should == @hash
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
describe "with :keys" do
|
225
|
-
it "is stable" do
|
226
|
-
Cachy.key(:x, :keys=>'asd').should == Cachy.key(:x, :keys=>'asd')
|
227
|
-
end
|
228
|
-
|
229
|
-
it "changes when dependent key changes" do
|
230
|
-
lambda{
|
231
|
-
Cachy.increment_key('asd')
|
232
|
-
}.should change{Cachy.key(:x, :keys=>'asd')}
|
233
|
-
end
|
234
|
-
|
235
|
-
it "is different for different keys" do
|
236
|
-
Cachy.key(:x, :keys=>'xxx').should_not == Cachy.key(:x, :keys=>'yyy')
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
describe 'with :without_locale' do
|
241
|
-
it "is stable with same locale" do
|
242
|
-
Cachy.stub!(:locale).and_return :de
|
243
|
-
Cachy.key(:x, :without_locale=>true).should == Cachy.key(:x, :without_locale=>true)
|
244
|
-
end
|
245
|
-
|
246
|
-
it "is stable with different locales" do
|
247
|
-
Cachy.stub!(:locale).and_return :de
|
248
|
-
de_key = Cachy.key(:x, :without_locale=>true)
|
249
|
-
Cachy.stub!(:locale).and_return :en
|
250
|
-
Cachy.key(:x, :without_locale=>true).should == de_key
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
describe 'with :locale' do
|
255
|
-
it "changes the default key" do
|
256
|
-
Cachy.key(:x, :locale=>:de).should_not == Cachy.key(:x)
|
257
|
-
end
|
258
|
-
|
259
|
-
it "is a different key for different locales" do
|
260
|
-
Cachy.key(:x, :locale=>:de).should_not == Cachy.key(:x, :locale=>:en)
|
261
|
-
end
|
262
|
-
|
263
|
-
it "is the same key for the same locales" do
|
264
|
-
Cachy.key(:x, :locale=>:de).should == Cachy.key(:x, :locale=>:de)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
describe :key_versions do
|
270
|
-
before do
|
271
|
-
Cachy.key_versions = nil
|
272
|
-
Cachy.key_versions.should == {}
|
273
|
-
end
|
274
|
-
|
275
|
-
it "merges in old when setting new" do
|
276
|
-
pending '!!!!!'
|
277
|
-
end
|
278
|
-
|
279
|
-
it "adds a key when cache is called the first time" do
|
280
|
-
Cachy.cache(:xxx){1}
|
281
|
-
Cachy.key_versions[:xxx].should == 1
|
282
|
-
@cache.read(Cachy::KEY_VERSIONS_KEY).should_not == nil
|
283
|
-
end
|
284
|
-
|
285
|
-
it "does not add a key when cache is called the first time and cache is not healthy" do
|
286
|
-
@cache.write(Cachy::HEALTH_CHECK_KEY, 'no')
|
287
|
-
Cachy.cache(:xxx){1}
|
288
|
-
@cache.read(Cachy::KEY_VERSIONS_KEY).should == nil
|
289
|
-
end
|
290
|
-
|
291
|
-
it "adds a string key as symbol" do
|
292
|
-
Cachy.cache('yyy'){1}
|
293
|
-
Cachy.key_versions[:yyy].should == 1
|
294
|
-
end
|
295
|
-
|
296
|
-
it "does not overwrite a key when it already exists" do
|
297
|
-
Cachy.key_versions = {:xxx => 3}
|
298
|
-
Cachy.cache(:xxx){1}
|
299
|
-
Cachy.cache(:xxx){1}
|
300
|
-
Cachy.key_versions[:xxx].should == 3
|
301
|
-
end
|
302
|
-
|
303
|
-
it "reloads when keys have expired" do
|
304
|
-
Cachy.key_versions.should == {} # fills cache
|
305
|
-
@cache.write Cachy::KEY_VERSIONS_KEY, {:xx=>1}
|
306
|
-
Cachy.send(:memory_store).clear
|
307
|
-
Cachy.key_versions.should == {:xx=>1}
|
308
|
-
end
|
309
|
-
|
310
|
-
it "expires when key_versions is set" do
|
311
|
-
Cachy.key_versions.should == {}
|
312
|
-
Cachy.key_versions = {:xx => 1}
|
313
|
-
Cachy.key_versions.should == {:xx => 1}
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
describe :key_versions, "with timeout" do
|
318
|
-
before do
|
319
|
-
@mock = mock = {}
|
320
|
-
@cache.instance_eval{@data = mock}
|
321
|
-
def @mock.read_error_occurred
|
322
|
-
false
|
323
|
-
end
|
324
|
-
def @mock.[](x)
|
325
|
-
{:x => 1}
|
326
|
-
end
|
327
|
-
Cachy.send(:class_variable_set, '@@cache_error', false)
|
328
|
-
end
|
329
|
-
|
330
|
-
it "reads normally" do
|
331
|
-
Cachy.send(:read_versions).should == {:x => 1}
|
332
|
-
end
|
333
|
-
|
334
|
-
it "reads empty when it crashes" do
|
335
|
-
@mock.should_receive(:[]).and_return nil # e.g. Timout happended
|
336
|
-
@mock.should_receive(:read_error_occurred).and_return true
|
337
|
-
Cachy.send(:read_versions).should == {}
|
338
|
-
end
|
339
|
-
|
340
|
-
it "marks as error when it crashes" do
|
341
|
-
Cachy.send(:class_variable_get, '@@cache_error').should == false
|
342
|
-
@mock.should_receive(:read_error_occurred).and_return true
|
343
|
-
Cachy.send(:read_versions)
|
344
|
-
Cachy.send(:class_variable_get, '@@cache_error').should == true
|
345
|
-
end
|
346
|
-
|
347
|
-
it "marks as error free when it reads successfully" do
|
348
|
-
Cachy.send(:class_variable_set, '@@cache_error', true)
|
349
|
-
Cachy.send(:class_variable_get, '@@cache_error').should == true
|
350
|
-
Cachy.send(:read_versions).should == {:x => 1}
|
351
|
-
Cachy.send(:class_variable_get, '@@cache_error').should == false
|
352
|
-
end
|
353
|
-
|
354
|
-
it "writes when it was not error before" do
|
355
|
-
Cachy.cache_store.should_receive(:write)
|
356
|
-
Cachy.send(:write_version, {})
|
357
|
-
end
|
358
|
-
|
359
|
-
it "does not write when it was error before" do
|
360
|
-
Cachy.send(:class_variable_set, '@@cache_error', true)
|
361
|
-
Cachy.cache_store.should_not_receive(:write)
|
362
|
-
Cachy.send(:write_version, {})
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
describe :key_versions, 'with separate store' do
|
367
|
-
let(:key_cache){ TestCache.new }
|
368
|
-
|
369
|
-
it "reads from separate store" do
|
370
|
-
key_cache.write(Cachy::KEY_VERSIONS_KEY, :x => 1)
|
371
|
-
Cachy.key_versions_cache_store = key_cache
|
372
|
-
Cachy.key_versions.should == {:x => 1}
|
373
|
-
end
|
374
|
-
|
375
|
-
it "writes to separate store" do
|
376
|
-
key_cache.write(Cachy::KEY_VERSIONS_KEY, :x => 1)
|
377
|
-
Cachy.key_versions_cache_store = key_cache
|
378
|
-
Cachy.increment_key :x
|
379
|
-
Cachy.key_versions.should == {:x => 2}
|
380
|
-
end
|
381
|
-
|
382
|
-
it "invalidates the cached key_versions_cache_store when a new cache store is used" do
|
383
|
-
key_cache.write(Cachy::KEY_VERSIONS_KEY, :x => 1)
|
384
|
-
Cachy.key_versions_cache_store = key_cache
|
385
|
-
Cachy.key_versions.should == {:x => 1}
|
386
|
-
Cachy.cache_store = @cache
|
387
|
-
Cachy.key_versions.should == {}
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
describe :delete_key do
|
392
|
-
it "removes a key from key versions" do
|
393
|
-
Cachy.cache(:xxx){1}
|
394
|
-
Cachy.key_versions.key?(:xxx).should == true
|
395
|
-
Cachy.delete_key :xxx
|
396
|
-
Cachy.key_versions.key?(:xxx).should == false
|
397
|
-
end
|
398
|
-
|
399
|
-
it "does not crash with unfound key" do
|
400
|
-
Cachy.delete_key :xxx
|
401
|
-
Cachy.delete_key :xxx
|
402
|
-
Cachy.key_versions.key?(:xxx).should == false
|
403
|
-
end
|
404
|
-
end
|
405
|
-
end
|
data/spec/mem_cache.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# stub to test memcache integration
|
2
|
-
class MemCache
|
3
|
-
def initialize
|
4
|
-
@wrapped = {}
|
5
|
-
end
|
6
|
-
|
7
|
-
def set(key, object, ttl = nil)
|
8
|
-
raise 'nope!' if ttl.is_a? Hash or (ttl and not ttl.is_a? Numeric)
|
9
|
-
@wrapped[key] = object
|
10
|
-
end
|
11
|
-
|
12
|
-
def get(key)
|
13
|
-
cache_get(key)
|
14
|
-
end
|
15
|
-
|
16
|
-
def cache_get(key)
|
17
|
-
stubable_cache_get(key)
|
18
|
-
end
|
19
|
-
|
20
|
-
def stubable_cache_get(key)
|
21
|
-
@wrapped[key]
|
22
|
-
end
|
23
|
-
|
24
|
-
def [](x)
|
25
|
-
@wrapped[x]
|
26
|
-
end
|
27
|
-
|
28
|
-
def clear
|
29
|
-
@wrapped.clear
|
30
|
-
end
|
31
|
-
|
32
|
-
def delete(key)
|
33
|
-
@wrapped.delete(key)
|
34
|
-
end
|
35
|
-
end
|
data/spec/spec_helper.rb
DELETED
data/spec/test_cache.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
class TestCache
|
2
|
-
def initialize
|
3
|
-
@data = {}
|
4
|
-
end
|
5
|
-
|
6
|
-
def read(name)
|
7
|
-
@data[name]
|
8
|
-
end
|
9
|
-
|
10
|
-
def write(name, value, options = nil)
|
11
|
-
@data[name] = value.freeze
|
12
|
-
end
|
13
|
-
|
14
|
-
def delete(name, options = nil)
|
15
|
-
@data.delete(name)
|
16
|
-
end
|
17
|
-
|
18
|
-
def clear
|
19
|
-
@data.clear
|
20
|
-
end
|
21
|
-
|
22
|
-
def keys
|
23
|
-
@data.keys
|
24
|
-
end
|
25
|
-
end
|