json 1.8.6 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -5
  4. data/{CHANGES → CHANGES.md} +179 -95
  5. data/Gemfile +10 -3
  6. data/LICENSE +56 -0
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/README.md +171 -107
  9. data/Rakefile +33 -22
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +105 -98
  13. data/ext/json/ext/generator/generator.h +0 -6
  14. data/ext/json/ext/parser/extconf.rb +3 -0
  15. data/ext/json/ext/parser/parser.c +376 -480
  16. data/ext/json/ext/parser/parser.h +4 -5
  17. data/ext/json/ext/parser/parser.rl +108 -175
  18. data/ext/json/extconf.rb +0 -1
  19. data/java/src/json/ext/Generator.java +35 -15
  20. data/java/src/json/ext/GeneratorState.java +2 -54
  21. data/java/src/json/ext/OptionsReader.java +1 -1
  22. data/java/src/json/ext/Parser.java +131 -413
  23. data/java/src/json/ext/Parser.rl +47 -122
  24. data/java/src/json/ext/RuntimeInfo.java +0 -4
  25. data/json-java.gemspec +1 -2
  26. data/json.gemspec +0 -0
  27. data/json_pure.gemspec +8 -7
  28. data/lib/json.rb +1 -0
  29. data/lib/json/add/bigdecimal.rb +3 -2
  30. data/lib/json/add/complex.rb +4 -3
  31. data/lib/json/add/core.rb +1 -0
  32. data/lib/json/add/date.rb +1 -1
  33. data/lib/json/add/date_time.rb +1 -1
  34. data/lib/json/add/exception.rb +1 -1
  35. data/lib/json/add/ostruct.rb +3 -3
  36. data/lib/json/add/range.rb +1 -1
  37. data/lib/json/add/rational.rb +3 -2
  38. data/lib/json/add/regexp.rb +3 -3
  39. data/lib/json/add/set.rb +29 -0
  40. data/lib/json/add/struct.rb +1 -1
  41. data/lib/json/add/symbol.rb +1 -1
  42. data/lib/json/add/time.rb +1 -1
  43. data/lib/json/common.rb +26 -54
  44. data/lib/json/ext.rb +0 -6
  45. data/lib/json/generic_object.rb +5 -4
  46. data/lib/json/pure.rb +2 -8
  47. data/lib/json/pure/generator.rb +53 -124
  48. data/lib/json/pure/parser.rb +41 -81
  49. data/lib/json/version.rb +2 -1
  50. data/references/rfc7159.txt +899 -0
  51. data/tests/fixtures/obsolete_fail1.json +1 -0
  52. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  53. data/tests/json_common_interface_test.rb +126 -0
  54. data/tests/json_encoding_test.rb +107 -0
  55. data/tests/json_ext_parser_test.rb +15 -0
  56. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  57. data/tests/{test_json_generate.rb → json_generator_test.rb} +112 -39
  58. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  59. data/tests/json_parser_test.rb +472 -0
  60. data/tests/json_string_matching_test.rb +38 -0
  61. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  62. data/tools/fuzz.rb +1 -9
  63. metadata +22 -37
  64. data/TODO +0 -1
  65. data/data/example.json +0 -1
  66. data/data/index.html +0 -38
  67. data/data/prototype.js +0 -4184
  68. data/tests/fixtures/fail1.json +0 -1
  69. data/tests/test_json.rb +0 -519
  70. data/tests/test_json_encoding.rb +0 -65
  71. data/tests/test_json_string_matching.rb +0 -39
  72. data/tests/test_json_unicode.rb +0 -72
@@ -1,9 +1,7 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
1
+ #frozen_string_literal: false
2
+ require 'test_helper'
3
3
 
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
- class TestJSONGenericObject < Test::Unit::TestCase
4
+ class JSONGenericObjectTest < Test::Unit::TestCase
7
5
  include JSON
8
6
 
9
7
  def setup
@@ -26,11 +24,20 @@ class TestJSONGenericObject < Test::Unit::TestCase
26
24
  end
27
25
 
28
26
  def test_parse_json
29
- assert_kind_of Hash, JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
27
+ assert_kind_of Hash,
28
+ JSON(
29
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
30
+ :create_additions => true
31
+ )
30
32
  switch_json_creatable do
31
- assert_equal @go, l = JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
33
+ assert_equal @go, l =
34
+ JSON(
35
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
36
+ :create_additions => true
37
+ )
32
38
  assert_equal 1, l.a
33
- assert_equal @go, l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
39
+ assert_equal @go,
40
+ l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
34
41
  assert_equal 1, l.a
35
42
  assert_equal GenericObject[:a => GenericObject[:b => 2]],
36
43
  l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
@@ -0,0 +1,472 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+ require 'test_helper'
4
+ require 'stringio'
5
+ require 'tempfile'
6
+ require 'ostruct'
7
+ require 'bigdecimal'
8
+
9
+ class JSONParserTest < Test::Unit::TestCase
10
+ include JSON
11
+
12
+ def test_construction
13
+ parser = JSON::Parser.new('test')
14
+ assert_equal 'test', parser.source
15
+ end
16
+
17
+ def test_argument_encoding
18
+ source = "{}".encode("UTF-16")
19
+ JSON::Parser.new(source)
20
+ assert_equal Encoding::UTF_16, source.encoding
21
+ end if defined?(Encoding::UTF_16)
22
+
23
+ def test_error_message_encoding
24
+ bug10705 = '[ruby-core:67386] [Bug #10705]'
25
+ json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
26
+ e = assert_raise(JSON::ParserError) {
27
+ JSON::Ext::Parser.new(json).parse
28
+ }
29
+ assert_equal(Encoding::UTF_8, e.message.encoding, bug10705)
30
+ assert_include(e.message, json, bug10705)
31
+ end if defined?(Encoding::UTF_8) and defined?(JSON::Ext::Parser)
32
+
33
+ def test_parsing
34
+ parser = JSON::Parser.new('"test"')
35
+ assert_equal 'test', parser.parse
36
+ end
37
+
38
+ def test_parser_reset
39
+ parser = Parser.new('{"a":"b"}')
40
+ assert_equal({ 'a' => 'b' }, parser.parse)
41
+ assert_equal({ 'a' => 'b' }, parser.parse)
42
+ end
43
+
44
+ def test_parse_values
45
+ assert_equal(nil, parse('null'))
46
+ assert_equal(false, parse('false'))
47
+ assert_equal(true, parse('true'))
48
+ assert_equal(-23, parse('-23'))
49
+ assert_equal(23, parse('23'))
50
+ assert_in_delta(0.23, parse('0.23'), 1e-2)
51
+ assert_in_delta(0.0, parse('0e0'), 1e-2)
52
+ assert_equal("", parse('""'))
53
+ assert_equal("foobar", parse('"foobar"'))
54
+ end
55
+
56
+ def test_parse_simple_arrays
57
+ assert_equal([], parse('[]'))
58
+ assert_equal([], parse(' [ ] '))
59
+ assert_equal([ nil ], parse('[null]'))
60
+ assert_equal([ false ], parse('[false]'))
61
+ assert_equal([ true ], parse('[true]'))
62
+ assert_equal([ -23 ], parse('[-23]'))
63
+ assert_equal([ 23 ], parse('[23]'))
64
+ assert_equal_float([ 0.23 ], parse('[0.23]'))
65
+ assert_equal_float([ 0.0 ], parse('[0e0]'))
66
+ assert_equal([""], parse('[""]'))
67
+ assert_equal(["foobar"], parse('["foobar"]'))
68
+ assert_equal([{}], parse('[{}]'))
69
+ end
70
+
71
+ def test_parse_simple_objects
72
+ assert_equal({}, parse('{}'))
73
+ assert_equal({}, parse(' { } '))
74
+ assert_equal({ "a" => nil }, parse('{ "a" : null}'))
75
+ assert_equal({ "a" => nil }, parse('{"a":null}'))
76
+ assert_equal({ "a" => false }, parse('{ "a" : false } '))
77
+ assert_equal({ "a" => false }, parse('{"a":false}'))
78
+ assert_raise(JSON::ParserError) { parse('{false}') }
79
+ assert_equal({ "a" => true }, parse('{"a":true}'))
80
+ assert_equal({ "a" => true }, parse(' { "a" : true } '))
81
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
82
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
83
+ assert_equal({ "a" => 23 }, parse('{"a":23 } '))
84
+ assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
85
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
86
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
87
+ end
88
+
89
+ def test_parse_numbers
90
+ assert_raise(JSON::ParserError) { parse('+23.2') }
91
+ assert_raise(JSON::ParserError) { parse('+23') }
92
+ assert_raise(JSON::ParserError) { parse('.23') }
93
+ assert_raise(JSON::ParserError) { parse('023') }
94
+ assert_equal(23, parse('23'))
95
+ assert_equal(-23, parse('-23'))
96
+ assert_equal_float(3.141, parse('3.141'))
97
+ assert_equal_float(-3.141, parse('-3.141'))
98
+ assert_equal_float(3.141, parse('3141e-3'))
99
+ assert_equal_float(3.141, parse('3141.1e-3'))
100
+ assert_equal_float(3.141, parse('3141E-3'))
101
+ assert_equal_float(3.141, parse('3141.0E-3'))
102
+ assert_equal_float(-3.141, parse('-3141.0e-3'))
103
+ assert_equal_float(-3.141, parse('-3141e-3'))
104
+ assert_raise(ParserError) { parse('NaN') }
105
+ assert parse('NaN', :allow_nan => true).nan?
106
+ assert_raise(ParserError) { parse('Infinity') }
107
+ assert_equal(1.0/0, parse('Infinity', :allow_nan => true))
108
+ assert_raise(ParserError) { parse('-Infinity') }
109
+ assert_equal(-1.0/0, parse('-Infinity', :allow_nan => true))
110
+ end
111
+
112
+ def test_parse_bigdecimals
113
+ assert_equal(BigDecimal, JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"].class)
114
+ assert_equal(BigDecimal("0.901234567890123456789E1"),JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"] )
115
+ end
116
+
117
+ if Array.method_defined?(:permutation)
118
+ def test_parse_more_complex_arrays
119
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
120
+ a.permutation.each do |perm|
121
+ json = pretty_generate(perm)
122
+ assert_equal perm, parse(json)
123
+ end
124
+ end
125
+
126
+ def test_parse_complex_objects
127
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
128
+ a.permutation.each do |perm|
129
+ s = "a"
130
+ orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
131
+ json = pretty_generate(orig_obj)
132
+ assert_equal orig_obj, parse(json)
133
+ end
134
+ end
135
+ end
136
+
137
+ def test_parse_arrays
138
+ assert_equal([1,2,3], parse('[1,2,3]'))
139
+ assert_equal([1.2,2,3], parse('[1.2,2,3]'))
140
+ assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
141
+ assert_equal([], parse('[]'))
142
+ assert_equal([], parse(' [ ] '))
143
+ assert_equal([1], parse('[1]'))
144
+ assert_equal([1], parse(' [ 1 ] '))
145
+ ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil],
146
+ [[1, -2, 3]], [false], [true]]
147
+ assert_equal(ary,
148
+ parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]'))
149
+ assert_equal(ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
150
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
151
+ end
152
+
153
+ def test_parse_json_primitive_values
154
+ assert_raise(JSON::ParserError) { parse('') }
155
+ assert_raise(TypeError) { parse(nil) }
156
+ assert_raise(JSON::ParserError) { parse(' /* foo */ ') }
157
+ assert_equal nil, parse('null')
158
+ assert_equal false, parse('false')
159
+ assert_equal true, parse('true')
160
+ assert_equal 23, parse('23')
161
+ assert_equal 1, parse('1')
162
+ assert_equal_float 3.141, parse('3.141'), 1E-3
163
+ assert_equal 2 ** 64, parse('18446744073709551616')
164
+ assert_equal 'foo', parse('"foo"')
165
+ assert parse('NaN', :allow_nan => true).nan?
166
+ assert parse('Infinity', :allow_nan => true).infinite?
167
+ assert parse('-Infinity', :allow_nan => true).infinite?
168
+ assert_raise(JSON::ParserError) { parse('[ 1, ]') }
169
+ end
170
+
171
+ def test_parse_some_strings
172
+ assert_equal([""], parse('[""]'))
173
+ assert_equal(["\\"], parse('["\\\\"]'))
174
+ assert_equal(['"'], parse('["\""]'))
175
+ assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
176
+ assert_equal(
177
+ ["\"\b\n\r\t\0\037"],
178
+ parse('["\"\b\n\r\t\u0000\u001f"]')
179
+ )
180
+ end
181
+
182
+ def test_parse_big_integers
183
+ json1 = JSON(orig = (1 << 31) - 1)
184
+ assert_equal orig, parse(json1)
185
+ json2 = JSON(orig = 1 << 31)
186
+ assert_equal orig, parse(json2)
187
+ json3 = JSON(orig = (1 << 62) - 1)
188
+ assert_equal orig, parse(json3)
189
+ json4 = JSON(orig = 1 << 62)
190
+ assert_equal orig, parse(json4)
191
+ json5 = JSON(orig = 1 << 64)
192
+ assert_equal orig, parse(json5)
193
+ end
194
+
195
+ def test_some_wrong_inputs
196
+ assert_raise(ParserError) { parse('[] bla') }
197
+ assert_raise(ParserError) { parse('[] 1') }
198
+ assert_raise(ParserError) { parse('[] []') }
199
+ assert_raise(ParserError) { parse('[] {}') }
200
+ assert_raise(ParserError) { parse('{} []') }
201
+ assert_raise(ParserError) { parse('{} {}') }
202
+ assert_raise(ParserError) { parse('[NULL]') }
203
+ assert_raise(ParserError) { parse('[FALSE]') }
204
+ assert_raise(ParserError) { parse('[TRUE]') }
205
+ assert_raise(ParserError) { parse('[07] ') }
206
+ assert_raise(ParserError) { parse('[0a]') }
207
+ assert_raise(ParserError) { parse('[1.]') }
208
+ assert_raise(ParserError) { parse(' ') }
209
+ end
210
+
211
+ def test_symbolize_names
212
+ assert_equal({ "foo" => "bar", "baz" => "quux" },
213
+ parse('{"foo":"bar", "baz":"quux"}'))
214
+ assert_equal({ :foo => "bar", :baz => "quux" },
215
+ parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
216
+ assert_raise(ArgumentError) do
217
+ parse('{}', :symbolize_names => true, :create_additions => true)
218
+ end
219
+ end
220
+
221
+ def test_parse_comments
222
+ json = <<EOT
223
+ {
224
+ "key1":"value1", // eol comment
225
+ "key2":"value2" /* multi line
226
+ * comment */,
227
+ "key3":"value3" /* multi line
228
+ // nested eol comment
229
+ * comment */
230
+ }
231
+ EOT
232
+ assert_equal(
233
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
234
+ parse(json))
235
+ json = <<EOT
236
+ {
237
+ "key1":"value1" /* multi line
238
+ // nested eol comment
239
+ /* illegal nested multi line comment */
240
+ * comment */
241
+ }
242
+ EOT
243
+ assert_raise(ParserError) { parse(json) }
244
+ json = <<EOT
245
+ {
246
+ "key1":"value1" /* multi line
247
+ // nested eol comment
248
+ closed multi comment */
249
+ and again, throw an Error */
250
+ }
251
+ EOT
252
+ assert_raise(ParserError) { parse(json) }
253
+ json = <<EOT
254
+ {
255
+ "key1":"value1" /*/*/
256
+ }
257
+ EOT
258
+ assert_equal({ "key1" => "value1" }, parse(json))
259
+ end
260
+
261
+ def test_nesting
262
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
263
+ too_deep_ary = eval too_deep
264
+ assert_raise(JSON::NestingError) { parse too_deep }
265
+ assert_raise(JSON::NestingError) { parse too_deep, :max_nesting => 100 }
266
+ ok = parse too_deep, :max_nesting => 101
267
+ assert_equal too_deep_ary, ok
268
+ ok = parse too_deep, :max_nesting => nil
269
+ assert_equal too_deep_ary, ok
270
+ ok = parse too_deep, :max_nesting => false
271
+ assert_equal too_deep_ary, ok
272
+ ok = parse too_deep, :max_nesting => 0
273
+ assert_equal too_deep_ary, ok
274
+ end
275
+
276
+ def test_backslash
277
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
278
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
279
+ assert_equal data, parse(json)
280
+ #
281
+ data = [ '\\"' ]
282
+ json = '["\\\\\""]'
283
+ assert_equal data, parse(json)
284
+ #
285
+ json = '["/"]'
286
+ data = [ '/' ]
287
+ assert_equal data, parse(json)
288
+ #
289
+ json = '["\""]'
290
+ data = ['"']
291
+ assert_equal data, parse(json)
292
+ #
293
+ json = '["\\\'"]'
294
+ data = ["'"]
295
+ assert_equal data, parse(json)
296
+ end
297
+
298
+ class SubArray < Array
299
+ def <<(v)
300
+ @shifted = true
301
+ super
302
+ end
303
+
304
+ def shifted?
305
+ @shifted
306
+ end
307
+ end
308
+
309
+ class SubArray2 < Array
310
+ def to_json(*a)
311
+ {
312
+ JSON.create_id => self.class.name,
313
+ 'ary' => to_a,
314
+ }.to_json(*a)
315
+ end
316
+
317
+ def self.json_create(o)
318
+ o.delete JSON.create_id
319
+ o['ary']
320
+ end
321
+ end
322
+
323
+ class SubArrayWrapper
324
+ def initialize
325
+ @data = []
326
+ end
327
+
328
+ attr_reader :data
329
+
330
+ def [](index)
331
+ @data[index]
332
+ end
333
+
334
+ def <<(value)
335
+ @data << value
336
+ @shifted = true
337
+ end
338
+
339
+ def shifted?
340
+ @shifted
341
+ end
342
+ end
343
+
344
+ def test_parse_array_custom_array_derived_class
345
+ res = parse('[1,2]', :array_class => SubArray)
346
+ assert_equal([1,2], res)
347
+ assert_equal(SubArray, res.class)
348
+ assert res.shifted?
349
+ end
350
+
351
+ def test_parse_array_custom_non_array_derived_class
352
+ res = parse('[1,2]', :array_class => SubArrayWrapper)
353
+ assert_equal([1,2], res.data)
354
+ assert_equal(SubArrayWrapper, res.class)
355
+ assert res.shifted?
356
+ end
357
+
358
+ def test_parse_object
359
+ assert_equal({}, parse('{}'))
360
+ assert_equal({}, parse(' { } '))
361
+ assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
362
+ assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
363
+ end
364
+
365
+ class SubHash < Hash
366
+ def []=(k, v)
367
+ @item_set = true
368
+ super
369
+ end
370
+
371
+ def item_set?
372
+ @item_set
373
+ end
374
+ end
375
+
376
+ class SubHash2 < Hash
377
+ def to_json(*a)
378
+ {
379
+ JSON.create_id => self.class.name,
380
+ }.merge(self).to_json(*a)
381
+ end
382
+
383
+ def self.json_create(o)
384
+ o.delete JSON.create_id
385
+ self[o]
386
+ end
387
+ end
388
+
389
+ class SubOpenStruct < OpenStruct
390
+ def [](k)
391
+ __send__(k)
392
+ end
393
+
394
+ def []=(k, v)
395
+ @item_set = true
396
+ __send__("#{k}=", v)
397
+ end
398
+
399
+ def item_set?
400
+ @item_set
401
+ end
402
+ end
403
+
404
+ def test_parse_object_custom_hash_derived_class
405
+ res = parse('{"foo":"bar"}', :object_class => SubHash)
406
+ assert_equal({"foo" => "bar"}, res)
407
+ assert_equal(SubHash, res.class)
408
+ assert res.item_set?
409
+ end
410
+
411
+ def test_parse_object_custom_non_hash_derived_class
412
+ res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
413
+ assert_equal "bar", res.foo
414
+ assert_equal(SubOpenStruct, res.class)
415
+ assert res.item_set?
416
+ end
417
+
418
+ def test_parse_generic_object
419
+ res = parse(
420
+ '{"foo":"bar", "baz":{}}',
421
+ :object_class => JSON::GenericObject
422
+ )
423
+ assert_equal(JSON::GenericObject, res.class)
424
+ assert_equal "bar", res.foo
425
+ assert_equal "bar", res["foo"]
426
+ assert_equal "bar", res[:foo]
427
+ assert_equal "bar", res.to_hash[:foo]
428
+ assert_equal(JSON::GenericObject, res.baz.class)
429
+ end
430
+
431
+ def test_generate_core_subclasses_with_new_to_json
432
+ obj = SubHash2["foo" => SubHash2["bar" => true]]
433
+ obj_json = JSON(obj)
434
+ obj_again = parse(obj_json, :create_additions => true)
435
+ assert_kind_of SubHash2, obj_again
436
+ assert_kind_of SubHash2, obj_again['foo']
437
+ assert obj_again['foo']['bar']
438
+ assert_equal obj, obj_again
439
+ assert_equal ["foo"],
440
+ JSON(JSON(SubArray2["foo"]), :create_additions => true)
441
+ end
442
+
443
+ def test_generate_core_subclasses_with_default_to_json
444
+ assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
445
+ assert_equal '["foo"]', JSON(SubArray["foo"])
446
+ end
447
+
448
+ def test_generate_of_core_subclasses
449
+ obj = SubHash["foo" => SubHash["bar" => true]]
450
+ obj_json = JSON(obj)
451
+ obj_again = JSON(obj_json)
452
+ assert_kind_of Hash, obj_again
453
+ assert_kind_of Hash, obj_again['foo']
454
+ assert obj_again['foo']['bar']
455
+ assert_equal obj, obj_again
456
+ end
457
+
458
+ def test_parsing_frozen_ascii8bit_string
459
+ assert_equal(
460
+ { 'foo' => 'bar' },
461
+ JSON('{ "foo": "bar" }'.force_encoding(Encoding::ASCII_8BIT).freeze)
462
+ )
463
+ end
464
+
465
+ private
466
+
467
+ def assert_equal_float(expected, actual, delta = 1e-2)
468
+ Array === expected and expected = expected.first
469
+ Array === actual and actual = actual.first
470
+ assert_in_delta(expected, actual, delta)
471
+ end
472
+ end