jbuilder 2.10.0 → 2.14.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +25 -0
  3. data/.github/workflows/ruby.yml +56 -0
  4. data/.gitignore +2 -0
  5. data/Appraisals +14 -13
  6. data/CONTRIBUTING.md +5 -13
  7. data/Gemfile +2 -0
  8. data/README.md +113 -26
  9. data/Rakefile +3 -1
  10. data/bin/release +14 -0
  11. data/bin/test +6 -0
  12. data/gemfiles/{rails_5_1.gemfile → rails_7_0.gemfile} +2 -1
  13. data/gemfiles/{rails_5_2.gemfile → rails_7_1.gemfile} +1 -1
  14. data/gemfiles/{rails_6_0.gemfile → rails_7_2.gemfile} +1 -1
  15. data/gemfiles/{rails_5_0.gemfile → rails_8_0.gemfile} +1 -1
  16. data/gemfiles/rails_head.gemfile +1 -1
  17. data/jbuilder.gemspec +22 -3
  18. data/lib/generators/rails/jbuilder_generator.rb +10 -0
  19. data/lib/generators/rails/scaffold_controller_generator.rb +2 -0
  20. data/lib/generators/rails/templates/api_controller.rb +8 -2
  21. data/lib/generators/rails/templates/controller.rb +19 -17
  22. data/lib/generators/rails/templates/index.json.jbuilder +1 -1
  23. data/lib/generators/rails/templates/partial.json.jbuilder +14 -0
  24. data/lib/generators/rails/templates/show.json.jbuilder +1 -1
  25. data/lib/jbuilder/blank.rb +2 -0
  26. data/lib/jbuilder/collection_renderer.rb +58 -0
  27. data/lib/jbuilder/errors.rb +3 -1
  28. data/lib/jbuilder/jbuilder.rb +3 -7
  29. data/lib/jbuilder/jbuilder_dependency_tracker.rb +75 -0
  30. data/lib/jbuilder/jbuilder_template.rb +82 -48
  31. data/lib/jbuilder/key_formatter.rb +19 -21
  32. data/lib/jbuilder/railtie.rb +17 -19
  33. data/lib/jbuilder/version.rb +5 -0
  34. data/lib/jbuilder.rb +96 -51
  35. data/test/jbuilder_dependency_tracker_test.rb +2 -3
  36. data/test/jbuilder_generator_test.rb +22 -0
  37. data/test/jbuilder_template_test.rb +133 -8
  38. data/test/jbuilder_test.rb +211 -9
  39. data/test/scaffold_api_controller_generator_test.rb +63 -47
  40. data/test/scaffold_controller_generator_test.rb +47 -11
  41. data/test/test_helper.rb +24 -11
  42. metadata +37 -18
  43. data/.travis.yml +0 -47
  44. data/CHANGELOG.md +0 -283
  45. data/lib/jbuilder/dependency_tracker.rb +0 -61
data/lib/jbuilder.rb CHANGED
@@ -1,31 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
1
4
  require 'jbuilder/jbuilder'
2
5
  require 'jbuilder/blank'
3
6
  require 'jbuilder/key_formatter'
4
7
  require 'jbuilder/errors'
5
8
  require 'json'
6
- require 'ostruct'
7
9
  require 'active_support/core_ext/hash/deep_merge'
8
10
 
9
11
  class Jbuilder
10
12
  @@key_formatter = nil
11
13
  @@ignore_nil = false
12
-
13
- def initialize(options = {})
14
+ @@deep_format_keys = false
15
+
16
+ def initialize(
17
+ key_formatter: @@key_formatter,
18
+ ignore_nil: @@ignore_nil,
19
+ deep_format_keys: @@deep_format_keys,
20
+ &block
21
+ )
14
22
  @attributes = {}
23
+ @key_formatter = key_formatter
24
+ @ignore_nil = ignore_nil
25
+ @deep_format_keys = deep_format_keys
15
26
 
16
- @key_formatter = options.fetch(:key_formatter){ @@key_formatter ? @@key_formatter.clone : nil}
17
- @ignore_nil = options.fetch(:ignore_nil, @@ignore_nil)
18
-
19
- yield self if ::Kernel.block_given?
27
+ yield self if block
20
28
  end
21
29
 
22
30
  # Yields a builder and automatically turns the result into a JSON string
23
- def self.encode(*args, &block)
24
- new(*args, &block).target!
31
+ def self.encode(...)
32
+ new(...).target!
25
33
  end
26
34
 
27
35
  BLANK = Blank.new
28
- NON_ENUMERABLES = [ ::Struct, ::OpenStruct ].to_set
29
36
 
30
37
  def set!(key, value = BLANK, *args, &block)
31
38
  result = if ::Kernel.block_given?
@@ -43,11 +50,11 @@ class Jbuilder
43
50
  # json.age 32
44
51
  # json.person another_jbuilder
45
52
  # { "age": 32, "person": { ... }
46
- value.attributes!
53
+ _format_keys(value.attributes!)
47
54
  else
48
55
  # json.age 32
49
56
  # { "age": 32 }
50
- value
57
+ _format_keys(value)
51
58
  end
52
59
  elsif _is_collection?(value)
53
60
  # json.comments @post.comments, :content, :created_at
@@ -56,20 +63,12 @@ class Jbuilder
56
63
  else
57
64
  # json.author @post.creator, :name, :email_address
58
65
  # { "author": { "name": "David", "email_address": "david@loudthinking.com" } }
59
- _merge_block(key){ extract! value, *args }
66
+ _merge_block(key){ _extract value, args }
60
67
  end
61
68
 
62
69
  _set_value key, result
63
70
  end
64
71
 
65
- def method_missing(*args, &block)
66
- if ::Kernel.block_given?
67
- set!(*args, &block)
68
- else
69
- set!(*args)
70
- end
71
- end
72
-
73
72
  # Specifies formatting to be applied to the key. Passing in a name of a function
74
73
  # will cause that function to be called on the key. So :upcase will upper case
75
74
  # the key. You can also pass in lambdas for more complex transformations.
@@ -98,13 +97,13 @@ class Jbuilder
98
97
  #
99
98
  # { "_first_name": "David" }
100
99
  #
101
- def key_format!(*args)
102
- @key_formatter = KeyFormatter.new(*args)
100
+ def key_format!(...)
101
+ @key_formatter = KeyFormatter.new(...)
103
102
  end
104
103
 
105
104
  # Same as the instance method key_format! except sets the default.
106
- def self.key_format(*args)
107
- @@key_formatter = KeyFormatter.new(*args)
105
+ def self.key_format(...)
106
+ @@key_formatter = KeyFormatter.new(...)
108
107
  end
109
108
 
110
109
  # If you want to skip adding nil values to your JSON hash. This is useful
@@ -131,6 +130,31 @@ class Jbuilder
131
130
  @@ignore_nil = value
132
131
  end
133
132
 
133
+ # Deeply apply key format to nested hashes and arrays passed to
134
+ # methods like set!, merge! or array!.
135
+ #
136
+ # Example:
137
+ #
138
+ # json.key_format! camelize: :lower
139
+ # json.settings({some_value: "abc"})
140
+ #
141
+ # { "settings": { "some_value": "abc" }}
142
+ #
143
+ # json.key_format! camelize: :lower
144
+ # json.deep_format_keys!
145
+ # json.settings({some_value: "abc"})
146
+ #
147
+ # { "settings": { "someValue": "abc" }}
148
+ #
149
+ def deep_format_keys!(value = true)
150
+ @deep_format_keys = value
151
+ end
152
+
153
+ # Same as instance method deep_format_keys! except sets the default.
154
+ def self.deep_format_keys(value = true)
155
+ @@deep_format_keys = value
156
+ end
157
+
134
158
  # Turns the current element into an array and yields a builder to add a hash.
135
159
  #
136
160
  # Example:
@@ -188,12 +212,12 @@ class Jbuilder
188
212
  elsif ::Kernel.block_given?
189
213
  _map_collection(collection, &block)
190
214
  elsif attributes.any?
191
- _map_collection(collection) { |element| extract! element, *attributes }
215
+ _map_collection(collection) { |element| _extract element, attributes }
192
216
  else
193
- collection.to_a
217
+ _format_keys(collection.to_a)
194
218
  end
195
219
 
196
- merge! array
220
+ @attributes = _merge_values(@attributes, array)
197
221
  end
198
222
 
199
223
  # Extracts the mentioned attributes or hash elements from the passed object and turns them into attributes of the JSON.
@@ -214,18 +238,14 @@ class Jbuilder
214
238
  #
215
239
  # json.(@person, :name, :age)
216
240
  def extract!(object, *attributes)
217
- if ::Hash === object
218
- _extract_hash_values(object, attributes)
219
- else
220
- _extract_method_values(object, attributes)
221
- end
241
+ _extract object, attributes
222
242
  end
223
243
 
224
244
  def call(object, *attributes, &block)
225
245
  if ::Kernel.block_given?
226
246
  array! object, &block
227
247
  else
228
- extract! object, *attributes
248
+ _extract object, attributes
229
249
  end
230
250
  end
231
251
 
@@ -241,9 +261,10 @@ class Jbuilder
241
261
  @attributes
242
262
  end
243
263
 
244
- # Merges hash or array into current builder.
245
- def merge!(hash_or_array)
246
- @attributes = _merge_values(@attributes, hash_or_array)
264
+ # Merges hash, array, or Jbuilder instance into current builder.
265
+ def merge!(object)
266
+ hash_or_array = ::Jbuilder === object ? object.attributes! : object
267
+ @attributes = _merge_values(@attributes, _format_keys(hash_or_array))
247
268
  end
248
269
 
249
270
  # Encodes the current builder as JSON.
@@ -253,17 +274,27 @@ class Jbuilder
253
274
 
254
275
  private
255
276
 
277
+ alias_method :method_missing, :set!
278
+
279
+ def _extract(object, attributes)
280
+ if ::Hash === object
281
+ _extract_hash_values(object, attributes)
282
+ else
283
+ _extract_method_values(object, attributes)
284
+ end
285
+ end
286
+
256
287
  def _extract_hash_values(object, attributes)
257
- attributes.each{ |key| _set_value key, object.fetch(key) }
288
+ attributes.each{ |key| _set_value key, _format_keys(object.fetch(key)) }
258
289
  end
259
290
 
260
291
  def _extract_method_values(object, attributes)
261
- attributes.each{ |key| _set_value key, object.public_send(key) }
292
+ attributes.each{ |key| _set_value key, _format_keys(object.public_send(key)) }
262
293
  end
263
294
 
264
295
  def _merge_block(key)
265
296
  current_value = _blank? ? BLANK : @attributes.fetch(_key(key), BLANK)
266
- raise NullError.build(key) if current_value.nil?
297
+ ::Kernel.raise NullError.build(key) if current_value.nil?
267
298
  new_value = _scope{ yield self }
268
299
  _merge_values(current_value, new_value)
269
300
  end
@@ -278,17 +309,35 @@ class Jbuilder
278
309
  elsif ::Hash === current_value && ::Hash === updates
279
310
  current_value.deep_merge(updates)
280
311
  else
281
- raise MergeError.build(current_value, updates)
312
+ ::Kernel.raise MergeError.build(current_value, updates)
282
313
  end
283
314
  end
284
315
 
285
316
  def _key(key)
286
- @key_formatter ? @key_formatter.format(key) : key.to_s
317
+ if @key_formatter
318
+ @key_formatter.format(key)
319
+ elsif key.is_a?(::Symbol)
320
+ key.name
321
+ else
322
+ key.to_s
323
+ end
324
+ end
325
+
326
+ def _format_keys(hash_or_array)
327
+ return hash_or_array unless @deep_format_keys
328
+
329
+ if ::Array === hash_or_array
330
+ hash_or_array.map { |value| _format_keys(value) }
331
+ elsif ::Hash === hash_or_array
332
+ ::Hash[hash_or_array.collect { |k, v| [_key(k), _format_keys(v)] }]
333
+ else
334
+ hash_or_array
335
+ end
287
336
  end
288
337
 
289
338
  def _set_value(key, value)
290
- raise NullError.build(key) if @attributes.nil?
291
- raise ArrayError.build(key) if ::Array === @attributes
339
+ ::Kernel.raise NullError.build(key) if @attributes.nil?
340
+ ::Kernel.raise ArrayError.build(key) if ::Array === @attributes
292
341
  return if @ignore_nil && value.nil? or _blank?(value)
293
342
  @attributes = {} if _blank?
294
343
  @attributes[_key(key)] = value
@@ -301,25 +350,21 @@ class Jbuilder
301
350
  end
302
351
 
303
352
  def _scope
304
- parent_attributes, parent_formatter = @attributes, @key_formatter
353
+ parent_attributes, parent_formatter, parent_deep_format_keys = @attributes, @key_formatter, @deep_format_keys
305
354
  @attributes = BLANK
306
355
  yield
307
356
  @attributes
308
357
  ensure
309
- @attributes, @key_formatter = parent_attributes, parent_formatter
358
+ @attributes, @key_formatter, @deep_format_keys = parent_attributes, parent_formatter, parent_deep_format_keys
310
359
  end
311
360
 
312
361
  def _is_collection?(object)
313
- _object_respond_to?(object, :map, :count) && NON_ENUMERABLES.none?{ |klass| klass === object }
362
+ object.respond_to?(:map) && object.respond_to?(:count) && !(::Struct === object)
314
363
  end
315
364
 
316
365
  def _blank?(value=@attributes)
317
366
  BLANK == value
318
367
  end
319
-
320
- def _object_respond_to?(object, *methods)
321
- methods.all?{ |m| object.respond_to?(m) }
322
- end
323
368
  end
324
369
 
325
370
  require 'jbuilder/railtie' if defined?(Rails)
@@ -1,6 +1,5 @@
1
1
  require 'test_helper'
2
- require 'jbuilder/dependency_tracker'
3
-
2
+ require 'jbuilder/jbuilder_dependency_tracker'
4
3
 
5
4
  class FakeTemplate
6
5
  attr_reader :source, :handler
@@ -61,7 +60,7 @@ class JbuilderDependencyTrackerTest < ActiveSupport::TestCase
61
60
  assert_equal %w[comments/comment], dependencies
62
61
  end
63
62
 
64
- test 'detects explicit depedency' do
63
+ test 'detects explicit dependency' do
65
64
  dependencies = track_dependencies <<-RUBY
66
65
  # Template Dependency: path/to/partial
67
66
  json.foo 'bar'
@@ -43,4 +43,26 @@ class JbuilderGeneratorTest < Rails::Generators::TestCase
43
43
  assert_no_match %r{:created_at, :updated_at}, content
44
44
  end
45
45
  end
46
+
47
+ test 'namespaced views are generated correctly for index' do
48
+ run_generator %w(Admin::Post --model-name=Post)
49
+
50
+ assert_file 'app/views/admin/posts/index.json.jbuilder' do |content|
51
+ assert_match %r{json\.array! @posts, partial: "admin/posts/post", as: :post}, content
52
+ end
53
+
54
+ assert_file 'app/views/admin/posts/show.json.jbuilder' do |content|
55
+ assert_match %r{json\.partial! "admin/posts/post", post: @post}, content
56
+ end
57
+ end
58
+
59
+ test 'handles virtual attributes' do
60
+ run_generator %w(Message content:rich_text video:attachment photos:attachments)
61
+
62
+ assert_file 'app/views/messages/_message.json.jbuilder' do |content|
63
+ assert_match %r{json\.content message\.content\.to_s}, content
64
+ assert_match %r{json\.video url_for\(message\.video\)}, content
65
+ assert_match %r{json\.photos do\n json\.array!\(message\.photos\) do \|photo\|\n json\.id photo\.id\n json\.url url_for\(photo\)\n end\nend}, content
66
+ end
67
+ end
46
68
  end
@@ -49,6 +49,17 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
49
49
  assert_equal "hello", result["content"]
50
50
  end
51
51
 
52
+ test "partial by name with hash value omission (punning) as last statement [3.1+]" do
53
+ major, minor, _ = RUBY_VERSION.split(".").map(&:to_i)
54
+ return unless (major == 3 && minor >= 1) || major > 3
55
+
56
+ result = render(<<-JBUILDER)
57
+ content = "hello"
58
+ json.partial! "partial", content:
59
+ JBUILDER
60
+ assert_equal "hello", result["content"]
61
+ end
62
+
52
63
  test "partial by options containing nested locals" do
53
64
  result = render('json.partial! partial: "partial", locals: { content: "hello" }')
54
65
  assert_equal "hello", result["content"]
@@ -73,6 +84,14 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
73
84
  assert_equal "Pavel", result[5]["author"]["first_name"]
74
85
  end
75
86
 
87
+ test "partial collection by name with caching" do
88
+ result = render('json.partial! "post", collection: @posts, cached: true, as: :post', posts: POSTS)
89
+ assert_equal 10, result.count
90
+ assert_equal "Post #5", result[4]["body"]
91
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
92
+ assert_equal "Pavel", result[5]["author"]["first_name"]
93
+ end
94
+
76
95
  test "partial collection by name with string local" do
77
96
  result = render('json.partial! "post", collection: @posts, as: "post"', posts: POSTS)
78
97
  assert_equal 10, result.count
@@ -90,10 +109,12 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
90
109
  end
91
110
 
92
111
  test "nil partial collection by name" do
112
+ Jbuilder::CollectionRenderer.expects(:new).never
93
113
  assert_equal [], render('json.partial! "post", collection: @posts, as: :post', posts: nil)
94
114
  end
95
115
 
96
116
  test "nil partial collection by options" do
117
+ Jbuilder::CollectionRenderer.expects(:new).never
97
118
  assert_equal [], render('json.partial! partial: "post", collection: @posts, as: :post', posts: nil)
98
119
  end
99
120
 
@@ -105,7 +126,13 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
105
126
  assert_equal "Pavel", result[5]["author"]["first_name"]
106
127
  end
107
128
 
129
+ test "empty array of partials from empty collection" do
130
+ Jbuilder::CollectionRenderer.expects(:new).never
131
+ assert_equal [], render('json.array! @posts, partial: "post", as: :post', posts: [])
132
+ end
133
+
108
134
  test "empty array of partials from nil collection" do
135
+ Jbuilder::CollectionRenderer.expects(:new).never
109
136
  assert_equal [], render('json.array! @posts, partial: "post", as: :post', posts: nil)
110
137
  end
111
138
 
@@ -118,10 +145,17 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
118
145
  end
119
146
 
120
147
  test "empty array of partials under key from nil collection" do
148
+ Jbuilder::CollectionRenderer.expects(:new).never
121
149
  result = render('json.posts @posts, partial: "post", as: :post', posts: nil)
122
150
  assert_equal [], result["posts"]
123
151
  end
124
152
 
153
+ test "empty array of partials under key from an empy collection" do
154
+ Jbuilder::CollectionRenderer.expects(:new).never
155
+ result = render('json.posts @posts, partial: "post", as: :post', posts: [])
156
+ assert_equal [], result["posts"]
157
+ end
158
+
125
159
  test "object fragment caching" do
126
160
  render(<<-JBUILDER)
127
161
  json.cache! "cache-key" do
@@ -159,7 +193,7 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
159
193
  end
160
194
 
161
195
  test "object fragment caching with expiry" do
162
- travel_to "2018-05-12 11:29:00 -0400"
196
+ travel_to Time.iso8601("2018-05-12T11:29:00-04:00")
163
197
 
164
198
  render <<-JBUILDER
165
199
  json.cache! "cache-key", expires_in: 1.minute do
@@ -283,6 +317,99 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
283
317
  assert_equal "David", result["firstName"]
284
318
  end
285
319
 
320
+ test "returns an empty array for an empty collection" do
321
+ Jbuilder::CollectionRenderer.expects(:new).never
322
+ result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: [])
323
+
324
+ # Do not use #assert_empty as it is important to ensure that the type of the JSON result is an array.
325
+ assert_equal [], result
326
+ end
327
+
328
+ test "works with an enumerable object" do
329
+ enumerable_class = Class.new do
330
+ include Enumerable
331
+
332
+ def each(&block)
333
+ [].each(&block)
334
+ end
335
+ end
336
+
337
+ result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: enumerable_class.new)
338
+
339
+ # Do not use #assert_empty as it is important to ensure that the type of the JSON result is an array.
340
+ assert_equal [], result
341
+ end
342
+
343
+ test "supports the cached: true option" do
344
+ result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: POSTS)
345
+
346
+ assert_equal 10, result.count
347
+ assert_equal "Post #5", result[4]["body"]
348
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
349
+ assert_equal "Pavel", result[5]["author"]["first_name"]
350
+
351
+ expected = {
352
+ "id" => 1,
353
+ "body" => "Post #1",
354
+ "author" => {
355
+ "first_name" => "David",
356
+ "last_name" => "Heinemeier Hansson"
357
+ }
358
+ }
359
+
360
+ assert_equal expected, Rails.cache.read("post-1")
361
+
362
+ result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: POSTS)
363
+
364
+ assert_equal 10, result.count
365
+ assert_equal "Post #5", result[4]["body"]
366
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
367
+ assert_equal "Pavel", result[5]["author"]["first_name"]
368
+ end
369
+
370
+ test "supports the cached: ->() {} option" do
371
+ result = render('json.array! @posts, partial: "post", as: :post, cached: ->(post) { [post, "foo"] }', posts: POSTS)
372
+
373
+ assert_equal 10, result.count
374
+ assert_equal "Post #5", result[4]["body"]
375
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
376
+ assert_equal "Pavel", result[5]["author"]["first_name"]
377
+
378
+ expected = {
379
+ "id" => 1,
380
+ "body" => "Post #1",
381
+ "author" => {
382
+ "first_name" => "David",
383
+ "last_name" => "Heinemeier Hansson"
384
+ }
385
+ }
386
+
387
+ assert_equal expected, Rails.cache.read("post-1/foo")
388
+
389
+ result = render('json.array! @posts, partial: "post", as: :post, cached: ->(post) { [post, "foo"] }', posts: POSTS)
390
+
391
+ assert_equal 10, result.count
392
+ assert_equal "Post #5", result[4]["body"]
393
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
394
+ assert_equal "Pavel", result[5]["author"]["first_name"]
395
+ end
396
+
397
+ test "raises an error on a render call with the :layout option" do
398
+ error = assert_raises NotImplementedError do
399
+ render('json.array! @posts, partial: "post", as: :post, layout: "layout"', posts: POSTS)
400
+ end
401
+
402
+ assert_equal "The `:layout' option is not supported in collection rendering.", error.message
403
+ end
404
+
405
+ test "raises an error on a render call with the :spacer_template option" do
406
+ error = assert_raises NotImplementedError do
407
+ render('json.array! @posts, partial: "post", as: :post, spacer_template: "template"', posts: POSTS)
408
+ end
409
+
410
+ assert_equal "The `:spacer_template' option is not supported in collection rendering.", error.message
411
+ end
412
+
286
413
  private
287
414
  def render(*args)
288
415
  JSON.load render_without_parsing(*args)
@@ -290,7 +417,7 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
290
417
 
291
418
  def render_without_parsing(source, assigns = {})
292
419
  view = build_view(fixtures: PARTIALS.merge("source.json.jbuilder" => source), assigns: assigns)
293
- view.render(template: "source.json.jbuilder")
420
+ view.render(template: "source")
294
421
  end
295
422
 
296
423
  def build_view(options = {})
@@ -298,14 +425,12 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
298
425
  lookup_context = ActionView::LookupContext.new([ resolver ], {}, [""])
299
426
  controller = ActionView::TestCase::TestController.new
300
427
 
301
- # TODO: Use with_empty_template_cache unconditionally after dropping support for Rails <6.0.
302
- view = if ActionView::Base.respond_to?(:with_empty_template_cache)
303
- ActionView::Base.with_empty_template_cache.new(lookup_context, options.fetch(:assigns, {}), controller)
304
- else
305
- ActionView::Base.new(lookup_context, options.fetch(:assigns, {}), controller)
306
- end
428
+ view = ActionView::Base.with_empty_template_cache.new(lookup_context, options.fetch(:assigns, {}), controller)
307
429
 
308
430
  def view.view_cache_dependencies; []; end
431
+ def view.combined_fragment_cache_key(key) [ key ] end
432
+ def view.cache_fragment_name(key, *) key end
433
+ def view.fragment_name_with_digest(key) key end
309
434
 
310
435
  view
311
436
  end