json 1.8.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -10
  4. data/{CHANGES → CHANGES.md} +186 -90
  5. data/Gemfile +10 -6
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/{README.rdoc → README.md} +184 -133
  8. data/Rakefile +33 -37
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +47 -61
  12. data/ext/json/ext/generator/generator.h +7 -2
  13. data/ext/json/ext/parser/extconf.rb +3 -0
  14. data/ext/json/ext/parser/parser.c +374 -459
  15. data/ext/json/ext/parser/parser.h +4 -5
  16. data/ext/json/ext/parser/parser.rl +133 -181
  17. data/ext/json/extconf.rb +0 -1
  18. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  19. data/java/src/json/ext/Generator.java +11 -12
  20. data/java/src/json/ext/GeneratorMethods.java +1 -2
  21. data/java/src/json/ext/GeneratorService.java +1 -2
  22. data/java/src/json/ext/GeneratorState.java +3 -56
  23. data/java/src/json/ext/OptionsReader.java +2 -3
  24. data/java/src/json/ext/Parser.java +132 -415
  25. data/java/src/json/ext/Parser.rl +48 -124
  26. data/java/src/json/ext/ParserService.java +1 -2
  27. data/java/src/json/ext/RuntimeInfo.java +1 -6
  28. data/java/src/json/ext/StringDecoder.java +1 -2
  29. data/java/src/json/ext/StringEncoder.java +5 -0
  30. data/java/src/json/ext/Utils.java +1 -2
  31. data/json-java.gemspec +15 -0
  32. data/json.gemspec +0 -0
  33. data/json_pure.gemspec +24 -26
  34. data/lib/json/add/bigdecimal.rb +1 -0
  35. data/lib/json/add/complex.rb +2 -1
  36. data/lib/json/add/core.rb +1 -0
  37. data/lib/json/add/date.rb +1 -1
  38. data/lib/json/add/date_time.rb +1 -1
  39. data/lib/json/add/exception.rb +1 -1
  40. data/lib/json/add/ostruct.rb +3 -3
  41. data/lib/json/add/range.rb +1 -1
  42. data/lib/json/add/rational.rb +1 -0
  43. data/lib/json/add/regexp.rb +1 -1
  44. data/lib/json/add/set.rb +29 -0
  45. data/lib/json/add/struct.rb +1 -1
  46. data/lib/json/add/symbol.rb +1 -1
  47. data/lib/json/add/time.rb +1 -1
  48. data/lib/json/common.rb +24 -52
  49. data/lib/json/ext.rb +0 -6
  50. data/lib/json/generic_object.rb +5 -4
  51. data/lib/json/pure/generator.rb +61 -125
  52. data/lib/json/pure/parser.rb +33 -81
  53. data/lib/json/pure.rb +2 -8
  54. data/lib/json/version.rb +2 -1
  55. data/lib/json.rb +1 -0
  56. data/references/rfc7159.txt +899 -0
  57. data/tests/fixtures/obsolete_fail1.json +1 -0
  58. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  59. data/tests/json_common_interface_test.rb +126 -0
  60. data/tests/json_encoding_test.rb +107 -0
  61. data/tests/json_ext_parser_test.rb +15 -0
  62. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  63. data/tests/{test_json_generate.rb → json_generator_test.rb} +79 -39
  64. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  65. data/tests/json_parser_test.rb +472 -0
  66. data/tests/json_string_matching_test.rb +38 -0
  67. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  68. data/tools/diff.sh +18 -0
  69. data/tools/fuzz.rb +1 -9
  70. metadata +29 -47
  71. data/COPYING +0 -58
  72. data/COPYING-json-jruby +0 -57
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/test_json.rb +0 -553
  80. data/tests/test_json_encoding.rb +0 -65
  81. data/tests/test_json_string_matching.rb +0 -39
  82. 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.new("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
@@ -0,0 +1,38 @@
1
+ #frozen_string_literal: false
2
+ require 'test_helper'
3
+ require 'time'
4
+
5
+ class JSONStringMatchingTest < Test::Unit::TestCase
6
+ include JSON
7
+
8
+ class TestTime < ::Time
9
+ def self.json_create(string)
10
+ Time.parse(string)
11
+ end
12
+
13
+ def to_json(*)
14
+ %{"#{strftime('%FT%T%z')}"}
15
+ end
16
+
17
+ def ==(other)
18
+ to_i == other.to_i
19
+ end
20
+ end
21
+
22
+ def test_match_date
23
+ t = TestTime.new
24
+ t_json = [ t ].to_json
25
+ time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
26
+ assert_equal [ t ],
27
+ parse(
28
+ t_json,
29
+ :create_additions => true,
30
+ :match_string => { time_regexp => TestTime }
31
+ )
32
+ assert_equal [ t.strftime('%FT%T%z') ],
33
+ parse(
34
+ t_json,
35
+ :match_string => { time_regexp => TestTime }
36
+ )
37
+ end
38
+ end
@@ -9,3 +9,9 @@ else
9
9
  $:.unshift 'ext', 'lib'
10
10
  require 'json'
11
11
  end
12
+
13
+ require 'test/unit'
14
+ begin
15
+ require 'byebug'
16
+ rescue LoadError
17
+ end
data/tools/diff.sh ADDED
@@ -0,0 +1,18 @@
1
+ #!/bin/sh
2
+
3
+ files=`find ext -name '*.[ch]' -o -name parser.rl`
4
+
5
+ for f in $files
6
+ do
7
+ b=`basename $f`
8
+ g=`find ../ruby/ext/json -name $b`
9
+ d=`diff -u $f $g`
10
+ test -z "$d" && continue
11
+ echo "$d"
12
+ read -p "Edit diff of $b? " a
13
+ case $a in
14
+ [yY]*)
15
+ vimdiff $f $g
16
+ ;;
17
+ esac
18
+ done
data/tools/fuzz.rb CHANGED
@@ -1,13 +1,5 @@
1
1
  require 'json'
2
2
 
3
- require 'iconv'
4
- ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15')
5
- class ::String
6
- def to_utf8
7
- ISO_8859_1_TO_UTF8.iconv self
8
- end
9
- end
10
-
11
3
  class Fuzzer
12
4
  def initialize(n, freqs = {})
13
5
  sum = freqs.inject(0.0) { |s, x| s + x.last }
@@ -25,7 +17,7 @@ class Fuzzer
25
17
  def random_string
26
18
  s = ''
27
19
  30.times { s << @alpha[rand(@alpha.size)] }
28
- s.to_utf8
20
+ s
29
21
  end
30
22
 
31
23
  def pick