jbuilder 1.5.3 → 2.11.5
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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +108 -0
- data/.gitignore +4 -1
- data/Appraisals +25 -0
- data/CONTRIBUTING.md +106 -0
- data/Gemfile +4 -5
- data/MIT-LICENSE +2 -2
- data/README.md +182 -40
- data/Rakefile +15 -10
- data/gemfiles/rails_5_0.gemfile +10 -0
- data/gemfiles/rails_5_1.gemfile +10 -0
- data/gemfiles/rails_5_2.gemfile +10 -0
- data/gemfiles/rails_6_0.gemfile +10 -0
- data/gemfiles/rails_6_1.gemfile +10 -0
- data/gemfiles/rails_head.gemfile +10 -0
- data/jbuilder.gemspec +25 -8
- data/lib/generators/rails/jbuilder_generator.rb +13 -2
- data/lib/generators/rails/scaffold_controller_generator.rb +9 -3
- data/lib/generators/rails/templates/api_controller.rb +63 -0
- data/lib/generators/rails/templates/controller.rb +18 -22
- data/lib/generators/rails/templates/index.json.jbuilder +1 -4
- data/lib/generators/rails/templates/partial.json.jbuilder +16 -0
- data/lib/generators/rails/templates/show.json.jbuilder +1 -1
- data/lib/jbuilder/blank.rb +11 -0
- data/lib/jbuilder/collection_renderer.rb +109 -0
- data/lib/jbuilder/dependency_tracker.rb +61 -0
- data/lib/jbuilder/errors.rb +24 -0
- data/lib/jbuilder/jbuilder.rb +7 -0
- data/lib/jbuilder/jbuilder_template.rb +228 -67
- data/lib/jbuilder/key_formatter.rb +34 -0
- data/lib/jbuilder/railtie.rb +31 -6
- data/lib/jbuilder.rb +144 -137
- data/test/jbuilder_dependency_tracker_test.rb +72 -0
- data/test/jbuilder_generator_test.rb +31 -4
- data/test/jbuilder_template_test.rb +319 -163
- data/test/jbuilder_test.rb +613 -298
- data/test/scaffold_api_controller_generator_test.rb +70 -0
- data/test/scaffold_controller_generator_test.rb +62 -19
- data/test/test_helper.rb +36 -0
- metadata +47 -22
- data/.travis.yml +0 -38
- data/Gemfile.old +0 -7
data/test/jbuilder_test.rb
CHANGED
@@ -1,295 +1,356 @@
|
|
1
|
-
require '
|
2
|
-
require 'active_support/test_case'
|
1
|
+
require 'test_helper'
|
3
2
|
require 'active_support/inflector'
|
4
3
|
require 'jbuilder'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
unless JbuilderProxy.method_defined? :instance_eval
|
9
|
-
# Faking Object#instance_eval for 1.8 and some newer JRubies
|
10
|
-
class JbuilderProxy
|
11
|
-
def instance_eval(code)
|
12
|
-
eval code
|
13
|
-
end
|
14
|
-
end
|
5
|
+
def jbuild(*args, &block)
|
6
|
+
Jbuilder.new(*args, &block).attributes!
|
15
7
|
end
|
16
8
|
|
9
|
+
Comment = Struct.new(:content, :id)
|
10
|
+
|
17
11
|
class NonEnumerable
|
18
12
|
def initialize(collection)
|
19
13
|
@collection = collection
|
20
14
|
end
|
21
15
|
|
22
|
-
|
23
|
-
|
16
|
+
delegate :map, :count, to: :@collection
|
17
|
+
end
|
18
|
+
|
19
|
+
class VeryBasicWrapper < BasicObject
|
20
|
+
def initialize(thing)
|
21
|
+
@thing = thing
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(name, *args, &block)
|
25
|
+
@thing.send name, *args, &block
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# This is not Struct, because structs are Enumerable
|
30
|
+
class Person
|
31
|
+
attr_reader :name, :age
|
32
|
+
|
33
|
+
def initialize(name, age)
|
34
|
+
@name, @age = name, age
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class RelationMock
|
39
|
+
include Enumerable
|
40
|
+
|
41
|
+
def each(&block)
|
42
|
+
[Person.new('Bob', 30), Person.new('Frank', 50)].each(&block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def empty?
|
46
|
+
false
|
24
47
|
end
|
25
48
|
end
|
26
49
|
|
50
|
+
|
27
51
|
class JbuilderTest < ActiveSupport::TestCase
|
52
|
+
teardown do
|
53
|
+
Jbuilder.send :class_variable_set, '@@key_formatter', nil
|
54
|
+
end
|
55
|
+
|
28
56
|
test 'single key' do
|
29
|
-
|
57
|
+
result = jbuild do |json|
|
30
58
|
json.content 'hello'
|
31
59
|
end
|
32
60
|
|
33
|
-
assert_equal 'hello',
|
61
|
+
assert_equal 'hello', result['content']
|
34
62
|
end
|
35
63
|
|
36
64
|
test 'single key with false value' do
|
37
|
-
|
65
|
+
result = jbuild do |json|
|
38
66
|
json.content false
|
39
67
|
end
|
40
68
|
|
41
|
-
assert_equal false,
|
69
|
+
assert_equal false, result['content']
|
42
70
|
end
|
43
71
|
|
44
72
|
test 'single key with nil value' do
|
45
|
-
|
73
|
+
result = jbuild do |json|
|
46
74
|
json.content nil
|
47
75
|
end
|
48
76
|
|
49
|
-
assert
|
50
|
-
|
77
|
+
assert result.has_key?('content')
|
78
|
+
assert_nil result['content']
|
51
79
|
end
|
52
80
|
|
53
81
|
test 'multiple keys' do
|
54
|
-
|
82
|
+
result = jbuild do |json|
|
55
83
|
json.title 'hello'
|
56
84
|
json.content 'world'
|
57
85
|
end
|
58
86
|
|
59
|
-
|
60
|
-
assert_equal '
|
61
|
-
assert_equal 'world', parsed['content']
|
87
|
+
assert_equal 'hello', result['title']
|
88
|
+
assert_equal 'world', result['content']
|
62
89
|
end
|
63
90
|
|
64
91
|
test 'extracting from object' do
|
65
92
|
person = Struct.new(:name, :age).new('David', 32)
|
66
93
|
|
67
|
-
|
94
|
+
result = jbuild do |json|
|
68
95
|
json.extract! person, :name, :age
|
69
96
|
end
|
70
97
|
|
71
|
-
|
72
|
-
assert_equal
|
73
|
-
assert_equal 32, parsed['age']
|
74
|
-
end
|
75
|
-
|
76
|
-
test 'extracting from object using private method' do
|
77
|
-
person = Struct.new(:name) do
|
78
|
-
private
|
79
|
-
def age
|
80
|
-
32
|
81
|
-
end
|
82
|
-
end.new('David')
|
83
|
-
|
84
|
-
message = 'Private method :age was used to extract value. This will be' +
|
85
|
-
' an error in future versions of Jbuilder'
|
86
|
-
|
87
|
-
::ActiveSupport::Deprecation.expects(:warn).with(message)
|
88
|
-
json = Jbuilder.encode do |json|
|
89
|
-
json.extract! person, :name, :age
|
90
|
-
end
|
98
|
+
assert_equal 'David', result['name']
|
99
|
+
assert_equal 32, result['age']
|
91
100
|
end
|
92
101
|
|
93
|
-
test 'extracting from object using call style
|
102
|
+
test 'extracting from object using call style' do
|
94
103
|
person = Struct.new(:name, :age).new('David', 32)
|
95
104
|
|
96
|
-
|
97
|
-
|
98
|
-
instance_eval 'json.(person, :name, :age)'
|
99
|
-
else
|
100
|
-
instance_eval 'json.call(person, :name, :age)'
|
101
|
-
end
|
105
|
+
result = jbuild do |json|
|
106
|
+
json.(person, :name, :age)
|
102
107
|
end
|
103
108
|
|
104
|
-
|
105
|
-
assert_equal
|
106
|
-
assert_equal 32, parsed['age']
|
109
|
+
assert_equal 'David', result['name']
|
110
|
+
assert_equal 32, result['age']
|
107
111
|
end
|
108
112
|
|
109
113
|
test 'extracting from hash' do
|
110
114
|
person = {:name => 'Jim', :age => 34}
|
111
115
|
|
112
|
-
|
116
|
+
result = jbuild do |json|
|
113
117
|
json.extract! person, :name, :age
|
114
118
|
end
|
115
119
|
|
116
|
-
|
117
|
-
assert_equal
|
118
|
-
assert_equal 34, parsed['age']
|
120
|
+
assert_equal 'Jim', result['name']
|
121
|
+
assert_equal 34, result['age']
|
119
122
|
end
|
120
123
|
|
121
124
|
test 'nesting single child with block' do
|
122
|
-
|
125
|
+
result = jbuild do |json|
|
123
126
|
json.author do
|
124
127
|
json.name 'David'
|
125
128
|
json.age 32
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
129
|
-
|
130
|
-
assert_equal
|
131
|
-
|
132
|
+
assert_equal 'David', result['author']['name']
|
133
|
+
assert_equal 32, result['author']['age']
|
134
|
+
end
|
135
|
+
|
136
|
+
test 'empty block handling' do
|
137
|
+
result = jbuild do |json|
|
138
|
+
json.foo 'bar'
|
139
|
+
json.author do
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
assert_equal 'bar', result['foo']
|
144
|
+
assert !result.key?('author')
|
145
|
+
end
|
146
|
+
|
147
|
+
test 'blocks are additive' do
|
148
|
+
result = jbuild do |json|
|
149
|
+
json.author do
|
150
|
+
json.name 'David'
|
151
|
+
end
|
152
|
+
|
153
|
+
json.author do
|
154
|
+
json.age 32
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
assert_equal 'David', result['author']['name']
|
159
|
+
assert_equal 32, result['author']['age']
|
160
|
+
end
|
161
|
+
|
162
|
+
test 'nested blocks are additive' do
|
163
|
+
result = jbuild do |json|
|
164
|
+
json.author do
|
165
|
+
json.name do
|
166
|
+
json.first 'David'
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
json.author do
|
171
|
+
json.name do
|
172
|
+
json.last 'Heinemeier Hansson'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
assert_equal 'David', result['author']['name']['first']
|
178
|
+
assert_equal 'Heinemeier Hansson', result['author']['name']['last']
|
179
|
+
end
|
180
|
+
|
181
|
+
test 'support merge! method' do
|
182
|
+
result = jbuild do |json|
|
183
|
+
json.merge! 'foo' => 'bar'
|
184
|
+
end
|
185
|
+
|
186
|
+
assert_equal 'bar', result['foo']
|
187
|
+
end
|
188
|
+
|
189
|
+
test 'support merge! method in a block' do
|
190
|
+
result = jbuild do |json|
|
191
|
+
json.author do
|
192
|
+
json.merge! 'name' => 'Pavel'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
assert_equal 'Pavel', result['author']['name']
|
197
|
+
end
|
198
|
+
|
199
|
+
test 'support merge! method with Jbuilder instance' do
|
200
|
+
obj = jbuild do |json|
|
201
|
+
json.foo 'bar'
|
202
|
+
end
|
203
|
+
|
204
|
+
result = jbuild do |json|
|
205
|
+
json.merge! obj
|
206
|
+
end
|
207
|
+
|
208
|
+
assert_equal 'bar', result['foo']
|
209
|
+
end
|
210
|
+
|
211
|
+
test 'blocks are additive via extract syntax' do
|
212
|
+
person = Person.new('Pavel', 27)
|
213
|
+
|
214
|
+
result = jbuild do |json|
|
215
|
+
json.author person, :age
|
216
|
+
json.author person, :name
|
217
|
+
end
|
218
|
+
|
219
|
+
assert_equal 'Pavel', result['author']['name']
|
220
|
+
assert_equal 27, result['author']['age']
|
221
|
+
end
|
222
|
+
|
223
|
+
test 'arrays are additive' do
|
224
|
+
result = jbuild do |json|
|
225
|
+
json.array! %w[foo]
|
226
|
+
json.array! %w[bar]
|
227
|
+
end
|
228
|
+
|
229
|
+
assert_equal %w[foo bar], result
|
132
230
|
end
|
133
231
|
|
134
232
|
test 'nesting multiple children with block' do
|
135
|
-
|
233
|
+
result = jbuild do |json|
|
136
234
|
json.comments do
|
137
235
|
json.child! { json.content 'hello' }
|
138
236
|
json.child! { json.content 'world' }
|
139
237
|
end
|
140
238
|
end
|
141
239
|
|
142
|
-
|
143
|
-
assert_equal '
|
144
|
-
assert_equal 'world', parsed['comments'].second['content']
|
240
|
+
assert_equal 'hello', result['comments'].first['content']
|
241
|
+
assert_equal 'world', result['comments'].second['content']
|
145
242
|
end
|
146
243
|
|
147
244
|
test 'nesting single child with inline extract' do
|
148
|
-
person =
|
149
|
-
attr_reader :name, :age
|
150
|
-
|
151
|
-
def initialize(name, age)
|
152
|
-
@name, @age = name, age
|
153
|
-
end
|
154
|
-
end.new('David', 32)
|
245
|
+
person = Person.new('David', 32)
|
155
246
|
|
156
|
-
|
247
|
+
result = jbuild do |json|
|
157
248
|
json.author person, :name, :age
|
158
249
|
end
|
159
250
|
|
160
|
-
|
161
|
-
assert_equal
|
162
|
-
assert_equal 32, parsed['author']['age']
|
251
|
+
assert_equal 'David', result['author']['name']
|
252
|
+
assert_equal 32, result['author']['age']
|
163
253
|
end
|
164
254
|
|
165
255
|
test 'nesting multiple children from array' do
|
166
256
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
167
257
|
|
168
|
-
|
258
|
+
result = jbuild do |json|
|
169
259
|
json.comments comments, :content
|
170
260
|
end
|
171
261
|
|
172
|
-
|
173
|
-
assert_equal
|
174
|
-
assert_equal '
|
175
|
-
assert_equal 'world', parsed['comments'].second['content']
|
262
|
+
assert_equal ['content'], result['comments'].first.keys
|
263
|
+
assert_equal 'hello', result['comments'].first['content']
|
264
|
+
assert_equal 'world', result['comments'].second['content']
|
176
265
|
end
|
177
266
|
|
178
267
|
test 'nesting multiple children from array when child array is empty' do
|
179
268
|
comments = []
|
180
269
|
|
181
|
-
|
270
|
+
result = jbuild do |json|
|
182
271
|
json.name 'Parent'
|
183
272
|
json.comments comments, :content
|
184
273
|
end
|
185
274
|
|
186
|
-
|
187
|
-
assert_equal
|
188
|
-
assert_equal [], parsed['comments']
|
275
|
+
assert_equal 'Parent', result['name']
|
276
|
+
assert_equal [], result['comments']
|
189
277
|
end
|
190
278
|
|
191
279
|
test 'nesting multiple children from array with inline loop' do
|
192
280
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
193
281
|
|
194
|
-
|
282
|
+
result = jbuild do |json|
|
195
283
|
json.comments comments do |comment|
|
196
284
|
json.content comment.content
|
197
285
|
end
|
198
286
|
end
|
199
287
|
|
200
|
-
|
201
|
-
assert_equal
|
202
|
-
assert_equal '
|
203
|
-
assert_equal 'world', parsed['comments'].second['content']
|
288
|
+
assert_equal ['content'], result['comments'].first.keys
|
289
|
+
assert_equal 'hello', result['comments'].first['content']
|
290
|
+
assert_equal 'world', result['comments'].second['content']
|
204
291
|
end
|
205
292
|
|
206
293
|
test 'handles nil-collections as empty arrays' do
|
207
|
-
|
294
|
+
result = jbuild do |json|
|
208
295
|
json.comments nil do |comment|
|
209
296
|
json.content comment.content
|
210
297
|
end
|
211
298
|
end
|
212
299
|
|
213
|
-
assert_equal [],
|
300
|
+
assert_equal [], result['comments']
|
214
301
|
end
|
215
302
|
|
216
303
|
test 'nesting multiple children from a non-Enumerable that responds to #map' do
|
217
304
|
comments = NonEnumerable.new([ Comment.new('hello', 1), Comment.new('world', 2) ])
|
218
305
|
|
219
|
-
|
306
|
+
result = jbuild do |json|
|
220
307
|
json.comments comments, :content
|
221
308
|
end
|
222
309
|
|
223
|
-
|
224
|
-
assert_equal
|
225
|
-
assert_equal '
|
226
|
-
assert_equal 'world', parsed['comments'].second['content']
|
310
|
+
assert_equal ['content'], result['comments'].first.keys
|
311
|
+
assert_equal 'hello', result['comments'].first['content']
|
312
|
+
assert_equal 'world', result['comments'].second['content']
|
227
313
|
end
|
228
314
|
|
229
|
-
test 'nesting multiple
|
315
|
+
test 'nesting multiple children from a non-Enumerable that responds to #map with inline loop' do
|
230
316
|
comments = NonEnumerable.new([ Comment.new('hello', 1), Comment.new('world', 2) ])
|
231
317
|
|
232
|
-
|
318
|
+
result = jbuild do |json|
|
233
319
|
json.comments comments do |comment|
|
234
320
|
json.content comment.content
|
235
321
|
end
|
236
322
|
end
|
237
323
|
|
238
|
-
|
239
|
-
assert_equal
|
240
|
-
assert_equal '
|
241
|
-
assert_equal 'world', parsed['comments'].second['content']
|
324
|
+
assert_equal ['content'], result['comments'].first.keys
|
325
|
+
assert_equal 'hello', result['comments'].first['content']
|
326
|
+
assert_equal 'world', result['comments'].second['content']
|
242
327
|
end
|
243
328
|
|
244
|
-
test '
|
245
|
-
|
329
|
+
test 'array! casts array-like objects to array before merging' do
|
330
|
+
wrapped_array = VeryBasicWrapper.new(%w[foo bar])
|
246
331
|
|
247
|
-
|
248
|
-
|
249
|
-
json.comments comments do |json, comment|
|
250
|
-
json.content comment.content
|
251
|
-
end
|
252
|
-
end
|
332
|
+
result = jbuild do |json|
|
333
|
+
json.array! wrapped_array
|
253
334
|
end
|
254
335
|
|
255
|
-
|
256
|
-
assert_equal ['content'], parsed['comments'].first.keys
|
257
|
-
assert_equal 'hello', parsed['comments'].first['content']
|
258
|
-
assert_equal 'world', parsed['comments'].second['content']
|
336
|
+
assert_equal %w[foo bar], result
|
259
337
|
end
|
260
338
|
|
261
339
|
test 'nesting multiple children from array with inline loop on root' do
|
262
340
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
263
341
|
|
264
|
-
|
342
|
+
result = jbuild do |json|
|
265
343
|
json.call(comments) do |comment|
|
266
344
|
json.content comment.content
|
267
345
|
end
|
268
346
|
end
|
269
347
|
|
270
|
-
|
271
|
-
assert_equal '
|
272
|
-
assert_equal 'world', parsed.second['content']
|
273
|
-
end
|
274
|
-
|
275
|
-
test 'nesting multiple children from array with inline loop on root with old api' do
|
276
|
-
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
277
|
-
|
278
|
-
json = Jbuilder.encode do |json|
|
279
|
-
::ActiveSupport::Deprecation.silence do
|
280
|
-
json.call(comments) do |json, comment|
|
281
|
-
json.content comment.content
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
parsed = MultiJson.load(json)
|
287
|
-
assert_equal 'hello', parsed.first['content']
|
288
|
-
assert_equal 'world', parsed.second['content']
|
348
|
+
assert_equal 'hello', result.first['content']
|
349
|
+
assert_equal 'world', result.second['content']
|
289
350
|
end
|
290
351
|
|
291
352
|
test 'array nested inside nested hash' do
|
292
|
-
|
353
|
+
result = jbuild do |json|
|
293
354
|
json.author do
|
294
355
|
json.name 'David'
|
295
356
|
json.age 32
|
@@ -301,13 +362,12 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
301
362
|
end
|
302
363
|
end
|
303
364
|
|
304
|
-
|
305
|
-
assert_equal '
|
306
|
-
assert_equal 'world', parsed['author']['comments'].second['content']
|
365
|
+
assert_equal 'hello', result['author']['comments'].first['content']
|
366
|
+
assert_equal 'world', result['author']['comments'].second['content']
|
307
367
|
end
|
308
368
|
|
309
369
|
test 'array nested inside array' do
|
310
|
-
|
370
|
+
result = jbuild do |json|
|
311
371
|
json.comments do
|
312
372
|
json.child! do
|
313
373
|
json.authors do
|
@@ -319,12 +379,13 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
319
379
|
end
|
320
380
|
end
|
321
381
|
|
322
|
-
assert_equal 'david',
|
382
|
+
assert_equal 'david', result['comments'].first['authors'].first['name']
|
323
383
|
end
|
324
384
|
|
325
385
|
test 'directly set an array nested in another array' do
|
326
386
|
data = [ { :department => 'QA', :not_in_json => 'hello', :names => ['John', 'David'] } ]
|
327
|
-
|
387
|
+
|
388
|
+
result = jbuild do |json|
|
328
389
|
json.array! data do |object|
|
329
390
|
json.department object[:department]
|
330
391
|
json.names do
|
@@ -333,294 +394,548 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
333
394
|
end
|
334
395
|
end
|
335
396
|
|
336
|
-
assert_equal 'David',
|
337
|
-
|
338
|
-
end
|
339
|
-
|
340
|
-
test 'directly set an array nested in another array with old api' do
|
341
|
-
data = [ { :department => 'QA', :not_in_json => 'hello', :names => ['John', 'David'] } ]
|
342
|
-
json = Jbuilder.encode do |json|
|
343
|
-
::ActiveSupport::Deprecation.silence do
|
344
|
-
json.array! data do |json, object|
|
345
|
-
json.department object[:department]
|
346
|
-
json.names do
|
347
|
-
json.array! object[:names]
|
348
|
-
end
|
349
|
-
end
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
parsed = MultiJson.load(json)
|
354
|
-
assert_equal 'David', parsed.first['names'].last
|
355
|
-
assert_not_equal 'hello', parsed.first['not_in_json']
|
397
|
+
assert_equal 'David', result[0]['names'].last
|
398
|
+
assert !result[0].key?('not_in_json')
|
356
399
|
end
|
357
400
|
|
358
401
|
test 'nested jbuilder objects' do
|
359
|
-
to_nest = Jbuilder.new
|
360
|
-
|
361
|
-
|
402
|
+
to_nest = Jbuilder.new{ |json| json.nested_value 'Nested Test' }
|
403
|
+
|
404
|
+
result = jbuild do |json|
|
362
405
|
json.value 'Test'
|
363
406
|
json.nested to_nest
|
364
407
|
end
|
365
408
|
|
366
|
-
|
367
|
-
assert_equal
|
409
|
+
expected = {'value' => 'Test', 'nested' => {'nested_value' => 'Nested Test'}}
|
410
|
+
assert_equal expected, result
|
368
411
|
end
|
369
412
|
|
370
413
|
test 'nested jbuilder object via set!' do
|
371
|
-
to_nest = Jbuilder.new
|
372
|
-
|
373
|
-
|
414
|
+
to_nest = Jbuilder.new{ |json| json.nested_value 'Nested Test' }
|
415
|
+
|
416
|
+
result = jbuild do |json|
|
374
417
|
json.value 'Test'
|
375
418
|
json.set! :nested, to_nest
|
376
419
|
end
|
377
420
|
|
378
|
-
|
379
|
-
assert_equal
|
421
|
+
expected = {'value' => 'Test', 'nested' => {'nested_value' => 'Nested Test'}}
|
422
|
+
assert_equal expected, result
|
380
423
|
end
|
381
424
|
|
382
425
|
test 'top-level array' do
|
383
426
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
384
427
|
|
385
|
-
|
386
|
-
json.array!
|
428
|
+
result = jbuild do |json|
|
429
|
+
json.array! comments do |comment|
|
387
430
|
json.content comment.content
|
388
431
|
end
|
389
432
|
end
|
390
433
|
|
391
|
-
|
392
|
-
assert_equal '
|
393
|
-
|
434
|
+
assert_equal 'hello', result.first['content']
|
435
|
+
assert_equal 'world', result.second['content']
|
436
|
+
end
|
437
|
+
|
438
|
+
test 'it allows using next in array block to skip value' do
|
439
|
+
comments = [ Comment.new('hello', 1), Comment.new('skip', 2), Comment.new('world', 3) ]
|
440
|
+
result = jbuild do |json|
|
441
|
+
json.array! comments do |comment|
|
442
|
+
next if comment.id == 2
|
443
|
+
json.content comment.content
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
assert_equal 2, result.length
|
448
|
+
assert_equal 'hello', result.first['content']
|
449
|
+
assert_equal 'world', result.second['content']
|
394
450
|
end
|
395
451
|
|
396
452
|
test 'extract attributes directly from array' do
|
397
453
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
398
454
|
|
399
|
-
|
455
|
+
result = jbuild do |json|
|
400
456
|
json.array! comments, :content, :id
|
401
457
|
end
|
402
458
|
|
403
|
-
|
404
|
-
assert_equal
|
405
|
-
assert_equal
|
406
|
-
assert_equal
|
407
|
-
assert_equal 2, parsed.second['id']
|
459
|
+
assert_equal 'hello', result.first['content']
|
460
|
+
assert_equal 1, result.first['id']
|
461
|
+
assert_equal 'world', result.second['content']
|
462
|
+
assert_equal 2, result.second['id']
|
408
463
|
end
|
409
464
|
|
410
465
|
test 'empty top-level array' do
|
411
466
|
comments = []
|
412
467
|
|
413
|
-
|
414
|
-
json.array!
|
468
|
+
result = jbuild do |json|
|
469
|
+
json.array! comments do |comment|
|
415
470
|
json.content comment.content
|
416
471
|
end
|
417
472
|
end
|
418
473
|
|
419
|
-
assert_equal [],
|
474
|
+
assert_equal [], result
|
420
475
|
end
|
421
476
|
|
422
477
|
test 'dynamically set a key/value' do
|
423
|
-
|
478
|
+
result = jbuild do |json|
|
424
479
|
json.set! :each, 'stuff'
|
425
480
|
end
|
426
481
|
|
427
|
-
assert_equal 'stuff',
|
482
|
+
assert_equal 'stuff', result['each']
|
428
483
|
end
|
429
484
|
|
430
485
|
test 'dynamically set a key/nested child with block' do
|
431
|
-
|
432
|
-
json.set!
|
486
|
+
result = jbuild do |json|
|
487
|
+
json.set! :author do
|
433
488
|
json.name 'David'
|
434
489
|
json.age 32
|
435
490
|
end
|
436
491
|
end
|
437
492
|
|
438
|
-
|
439
|
-
assert_equal
|
440
|
-
assert_equal 32, parsed['author']['age']
|
493
|
+
assert_equal 'David', result['author']['name']
|
494
|
+
assert_equal 32, result['author']['age']
|
441
495
|
end
|
442
496
|
|
443
497
|
test 'dynamically sets a collection' do
|
444
498
|
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
445
499
|
|
446
|
-
|
500
|
+
result = jbuild do |json|
|
447
501
|
json.set! :comments, comments, :content
|
448
502
|
end
|
449
503
|
|
450
|
-
|
451
|
-
assert_equal
|
452
|
-
assert_equal '
|
453
|
-
assert_equal 'world', parsed['comments'].second['content']
|
504
|
+
assert_equal ['content'], result['comments'].first.keys
|
505
|
+
assert_equal 'hello', result['comments'].first['content']
|
506
|
+
assert_equal 'world', result['comments'].second['content']
|
454
507
|
end
|
455
508
|
|
456
509
|
test 'query like object' do
|
457
|
-
|
458
|
-
attr_reader :name, :age
|
459
|
-
|
460
|
-
def initialize(name, age)
|
461
|
-
@name, @age = name, age
|
462
|
-
end
|
463
|
-
end
|
464
|
-
class RelationMock
|
465
|
-
include Enumerable
|
466
|
-
|
467
|
-
def each(&block)
|
468
|
-
[Person.new('Bob', 30), Person.new('Frank', 50)].each(&block)
|
469
|
-
end
|
470
|
-
def empty?
|
471
|
-
false
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
result = Jbuilder.encode do |json|
|
510
|
+
result = jbuild do |json|
|
476
511
|
json.relations RelationMock.new, :name, :age
|
477
512
|
end
|
478
513
|
|
479
|
-
|
480
|
-
assert_equal
|
481
|
-
assert_equal
|
482
|
-
assert_equal 50, parsed['relations'][1]['age']
|
514
|
+
assert_equal 2, result['relations'].length
|
515
|
+
assert_equal 'Bob', result['relations'][0]['name']
|
516
|
+
assert_equal 50, result['relations'][1]['age']
|
483
517
|
end
|
484
518
|
|
485
519
|
test 'initialize via options hash' do
|
486
|
-
jbuilder = Jbuilder.new(:
|
487
|
-
assert_equal 1, jbuilder.instance_eval
|
488
|
-
assert_equal 2, jbuilder.instance_eval
|
520
|
+
jbuilder = Jbuilder.new(key_formatter: 1, ignore_nil: 2)
|
521
|
+
assert_equal 1, jbuilder.instance_eval{ @key_formatter }
|
522
|
+
assert_equal 2, jbuilder.instance_eval{ @ignore_nil }
|
489
523
|
end
|
490
524
|
|
491
525
|
test 'key_format! with parameter' do
|
492
|
-
|
493
|
-
|
494
|
-
|
526
|
+
result = jbuild do |json|
|
527
|
+
json.key_format! camelize: [:lower]
|
528
|
+
json.camel_style 'for JS'
|
529
|
+
end
|
495
530
|
|
496
|
-
assert_equal ['camelStyle'],
|
531
|
+
assert_equal ['camelStyle'], result.keys
|
497
532
|
end
|
498
533
|
|
499
534
|
test 'key_format! with parameter not as an array' do
|
500
|
-
|
501
|
-
|
502
|
-
|
535
|
+
result = jbuild do |json|
|
536
|
+
json.key_format! :camelize => :lower
|
537
|
+
json.camel_style 'for JS'
|
538
|
+
end
|
503
539
|
|
504
|
-
assert_equal ['camelStyle'],
|
540
|
+
assert_equal ['camelStyle'], result.keys
|
505
541
|
end
|
506
542
|
|
507
543
|
test 'key_format! propagates to child elements' do
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
544
|
+
result = jbuild do |json|
|
545
|
+
json.key_format! :upcase
|
546
|
+
json.level1 'one'
|
547
|
+
json.level2 do
|
548
|
+
json.value 'two'
|
549
|
+
end
|
513
550
|
end
|
514
551
|
|
515
|
-
result = json.attributes!
|
516
552
|
assert_equal 'one', result['LEVEL1']
|
517
553
|
assert_equal 'two', result['LEVEL2']['VALUE']
|
518
554
|
end
|
519
555
|
|
520
556
|
test 'key_format! resets after child element' do
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
557
|
+
result = jbuild do |json|
|
558
|
+
json.level2 do
|
559
|
+
json.key_format! :upcase
|
560
|
+
json.value 'two'
|
561
|
+
end
|
562
|
+
json.level1 'one'
|
525
563
|
end
|
526
|
-
json.level1 'one'
|
527
564
|
|
528
|
-
result = json.attributes!
|
529
565
|
assert_equal 'two', result['level2']['VALUE']
|
530
566
|
assert_equal 'one', result['level1']
|
531
567
|
end
|
532
568
|
|
569
|
+
test 'key_format! can be changed in child elements' do
|
570
|
+
result = jbuild do |json|
|
571
|
+
json.key_format! camelize: :lower
|
572
|
+
|
573
|
+
json.level_one do
|
574
|
+
json.key_format! :upcase
|
575
|
+
json.value 'two'
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
assert_equal ['levelOne'], result.keys
|
580
|
+
assert_equal ['VALUE'], result['levelOne'].keys
|
581
|
+
end
|
582
|
+
|
583
|
+
test 'key_format! can be changed in array!' do
|
584
|
+
result = jbuild do |json|
|
585
|
+
json.key_format! camelize: :lower
|
586
|
+
|
587
|
+
json.level_one do
|
588
|
+
json.array! [{value: 'two'}] do |object|
|
589
|
+
json.key_format! :upcase
|
590
|
+
json.value object[:value]
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
assert_equal ['levelOne'], result.keys
|
596
|
+
assert_equal ['VALUE'], result['levelOne'][0].keys
|
597
|
+
end
|
598
|
+
|
533
599
|
test 'key_format! with no parameter' do
|
534
|
-
|
535
|
-
|
536
|
-
|
600
|
+
result = jbuild do |json|
|
601
|
+
json.key_format! :upcase
|
602
|
+
json.lower 'Value'
|
603
|
+
end
|
537
604
|
|
538
|
-
assert_equal ['LOWER'],
|
605
|
+
assert_equal ['LOWER'], result.keys
|
539
606
|
end
|
540
607
|
|
541
608
|
test 'key_format! with multiple steps' do
|
542
|
-
|
543
|
-
|
544
|
-
|
609
|
+
result = jbuild do |json|
|
610
|
+
json.key_format! :upcase, :pluralize
|
611
|
+
json.pill 'foo'
|
612
|
+
end
|
545
613
|
|
546
|
-
assert_equal ['PILLs'],
|
614
|
+
assert_equal ['PILLs'], result.keys
|
547
615
|
end
|
548
616
|
|
549
617
|
test 'key_format! with lambda/proc' do
|
550
|
-
|
551
|
-
|
552
|
-
|
618
|
+
result = jbuild do |json|
|
619
|
+
json.key_format! ->(key){ key + ' and friends' }
|
620
|
+
json.oats 'foo'
|
621
|
+
end
|
553
622
|
|
554
|
-
assert_equal ['oats and friends'],
|
623
|
+
assert_equal ['oats and friends'], result.keys
|
555
624
|
end
|
556
625
|
|
557
|
-
test '
|
558
|
-
|
559
|
-
|
560
|
-
|
626
|
+
test 'key_format! is not applied deeply by default' do
|
627
|
+
names = { first_name: 'camel', last_name: 'case' }
|
628
|
+
result = jbuild do |json|
|
629
|
+
json.key_format! camelize: :lower
|
630
|
+
json.set! :all_names, names
|
631
|
+
end
|
561
632
|
|
562
|
-
assert_equal ['
|
563
|
-
Jbuilder.send(:class_variable_set, '@@key_formatter', Jbuilder::KeyFormatter.new)
|
633
|
+
assert_equal %i[first_name last_name], result['allNames'].keys
|
564
634
|
end
|
565
635
|
|
566
|
-
test '
|
567
|
-
|
568
|
-
json
|
636
|
+
test 'applying key_format! deeply can be enabled per scope' do
|
637
|
+
names = { first_name: 'camel', last_name: 'case' }
|
638
|
+
result = jbuild do |json|
|
639
|
+
json.key_format! camelize: :lower
|
640
|
+
json.scope do
|
641
|
+
json.deep_format_keys!
|
642
|
+
json.set! :all_names, names
|
643
|
+
end
|
644
|
+
json.set! :all_names, names
|
645
|
+
end
|
569
646
|
|
570
|
-
assert_equal [],
|
647
|
+
assert_equal %w[firstName lastName], result['scope']['allNames'].keys
|
648
|
+
assert_equal %i[first_name last_name], result['allNames'].keys
|
649
|
+
end
|
650
|
+
|
651
|
+
test 'applying key_format! deeply can be disabled per scope' do
|
652
|
+
names = { first_name: 'camel', last_name: 'case' }
|
653
|
+
result = jbuild do |json|
|
654
|
+
json.key_format! camelize: :lower
|
655
|
+
json.deep_format_keys!
|
656
|
+
json.set! :all_names, names
|
657
|
+
json.scope do
|
658
|
+
json.deep_format_keys! false
|
659
|
+
json.set! :all_names, names
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
assert_equal %w[firstName lastName], result['allNames'].keys
|
664
|
+
assert_equal %i[first_name last_name], result['scope']['allNames'].keys
|
665
|
+
end
|
666
|
+
|
667
|
+
test 'applying key_format! deeply can be enabled globally' do
|
668
|
+
names = { first_name: 'camel', last_name: 'case' }
|
669
|
+
|
670
|
+
Jbuilder.deep_format_keys true
|
671
|
+
result = jbuild do |json|
|
672
|
+
json.key_format! camelize: :lower
|
673
|
+
json.set! :all_names, names
|
674
|
+
end
|
675
|
+
|
676
|
+
assert_equal %w[firstName lastName], result['allNames'].keys
|
677
|
+
Jbuilder.send(:class_variable_set, '@@deep_format_keys', false)
|
678
|
+
end
|
679
|
+
|
680
|
+
test 'deep key_format! with merge!' do
|
681
|
+
hash = { camel_style: 'for JS' }
|
682
|
+
result = jbuild do |json|
|
683
|
+
json.key_format! camelize: :lower
|
684
|
+
json.deep_format_keys!
|
685
|
+
json.merge! hash
|
686
|
+
end
|
687
|
+
|
688
|
+
assert_equal ['camelStyle'], result.keys
|
689
|
+
end
|
690
|
+
|
691
|
+
test 'deep key_format! with merge! deep' do
|
692
|
+
hash = { camel_style: { sub_attr: 'for JS' } }
|
693
|
+
result = jbuild do |json|
|
694
|
+
json.key_format! camelize: :lower
|
695
|
+
json.deep_format_keys!
|
696
|
+
json.merge! hash
|
697
|
+
end
|
698
|
+
|
699
|
+
assert_equal ['subAttr'], result['camelStyle'].keys
|
700
|
+
end
|
701
|
+
|
702
|
+
test 'deep key_format! with set! array of hashes' do
|
703
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
704
|
+
result = jbuild do |json|
|
705
|
+
json.key_format! camelize: :lower
|
706
|
+
json.deep_format_keys!
|
707
|
+
json.set! :names, names
|
708
|
+
end
|
709
|
+
|
710
|
+
assert_equal %w[firstName lastName], result['names'][0].keys
|
711
|
+
end
|
712
|
+
|
713
|
+
test 'deep key_format! with set! extracting hash from object' do
|
714
|
+
comment = Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })
|
715
|
+
result = jbuild do |json|
|
716
|
+
json.key_format! camelize: :lower
|
717
|
+
json.deep_format_keys!
|
718
|
+
json.set! :comment, comment, :author
|
719
|
+
end
|
720
|
+
|
721
|
+
assert_equal %w[firstName lastName], result['comment']['author'].keys
|
722
|
+
end
|
723
|
+
|
724
|
+
test 'deep key_format! with array! of hashes' do
|
725
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
726
|
+
result = jbuild do |json|
|
727
|
+
json.key_format! camelize: :lower
|
728
|
+
json.deep_format_keys!
|
729
|
+
json.array! names
|
730
|
+
end
|
731
|
+
|
732
|
+
assert_equal %w[firstName lastName], result[0].keys
|
733
|
+
end
|
734
|
+
|
735
|
+
test 'deep key_format! with merge! array of hashes' do
|
736
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
737
|
+
new_names = [{ first_name: 'snake', last_name: 'case' }]
|
738
|
+
result = jbuild do |json|
|
739
|
+
json.key_format! camelize: :lower
|
740
|
+
json.deep_format_keys!
|
741
|
+
json.array! names
|
742
|
+
json.merge! new_names
|
743
|
+
end
|
744
|
+
|
745
|
+
assert_equal %w[firstName lastName], result[1].keys
|
746
|
+
end
|
747
|
+
|
748
|
+
test 'deep key_format! is applied to hash extracted from object' do
|
749
|
+
comment = Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })
|
750
|
+
result = jbuild do |json|
|
751
|
+
json.key_format! camelize: :lower
|
752
|
+
json.deep_format_keys!
|
753
|
+
json.extract! comment, :author
|
754
|
+
end
|
755
|
+
|
756
|
+
assert_equal %w[firstName lastName], result['author'].keys
|
757
|
+
end
|
758
|
+
|
759
|
+
test 'deep key_format! is applied to hash extracted from hash' do
|
760
|
+
comment = {author: { first_name: 'camel', last_name: 'case' }}
|
761
|
+
result = jbuild do |json|
|
762
|
+
json.key_format! camelize: :lower
|
763
|
+
json.deep_format_keys!
|
764
|
+
json.extract! comment, :author
|
765
|
+
end
|
766
|
+
|
767
|
+
assert_equal %w[firstName lastName], result['author'].keys
|
768
|
+
end
|
769
|
+
|
770
|
+
test 'deep key_format! is applied to hash extracted directly from array' do
|
771
|
+
comments = [Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })]
|
772
|
+
result = jbuild do |json|
|
773
|
+
json.key_format! camelize: :lower
|
774
|
+
json.deep_format_keys!
|
775
|
+
json.array! comments, :author
|
776
|
+
end
|
777
|
+
|
778
|
+
assert_equal %w[firstName lastName], result[0]['author'].keys
|
779
|
+
end
|
780
|
+
|
781
|
+
test 'default key_format!' do
|
782
|
+
Jbuilder.key_format camelize: :lower
|
783
|
+
result = jbuild{ |json| json.camel_style 'for JS' }
|
784
|
+
assert_equal ['camelStyle'], result.keys
|
785
|
+
end
|
786
|
+
|
787
|
+
test 'do not use default key formatter directly' do
|
788
|
+
Jbuilder.key_format
|
789
|
+
jbuild{ |json| json.key 'value' }
|
790
|
+
formatter = Jbuilder.send(:class_variable_get, '@@key_formatter')
|
791
|
+
cache = formatter.instance_variable_get('@cache')
|
792
|
+
assert_empty cache
|
571
793
|
end
|
572
794
|
|
573
795
|
test 'ignore_nil! without a parameter' do
|
574
|
-
|
575
|
-
|
576
|
-
|
796
|
+
result = jbuild do |json|
|
797
|
+
json.ignore_nil!
|
798
|
+
json.test nil
|
799
|
+
end
|
577
800
|
|
578
|
-
|
801
|
+
assert_empty result.keys
|
579
802
|
end
|
580
803
|
|
581
804
|
test 'ignore_nil! with parameter' do
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
805
|
+
result = jbuild do |json|
|
806
|
+
json.ignore_nil! true
|
807
|
+
json.name 'Bob'
|
808
|
+
json.dne nil
|
809
|
+
end
|
586
810
|
|
587
|
-
assert_equal ['name'],
|
811
|
+
assert_equal ['name'], result.keys
|
588
812
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
813
|
+
result = jbuild do |json|
|
814
|
+
json.ignore_nil! false
|
815
|
+
json.name 'Bob'
|
816
|
+
json.dne nil
|
817
|
+
end
|
593
818
|
|
594
|
-
assert_equal ['name', 'dne'],
|
819
|
+
assert_equal ['name', 'dne'], result.keys
|
595
820
|
end
|
596
821
|
|
597
822
|
test 'default ignore_nil!' do
|
598
823
|
Jbuilder.ignore_nil
|
599
|
-
json = Jbuilder.new
|
600
|
-
json.name 'Bob'
|
601
|
-
json.dne nil
|
602
824
|
|
603
|
-
|
825
|
+
result = jbuild do |json|
|
826
|
+
json.name 'Bob'
|
827
|
+
json.dne nil
|
828
|
+
end
|
829
|
+
|
830
|
+
assert_equal ['name'], result.keys
|
604
831
|
Jbuilder.send(:class_variable_set, '@@ignore_nil', false)
|
605
832
|
end
|
606
833
|
|
607
834
|
test 'nil!' do
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
835
|
+
result = jbuild do |json|
|
836
|
+
json.key 'value'
|
837
|
+
json.nil!
|
838
|
+
end
|
839
|
+
|
840
|
+
assert_nil result
|
612
841
|
end
|
613
842
|
|
614
843
|
test 'null!' do
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
844
|
+
result = jbuild do |json|
|
845
|
+
json.key 'value'
|
846
|
+
json.null!
|
847
|
+
end
|
848
|
+
|
849
|
+
assert_nil result
|
850
|
+
end
|
851
|
+
|
852
|
+
test 'null! in a block' do
|
853
|
+
result = jbuild do |json|
|
854
|
+
json.author do
|
855
|
+
json.name 'David'
|
856
|
+
end
|
857
|
+
|
858
|
+
json.author do
|
859
|
+
json.null!
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
assert result.key?('author')
|
864
|
+
assert_nil result['author']
|
865
|
+
end
|
866
|
+
|
867
|
+
test 'empty attributes respond to empty?' do
|
868
|
+
attributes = Jbuilder.new.attributes!
|
869
|
+
assert attributes.empty?
|
870
|
+
assert attributes.blank?
|
871
|
+
assert !attributes.present?
|
872
|
+
end
|
873
|
+
|
874
|
+
test 'throws ArrayError when trying to add a key to an array' do
|
875
|
+
assert_raise Jbuilder::ArrayError do
|
876
|
+
jbuild do |json|
|
877
|
+
json.array! %w[foo bar]
|
878
|
+
json.fizz "buzz"
|
879
|
+
end
|
880
|
+
end
|
881
|
+
end
|
882
|
+
|
883
|
+
test 'throws NullError when trying to add properties to null' do
|
884
|
+
assert_raise Jbuilder::NullError do
|
885
|
+
jbuild do |json|
|
886
|
+
json.null!
|
887
|
+
json.foo 'bar'
|
888
|
+
end
|
889
|
+
end
|
619
890
|
end
|
620
891
|
|
621
|
-
test 'throws
|
622
|
-
|
623
|
-
|
624
|
-
|
892
|
+
test 'throws NullError when trying to add properties to null using block syntax' do
|
893
|
+
assert_raise Jbuilder::NullError do
|
894
|
+
jbuild do |json|
|
895
|
+
json.author do
|
896
|
+
json.null!
|
897
|
+
end
|
898
|
+
|
899
|
+
json.author do
|
900
|
+
json.name "Pavel"
|
901
|
+
end
|
902
|
+
end
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
test "throws MergeError when trying to merge array with non-empty hash" do
|
907
|
+
assert_raise Jbuilder::MergeError do
|
908
|
+
jbuild do |json|
|
909
|
+
json.name "Daniel"
|
910
|
+
json.merge! []
|
911
|
+
end
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
test "throws MergeError when trying to merge hash with array" do
|
916
|
+
assert_raise Jbuilder::MergeError do
|
917
|
+
jbuild do |json|
|
918
|
+
json.array!
|
919
|
+
json.merge!({})
|
920
|
+
end
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
test "throws MergeError when trying to merge invalid objects" do
|
925
|
+
assert_raise Jbuilder::MergeError do
|
926
|
+
jbuild do |json|
|
927
|
+
json.name "Daniel"
|
928
|
+
json.merge! "Nope"
|
929
|
+
end
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
if RUBY_VERSION >= "2.2.10"
|
934
|
+
test "respects JSON encoding customizations" do
|
935
|
+
# Active Support overrides Time#as_json for custom formatting.
|
936
|
+
# Ensure we call #to_json on the final attributes instead of JSON.dump.
|
937
|
+
result = JSON.load(Jbuilder.encode { |json| json.time Time.parse("2018-05-13 11:51:00.485 -0400") })
|
938
|
+
assert_equal "2018-05-13T11:51:00.485-04:00", result["time"]
|
939
|
+
end
|
625
940
|
end
|
626
941
|
end
|