jbuilder_cache_multi 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.travis.yml +14 -0
  4. data/Appraisals +1 -1
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +50 -0
  7. data/README.md +6 -0
  8. data/gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile +13 -0
  9. data/gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile.lock +76 -0
  10. data/gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile +13 -0
  11. data/gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile.lock +76 -0
  12. data/gemfiles/rails_3.1.0_jbuilder_1.5.0.gemfile +13 -0
  13. data/gemfiles/rails_3.1.0_jbuilder_1.5.0.gemfile.lock +86 -0
  14. data/gemfiles/rails_3.1.0_jbuilder_2.0.0.gemfile +13 -0
  15. data/gemfiles/rails_3.1.0_jbuilder_2.0.0.gemfile.lock +86 -0
  16. data/gemfiles/rails_3.2.0_jbuilder_1.5.0.gemfile +13 -0
  17. data/gemfiles/rails_3.2.0_jbuilder_1.5.0.gemfile.lock +85 -0
  18. data/gemfiles/rails_3.2.0_jbuilder_2.0.0.gemfile +13 -0
  19. data/gemfiles/rails_3.2.0_jbuilder_2.0.0.gemfile.lock +85 -0
  20. data/gemfiles/rails_4.0.0_jbuilder_1.5.0.gemfile +13 -0
  21. data/gemfiles/rails_4.0.0_jbuilder_1.5.0.gemfile.lock +67 -0
  22. data/gemfiles/rails_4.0.0_jbuilder_2.0.0.gemfile +13 -0
  23. data/gemfiles/rails_4.0.0_jbuilder_2.0.0.gemfile.lock +67 -0
  24. data/gemfiles/rails_4.1.0_jbuilder_1.5.0.gemfile +13 -0
  25. data/gemfiles/rails_4.1.0_jbuilder_1.5.0.gemfile.lock +72 -0
  26. data/gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile +13 -0
  27. data/gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile.lock +72 -0
  28. data/gemfiles/rails_5.0.0_jbuilder_1.5.0.gemfile +13 -0
  29. data/gemfiles/rails_5.0.0_jbuilder_1.5.0.gemfile.lock +87 -0
  30. data/gemfiles/rails_5.0.0_jbuilder_2.0.0.gemfile +13 -0
  31. data/gemfiles/rails_5.0.0_jbuilder_2.0.0.gemfile.lock +87 -0
  32. data/lib/jbuilder_cache_multi/jbuilder_ext.rb +40 -17
  33. data/lib/jbuilder_cache_multi/version.rb +1 -1
  34. data/test/jbuilder_template_test.rb +57 -4
  35. metadata +29 -3
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 4.1.0"
10
+ gem "actionpack", "~> 4.1.0"
11
+ gem "jbuilder", "~> 2.0.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (4.1.13)
11
+ actionview (= 4.1.13)
12
+ activesupport (= 4.1.13)
13
+ rack (~> 1.5.2)
14
+ rack-test (~> 0.6.2)
15
+ actionview (4.1.13)
16
+ activesupport (= 4.1.13)
17
+ builder (~> 3.1)
18
+ erubis (~> 2.7.0)
19
+ activesupport (4.1.13)
20
+ i18n (~> 0.6, >= 0.6.9)
21
+ json (~> 1.7, >= 1.7.7)
22
+ minitest (~> 5.1)
23
+ thread_safe (~> 0.1)
24
+ tzinfo (~> 1.1)
25
+ appraisal (2.1.0)
26
+ bundler
27
+ rake
28
+ thor (>= 0.14.0)
29
+ builder (3.2.2)
30
+ erubis (2.7.0)
31
+ i18n (0.7.0)
32
+ jbuilder (2.0.8)
33
+ activesupport (>= 3.0.0, < 5)
34
+ multi_json (~> 1.2)
35
+ json (1.8.3)
36
+ metaclass (0.0.4)
37
+ minitest (5.8.0)
38
+ mocha (1.1.0)
39
+ metaclass (~> 0.0.1)
40
+ multi_json (1.11.2)
41
+ power_assert (0.2.2)
42
+ rack (1.5.5)
43
+ rack-test (0.6.3)
44
+ rack (>= 1.0)
45
+ railties (4.1.13)
46
+ actionpack (= 4.1.13)
47
+ activesupport (= 4.1.13)
48
+ rake (>= 0.8.7)
49
+ thor (>= 0.18.1, < 2.0)
50
+ rake (10.4.2)
51
+ test-unit (3.0.8)
52
+ power_assert
53
+ thor (0.19.1)
54
+ thread_safe (0.3.5)
55
+ tzinfo (1.2.2)
56
+ thread_safe (~> 0.1)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ actionpack (~> 4.1.0)
63
+ appraisal
64
+ jbuilder (~> 2.0.0)
65
+ jbuilder_cache_multi!
66
+ mocha
67
+ railties (~> 4.1.0)
68
+ rake
69
+ test-unit
70
+
71
+ BUNDLED WITH
72
+ 1.14.6
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 5.0.0"
10
+ gem "actionpack", "~> 5.0.0"
11
+ gem "jbuilder", "~> 1.5.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (5.0.2)
11
+ actionview (= 5.0.2)
12
+ activesupport (= 5.0.2)
13
+ rack (~> 2.0)
14
+ rack-test (~> 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
+ actionview (5.0.2)
18
+ activesupport (= 5.0.2)
19
+ builder (~> 3.1)
20
+ erubis (~> 2.7.0)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
+ activesupport (5.0.2)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (~> 0.7)
26
+ minitest (~> 5.1)
27
+ tzinfo (~> 1.1)
28
+ appraisal (2.2.0)
29
+ bundler
30
+ rake
31
+ thor (>= 0.14.0)
32
+ builder (3.2.3)
33
+ concurrent-ruby (1.0.5)
34
+ erubis (2.7.0)
35
+ i18n (0.8.1)
36
+ jbuilder (1.5.3)
37
+ activesupport (>= 3.0.0)
38
+ multi_json (>= 1.2.0)
39
+ loofah (2.0.3)
40
+ nokogiri (>= 1.5.9)
41
+ metaclass (0.0.4)
42
+ method_source (0.8.2)
43
+ mini_portile2 (2.1.0)
44
+ minitest (5.10.1)
45
+ mocha (1.2.1)
46
+ metaclass (~> 0.0.1)
47
+ multi_json (1.12.1)
48
+ nokogiri (1.7.1)
49
+ mini_portile2 (~> 2.1.0)
50
+ power_assert (1.0.2)
51
+ rack (2.0.2)
52
+ rack-test (0.6.3)
53
+ rack (>= 1.0)
54
+ rails-dom-testing (2.0.2)
55
+ activesupport (>= 4.2.0, < 6.0)
56
+ nokogiri (~> 1.6)
57
+ rails-html-sanitizer (1.0.3)
58
+ loofah (~> 2.0)
59
+ railties (5.0.2)
60
+ actionpack (= 5.0.2)
61
+ activesupport (= 5.0.2)
62
+ method_source
63
+ rake (>= 0.8.7)
64
+ thor (>= 0.18.1, < 2.0)
65
+ rake (12.0.0)
66
+ test-unit (3.2.3)
67
+ power_assert
68
+ thor (0.19.4)
69
+ thread_safe (0.3.6)
70
+ tzinfo (1.2.3)
71
+ thread_safe (~> 0.1)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ actionpack (~> 5.0.0)
78
+ appraisal
79
+ jbuilder (~> 1.5.0)
80
+ jbuilder_cache_multi!
81
+ mocha
82
+ railties (~> 5.0.0)
83
+ rake
84
+ test-unit
85
+
86
+ BUNDLED WITH
87
+ 1.14.6
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 5.0.0"
10
+ gem "actionpack", "~> 5.0.0"
11
+ gem "jbuilder", "~> 2.0.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (5.0.2)
11
+ actionview (= 5.0.2)
12
+ activesupport (= 5.0.2)
13
+ rack (~> 2.0)
14
+ rack-test (~> 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
+ actionview (5.0.2)
18
+ activesupport (= 5.0.2)
19
+ builder (~> 3.1)
20
+ erubis (~> 2.7.0)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
+ activesupport (5.0.2)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (~> 0.7)
26
+ minitest (~> 5.1)
27
+ tzinfo (~> 1.1)
28
+ appraisal (2.2.0)
29
+ bundler
30
+ rake
31
+ thor (>= 0.14.0)
32
+ builder (3.2.3)
33
+ concurrent-ruby (1.0.5)
34
+ erubis (2.7.0)
35
+ i18n (0.8.1)
36
+ jbuilder (2.0.5)
37
+ activesupport (>= 3.0.0)
38
+ multi_json (>= 1.2.0)
39
+ loofah (2.0.3)
40
+ nokogiri (>= 1.5.9)
41
+ metaclass (0.0.4)
42
+ method_source (0.8.2)
43
+ mini_portile2 (2.1.0)
44
+ minitest (5.10.1)
45
+ mocha (1.2.1)
46
+ metaclass (~> 0.0.1)
47
+ multi_json (1.12.1)
48
+ nokogiri (1.7.1)
49
+ mini_portile2 (~> 2.1.0)
50
+ power_assert (1.0.2)
51
+ rack (2.0.2)
52
+ rack-test (0.6.3)
53
+ rack (>= 1.0)
54
+ rails-dom-testing (2.0.2)
55
+ activesupport (>= 4.2.0, < 6.0)
56
+ nokogiri (~> 1.6)
57
+ rails-html-sanitizer (1.0.3)
58
+ loofah (~> 2.0)
59
+ railties (5.0.2)
60
+ actionpack (= 5.0.2)
61
+ activesupport (= 5.0.2)
62
+ method_source
63
+ rake (>= 0.8.7)
64
+ thor (>= 0.18.1, < 2.0)
65
+ rake (12.0.0)
66
+ test-unit (3.2.3)
67
+ power_assert
68
+ thor (0.19.4)
69
+ thread_safe (0.3.6)
70
+ tzinfo (1.2.3)
71
+ thread_safe (~> 0.1)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ actionpack (~> 5.0.0)
78
+ appraisal
79
+ jbuilder (~> 2.0.0)
80
+ jbuilder_cache_multi!
81
+ mocha
82
+ railties (~> 5.0.0)
83
+ rake
84
+ test-unit
85
+
86
+ BUNDLED WITH
87
+ 1.14.6
@@ -7,55 +7,78 @@ JbuilderTemplate.class_eval do
7
7
  # json.cache_collection! @people, expires_in: 10.minutes do |person|
8
8
  # json.partial! 'person', :person => person
9
9
  # end
10
- def cache_collection!(collection, options = {}, &block)
11
- if @context.controller.perform_caching
12
- keys_to_collection_map = _keys_to_collection_map(collection, options)
10
+ def cache_collection!(collection, options = {}, &block)
11
+ if @context.controller.perform_caching && !collection.empty?
12
+ keys_to_collection_map = _keys_to_collection_map(collection, options)
13
13
 
14
14
  if ::Rails.cache.respond_to?(:fetch_multi)
15
15
  results = ::Rails.cache.fetch_multi(*keys_to_collection_map.keys, options) do |key|
16
16
  _scope { yield keys_to_collection_map[key] }
17
- end
17
+ end
18
18
  else
19
19
  results = keys_to_collection_map.map do |key, item|
20
20
  ::Rails.cache.fetch(key, options) { _scope { yield item } }
21
21
  end
22
22
  end
23
-
23
+
24
24
  _process_collection_results(results)
25
25
  else
26
26
  array! collection, options, &block
27
27
  end
28
28
  end
29
-
30
-
31
-
29
+
30
+ # Conditionally caches a collection of objects depending in the condition given as first parameter.
31
+ #
32
+ # Example:
33
+ #
34
+ # json.cache_collection_if! do_cache?, @people, expires_in: 10.minutes do |person|
35
+ # json.partial! 'person', :person => person
36
+ # end
37
+ def cache_collection_if!(condition, collection, options = {}, &block)
38
+ condition ?
39
+ cache_collection!(collection, options, &block) :
40
+ array!(collection, options, &block)
41
+ end
42
+
32
43
  protected
33
-
44
+
34
45
  ## Implementing our own version of _cache_key because jbuilder's is protected
35
46
  def _cache_key_fetch_multi(key, options)
47
+ key = _fragment_name_with_digest_fetch_multi(key, options)
48
+ key = url_for(key).split('://', 2).last if ::Hash === key
49
+ ::ActiveSupport::Cache.expand_cache_key(key, :jbuilder)
50
+ end
51
+
52
+ def _fragment_name_with_digest_fetch_multi(key, options)
36
53
  if @context.respond_to?(:cache_fragment_name)
37
54
  # Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
38
55
  # should be used instead.
39
- @context.cache_fragment_name(key, options)
56
+ @context.cache_fragment_name(key, options.slice(:skip_digest, :virtual_path))
40
57
  elsif @context.respond_to?(:fragment_name_with_digest)
41
58
  # Backwards compatibility for period of time when fragment_name_with_digest was made public.
42
59
  @context.fragment_name_with_digest(key)
43
60
  else
44
- ::ActiveSupport::Cache.expand_cache_key(key.is_a?(::Hash) ? url_for(key).split('://').last : key, :jbuilder)
61
+ key
45
62
  end
46
63
  end
47
-
64
+
48
65
  def _keys_to_collection_map(collection, options)
49
66
  key = options.delete(:key)
50
67
 
51
68
  collection.inject({}) do |result, item|
52
- key = key.respond_to?(:call) ? key.call(item) : key
53
- cache_key = key ? [key, item] : item
69
+ cache_key =
70
+ if key.respond_to?(:call)
71
+ key.call(item)
72
+ elsif key
73
+ [key, item]
74
+ else
75
+ item
76
+ end
54
77
  result[_cache_key_fetch_multi(cache_key, options)] = item
55
78
  result
56
79
  end
57
80
  end
58
-
81
+
59
82
  def _process_collection_results(results)
60
83
  _results = results.class == Hash ? results.values : results
61
84
  #support pre 2.0 versions of jbuilder where merge! is still private
@@ -67,5 +90,5 @@ JbuilderTemplate.class_eval do
67
90
  _results
68
91
  end
69
92
  end
70
-
71
- end
93
+
94
+ end
@@ -1,3 +1,3 @@
1
1
  module JbuilderCacheMulti
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -17,7 +17,7 @@ BLOG_POST_PARTIAL = <<-JBUILDER
17
17
  end
18
18
  JBUILDER
19
19
 
20
- CACHE_KEY_PROC = Proc.new { |blog_post| true }
20
+ CACHE_KEY_PROC = Proc.new { |blog_post| blog_post.id }
21
21
 
22
22
  BlogPost = Struct.new(:id, :body, :author_name)
23
23
  blog_authors = [ 'David Heinemeier Hansson', 'Pavel Pravosud' ].cycle
@@ -42,6 +42,14 @@ class JbuilderTemplateTest < ActionView::TestCase
42
42
  }
43
43
  end
44
44
 
45
+ # Stub out a couple of methods that'll get called from cache_fragment_name
46
+ def view_cache_dependencies
47
+ []
48
+ end
49
+ def formats
50
+ [:json]
51
+ end
52
+
45
53
  def render_jbuilder(source)
46
54
  @rendered = []
47
55
  lookup_context.view_paths = [ActionView::FixtureResolver.new(partials.merge('test.json.jbuilder' => source))]
@@ -79,9 +87,18 @@ class JbuilderTemplateTest < ActionView::TestCase
79
87
  assert_collection_rendered json
80
88
  end
81
89
 
90
+ test 'allows additional options' do
91
+ json = render_jbuilder <<-JBUILDER
92
+ json.cache_collection! BLOG_POST_COLLECTION, expires_in: 1.hour do |blog_post|
93
+ json.partial! 'blog_post', :blog_post => blog_post
94
+ end
95
+ JBUILDER
96
+
97
+ assert_collection_rendered json
98
+ end
99
+
82
100
  test 'renders cached array with a key specified as a proc' do
83
101
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
84
- CACHE_KEY_PROC.expects(:call)
85
102
 
86
103
  json = render_jbuilder <<-JBUILDER
87
104
  json.cache_collection! BLOG_POST_COLLECTION, key: CACHE_KEY_PROC do |blog_post|
@@ -91,7 +108,7 @@ class JbuilderTemplateTest < ActionView::TestCase
91
108
 
92
109
  assert_collection_rendered json
93
110
  end
94
-
111
+
95
112
  test 'reverts to cache! if cache does not support fetch_multi' do
96
113
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
97
114
  ActiveSupport::Cache::Store.send(:undef_method, :fetch_multi) if ActiveSupport::Cache::Store.method_defined?(:fetch_multi)
@@ -104,7 +121,7 @@ class JbuilderTemplateTest < ActionView::TestCase
104
121
 
105
122
  assert_collection_rendered json
106
123
  end
107
-
124
+
108
125
  test 'reverts to array! when controller.perform_caching is false' do
109
126
  controller.perform_caching = false
110
127
 
@@ -117,4 +134,40 @@ class JbuilderTemplateTest < ActionView::TestCase
117
134
  assert_collection_rendered json
118
135
  end
119
136
 
137
+ test 'reverts to array! when collection is empty' do
138
+ json = render_jbuilder <<-JBUILDER
139
+ json.cache_collection! [] do |blog_post|
140
+ json.partial! 'blog_post', :blog_post => blog_post
141
+ end
142
+ JBUILDER
143
+
144
+ assert_equal '[]', json
145
+ end
146
+
147
+ test 'conditionally fragment caching a JSON object' do
148
+ undef_context_methods :fragment_name_with_digest, :cache_fragment_name
149
+
150
+ render_jbuilder <<-JBUILDER
151
+ json.cache_collection_if! true, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
152
+ json.partial! 'blog_post', :blog_post => blog_post
153
+ end
154
+ JBUILDER
155
+
156
+ json = render_jbuilder <<-JBUILDER
157
+ json.cache_collection_if! true, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
158
+ json.test 'Miss'
159
+ end
160
+ JBUILDER
161
+
162
+ assert_collection_rendered json
163
+
164
+ json = render_jbuilder <<-JBUILDER
165
+ json.cache_collection_if! false, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
166
+ json.test 'Miss'
167
+ end
168
+ JBUILDER
169
+
170
+ result = MultiJson.load(json)
171
+ assert_equal 'Miss', result[4]['test']
172
+ end
120
173
  end