def_cache 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ Njg0YzFlNjJkYWE0N2M5ZmFlMTE1ZmJkNjgwY2E5NjI5M2M3Mjc2MA==
5
+ data.tar.gz: !binary |-
6
+ NTY1ZTcwODU3NGU0Zjg0MDhmZDVlOTg2ZjNjNTI1YTgzMDdkZmY1OA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NDBjMGIxZWJiY2MwMTNiMDA1Y2QzODk4ODE4NGNjZDVkZjkxNDVlYzJjY2U5
10
+ MTgzZjgyYTE2ZTNjYmYxN2RmN2UzMTE1YTBhNTEyODg0ZDdhNTZlZGFlOTcx
11
+ NjBhYTBjYWM3ZWJiYThjNjI0MmYzYjkzMjIwZTU4MWEwODRhYzc=
12
+ data.tar.gz: !binary |-
13
+ ZDQxMjZlNDRhMzEyNzg1YmRlMWQ5OTgyNjA4NTI3M2Y5MDM4Y2FmM2M2Mzc3
14
+ OTI5NWZiYjFmNjY5OTY2NGIyM2EyZWJiMDhhNGU3NDdlOWYzNjcyYjBmMWM2
15
+ MTQwNWM2OGQ4ZjRjZjAzZWRkOTk5ZmQ1YjcyMzg2ZjY4YWFhYTg=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in funky_cache.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'bundler' do
5
+ watch('Gemfile')
6
+ watch(/^.+\.gemspec/)
7
+ end
8
+
9
+ guard :rspec do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
12
+ watch('spec/spec_helper.rb') { "spec" }
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jason Waldrip
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # DefCache
2
+
3
+ [![Version](http://allthebadges.io/jwaldrip/def_cache/badge_fury.png)](http://allthebadges.io/jwaldrip/def_cache/badge_fury)
4
+ [![Dependencies](http://allthebadges.io/jwaldrip/def_cache/gemnasium.png)](http://allthebadges.io/jwaldrip/def_cache/gemnasium)
5
+ [![Build Status](http://allthebadges.io/jwaldrip/def_cache/travis.png)](http://allthebadges.io/jwaldrip/def_cache/travis)
6
+ [![Coverage](http://allthebadges.io/jwaldrip/def_cache/coveralls.png)](http://allthebadges.io/jwaldrip/def_cache/coveralls)
7
+ [![Code Climate](http://allthebadges.io/jwaldrip/def_cache/code_climate.png)](http://allthebadges.io/jwaldrip/def_cache/code_climate)
8
+
9
+ A gem for dynamically caching methods in your classes
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'def_cache'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install funky_cache
24
+
25
+ ## Usage
26
+
27
+ ### Basic
28
+
29
+ ```ruby
30
+
31
+ class MyClass
32
+ include DefCache
33
+
34
+ cache_method :my_foo_method
35
+
36
+ def my_foo_method(bar, baz)
37
+ "hello world"
38
+ end
39
+ end
40
+
41
+ ```
42
+
43
+ ### With Cache Options
44
+
45
+ ```ruby
46
+
47
+ class MyClass
48
+ include DefCache
49
+
50
+ cache_method :my_foo_method, expires_in: 30.minutes
51
+
52
+ def my_foo_method(bar, baz)
53
+ "hello world"
54
+ end
55
+ end
56
+
57
+ ```
58
+
59
+ ### With Dynamic Keys
60
+
61
+ ```ruby
62
+
63
+ class MyClass
64
+ include DefCache
65
+
66
+ cache_method :my_foo_method, keys: [:dyno_key]
67
+
68
+ def my_foo_method(bar, baz)
69
+ "hello world"
70
+ end
71
+
72
+ def dyno_key
73
+ "value of key"
74
+ end
75
+ end
76
+
77
+ ```
78
+
79
+ ### With a custom store
80
+
81
+ ***defaults to Rails.cache in rails or :memory_store in ruby***
82
+
83
+ ```ruby
84
+
85
+ class MyClass
86
+ include DefCache
87
+
88
+ cache_method :my_foo_method, with: :redis_store
89
+
90
+ def my_foo_method(bar, baz)
91
+ "hello world"
92
+ end
93
+ end
94
+
95
+ ```
96
+
97
+ ## Contributing
98
+
99
+ 1. Fork it
100
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
101
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
102
+ 4. Push to the branch (`git push origin my-new-feature`)
103
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
data/def_cache.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'def_cache/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "def_cache"
8
+ spec.version = DefCache::VERSION
9
+ spec.authors = ["Jason Waldrip"]
10
+ spec.email = ["jason@waldrip.net"]
11
+ spec.description = 'An agnostic ActiveSupport::Cache helper to enable easy caching of methods inside your classes.'
12
+ spec.summary = 'An agnostic ActiveSupport::Cache helper to enable easy caching of methods inside your classes.'
13
+ spec.homepage = "https://github.com/jwaldrip/funky_cache"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport", '>= 3.2'
22
+ spec.add_dependency "method_source"
23
+
24
+ spec.add_development_dependency "yard"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "bundler", "~> 1.3"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "guard"
30
+ spec.add_development_dependency "guard-rspec"
31
+ spec.add_development_dependency "guard-bundler"
32
+ spec.add_development_dependency "simplecov"
33
+ spec.add_development_dependency "coveralls"
34
+
35
+ end
@@ -0,0 +1,98 @@
1
+ class DefCache::CacheHandler
2
+
3
+ delegate :lookup_store, to: ActiveSupport::Cache
4
+ attr_reader :method_name, :instance, :keys, :cache_store, :cache_options, :miss_method
5
+
6
+ def initialize(method, instance, options={})
7
+ cached_target, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
8
+ @cache_options = options.except(:with, :keys)
9
+ @logger = options[:logger]
10
+ @cache_store = fetch_store options[:with]
11
+ @miss_method = "#{cached_target}_without_cache#{punctuation}"
12
+ @method_name = method
13
+ @keys = Array.wrap(options[:keys]) || []
14
+ @instance = instance
15
+ end
16
+
17
+ def cache_key(*values)
18
+ key_values = keys.map { |key| instance.send(key) || '*' }
19
+ [instance_cache_key, *key_values, method_name, *values].select(&:present?).join('/')
20
+ end
21
+
22
+ def instance_method
23
+ instance.method(miss_method)
24
+ end
25
+
26
+ def instance_cache_key
27
+ instance.cache_key
28
+ rescue NoMethodError
29
+ instance.class.name
30
+ end
31
+
32
+ def logger
33
+ @logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
34
+ end
35
+
36
+ def method_cache_key(*args, &block)
37
+ params = instance_method.parameters.each_with_index do |(req, param), n|
38
+ send "#{req}_parameter_key", param, args[n], &block
39
+ end.compact.join(',')
40
+ cache_key *params
41
+ end
42
+
43
+ def index_cache_key
44
+ cache_key(:__index__)
45
+ end
46
+
47
+ def index
48
+ cache_store.fetch(index_cache_key){[]}
49
+ end
50
+
51
+ def remove_reference(cache_key)
52
+ new_index = index.delete(cache_key)
53
+ cache_store.write index_cache_key, new_index
54
+ end
55
+
56
+ def add_reference(cache_key)
57
+ unless index.include? cache_key
58
+ logger.info "adding cache ref: #{cache_key}"
59
+ new_index = index << cache_key
60
+ cache_store.write index_cache_key, new_index
61
+ end
62
+ end
63
+
64
+ def flush!
65
+ index.each do |subkey|
66
+ logger.info "removing cache ref: #{subkey}"
67
+ cache_store.delete subkey
68
+ remove_reference subkey
69
+ end
70
+ end
71
+
72
+ private :lookup_store
73
+
74
+ def fetch_store(store, options = {})
75
+ (store.is_a?(Symbol) ? lookup_store(store, options) : store) || default_store
76
+ end
77
+
78
+ def default_store
79
+ defined?(Rails) ? Rails.cache : ActiveSupport::Cache.lookup_store(:memory_store)
80
+ end
81
+
82
+ def req_parameter_key(param, value)
83
+ "#{param}=#{value.inspect}"
84
+ end
85
+
86
+ def opt_parameter_key(param, value)
87
+ "#{param}=#{value.inspect}" if value.present?
88
+ end
89
+
90
+ def rest_parameter_key(param, values)
91
+ "*#{param}=#{values.map(&:inspect)}" if values.present?
92
+ end
93
+
94
+ def block_parameter_key(param, value, &block)
95
+ "&#{param}(#{Digest::MD5.hexdigest(block.source)})" if block_given?
96
+ end
97
+
98
+ end
@@ -0,0 +1,70 @@
1
+ module DefCache::ClassMethods
2
+
3
+ protected
4
+
5
+ # Add method(s) to be cached
6
+ def cache_method(*methods)
7
+ options = methods.extract_options!
8
+ methods.each do |method|
9
+ define_cache_method method, options
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ # Define the cache_method
16
+ def define_cache_method(method, options={})
17
+ stub_cache_method_original(method)
18
+ define_cache_handler_method(method, options)
19
+ define_cache_with_method(method)
20
+ cached_methods_just_added << method
21
+ alias_method_chain method, :cache
22
+ end
23
+
24
+ # Define cache with method
25
+ def define_cache_with_method(method)
26
+ target, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
27
+ class_eval <<-RUBY
28
+ def #{target}_with_cache#{punctuation}(*args, &block)
29
+ handler = cache_handler_for_#{method}
30
+ handler.cache_store.fetch(handler.cache_key, handler.cache_options) do
31
+ handler.add_reference(handler.cache_key)
32
+ #{target}_without_cache#{punctuation} *args, &block
33
+ end
34
+ rescue MethodSource::SourceNotFoundError => e
35
+ warn e
36
+ #{target}_without_cache#{punctuation} *args, &block
37
+ end unless method_defined? :#{target}_with_cache#{punctuation}
38
+ RUBY
39
+ end
40
+
41
+ # Define cache handler method
42
+ def define_cache_handler_method(method, options = {})
43
+ define_method "cache_handler_for_#{method}" do
44
+ eval <<-RUBY
45
+ @cache_handler_for_#{method} ||= DefCache::CacheHandler.new(:#{method}, self, options)
46
+ RUBY
47
+ end unless method_defined? "cache_handler_for_#{method}"
48
+ end
49
+
50
+ # Define an empty method to avoid alias method chain errors
51
+ def stub_cache_method_original(method)
52
+ class_eval <<-RUBY
53
+ def #{method}
54
+ raise NoMethodError, "undefined method `#{method}' for #{self}"
55
+ end unless method_defined? :#{method}
56
+ RUBY
57
+ end
58
+
59
+ # Relink the original method if it is redefined
60
+ def method_added(method)
61
+ define_cache_method(method) if !cached_methods_just_added.delete(method) && method_defined?("#{method}_with_cache")
62
+ super
63
+ end
64
+
65
+ # A collection for just added methods
66
+ def cached_methods_just_added
67
+ @cached_methods_added ||= []
68
+ end
69
+
70
+ end
@@ -0,0 +1,3 @@
1
+ module DefCache
2
+ VERSION = "0.1.0"
3
+ end
data/lib/def_cache.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "def_cache/version"
2
+ require "active_support/all"
3
+
4
+ module DefCache
5
+ extend ActiveSupport::Concern
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :ClassMethods
9
+ autoload :CacheHandler
10
+
11
+ def flush_method_cache!
12
+ methods.select { |m| m.to_s.include? 'cache_handler_for_' }.each { |m| send(m).flush! }
13
+ end
14
+
15
+ end
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ describe DefCache::CacheHandler do
4
+
5
+ let(:method_name){ nil }
6
+ let(:options){{}}
7
+ let(:klass){ stub_const 'SampleClass', Class.new { include DefCache } }
8
+ let(:instance){ klass.new }
9
+ before(:each){ klass.send(:cache_method, method_name) if method_name }
10
+ subject(:handler){ DefCache::CacheHandler.new(method_name, instance, options) }
11
+
12
+ describe '.new' do
13
+ context 'with defaults' do
14
+ let(:method_name){ :foo! }
15
+ let(:options){ { foo: :bar, baz: :raz } }
16
+
17
+ its(:cache_options){ should eq options.except(:with, :keys) }
18
+ its(:cache_store){ should be_a ActiveSupport::Cache::Store }
19
+ its(:miss_method){ should eq 'foo_without_cache!' }
20
+ its(:method_name){ should eq method_name }
21
+ its(:keys){ should be_empty }
22
+ its(:instance){ should eq instance }
23
+ end
24
+ end
25
+
26
+ describe '#cache_key' do
27
+ let(:method_name){ :raz }
28
+ let(:keys){ [:foo, :bar, :baz] }
29
+ let(:options){ { keys: keys } }
30
+ before(:each) { keys.each { |key| allow(instance).to receive(key).and_return(SecureRandom.hex) } }
31
+
32
+ it 'should call each key on the instance' do
33
+ keys.each { |key| expect(instance).to receive(key) }
34
+ handler.cache_key
35
+ end
36
+
37
+ it 'should return the proper key' do
38
+ handler.cache_key(:test).should eq [klass.name, *keys.map { |k| instance.send(k) }, method_name, :test].join('/')
39
+ end
40
+
41
+ end
42
+
43
+ describe '#instance_method' do
44
+ let(:method_name){ :foo }
45
+ it 'should be the proper method' do
46
+ handler.instance_method.should be_a Method
47
+ handler.instance_method.name.should eq :foo_without_cache
48
+ end
49
+ end
50
+
51
+ describe '#instance_cache_key' do
52
+ pending
53
+ end
54
+
55
+ describe '#logger' do
56
+ pending
57
+ end
58
+
59
+ describe '#method_cache_key' do
60
+ pending
61
+ end
62
+
63
+ describe '#index_cache_key' do
64
+ pending
65
+ end
66
+
67
+ describe '#index' do
68
+ pending
69
+ end
70
+
71
+ describe '#remove_reference' do
72
+ pending
73
+ end
74
+
75
+ describe '#add_reference' do
76
+ pending
77
+ end
78
+
79
+ describe '#flush!' do
80
+ pending
81
+ end
82
+
83
+ describe '#fetch_store' do
84
+ pending
85
+ end
86
+
87
+ describe '#default_store' do
88
+ pending
89
+ end
90
+
91
+ describe '#req_parameter_key' do
92
+ pending
93
+ end
94
+
95
+ describe '#opt_parameter_key' do
96
+ pending
97
+ end
98
+
99
+ describe '#rest_parameter_key' do
100
+ pending
101
+ end
102
+
103
+ describe '#block_parameter_key' do
104
+ pending
105
+ end
106
+
107
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ describe DefCache::ClassMethods do
4
+
5
+ subject(:klass) { stub_const 'SampleClass', Class.new { extend DefCache::ClassMethods } }
6
+
7
+ describe '.cache_method' do
8
+ it 'should call .define_cache_method for each method with the passed options' do
9
+ methods = [:foo, :bar, :baz]
10
+ options = { option: :value }
11
+ methods.each do |method|
12
+ expect(klass).to receive(:define_cache_method).with(method, options)
13
+ end
14
+ klass.send :cache_method, *methods, options
15
+ end
16
+ end
17
+
18
+ describe '.define_cache_method' do
19
+ it 'should call .stub_cache_method_original with the method' do
20
+ expect(klass).to receive(:stub_cache_method_original).at_least(:once).with(:foo).and_call_original
21
+ klass.send :define_cache_method, :foo
22
+ end
23
+
24
+ it 'should call .define_cache_handler_method with the method' do
25
+ options = { option: :value }
26
+ expect(klass).to receive(:define_cache_handler_method).at_least(:once).with(:foo, options).and_call_original
27
+ klass.send :define_cache_handler_method, :foo, options
28
+ end
29
+
30
+ it 'should call .define_cache_with_method' do
31
+ expect(klass).to receive(:define_cache_with_method).at_least(:once).with(:foo).and_call_original
32
+ klass.send :define_cache_method, :foo
33
+ end
34
+
35
+ it 'should call alias_method_chain with the method and :cache' do
36
+ expect(klass).to receive(:alias_method_chain).at_least(:once).with(:foo, :cache).and_call_original
37
+ klass.send :define_cache_method, :foo
38
+ end
39
+ end
40
+
41
+ describe '.define_cache_with_method' do
42
+ it 'should define the cache with method' do
43
+ expect(klass).to receive(:method_added).with(:foo_with_cache)
44
+ klass.send :define_cache_with_method, :foo
45
+ end
46
+
47
+ context 'if the method is already defined' do
48
+ it 'should not define the method' do
49
+ klass.send(:define_method, :foo_with_cache) { 'value' }
50
+ expect(klass).to_not receive(:method_added).with(:foo_with_cache)
51
+ klass.send :define_cache_with_method, :foo
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#cache_with_method' do
57
+ let(:instance) { klass.new }
58
+
59
+ before(:each) do
60
+ klass.send :cache_method, :foo, with: :memory_store, logger: Logger.new('/dev/null')
61
+ end
62
+
63
+ it 'should cache miss once' do
64
+ expect(instance).to receive(:foo_without_cache).exactly(:once)
65
+ 2.times { instance.foo }
66
+ end
67
+ end
68
+
69
+ describe '.define_cache_handler_method' do
70
+ it 'should define the cache handler method' do
71
+ expect(klass).to receive(:method_added).with(:cache_handler_for_foo)
72
+ klass.send :define_cache_handler_method, :foo
73
+ end
74
+
75
+ it 'should create a cache handler with the proper options' do
76
+ options = { foo: :bar }
77
+ klass.send :define_cache_handler_method, :foo, options
78
+ instance = klass.new
79
+ expect(DefCache::CacheHandler).to receive(:new).with :foo, instance, options
80
+ instance.cache_handler_for_foo
81
+ end
82
+
83
+ it 'should define a method that returns a cache handler' do
84
+ options = { foo: :bar }
85
+ klass.send :define_cache_handler_method, :foo, options
86
+ instance = klass.new
87
+ handler = instance.cache_handler_for_foo
88
+ handler.should be_a DefCache::CacheHandler
89
+ handler.instance.should eq instance
90
+ handler.cache_options.should eq options
91
+ end
92
+
93
+ context 'if the method is already defined' do
94
+ it 'should not define the method' do
95
+ klass.send(:define_method, :cache_handler_for_foo) { 'value' }
96
+ expect(klass).to_not receive(:method_added).with(:cache_handler_for_foo)
97
+ klass.send :define_cache_handler_method, :foo
98
+ end
99
+ end
100
+ end
101
+
102
+ describe '.stub_cache_method_original' do
103
+ it 'should stub the original method' do
104
+ expect(klass).to receive(:method_added).with(:foo)
105
+ klass.send :stub_cache_method_original, :foo
106
+ end
107
+
108
+ it 'should define a method that raises an error' do
109
+ klass.send :stub_cache_method_original, :foo
110
+ expect { klass.new.foo }.to raise_error NoMethodError
111
+ end
112
+
113
+ context 'if the method is already defined' do
114
+ it 'should not stub the method' do
115
+ klass.send(:define_method, :foo) { 'value' }
116
+ expect(klass).to_not receive(:method_added).with(:foo)
117
+ klass.send :stub_cache_method_original, :foo
118
+ end
119
+ end
120
+ end
121
+
122
+ describe '.method_added' do
123
+ context 'if the with cache method is defined' do
124
+ before(:each) { klass.send(:define_method, :foo_with_cache) { 'value' } }
125
+ it 'should call define_cache_method' do
126
+ expect(klass).to receive(:define_cache_method).with(:foo)
127
+ klass.send(:method_added, :foo)
128
+ end
129
+
130
+ context 'if the method has just been added' do
131
+ it 'should call define_cache_method' do
132
+ klass.send(:cached_methods_just_added) << :foo
133
+ expect(klass).to_not receive(:define_cache_method).with(:foo)
134
+ klass.send(:method_added, :foo)
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe DefCache do
4
+
5
+ let(:klass){ stub_const 'SampleClass', Class.new { include DefCache } }
6
+ subject(:instance){ klass.new }
7
+
8
+ describe '#flush_method_cache!' do
9
+ before do
10
+ klass.send :cache_method, :foo, :bar
11
+ end
12
+
13
+ it 'should call flush on the handlers' do
14
+ [:foo, :bar].each do |m|
15
+ expect(instance.send "cache_handler_for_#{m}").to receive(:flush!)
16
+ end
17
+ instance.flush_method_cache!
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,16 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start
9
+
10
+ require 'def_cache'
11
+
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ end
metadata ADDED
@@ -0,0 +1,236 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: def_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Waldrip
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: method_source
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-bundler
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: coveralls
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: An agnostic ActiveSupport::Cache helper to enable easy caching of methods
182
+ inside your classes.
183
+ email:
184
+ - jason@waldrip.net
185
+ executables: []
186
+ extensions: []
187
+ extra_rdoc_files: []
188
+ files:
189
+ - .gitignore
190
+ - .rspec
191
+ - .travis.yml
192
+ - Gemfile
193
+ - Guardfile
194
+ - LICENSE.txt
195
+ - README.md
196
+ - Rakefile
197
+ - def_cache.gemspec
198
+ - lib/def_cache.rb
199
+ - lib/def_cache/cache_handler.rb
200
+ - lib/def_cache/class_methods.rb
201
+ - lib/def_cache/version.rb
202
+ - spec/lib/def_cache/cache_handler_spec.rb
203
+ - spec/lib/def_cache/class_methods_spec.rb
204
+ - spec/lib/def_cache_spec.rb
205
+ - spec/spec_helper.rb
206
+ homepage: https://github.com/jwaldrip/funky_cache
207
+ licenses:
208
+ - MIT
209
+ metadata: {}
210
+ post_install_message:
211
+ rdoc_options: []
212
+ require_paths:
213
+ - lib
214
+ required_ruby_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - ! '>='
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ! '>='
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ requirements: []
225
+ rubyforge_project:
226
+ rubygems_version: 2.0.6
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: An agnostic ActiveSupport::Cache helper to enable easy caching of methods
230
+ inside your classes.
231
+ test_files:
232
+ - spec/lib/def_cache/cache_handler_spec.rb
233
+ - spec/lib/def_cache/class_methods_spec.rb
234
+ - spec/lib/def_cache_spec.rb
235
+ - spec/spec_helper.rb
236
+ has_rdoc: