json 1.7.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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