json 1.8.3 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -11
  4. data/{CHANGES → CHANGES.md} +186 -90
  5. data/Gemfile +10 -6
  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} +185 -134
  9. data/Rakefile +41 -40
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +142 -101
  13. data/ext/json/ext/generator/generator.h +7 -2
  14. data/ext/json/ext/parser/extconf.rb +3 -0
  15. data/ext/json/ext/parser/parser.c +383 -463
  16. data/ext/json/ext/parser/parser.h +4 -5
  17. data/ext/json/ext/parser/parser.rl +141 -184
  18. data/ext/json/extconf.rb +0 -1
  19. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  20. data/java/src/json/ext/Generator.java +44 -22
  21. data/java/src/json/ext/GeneratorMethods.java +1 -2
  22. data/java/src/json/ext/GeneratorService.java +1 -2
  23. data/java/src/json/ext/GeneratorState.java +3 -56
  24. data/java/src/json/ext/OptionsReader.java +2 -3
  25. data/java/src/json/ext/Parser.java +132 -415
  26. data/java/src/json/ext/Parser.rl +48 -124
  27. data/java/src/json/ext/ParserService.java +1 -2
  28. data/java/src/json/ext/RuntimeInfo.java +1 -6
  29. data/java/src/json/ext/StringDecoder.java +1 -2
  30. data/java/src/json/ext/StringEncoder.java +5 -0
  31. data/java/src/json/ext/Utils.java +1 -2
  32. data/json-java.gemspec +16 -2
  33. data/json.gemspec +0 -0
  34. data/json_pure.gemspec +24 -26
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -3
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -2
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +26 -54
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure/generator.rb +63 -126
  53. data/lib/json/pure/parser.rb +41 -81
  54. data/lib/json/pure.rb +2 -8
  55. data/lib/json/version.rb +2 -1
  56. data/lib/json.rb +1 -0
  57. data/references/rfc7159.txt +899 -0
  58. data/tests/fixtures/obsolete_fail1.json +1 -0
  59. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  60. data/tests/json_common_interface_test.rb +126 -0
  61. data/tests/json_encoding_test.rb +107 -0
  62. data/tests/json_ext_parser_test.rb +15 -0
  63. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  64. data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
  65. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  66. data/tests/json_parser_test.rb +472 -0
  67. data/tests/json_string_matching_test.rb +38 -0
  68. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  69. data/tools/diff.sh +18 -0
  70. data/tools/fuzz.rb +1 -9
  71. metadata +30 -47
  72. data/COPYING +0 -58
  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
@@ -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
@@ -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