jbuilder 2.2.16 → 2.6.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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