def_cache 0.1.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 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: