jbuilder 2.2.16 → 2.6.4

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.
@@ -1,16 +1,17 @@
1
- require 'test_helper'
2
- require 'mocha/setup'
3
- require 'action_view'
4
- require 'action_view/testing/resolvers'
5
- require 'active_support/cache'
6
- require 'jbuilder/jbuilder_template'
1
+ require "test_helper"
2
+ require "mocha/setup"
3
+ require "active_model"
4
+ require "action_view"
5
+ require "action_view/testing/resolvers"
6
+ require "active_support/cache"
7
+ require "jbuilder/jbuilder_template"
7
8
 
8
9
  BLOG_POST_PARTIAL = <<-JBUILDER
9
10
  json.extract! blog_post, :id, :body
10
11
  json.author do
11
- name = blog_post.author_name.split(nil, 2)
12
- json.first_name name[0]
13
- json.last_name name[1]
12
+ first_name, last_name = blog_post.author_name.split(nil, 2)
13
+ json.first_name first_name
14
+ json.last_name last_name
14
15
  end
15
16
  JBUILDER
16
17
 
@@ -18,14 +19,37 @@ COLLECTION_PARTIAL = <<-JBUILDER
18
19
  json.extract! collection, :id, :name
19
20
  JBUILDER
20
21
 
22
+ RACER_PARTIAL = <<-JBUILDER
23
+ json.extract! racer, :id, :name
24
+ JBUILDER
25
+
26
+ class Racer
27
+ extend ActiveModel::Naming
28
+ include ActiveModel::Conversion
29
+
30
+ def initialize(id, name)
31
+ @id, @name = id, name
32
+ end
33
+
34
+ attr_reader :id, :name
35
+ end
36
+
37
+
21
38
  BlogPost = Struct.new(:id, :body, :author_name)
22
39
  Collection = Struct.new(:id, :name)
23
- blog_authors = [ 'David Heinemeier Hansson', 'Pavel Pravosud' ].cycle
24
- BLOG_POST_COLLECTION = 10.times.map{ |i| BlogPost.new(i+1, "post body #{i+1}", blog_authors.next) }
25
- COLLECTION_COLLECTION = 5.times.map{ |i| Collection.new(i+1, "collection #{i+1}") }
40
+ blog_authors = [ "David Heinemeier Hansson", "Pavel Pravosud" ].cycle
41
+ BLOG_POST_COLLECTION = Array.new(10){ |i| BlogPost.new(i+1, "post body #{i+1}", blog_authors.next) }
42
+ COLLECTION_COLLECTION = Array.new(5){ |i| Collection.new(i+1, "collection #{i+1}") }
26
43
 
27
44
  ActionView::Template.register_template_handler :jbuilder, JbuilderHandler
28
45
 
46
+ PARTIALS = {
47
+ "_partial.json.jbuilder" => "foo ||= 'hello'; json.content foo",
48
+ "_blog_post.json.jbuilder" => BLOG_POST_PARTIAL,
49
+ "racers/_racer.json.jbuilder" => RACER_PARTIAL,
50
+ "_collection.json.jbuilder" => COLLECTION_PARTIAL
51
+ }
52
+
29
53
  module Rails
30
54
  def self.cache
31
55
  @cache ||= ActiveSupport::Cache::MemoryStore.new
@@ -38,18 +62,15 @@ class JbuilderTemplateTest < ActionView::TestCase
38
62
  Rails.cache.clear
39
63
  end
40
64
 
41
- def partials
42
- {
43
- '_partial.json.jbuilder' => 'foo ||= "hello"; json.content foo',
44
- '_blog_post.json.jbuilder' => BLOG_POST_PARTIAL,
45
- '_collection.json.jbuilder' => COLLECTION_PARTIAL
46
- }
47
- end
48
-
49
- def render_jbuilder(source)
65
+ def jbuild(source)
50
66
  @rendered = []
51
- lookup_context.view_paths = [ActionView::FixtureResolver.new(partials.merge('test.json.jbuilder' => source))]
52
- ActionView::Template.new(source, 'test', JbuilderHandler, :virtual_path => 'test').render(self, {}).strip
67
+ partials = PARTIALS.clone
68
+ partials["test.json.jbuilder"] = source
69
+ resolver = ActionView::FixtureResolver.new(partials)
70
+ lookup_context.view_paths = [resolver]
71
+ template = ActionView::Template.new(source, "test", JbuilderHandler, virtual_path: "test")
72
+ json = template.render(self, {}).strip
73
+ MultiJson.load(json)
53
74
  end
54
75
 
55
76
  def undef_context_methods(*names)
@@ -60,284 +81,361 @@ class JbuilderTemplateTest < ActionView::TestCase
60
81
  end
61
82
  end
62
83
 
63
- def assert_collection_rendered(json, context = nil)
64
- result = MultiJson.load(json)
84
+ def assert_collection_rendered(result, context = nil)
65
85
  result = result.fetch(context) if context
66
86
 
67
87
  assert_equal 10, result.length
68
88
  assert_equal Array, result.class
69
- assert_equal 'post body 5', result[4]['body']
70
- assert_equal 'Heinemeier Hansson', result[2]['author']['last_name']
71
- assert_equal 'Pavel', result[5]['author']['first_name']
89
+ assert_equal "post body 5", result[4]["body"]
90
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
91
+ assert_equal "Pavel", result[5]["author"]["first_name"]
72
92
  end
73
93
 
74
- test 'rendering' do
75
- json = render_jbuilder <<-JBUILDER
76
- json.content 'hello'
94
+ test "rendering" do
95
+ result = jbuild(<<-JBUILDER)
96
+ json.content "hello"
77
97
  JBUILDER
78
98
 
79
- assert_equal 'hello', MultiJson.load(json)['content']
99
+ assert_equal "hello", result["content"]
80
100
  end
81
101
 
82
- test 'key_format! with parameter' do
83
- json = render_jbuilder <<-JBUILDER
84
- json.key_format! :camelize => [:lower]
85
- json.camel_style 'for JS'
102
+ test "key_format! with parameter" do
103
+ result = jbuild(<<-JBUILDER)
104
+ json.key_format! camelize: [:lower]
105
+ json.camel_style "for JS"
86
106
  JBUILDER
87
107
 
88
- assert_equal ['camelStyle'], MultiJson.load(json).keys
108
+ assert_equal ["camelStyle"], result.keys
89
109
  end
90
110
 
91
- test 'key_format! propagates to child elements' do
92
- json = render_jbuilder <<-JBUILDER
111
+ test "key_format! propagates to child elements" do
112
+ result = jbuild(<<-JBUILDER)
93
113
  json.key_format! :upcase
94
- json.level1 'one'
114
+ json.level1 "one"
95
115
  json.level2 do
96
- json.value 'two'
116
+ json.value "two"
97
117
  end
98
118
  JBUILDER
99
119
 
100
- result = MultiJson.load(json)
101
- assert_equal 'one', result['LEVEL1']
102
- assert_equal 'two', result['LEVEL2']['VALUE']
120
+ assert_equal "one", result["LEVEL1"]
121
+ assert_equal "two", result["LEVEL2"]["VALUE"]
103
122
  end
104
123
 
105
- test 'partial! renders partial' do
106
- json = render_jbuilder <<-JBUILDER
107
- json.partial! 'partial'
124
+ test "partial! renders partial" do
125
+ result = jbuild(<<-JBUILDER)
126
+ json.partial! "partial"
108
127
  JBUILDER
109
128
 
110
- assert_equal 'hello', MultiJson.load(json)['content']
129
+ assert_equal "hello", result["content"]
111
130
  end
112
131
 
113
- test 'partial! + locals via :locals option' do
114
- json = render_jbuilder <<-JBUILDER
115
- json.partial! 'partial', locals: { foo: 'howdy' }
132
+ test "partial! + locals via :locals option" do
133
+ result = jbuild(<<-JBUILDER)
134
+ json.partial! "partial", locals: { foo: "howdy" }
116
135
  JBUILDER
117
136
 
118
- assert_equal 'howdy', MultiJson.load(json)['content']
137
+ assert_equal "howdy", result["content"]
119
138
  end
120
139
 
121
- test 'partial! + locals without :locals key' do
122
- json = render_jbuilder <<-JBUILDER
123
- json.partial! 'partial', foo: 'goodbye'
140
+ test "partial! + locals without :locals key" do
141
+ result = jbuild(<<-JBUILDER)
142
+ json.partial! "partial", foo: "goodbye"
124
143
  JBUILDER
125
144
 
126
- assert_equal 'goodbye', MultiJson.load(json)['content']
145
+ assert_equal "goodbye", result["content"]
127
146
  end
128
147
 
129
- test 'partial! renders collections' do
130
- json = render_jbuilder <<-JBUILDER
131
- json.partial! 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
148
+ test "partial! renders collections" do
149
+ result = jbuild(<<-JBUILDER)
150
+ json.partial! "blog_post", collection: BLOG_POST_COLLECTION, as: :blog_post
132
151
  JBUILDER
133
152
 
134
- assert_collection_rendered json
153
+ assert_collection_rendered result
135
154
  end
136
155
 
137
- test 'partial! renders collections when as argument is a string' do
138
- json = render_jbuilder <<-JBUILDER
139
- json.partial! 'blog_post', collection: BLOG_POST_COLLECTION, as: "blog_post"
156
+ test "partial! renders collections when as argument is a string" do
157
+ result = jbuild(<<-JBUILDER)
158
+ json.partial! "blog_post", collection: BLOG_POST_COLLECTION, as: "blog_post"
140
159
  JBUILDER
141
160
 
142
- assert_collection_rendered json
161
+ assert_collection_rendered result
143
162
  end
144
163
 
145
- test 'partial! renders collections as collections' do
146
- json = render_jbuilder <<-JBUILDER
147
- json.partial! 'collection', collection: COLLECTION_COLLECTION, as: :collection
164
+ test "partial! renders collections as collections" do
165
+ result = jbuild(<<-JBUILDER)
166
+ json.partial! "collection", collection: COLLECTION_COLLECTION, as: :collection
148
167
  JBUILDER
149
168
 
150
- assert_equal 5, MultiJson.load(json).length
169
+ assert_equal 5, result.length
151
170
  end
152
171
 
153
- test 'partial! renders as empty array for nil-collection' do
154
- json = render_jbuilder <<-JBUILDER
155
- json.partial! 'blog_post', :collection => nil, :as => :blog_post
172
+ test "partial! renders as empty array for nil-collection" do
173
+ result = jbuild(<<-JBUILDER)
174
+ json.partial! "blog_post", collection: nil, as: :blog_post
156
175
  JBUILDER
157
176
 
158
- assert_equal '[]', json
177
+ assert_equal [], result
159
178
  end
160
179
 
161
- test 'partial! renders collection (alt. syntax)' do
162
- json = render_jbuilder <<-JBUILDER
163
- json.partial! :partial => 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
180
+ test "partial! renders collection (alt. syntax)" do
181
+ result = jbuild(<<-JBUILDER)
182
+ json.partial! partial: "blog_post", collection: BLOG_POST_COLLECTION, as: :blog_post
164
183
  JBUILDER
165
184
 
166
- assert_collection_rendered json
185
+ assert_collection_rendered result
167
186
  end
168
187
 
169
- test 'partial! renders as empty array for nil-collection (alt. syntax)' do
170
- json = render_jbuilder <<-JBUILDER
171
- json.partial! :partial => 'blog_post', :collection => nil, :as => :blog_post
188
+ test "partial! renders as empty array for nil-collection (alt. syntax)" do
189
+ result = jbuild(<<-JBUILDER)
190
+ json.partial! partial: "blog_post", collection: nil, as: :blog_post
172
191
  JBUILDER
173
192
 
174
- assert_equal '[]', json
193
+ assert_equal [], result
175
194
  end
176
195
 
177
- test 'render array of partials' do
178
- json = render_jbuilder <<-JBUILDER
179
- json.array! BLOG_POST_COLLECTION, :partial => 'blog_post', :as => :blog_post
196
+ test "render array of partials" do
197
+ result = jbuild(<<-JBUILDER)
198
+ json.array! BLOG_POST_COLLECTION, partial: "blog_post", as: :blog_post
180
199
  JBUILDER
181
200
 
182
- assert_collection_rendered json
201
+ assert_collection_rendered result
183
202
  end
184
203
 
185
- test 'render array of partials as empty array with nil-collection' do
186
- json = render_jbuilder <<-JBUILDER
187
- json.array! nil, :partial => 'blog_post', :as => :blog_post
204
+ test "render array of partials as empty array with nil-collection" do
205
+ result = jbuild(<<-JBUILDER)
206
+ json.array! nil, partial: "blog_post", as: :blog_post
188
207
  JBUILDER
189
208
 
190
- assert_equal '[]', json
209
+ assert_equal [], result
191
210
  end
192
211
 
193
- test 'render array if partials as a value' do
194
- json = render_jbuilder <<-JBUILDER
195
- json.posts BLOG_POST_COLLECTION, :partial => 'blog_post', :as => :blog_post
212
+ test "render array of partials as a value" do
213
+ result = jbuild(<<-JBUILDER)
214
+ json.posts BLOG_POST_COLLECTION, partial: "blog_post", as: :blog_post
196
215
  JBUILDER
197
216
 
198
- assert_collection_rendered json, 'posts'
217
+ assert_collection_rendered result, "posts"
199
218
  end
200
219
 
201
- test 'render as empty array if partials as a nil value' do
202
- json = render_jbuilder <<-JBUILDER
203
- json.posts nil, :partial => 'blog_post', :as => :blog_post
220
+ test "render as empty array if partials as a nil value" do
221
+ result = jbuild <<-JBUILDER
222
+ json.posts nil, partial: "blog_post", as: :blog_post
204
223
  JBUILDER
205
224
 
206
- assert_equal '{"posts":[]}', json
225
+ assert_equal [], result["posts"]
207
226
  end
208
227
 
209
- test 'cache an empty block' do
228
+ test "cache an empty block" do
210
229
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
211
230
 
212
- render_jbuilder <<-JBUILDER
213
- json.cache! 'nothing' do
231
+ jbuild <<-JBUILDER
232
+ json.cache! "nothing" do
214
233
  end
215
234
  JBUILDER
216
235
 
217
- json = nil
236
+ result = nil
218
237
 
219
238
  assert_nothing_raised do
220
- json = render_jbuilder <<-JBUILDER
221
- json.foo 'bar'
222
- json.cache! 'nothing' do
239
+ result = jbuild(<<-JBUILDER)
240
+ json.foo "bar"
241
+ json.cache! "nothing" do
223
242
  end
224
243
  JBUILDER
225
244
  end
226
245
 
227
- assert_equal 'bar', MultiJson.load(json)['foo']
246
+ assert_equal "bar", result["foo"]
228
247
  end
229
248
 
230
- test 'fragment caching a JSON object' do
249
+ test "fragment caching a JSON object" do
231
250
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
232
251
 
233
- render_jbuilder <<-JBUILDER
234
- json.cache! 'cachekey' do
235
- json.name 'Cache'
252
+ jbuild <<-JBUILDER
253
+ json.cache! "cachekey" do
254
+ json.name "Cache"
236
255
  end
237
256
  JBUILDER
238
257
 
239
- json = render_jbuilder <<-JBUILDER
240
- json.cache! 'cachekey' do
241
- json.name 'Miss'
258
+ result = jbuild(<<-JBUILDER)
259
+ json.cache! "cachekey" do
260
+ json.name "Miss"
242
261
  end
243
262
  JBUILDER
244
263
 
245
- parsed = MultiJson.load(json)
246
- assert_equal 'Cache', parsed['name']
264
+ assert_equal "Cache", result["name"]
247
265
  end
248
266
 
249
- test 'conditionally fragment caching a JSON object' do
267
+ test "conditionally fragment caching a JSON object" do
250
268
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
251
269
 
252
- render_jbuilder <<-JBUILDER
253
- json.cache_if! true, 'cachekey' do
254
- json.test1 'Cache'
270
+ jbuild <<-JBUILDER
271
+ json.cache_if! true, "cachekey" do
272
+ json.test1 "Cache"
255
273
  end
256
- json.cache_if! false, 'cachekey' do
257
- json.test2 'Cache'
274
+ json.cache_if! false, "cachekey" do
275
+ json.test2 "Cache"
258
276
  end
259
277
  JBUILDER
260
278
 
261
- json = render_jbuilder <<-JBUILDER
262
- json.cache_if! true, 'cachekey' do
263
- json.test1 'Miss'
279
+ result = jbuild(<<-JBUILDER)
280
+ json.cache_if! true, "cachekey" do
281
+ json.test1 "Miss"
264
282
  end
265
- json.cache_if! false, 'cachekey' do
266
- json.test2 'Miss'
283
+ json.cache_if! false, "cachekey" do
284
+ json.test2 "Miss"
267
285
  end
268
286
  JBUILDER
269
287
 
270
- parsed = MultiJson.load(json)
271
- assert_equal 'Cache', parsed['test1']
272
- assert_equal 'Miss', parsed['test2']
288
+ assert_equal "Cache", result["test1"]
289
+ assert_equal "Miss", result["test2"]
273
290
  end
274
291
 
275
- test 'fragment caching deserializes an array' do
292
+ test "fragment caching deserializes an array" do
276
293
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
277
294
 
278
- render_jbuilder <<-JBUILDER
279
- json.cache! 'cachekey' do
295
+ jbuild <<-JBUILDER
296
+ json.cache! "cachekey" do
280
297
  json.array! %w[a b c]
281
298
  end
282
299
  JBUILDER
283
300
 
284
- json = render_jbuilder <<-JBUILDER
285
- json.cache! 'cachekey' do
301
+ result = jbuild(<<-JBUILDER)
302
+ json.cache! "cachekey" do
286
303
  json.array! %w[1 2 3]
287
304
  end
288
305
  JBUILDER
289
306
 
290
- parsed = MultiJson.load(json)
291
- assert_equal %w[a b c], parsed
307
+ assert_equal %w[a b c], result
308
+ end
309
+
310
+ test "fragment caching works with current cache digests" do
311
+ undef_context_methods :fragment_name_with_digest
312
+
313
+ @context.expects :cache_fragment_name
314
+ ActiveSupport::Cache.expects :expand_cache_key
315
+
316
+ jbuild <<-JBUILDER
317
+ json.cache! "cachekey" do
318
+ json.name "Cache"
319
+ end
320
+ JBUILDER
321
+ end
322
+
323
+ test "fragment caching uses fragment_cache_key" do
324
+ undef_context_methods :fragment_name_with_digest, :cache_fragment_name
325
+
326
+ @context.expects(:fragment_cache_key).with("cachekey")
327
+
328
+ jbuild <<-JBUILDER
329
+ json.cache! "cachekey" do
330
+ json.name "Cache"
331
+ end
332
+ JBUILDER
292
333
  end
293
334
 
294
- test 'fragment caching works with previous version of cache digests' do
295
- undef_context_methods :cache_fragment_name
335
+ test "fragment caching instrumentation" do
336
+ undef_context_methods :fragment_name_with_digest, :cache_fragment_name
296
337
 
297
- @context.expects :fragment_name_with_digest
338
+ payloads = {}
339
+ ActiveSupport::Notifications.subscribe("read_fragment.action_controller") { |*args| payloads[:read_fragment] = args.last }
340
+ ActiveSupport::Notifications.subscribe("write_fragment.action_controller") { |*args| payloads[:write_fragment] = args.last }
298
341
 
299
- render_jbuilder <<-JBUILDER
300
- json.cache! 'cachekey' do
301
- json.name 'Cache'
342
+ jbuild <<-JBUILDER
343
+ json.cache! "cachekey" do
344
+ json.name "Cache"
302
345
  end
303
346
  JBUILDER
347
+
348
+ assert_equal "jbuilder/cachekey", payloads[:read_fragment][:key]
349
+ assert_equal "jbuilder/cachekey", payloads[:write_fragment][:key]
304
350
  end
305
351
 
306
- test 'fragment caching works with current cache digests' do
352
+ test "current cache digest option accepts options" do
307
353
  undef_context_methods :fragment_name_with_digest
308
354
 
309
- @context.expects :cache_fragment_name
355
+ @context.expects(:cache_fragment_name).with("cachekey", skip_digest: true)
310
356
  ActiveSupport::Cache.expects :expand_cache_key
311
357
 
312
- render_jbuilder <<-JBUILDER
313
- json.cache! 'cachekey' do
314
- json.name 'Cache'
358
+ jbuild <<-JBUILDER
359
+ json.cache! "cachekey", skip_digest: true do
360
+ json.name "Cache"
315
361
  end
316
362
  JBUILDER
317
363
  end
318
364
 
319
- test 'current cache digest option accepts options' do
365
+ test "fragment caching accepts expires_in option" do
320
366
  undef_context_methods :fragment_name_with_digest
321
367
 
322
- @context.expects(:cache_fragment_name).with('cachekey', skip_digest: true)
323
- ActiveSupport::Cache.expects :expand_cache_key
368
+ @context.expects(:cache_fragment_name).with("cachekey", {})
369
+
370
+ jbuild <<-JBUILDER
371
+ json.cache! "cachekey", expires_in: 1.minute do
372
+ json.name "Cache"
373
+ end
374
+ JBUILDER
375
+ end
324
376
 
325
- render_jbuilder <<-JBUILDER
326
- json.cache! 'cachekey', skip_digest: true do
327
- json.name 'Cache'
377
+ test "caching root structure" do
378
+ undef_context_methods :fragment_name_with_digest, :cache_fragment_name
379
+
380
+ cache_miss_result = jbuild <<-JBUILDER
381
+ json.cache_root! "cachekey" do
382
+ json.name "Miss"
328
383
  end
329
384
  JBUILDER
385
+
386
+ cache_hit_result = jbuild <<-JBUILDER
387
+ json.cache_root! "cachekey" do
388
+ json.name "Hit"
389
+ end
390
+ JBUILDER
391
+
392
+ assert_equal cache_miss_result, cache_hit_result
393
+ end
394
+
395
+ test "failing to cache root after attributes have been defined" do
396
+ assert_raises ActionView::Template::Error, "cache_root! can't be used after JSON structures have been defined" do
397
+ jbuild <<-JBUILDER
398
+ json.name "Kaboom"
399
+ json.cache_root! "cachekey" do
400
+ json.name "Miss"
401
+ end
402
+ JBUILDER
403
+ end
330
404
  end
331
405
 
332
- test 'does not perform caching when controller.perform_caching is false' do
406
+ test "does not perform caching when controller.perform_caching is false" do
333
407
  controller.perform_caching = false
334
- render_jbuilder <<-JBUILDER
335
- json.cache! 'cachekey' do
336
- json.name 'Cache'
408
+
409
+ jbuild <<-JBUILDER
410
+ json.cache! "cachekey" do
411
+ json.name "Cache"
337
412
  end
338
413
  JBUILDER
339
414
 
340
- assert_equal Rails.cache.inspect[/entries=(\d+)/, 1], '0'
415
+ assert_equal Rails.cache.inspect[/entries=(\d+)/, 1], "0"
416
+ end
417
+
418
+ test "invokes templates via params via set!" do
419
+ @post = BLOG_POST_COLLECTION.first
420
+
421
+ result = jbuild(<<-JBUILDER)
422
+ json.post @post, partial: "blog_post", as: :blog_post
423
+ JBUILDER
424
+
425
+ assert_equal 1, result["post"]["id"]
426
+ assert_equal "post body 1", result["post"]["body"]
427
+ assert_equal "David", result["post"]["author"]["first_name"]
341
428
  end
342
429
 
430
+ test "invokes templates implicitly for ActiveModel objects" do
431
+ @racer = Racer.new(123, "Chris Harris")
432
+
433
+ result = jbuild(<<-JBUILDER)
434
+ json.partial! @racer
435
+ JBUILDER
436
+
437
+ assert_equal %w[id name], result.keys
438
+ assert_equal 123, result["id"]
439
+ assert_equal "Chris Harris", result["name"]
440
+ end
343
441
  end
@@ -13,9 +13,7 @@ class NonEnumerable
13
13
  @collection = collection
14
14
  end
15
15
 
16
- def map(&block)
17
- @collection.map(&block)
18
- end
16
+ delegate :map, :count, to: :@collection
19
17
  end
20
18
 
21
19
  class VeryBasicWrapper < BasicObject
@@ -688,4 +686,31 @@ class JbuilderTest < ActiveSupport::TestCase
688
686
  end
689
687
  end
690
688
  end
689
+
690
+ test "throws MergeError when trying to merge array with non-empty hash" do
691
+ assert_raise Jbuilder::MergeError do
692
+ jbuild do |json|
693
+ json.name "Daniel"
694
+ json.merge! []
695
+ end
696
+ end
697
+ end
698
+
699
+ test "throws MergeError when trying to merge hash with array" do
700
+ assert_raise Jbuilder::MergeError do
701
+ jbuild do |json|
702
+ json.array!
703
+ json.merge!({})
704
+ end
705
+ end
706
+ end
707
+
708
+ test "throws MergeError when trying to merge invalid objects" do
709
+ assert_raise Jbuilder::MergeError do
710
+ jbuild do |json|
711
+ json.name "Daniel"
712
+ json.merge! "Nope"
713
+ end
714
+ end
715
+ end
691
716
  end