cache_digests 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -39,7 +39,7 @@ Now if I change app/views/comments/_comment.html.erb, I'll be forced to manually
39
39
 
40
40
  That puts a serious cramp in our rocking caching style.
41
41
 
42
- Enter Cache Digests: With this plugin, all calls to #cache in the view will automatically append a digest of that template _and_ all of it's dependencies! So you no longer need to manually increment versions in the specific templates you're working on or care about what other templates are depending on the change you make.
42
+ Enter Cache Digests: With this plugin, all calls to #cache in the view will automatically append a digest of that template _and_ all of its dependencies! So you no longer need to manually increment versions in the specific templates you're working on or care about what other templates are depending on the change you make.
43
43
 
44
44
  Our code from above can just look like:
45
45
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'cache_digests'
3
- s.version = '0.1.0'
3
+ s.version = '0.2.0'
4
4
  s.author = 'David Heinemeier Hansson'
5
5
  s.email = 'david@37signals.com'
6
6
  s.summary = 'Nested fragment caches with (even) less situps'
@@ -1,10 +1,14 @@
1
1
  module CacheDigests
2
2
  module FragmentHelper
3
+ def fragment_name_with_digest(name)
4
+ [*name, TemplateDigestor.digest(@virtual_path, formats.last.to_sym, lookup_context)]
5
+ end
6
+
3
7
  private
4
8
  # Automatically include this template's digest -- and its childrens' -- in the cache key.
5
9
  def fragment_for(key, options = nil, &block)
6
10
  if !explicitly_versioned_cache_key?(key)
7
- super [*key, TemplateDigestor.digest(@virtual_path, formats.last.to_sym, lookup_context)], options, &block
11
+ super fragment_name_with_digest(key), options, &block
8
12
  else
9
13
  super
10
14
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext'
2
+ require 'active_support/cache'
2
3
  require 'logger'
3
4
 
4
5
  module CacheDigests
@@ -15,17 +16,21 @@ module CacheDigests
15
16
  # render(topics) => render("topics/topic")
16
17
  # render(message.topics) => render("topics/topic")
17
18
  RENDER_DEPENDENCY = /
18
- render\s? # render, followed by an optional space
19
- \(? # start a optional parenthesis for the render call
20
- (partial:)?\s? # naming the partial, used with collection -- 1st capture
21
- ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture
19
+ render\s* # render, followed by optional whitespace
20
+ \(? # start an optional parenthesis for the render call
21
+ (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture
22
+ ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture
22
23
  /x
23
24
 
24
- cattr_accessor(:cache) { Hash.new }
25
+ cattr_accessor(:cache) { ActiveSupport::Cache::MemoryStore.new }
26
+ cattr_accessor(:cache_prefix)
27
+
25
28
  cattr_accessor(:logger, instance_reader: true)
26
29
 
27
30
  def self.digest(name, format, finder, options = {})
28
- cache["#{name}.#{format}"] ||= new(name, format, finder, options).digest
31
+ cache.fetch([ "digestor", cache_prefix, name, format ].compact.join("/")) do
32
+ new(name, format, finder, options).digest
33
+ end
29
34
  end
30
35
 
31
36
  attr_reader :name, :format, :finder, :options
@@ -35,7 +40,7 @@ module CacheDigests
35
40
  end
36
41
 
37
42
  def digest
38
- Digest::MD5.hexdigest("#{name}.#{format}-#{source}-#{dependency_digest}").tap do |digest|
43
+ Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest|
39
44
  logger.try :info, "Cache digest for #{name}.#{format}: #{digest}"
40
45
  end
41
46
  rescue ActionView::MissingTemplate
@@ -94,7 +99,7 @@ module CacheDigests
94
99
  collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.
95
100
 
96
101
  # replace quotes from string renders
97
- collect { |name| name.gsub(%r|["']|, "") }
102
+ collect { |name| name.gsub(/["']/, "") }
98
103
  end
99
104
 
100
105
  def explicit_dependencies
@@ -1,4 +1,53 @@
1
1
  require 'cache_digests/test_helper'
2
2
 
3
+ class Fragmenter
4
+ include CacheDigests::FragmentHelper
5
+ attr_accessor :virtual_path, :formats, :lookup_context
6
+ def initialize
7
+ @virtual_path = ''
8
+ @formats = [:html]
9
+ end
10
+ end
11
+
3
12
  class FragmentHelperTest < MiniTest::Unit::TestCase
13
+ def setup
14
+ # would love some mocha here
15
+ @old_digest = CacheDigests::TemplateDigestor.method(:digest)
16
+ CacheDigests::TemplateDigestor.send(:define_singleton_method, :digest) do |p,f,lc|
17
+ "digest"
18
+ end
19
+ end
20
+ def teardown
21
+ CacheDigests::TemplateDigestor.send(:define_singleton_method, :digest, &@old_digest)
22
+ @fragmenter = nil
23
+ end
24
+
25
+ def test_passes_correct_parameters_to_digestor
26
+ CacheDigests::TemplateDigestor.send(:define_singleton_method, :digest) do |p,f,lc|
27
+ extend MiniTest::Assertions
28
+ assert_equal 'path', p
29
+ assert_equal :formats, f
30
+ assert_equal 'lookup context', lc
31
+ end
32
+ fragmenter.virtual_path = 'path'
33
+ fragmenter.formats = ['formats']
34
+ fragmenter.lookup_context = 'lookup context'
35
+
36
+ fragmenter.fragment_name_with_digest("key")
37
+ end
38
+
39
+ def test_appends_the_key_with_digest
40
+ key_with_digest = fragmenter.fragment_name_with_digest("key")
41
+ assert_equal ['key', 'digest'], key_with_digest
42
+ end
43
+
44
+ def test_appends_the_array_key_with_digest
45
+ key_with_digest = fragmenter.fragment_name_with_digest(["key1", "key2"])
46
+ assert_equal ['key1', 'key2', 'digest'], key_with_digest
47
+ end
48
+
49
+ private
50
+ def fragmenter
51
+ @fragmenter ||= Fragmenter.new
52
+ end
4
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_digests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-14 00:00:00.000000000 Z
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -65,7 +65,6 @@ executables: []
65
65
  extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
- - ./bin/bundle
69
68
  - ./cache_digests.gemspec
70
69
  - ./Gemfile
71
70
  - ./Gemfile.lock
data/bin/bundle DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby-local-exec
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
- require 'rubygems'
4
- load Gem.bin_path('bundler', 'bundle')