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