json 1.7.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +18 -10
  4. data/{CHANGES → CHANGES.md} +217 -69
  5. data/Gemfile +11 -12
  6. data/{COPYING-json-jruby → LICENSE} +5 -6
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/{README.rdoc → README.md} +188 -137
  9. data/Rakefile +52 -37
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +38 -7
  12. data/ext/json/ext/generator/depend +1 -0
  13. data/ext/json/ext/generator/extconf.rb +1 -10
  14. data/ext/json/ext/generator/generator.c +239 -133
  15. data/ext/json/ext/generator/generator.h +35 -26
  16. data/ext/json/ext/parser/depend +1 -0
  17. data/ext/json/ext/parser/extconf.rb +2 -9
  18. data/ext/json/ext/parser/parser.c +446 -514
  19. data/ext/json/ext/parser/parser.h +23 -9
  20. data/ext/json/ext/parser/parser.rl +177 -208
  21. data/ext/json/extconf.rb +2 -0
  22. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  23. data/java/src/json/ext/Generator.java +49 -20
  24. data/java/src/json/ext/GeneratorMethods.java +1 -2
  25. data/java/src/json/ext/GeneratorService.java +1 -2
  26. data/java/src/json/ext/GeneratorState.java +25 -57
  27. data/java/src/json/ext/OptionsReader.java +5 -5
  28. data/java/src/json/ext/Parser.java +141 -419
  29. data/java/src/json/ext/Parser.rl +57 -128
  30. data/java/src/json/ext/ParserService.java +1 -2
  31. data/java/src/json/ext/RuntimeInfo.java +1 -6
  32. data/java/src/json/ext/StringDecoder.java +1 -2
  33. data/java/src/json/ext/StringEncoder.java +5 -0
  34. data/java/src/json/ext/Utils.java +1 -2
  35. data/json-java.gemspec +17 -2
  36. data/json.gemspec +0 -0
  37. data/json_pure.gemspec +25 -26
  38. data/lib/json.rb +3 -2
  39. data/lib/json/add/bigdecimal.rb +10 -2
  40. data/lib/json/add/complex.rb +9 -2
  41. data/lib/json/add/core.rb +1 -0
  42. data/lib/json/add/date.rb +1 -1
  43. data/lib/json/add/date_time.rb +1 -1
  44. data/lib/json/add/exception.rb +1 -1
  45. data/lib/json/add/ostruct.rb +3 -3
  46. data/lib/json/add/range.rb +1 -1
  47. data/lib/json/add/rational.rb +8 -2
  48. data/lib/json/add/regexp.rb +3 -3
  49. data/lib/json/add/set.rb +29 -0
  50. data/lib/json/add/struct.rb +1 -1
  51. data/lib/json/add/symbol.rb +1 -1
  52. data/lib/json/add/time.rb +6 -3
  53. data/lib/json/common.rb +51 -66
  54. data/lib/json/ext.rb +0 -6
  55. data/lib/json/generic_object.rb +36 -4
  56. data/lib/json/pure.rb +2 -8
  57. data/lib/json/pure/generator.rb +106 -119
  58. data/lib/json/pure/parser.rb +48 -88
  59. data/lib/json/version.rb +2 -1
  60. data/references/rfc7159.txt +899 -0
  61. data/tests/fixtures/fail18.json +1 -1
  62. data/tests/fixtures/obsolete_fail1.json +1 -0
  63. data/tests/{test_json_addition.rb → json_addition_test.rb} +53 -38
  64. data/tests/json_common_interface_test.rb +126 -0
  65. data/tests/json_encoding_test.rb +107 -0
  66. data/tests/json_ext_parser_test.rb +15 -0
  67. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  68. data/tests/json_generator_test.rb +421 -0
  69. data/tests/json_generic_object_test.rb +82 -0
  70. data/tests/json_parser_test.rb +472 -0
  71. data/tests/json_string_matching_test.rb +38 -0
  72. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  73. data/tools/diff.sh +18 -0
  74. data/tools/fuzz.rb +1 -9
  75. metadata +49 -72
  76. data/COPYING +0 -58
  77. data/GPL +0 -340
  78. data/TODO +0 -1
  79. data/data/example.json +0 -1
  80. data/data/index.html +0 -38
  81. data/data/prototype.js +0 -4184
  82. data/tests/fixtures/fail1.json +0 -1
  83. data/tests/test_json.rb +0 -539
  84. data/tests/test_json_encoding.rb +0 -65
  85. data/tests/test_json_generate.rb +0 -251
  86. data/tests/test_json_generic_object.rb +0 -35
  87. data/tests/test_json_string_matching.rb +0 -40
  88. data/tests/test_json_unicode.rb +0 -72
@@ -0,0 +1,421 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # frozen_string_literal: false
4
+
5
+ require 'test_helper'
6
+
7
+ class JSONGeneratorTest < Test::Unit::TestCase
8
+ include JSON
9
+
10
+ def setup
11
+ @hash = {
12
+ 'a' => 2,
13
+ 'b' => 3.141,
14
+ 'c' => 'c',
15
+ 'd' => [ 1, "b", 3.14 ],
16
+ 'e' => { 'foo' => 'bar' },
17
+ 'g' => "\"\0\037",
18
+ 'h' => 1000.0,
19
+ 'i' => 0.001
20
+ }
21
+ @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
22
+ '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
23
+ @json3 = <<'EOT'.chomp
24
+ {
25
+ "a": 2,
26
+ "b": 3.141,
27
+ "c": "c",
28
+ "d": [
29
+ 1,
30
+ "b",
31
+ 3.14
32
+ ],
33
+ "e": {
34
+ "foo": "bar"
35
+ },
36
+ "g": "\"\u0000\u001f",
37
+ "h": 1000.0,
38
+ "i": 0.001
39
+ }
40
+ EOT
41
+ end
42
+
43
+ def silence
44
+ v = $VERBOSE
45
+ $VERBOSE = nil
46
+ yield
47
+ ensure
48
+ $VERBOSE = v
49
+ end
50
+
51
+ def test_remove_const_segv
52
+ return if RUBY_ENGINE == 'jruby'
53
+ stress = GC.stress
54
+ const = JSON::SAFE_STATE_PROTOTYPE.dup
55
+
56
+ bignum_too_long_to_embed_as_string = 1234567890123456789012345
57
+ expect = bignum_too_long_to_embed_as_string.to_s
58
+ GC.stress = true
59
+
60
+ 10.times do |i|
61
+ tmp = bignum_too_long_to_embed_as_string.to_json
62
+ raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
63
+ end
64
+
65
+ silence do
66
+ JSON.const_set :SAFE_STATE_PROTOTYPE, nil
67
+ end
68
+
69
+ 10.times do |i|
70
+ assert_raise TypeError do
71
+ bignum_too_long_to_embed_as_string.to_json
72
+ end
73
+ end
74
+ ensure
75
+ GC.stress = stress
76
+ silence do
77
+ JSON.const_set :SAFE_STATE_PROTOTYPE, const
78
+ end
79
+ end if JSON.const_defined?("Ext")
80
+
81
+ def test_generate
82
+ json = generate(@hash)
83
+ assert_equal(parse(@json2), parse(json))
84
+ json = JSON[@hash]
85
+ assert_equal(parse(@json2), parse(json))
86
+ parsed_json = parse(json)
87
+ assert_equal(@hash, parsed_json)
88
+ json = generate({1=>2})
89
+ assert_equal('{"1":2}', json)
90
+ parsed_json = parse(json)
91
+ assert_equal({"1"=>2}, parsed_json)
92
+ assert_equal '666', generate(666)
93
+ end
94
+
95
+ def test_generate_pretty
96
+ json = pretty_generate(@hash)
97
+ # hashes aren't (insertion) ordered on every ruby implementation
98
+ # assert_equal(@json3, json)
99
+ assert_equal(parse(@json3), parse(json))
100
+ parsed_json = parse(json)
101
+ assert_equal(@hash, parsed_json)
102
+ json = pretty_generate({1=>2})
103
+ assert_equal(<<'EOT'.chomp, json)
104
+ {
105
+ "1": 2
106
+ }
107
+ EOT
108
+ parsed_json = parse(json)
109
+ assert_equal({"1"=>2}, parsed_json)
110
+ assert_equal '666', pretty_generate(666)
111
+ end
112
+
113
+ def test_generate_custom
114
+ state = State.new(:space_before => " ", :space => " ", :indent => "<i>", :object_nl => "\n", :array_nl => "<a_nl>")
115
+ json = generate({1=>{2=>3,4=>[5,6]}}, state)
116
+ assert_equal(<<'EOT'.chomp, json)
117
+ {
118
+ <i>"1" : {
119
+ <i><i>"2" : 3,
120
+ <i><i>"4" : [<a_nl><i><i><i>5,<a_nl><i><i><i>6<a_nl><i><i>]
121
+ <i>}
122
+ }
123
+ EOT
124
+ end
125
+
126
+ def test_fast_generate
127
+ json = fast_generate(@hash)
128
+ assert_equal(parse(@json2), parse(json))
129
+ parsed_json = parse(json)
130
+ assert_equal(@hash, parsed_json)
131
+ json = fast_generate({1=>2})
132
+ assert_equal('{"1":2}', json)
133
+ parsed_json = parse(json)
134
+ assert_equal({"1"=>2}, parsed_json)
135
+ assert_equal '666', fast_generate(666)
136
+ end
137
+
138
+ def test_own_state
139
+ state = State.new
140
+ json = generate(@hash, state)
141
+ assert_equal(parse(@json2), parse(json))
142
+ parsed_json = parse(json)
143
+ assert_equal(@hash, parsed_json)
144
+ json = generate({1=>2}, state)
145
+ assert_equal('{"1":2}', json)
146
+ parsed_json = parse(json)
147
+ assert_equal({"1"=>2}, parsed_json)
148
+ assert_equal '666', generate(666, state)
149
+ end
150
+
151
+ def test_states
152
+ json = generate({1=>2}, nil)
153
+ assert_equal('{"1":2}', json)
154
+ s = JSON.state.new
155
+ assert s.check_circular?
156
+ assert s[:check_circular?]
157
+ h = { 1=>2 }
158
+ h[3] = h
159
+ assert_raise(JSON::NestingError) { generate(h) }
160
+ assert_raise(JSON::NestingError) { generate(h, s) }
161
+ s = JSON.state.new
162
+ a = [ 1, 2 ]
163
+ a << a
164
+ assert_raise(JSON::NestingError) { generate(a, s) }
165
+ assert s.check_circular?
166
+ assert s[:check_circular?]
167
+ end
168
+
169
+ def test_pretty_state
170
+ state = PRETTY_STATE_PROTOTYPE.dup
171
+ assert_equal({
172
+ :allow_nan => false,
173
+ :array_nl => "\n",
174
+ :ascii_only => false,
175
+ :buffer_initial_length => 1024,
176
+ :depth => 0,
177
+ :indent => " ",
178
+ :max_nesting => 100,
179
+ :object_nl => "\n",
180
+ :space => " ",
181
+ :space_before => "",
182
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
183
+ end
184
+
185
+ def test_safe_state
186
+ state = SAFE_STATE_PROTOTYPE.dup
187
+ assert_equal({
188
+ :allow_nan => false,
189
+ :array_nl => "",
190
+ :ascii_only => false,
191
+ :buffer_initial_length => 1024,
192
+ :depth => 0,
193
+ :indent => "",
194
+ :max_nesting => 100,
195
+ :object_nl => "",
196
+ :space => "",
197
+ :space_before => "",
198
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
199
+ end
200
+
201
+ def test_fast_state
202
+ state = FAST_STATE_PROTOTYPE.dup
203
+ assert_equal({
204
+ :allow_nan => false,
205
+ :array_nl => "",
206
+ :ascii_only => false,
207
+ :buffer_initial_length => 1024,
208
+ :depth => 0,
209
+ :indent => "",
210
+ :max_nesting => 0,
211
+ :object_nl => "",
212
+ :space => "",
213
+ :space_before => "",
214
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
215
+ end
216
+
217
+ def test_allow_nan
218
+ assert_raise(GeneratorError) { generate([JSON::NaN]) }
219
+ assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
220
+ assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
221
+ assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
222
+ assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
223
+ assert_raise(GeneratorError) { generate([JSON::Infinity]) }
224
+ assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
225
+ assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
226
+ assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
227
+ assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
228
+ assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
229
+ assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
230
+ assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
231
+ assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
232
+ assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
233
+ end
234
+
235
+ def test_depth
236
+ ary = []; ary << ary
237
+ assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
238
+ assert_raise(JSON::NestingError) { generate(ary) }
239
+ assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
240
+ assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
241
+ assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
242
+ assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
243
+ s = JSON.state.new
244
+ assert_equal 0, s.depth
245
+ assert_raise(JSON::NestingError) { ary.to_json(s) }
246
+ assert_equal 100, s.depth
247
+ end
248
+
249
+ def test_buffer_initial_length
250
+ s = JSON.state.new
251
+ assert_equal 1024, s.buffer_initial_length
252
+ s.buffer_initial_length = 0
253
+ assert_equal 1024, s.buffer_initial_length
254
+ s.buffer_initial_length = -1
255
+ assert_equal 1024, s.buffer_initial_length
256
+ s.buffer_initial_length = 128
257
+ assert_equal 128, s.buffer_initial_length
258
+ end
259
+
260
+ def test_gc
261
+ if respond_to?(:assert_in_out_err)
262
+ assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], [])
263
+ bignum_too_long_to_embed_as_string = 1234567890123456789012345
264
+ expect = bignum_too_long_to_embed_as_string.to_s
265
+ GC.stress = true
266
+
267
+ 10.times do |i|
268
+ tmp = bignum_too_long_to_embed_as_string.to_json
269
+ raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
270
+ end
271
+ EOS
272
+ end
273
+ end if GC.respond_to?(:stress=)
274
+
275
+ def test_configure_using_configure_and_merge
276
+ numbered_state = {
277
+ :indent => "1",
278
+ :space => '2',
279
+ :space_before => '3',
280
+ :object_nl => '4',
281
+ :array_nl => '5'
282
+ }
283
+ state1 = JSON.state.new
284
+ state1.merge(numbered_state)
285
+ assert_equal '1', state1.indent
286
+ assert_equal '2', state1.space
287
+ assert_equal '3', state1.space_before
288
+ assert_equal '4', state1.object_nl
289
+ assert_equal '5', state1.array_nl
290
+ state2 = JSON.state.new
291
+ state2.configure(numbered_state)
292
+ assert_equal '1', state2.indent
293
+ assert_equal '2', state2.space
294
+ assert_equal '3', state2.space_before
295
+ assert_equal '4', state2.object_nl
296
+ assert_equal '5', state2.array_nl
297
+ end
298
+
299
+ def test_configure_hash_conversion
300
+ state = JSON.state.new
301
+ state.configure(:indent => '1')
302
+ assert_equal '1', state.indent
303
+ state = JSON.state.new
304
+ foo = 'foo'
305
+ assert_raise(TypeError) do
306
+ state.configure(foo)
307
+ end
308
+ def foo.to_h
309
+ { :indent => '2' }
310
+ end
311
+ state.configure(foo)
312
+ assert_equal '2', state.indent
313
+ end
314
+
315
+ if defined?(JSON::Ext::Generator)
316
+ def test_broken_bignum # [ruby-core:38867]
317
+ pid = fork do
318
+ x = 1 << 64
319
+ x.class.class_eval do
320
+ def to_s
321
+ end
322
+ end
323
+ begin
324
+ JSON::Ext::Generator::State.new.generate(x)
325
+ exit 1
326
+ rescue TypeError
327
+ exit 0
328
+ end
329
+ end
330
+ _, status = Process.waitpid2(pid)
331
+ assert status.success?
332
+ rescue NotImplementedError
333
+ # forking to avoid modifying core class of a parent process and
334
+ # introducing race conditions of tests are run in parallel
335
+ end
336
+ end
337
+
338
+ def test_hash_likeness_set_symbol
339
+ state = JSON.state.new
340
+ assert_equal nil, state[:foo]
341
+ assert_equal nil.class, state[:foo].class
342
+ assert_equal nil, state['foo']
343
+ state[:foo] = :bar
344
+ assert_equal :bar, state[:foo]
345
+ assert_equal :bar, state['foo']
346
+ state_hash = state.to_hash
347
+ assert_kind_of Hash, state_hash
348
+ assert_equal :bar, state_hash[:foo]
349
+ end
350
+
351
+ def test_hash_likeness_set_string
352
+ state = JSON.state.new
353
+ assert_equal nil, state[:foo]
354
+ assert_equal nil, state['foo']
355
+ state['foo'] = :bar
356
+ assert_equal :bar, state[:foo]
357
+ assert_equal :bar, state['foo']
358
+ state_hash = state.to_hash
359
+ assert_kind_of Hash, state_hash
360
+ assert_equal :bar, state_hash[:foo]
361
+ end
362
+
363
+ def test_json_generate
364
+ assert_raise JSON::GeneratorError do
365
+ assert_equal true, generate(["\xea"])
366
+ end
367
+ end
368
+
369
+ def test_nesting
370
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
371
+ too_deep_ary = eval too_deep
372
+ assert_raise(JSON::NestingError) { generate too_deep_ary }
373
+ assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
374
+ ok = generate too_deep_ary, :max_nesting => 101
375
+ assert_equal too_deep, ok
376
+ ok = generate too_deep_ary, :max_nesting => nil
377
+ assert_equal too_deep, ok
378
+ ok = generate too_deep_ary, :max_nesting => false
379
+ assert_equal too_deep, ok
380
+ ok = generate too_deep_ary, :max_nesting => 0
381
+ assert_equal too_deep, ok
382
+ end
383
+
384
+ def test_backslash
385
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
386
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
387
+ assert_equal json, generate(data)
388
+ #
389
+ data = [ '\\"' ]
390
+ json = '["\\\\\""]'
391
+ assert_equal json, generate(data)
392
+ #
393
+ data = [ '/' ]
394
+ json = '["/"]'
395
+ assert_equal json, generate(data)
396
+ #
397
+ data = ['"']
398
+ json = '["\""]'
399
+ assert_equal json, generate(data)
400
+ #
401
+ data = ["'"]
402
+ json = '["\\\'"]'
403
+ assert_equal '["\'"]', generate(data)
404
+ end
405
+
406
+ def test_string_subclass
407
+ s = Class.new(String) do
408
+ def to_s; self; end
409
+ undef to_json
410
+ end
411
+ assert_nothing_raised(SystemStackError) do
412
+ assert_equal '["foo"]', JSON.generate([s.new('foo')])
413
+ end
414
+ end
415
+
416
+ if defined?(Encoding)
417
+ def test_nonutf8_encoding
418
+ assert_equal("\"5\u{b0}\"", "5\xb0".force_encoding("iso-8859-1").to_json)
419
+ end
420
+ end
421
+ end
@@ -0,0 +1,82 @@
1
+ #frozen_string_literal: false
2
+ require 'test_helper'
3
+
4
+ class JSONGenericObjectTest < Test::Unit::TestCase
5
+ include JSON
6
+
7
+ def setup
8
+ @go = GenericObject[ :a => 1, :b => 2 ]
9
+ end
10
+
11
+ def test_attributes
12
+ assert_equal 1, @go.a
13
+ assert_equal 1, @go[:a]
14
+ assert_equal 2, @go.b
15
+ assert_equal 2, @go[:b]
16
+ assert_nil @go.c
17
+ assert_nil @go[:c]
18
+ end
19
+
20
+ def test_generate_json
21
+ switch_json_creatable do
22
+ assert_equal @go, JSON(JSON(@go), :create_additions => true)
23
+ end
24
+ end
25
+
26
+ def test_parse_json
27
+ assert_kind_of Hash,
28
+ JSON(
29
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
30
+ :create_additions => true
31
+ )
32
+ switch_json_creatable do
33
+ assert_equal @go, l =
34
+ JSON(
35
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
36
+ :create_additions => true
37
+ )
38
+ assert_equal 1, l.a
39
+ assert_equal @go,
40
+ l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
41
+ assert_equal 1, l.a
42
+ assert_equal GenericObject[:a => GenericObject[:b => 2]],
43
+ l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
44
+ assert_equal 2, l.a.b
45
+ end
46
+ end
47
+
48
+ def test_from_hash
49
+ result = GenericObject.from_hash(
50
+ :foo => { :bar => { :baz => true }, :quux => [ { :foobar => true } ] })
51
+ assert_kind_of GenericObject, result.foo
52
+ assert_kind_of GenericObject, result.foo.bar
53
+ assert_equal true, result.foo.bar.baz
54
+ assert_kind_of GenericObject, result.foo.quux.first
55
+ assert_equal true, result.foo.quux.first.foobar
56
+ assert_equal true, GenericObject.from_hash(true)
57
+ end
58
+
59
+ def test_json_generic_object_load
60
+ empty = JSON::GenericObject.load(nil)
61
+ assert_kind_of JSON::GenericObject, empty
62
+ simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}'
63
+ simple = JSON::GenericObject.load(simple_json)
64
+ assert_kind_of JSON::GenericObject, simple
65
+ assert_equal "world", simple.hello
66
+ converting = JSON::GenericObject.load('{ "hello": "world" }')
67
+ assert_kind_of JSON::GenericObject, converting
68
+ assert_equal "world", converting.hello
69
+
70
+ json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world'])
71
+ assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}')
72
+ end
73
+
74
+ private
75
+
76
+ def switch_json_creatable
77
+ JSON::GenericObject.json_creatable = true
78
+ yield
79
+ ensure
80
+ JSON::GenericObject.json_creatable = false
81
+ end
82
+ end