json 1.8.6-java → 2.0.0-java

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.

Potentially problematic release.


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

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/json.rb +1 -0
  3. data/lib/json/add/bigdecimal.rb +1 -0
  4. data/lib/json/add/complex.rb +2 -1
  5. data/lib/json/add/core.rb +1 -0
  6. data/lib/json/add/date.rb +1 -1
  7. data/lib/json/add/date_time.rb +1 -1
  8. data/lib/json/add/exception.rb +1 -1
  9. data/lib/json/add/ostruct.rb +1 -1
  10. data/lib/json/add/range.rb +1 -1
  11. data/lib/json/add/rational.rb +1 -0
  12. data/lib/json/add/regexp.rb +1 -1
  13. data/lib/json/add/struct.rb +1 -1
  14. data/lib/json/add/symbol.rb +1 -1
  15. data/lib/json/add/time.rb +1 -1
  16. data/lib/json/common.rb +24 -52
  17. data/lib/json/ext.rb +0 -6
  18. data/lib/json/ext/generator.jar +0 -0
  19. data/lib/json/ext/parser.jar +0 -0
  20. data/lib/json/generic_object.rb +5 -4
  21. data/lib/json/pure.rb +2 -8
  22. data/lib/json/pure/generator.rb +51 -123
  23. data/lib/json/pure/parser.rb +28 -80
  24. data/lib/json/version.rb +2 -1
  25. data/tests/fixtures/obsolete_fail1.json +1 -0
  26. data/tests/{test_json_addition.rb → json_addition_test.rb} +22 -25
  27. data/tests/json_common_interface_test.rb +126 -0
  28. data/tests/json_encoding_test.rb +105 -0
  29. data/tests/json_ext_parser_test.rb +15 -0
  30. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  31. data/tests/{test_json_generate.rb → json_generator_test.rb} +65 -37
  32. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  33. data/tests/json_parser_test.rb +448 -0
  34. data/tests/json_string_matching_test.rb +38 -0
  35. data/tests/test_helper.rb +23 -0
  36. metadata +14 -13
  37. data/tests/fixtures/fail1.json +0 -1
  38. data/tests/setup_variant.rb +0 -11
  39. data/tests/test_json.rb +0 -519
  40. data/tests/test_json_encoding.rb +0 -65
  41. data/tests/test_json_string_matching.rb +0 -39
  42. data/tests/test_json_unicode.rb +0 -72
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ #frozen_string_literal: false
3
+ require 'test_helper'
4
+
5
+ class JSONEncodingTest < Test::Unit::TestCase
6
+ include JSON
7
+
8
+ def setup
9
+ @utf_8 = '"© ≠ €!"'
10
+ @ascii_8bit = @utf_8.dup.force_encoding('ascii-8bit')
11
+ @parsed = "© ≠ €!"
12
+ @generated = '"\u00a9 \u2260 \u20ac!"'
13
+ if String.method_defined?(:encode)
14
+ @utf_16_data = @parsed.encode('utf-16be', 'utf-8')
15
+ @utf_16be = @utf_8.encode('utf-16be', 'utf-8')
16
+ @utf_16le = @utf_8.encode('utf-16le', 'utf-8')
17
+ @utf_32be = @utf_8.encode('utf-32be', 'utf-8')
18
+ @utf_32le = @utf_8.encode('utf-32le', 'utf-8')
19
+ else
20
+ require 'iconv'
21
+ @utf_16_data, = Iconv.iconv('utf-16be', 'utf-8', @parsed)
22
+ @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
23
+ @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
24
+ @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
25
+ @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
26
+ end
27
+ end
28
+
29
+ def test_parse
30
+ assert_equal @parsed, JSON.parse(@ascii_8bit)
31
+ assert_equal @parsed, JSON.parse(@utf_8)
32
+ assert_equal @parsed, JSON.parse(@utf_16be)
33
+ assert_equal @parsed, JSON.parse(@utf_16le)
34
+ assert_equal @parsed, JSON.parse(@utf_32be)
35
+ assert_equal @parsed, JSON.parse(@utf_32le)
36
+ end
37
+
38
+ def test_generate
39
+ assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
40
+ assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
41
+ end
42
+
43
+ def test_unicode
44
+ assert_equal '""', ''.to_json
45
+ assert_equal '"\\b"', "\b".to_json
46
+ assert_equal '"\u0001"', 0x1.chr.to_json
47
+ assert_equal '"\u001f"', 0x1f.chr.to_json
48
+ assert_equal '" "', ' '.to_json
49
+ assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
50
+ utf8 = [ "© ≠ €! \01" ]
51
+ json = '["© ≠ €! \u0001"]'
52
+ assert_equal json, utf8.to_json(:ascii_only => false)
53
+ assert_equal utf8, parse(json)
54
+ json = '["\u00a9 \u2260 \u20ac! \u0001"]'
55
+ assert_equal json, utf8.to_json(:ascii_only => true)
56
+ assert_equal utf8, parse(json)
57
+ utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
58
+ json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
59
+ assert_equal utf8, parse(json)
60
+ assert_equal json, utf8.to_json(:ascii_only => false)
61
+ utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
62
+ assert_equal utf8, parse(json)
63
+ json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
64
+ assert_equal json, utf8.to_json(:ascii_only => true)
65
+ assert_equal utf8, parse(json)
66
+ utf8 = ['საქართველო']
67
+ json = '["საქართველო"]'
68
+ assert_equal json, utf8.to_json(:ascii_only => false)
69
+ json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
70
+ assert_equal json, utf8.to_json(:ascii_only => true)
71
+ assert_equal utf8, parse(json)
72
+ assert_equal '["Ã"]', generate(["Ã"], :ascii_only => false)
73
+ assert_equal '["\\u00c3"]', generate(["Ã"], :ascii_only => true)
74
+ assert_equal ["€"], parse('["\u20ac"]')
75
+ utf8 = ["\xf0\xa0\x80\x81"]
76
+ json = "[\"\xf0\xa0\x80\x81\"]"
77
+ assert_equal json, generate(utf8, :ascii_only => false)
78
+ assert_equal utf8, parse(json)
79
+ json = '["\ud840\udc01"]'
80
+ assert_equal json, generate(utf8, :ascii_only => true)
81
+ assert_equal utf8, parse(json)
82
+ end
83
+
84
+ def test_chars
85
+ (0..0x7f).each do |i|
86
+ json = '["\u%04x"]' % i
87
+ if RUBY_VERSION >= "1.9."
88
+ i = i.chr
89
+ end
90
+ assert_equal i, parse(json).first[0]
91
+ if i == ?\b
92
+ generated = generate(["" << i])
93
+ assert '["\b"]' == generated || '["\10"]' == generated
94
+ elsif [?\n, ?\r, ?\t, ?\f].include?(i)
95
+ assert_equal '[' << ('' << i).dump << ']', generate(["" << i])
96
+ elsif i.chr < 0x20.chr
97
+ assert_equal json, generate(["" << i])
98
+ end
99
+ end
100
+ assert_raise(JSON::GeneratorError) do
101
+ generate(["\x80"], :ascii_only => true)
102
+ end
103
+ assert_equal "\302\200", parse('["\u0080"]').first
104
+ end
105
+ end
@@ -0,0 +1,15 @@
1
+ #frozen_string_literal: false
2
+ require 'test_helper'
3
+
4
+ class JSONExtParserTest < Test::Unit::TestCase
5
+ if defined?(JSON::Ext::Parser)
6
+ def test_allocate
7
+ parser = JSON::Ext::Parser.new("{}")
8
+ assert_raise(TypeError, '[ruby-core:35079]') do
9
+ parser.__send__(:initialize, "{}")
10
+ end
11
+ parser = JSON::Ext::Parser.allocate
12
+ assert_raise(TypeError, '[ruby-core:35079]') { parser.source }
13
+ end
14
+ end
15
+ end
@@ -1,12 +1,9 @@
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
-
7
- class TestJSONFixtures < Test::Unit::TestCase
4
+ class JSONFixturesTest < Test::Unit::TestCase
8
5
  def setup
9
- fixtures = File.join(File.dirname(__FILE__), 'fixtures/*.json')
6
+ fixtures = File.join(File.dirname(__FILE__), 'fixtures/{fail,pass}.json')
10
7
  passed, failed = Dir[fixtures].partition { |f| f['pass'] }
11
8
  @passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
12
9
  @failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
@@ -26,7 +23,7 @@ class TestJSONFixtures < Test::Unit::TestCase
26
23
 
27
24
  def test_failing
28
25
  for name, source in @failed
29
- assert_raises(JSON::ParserError, JSON::NestingError,
26
+ assert_raise(JSON::ParserError, JSON::NestingError,
30
27
  "Did not fail for fixture '#{name}': #{source.inspect}") do
31
28
  JSON.parse(source)
32
29
  end
@@ -2,10 +2,9 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: false
4
4
 
5
- require 'test/unit'
6
- require File.join(File.dirname(__FILE__), 'setup_variant')
5
+ require 'test_helper'
7
6
 
8
- class TestJSONGenerate < Test::Unit::TestCase
7
+ class JSONGeneratorTest < Test::Unit::TestCase
9
8
  include JSON
10
9
 
11
10
  def setup
@@ -43,23 +42,23 @@ EOT
43
42
 
44
43
  def test_generate
45
44
  json = generate(@hash)
46
- assert_equal(JSON.parse(@json2), JSON.parse(json))
45
+ assert_equal(parse(@json2), parse(json))
47
46
  json = JSON[@hash]
48
- assert_equal(JSON.parse(@json2), JSON.parse(json))
47
+ assert_equal(parse(@json2), parse(json))
49
48
  parsed_json = parse(json)
50
49
  assert_equal(@hash, parsed_json)
51
50
  json = generate({1=>2})
52
51
  assert_equal('{"1":2}', json)
53
52
  parsed_json = parse(json)
54
53
  assert_equal({"1"=>2}, parsed_json)
55
- assert_raise(GeneratorError) { generate(666) }
56
- assert_equal '666', generate(666, :quirks_mode => true)
54
+ assert_equal '666', generate(666)
57
55
  end
58
56
 
59
57
  def test_generate_pretty
60
58
  json = pretty_generate(@hash)
61
- # hashes aren't (insertion) ordered on every ruby implementation assert_equal(@json3, json)
62
- assert_equal(JSON.parse(@json3), JSON.parse(json))
59
+ # hashes aren't (insertion) ordered on every ruby implementation
60
+ # assert_equal(@json3, json)
61
+ assert_equal(parse(@json3), parse(json))
63
62
  parsed_json = parse(json)
64
63
  assert_equal(@hash, parsed_json)
65
64
  json = pretty_generate({1=>2})
@@ -70,8 +69,7 @@ EOT
70
69
  EOT
71
70
  parsed_json = parse(json)
72
71
  assert_equal({"1"=>2}, parsed_json)
73
- assert_raise(GeneratorError) { pretty_generate(666) }
74
- assert_equal '666', pretty_generate(666, :quirks_mode => true)
72
+ assert_equal '666', pretty_generate(666)
75
73
  end
76
74
 
77
75
  def test_generate_custom
@@ -89,30 +87,26 @@ EOT
89
87
 
90
88
  def test_fast_generate
91
89
  json = fast_generate(@hash)
92
- assert_equal(JSON.parse(@json2), JSON.parse(json))
90
+ assert_equal(parse(@json2), parse(json))
93
91
  parsed_json = parse(json)
94
92
  assert_equal(@hash, parsed_json)
95
93
  json = fast_generate({1=>2})
96
94
  assert_equal('{"1":2}', json)
97
95
  parsed_json = parse(json)
98
96
  assert_equal({"1"=>2}, parsed_json)
99
- assert_raise(GeneratorError) { fast_generate(666) }
100
- assert_equal '666', fast_generate(666, :quirks_mode => true)
97
+ assert_equal '666', fast_generate(666)
101
98
  end
102
99
 
103
100
  def test_own_state
104
101
  state = State.new
105
102
  json = generate(@hash, state)
106
- assert_equal(JSON.parse(@json2), JSON.parse(json))
103
+ assert_equal(parse(@json2), parse(json))
107
104
  parsed_json = parse(json)
108
105
  assert_equal(@hash, parsed_json)
109
106
  json = generate({1=>2}, state)
110
107
  assert_equal('{"1":2}', json)
111
108
  parsed_json = parse(json)
112
109
  assert_equal({"1"=>2}, parsed_json)
113
- assert_raise(GeneratorError) { generate(666, state) }
114
- state.quirks_mode = true
115
- assert state.quirks_mode?
116
110
  assert_equal '666', generate(666, state)
117
111
  end
118
112
 
@@ -124,12 +118,12 @@ EOT
124
118
  assert s[:check_circular?]
125
119
  h = { 1=>2 }
126
120
  h[3] = h
127
- assert_raises(JSON::NestingError) { generate(h) }
128
- assert_raises(JSON::NestingError) { generate(h, s) }
121
+ assert_raise(JSON::NestingError) { generate(h) }
122
+ assert_raise(JSON::NestingError) { generate(h, s) }
129
123
  s = JSON.state.new
130
124
  a = [ 1, 2 ]
131
125
  a << a
132
- assert_raises(JSON::NestingError) { generate(a, s) }
126
+ assert_raise(JSON::NestingError) { generate(a, s) }
133
127
  assert s.check_circular?
134
128
  assert s[:check_circular?]
135
129
  end
@@ -141,7 +135,6 @@ EOT
141
135
  :array_nl => "\n",
142
136
  :ascii_only => false,
143
137
  :buffer_initial_length => 1024,
144
- :quirks_mode => false,
145
138
  :depth => 0,
146
139
  :indent => " ",
147
140
  :max_nesting => 100,
@@ -158,7 +151,6 @@ EOT
158
151
  :array_nl => "",
159
152
  :ascii_only => false,
160
153
  :buffer_initial_length => 1024,
161
- :quirks_mode => false,
162
154
  :depth => 0,
163
155
  :indent => "",
164
156
  :max_nesting => 100,
@@ -175,7 +167,6 @@ EOT
175
167
  :array_nl => "",
176
168
  :ascii_only => false,
177
169
  :buffer_initial_length => 1024,
178
- :quirks_mode => false,
179
170
  :depth => 0,
180
171
  :indent => "",
181
172
  :max_nesting => 0,
@@ -186,34 +177,34 @@ EOT
186
177
  end
187
178
 
188
179
  def test_allow_nan
189
- assert_raises(GeneratorError) { generate([JSON::NaN]) }
180
+ assert_raise(GeneratorError) { generate([JSON::NaN]) }
190
181
  assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
191
- assert_raises(GeneratorError) { fast_generate([JSON::NaN]) }
192
- assert_raises(GeneratorError) { pretty_generate([JSON::NaN]) }
182
+ assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
183
+ assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
193
184
  assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
194
- assert_raises(GeneratorError) { generate([JSON::Infinity]) }
185
+ assert_raise(GeneratorError) { generate([JSON::Infinity]) }
195
186
  assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
196
- assert_raises(GeneratorError) { fast_generate([JSON::Infinity]) }
197
- assert_raises(GeneratorError) { pretty_generate([JSON::Infinity]) }
187
+ assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
188
+ assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
198
189
  assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
199
- assert_raises(GeneratorError) { generate([JSON::MinusInfinity]) }
190
+ assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
200
191
  assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
201
- assert_raises(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
202
- assert_raises(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
192
+ assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
193
+ assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
203
194
  assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
204
195
  end
205
196
 
206
197
  def test_depth
207
198
  ary = []; ary << ary
208
199
  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
209
- assert_raises(JSON::NestingError) { JSON.generate(ary) }
200
+ assert_raise(JSON::NestingError) { generate(ary) }
210
201
  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
211
202
  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
212
- assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) }
203
+ assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
213
204
  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
214
205
  s = JSON.state.new
215
206
  assert_equal 0, s.depth
216
- assert_raises(JSON::NestingError) { ary.to_json(s) }
207
+ assert_raise(JSON::NestingError) { ary.to_json(s) }
217
208
  assert_equal 100, s.depth
218
209
  end
219
210
 
@@ -332,10 +323,47 @@ EOT
332
323
 
333
324
  def test_json_generate
334
325
  assert_raise JSON::GeneratorError do
335
- assert_equal true, JSON.generate(["\xea"])
326
+ assert_equal true, generate(["\xea"])
336
327
  end
337
328
  end
338
329
 
330
+ def test_nesting
331
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
332
+ too_deep_ary = eval too_deep
333
+ assert_raise(JSON::NestingError) { generate too_deep_ary }
334
+ assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
335
+ ok = generate too_deep_ary, :max_nesting => 101
336
+ assert_equal too_deep, ok
337
+ ok = generate too_deep_ary, :max_nesting => nil
338
+ assert_equal too_deep, ok
339
+ ok = generate too_deep_ary, :max_nesting => false
340
+ assert_equal too_deep, ok
341
+ ok = generate too_deep_ary, :max_nesting => 0
342
+ assert_equal too_deep, ok
343
+ end
344
+
345
+ def test_backslash
346
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
347
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
348
+ assert_equal json, generate(data)
349
+ #
350
+ data = [ '\\"' ]
351
+ json = '["\\\\\""]'
352
+ assert_equal json, generate(data)
353
+ #
354
+ data = [ '/' ]
355
+ json = '["/"]'
356
+ assert_equal json, generate(data)
357
+ #
358
+ data = ['"']
359
+ json = '["\""]'
360
+ assert_equal json, generate(data)
361
+ #
362
+ data = ["'"]
363
+ json = '["\\\'"]'
364
+ assert_equal '["\'"]', generate(data)
365
+ end
366
+
339
367
  def test_string_subclass
340
368
  s = Class.new(String) do
341
369
  def to_s; self; end
@@ -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,448 @@
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_simple_arrays
44
+ assert_equal([], parse('[]'))
45
+ assert_equal([], parse(' [ ] '))
46
+ assert_equal([ nil ], parse('[null]'))
47
+ assert_equal([ false ], parse('[false]'))
48
+ assert_equal([ true ], parse('[true]'))
49
+ assert_equal([ -23 ], parse('[-23]'))
50
+ assert_equal([ 23 ], parse('[23]'))
51
+ assert_equal_float([ 0.23 ], parse('[0.23]'))
52
+ assert_equal_float([ 0.0 ], parse('[0e0]'))
53
+ assert_equal([""], parse('[""]'))
54
+ assert_equal(["foobar"], parse('["foobar"]'))
55
+ assert_equal([{}], parse('[{}]'))
56
+ end
57
+
58
+ def test_parse_simple_objects
59
+ assert_equal({}, parse('{}'))
60
+ assert_equal({}, parse(' { } '))
61
+ assert_equal({ "a" => nil }, parse('{ "a" : null}'))
62
+ assert_equal({ "a" => nil }, parse('{"a":null}'))
63
+ assert_equal({ "a" => false }, parse('{ "a" : false } '))
64
+ assert_equal({ "a" => false }, parse('{"a":false}'))
65
+ assert_raise(JSON::ParserError) { parse('{false}') }
66
+ assert_equal({ "a" => true }, parse('{"a":true}'))
67
+ assert_equal({ "a" => true }, parse(' { "a" : true } '))
68
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
69
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
70
+ assert_equal({ "a" => 23 }, parse('{"a":23 } '))
71
+ assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
72
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
73
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
74
+ end
75
+
76
+ def test_parse_numbers
77
+ assert_raise(JSON::ParserError) { parse('+23.2') }
78
+ assert_raise(JSON::ParserError) { parse('+23') }
79
+ assert_raise(JSON::ParserError) { parse('.23') }
80
+ assert_raise(JSON::ParserError) { parse('023') }
81
+ assert_equal 23, parse('23')
82
+ assert_equal -23, parse('-23')
83
+ assert_equal_float 3.141, parse('3.141')
84
+ assert_equal_float -3.141, parse('-3.141')
85
+ assert_equal_float 3.141, parse('3141e-3')
86
+ assert_equal_float 3.141, parse('3141.1e-3')
87
+ assert_equal_float 3.141, parse('3141E-3')
88
+ assert_equal_float 3.141, parse('3141.0E-3')
89
+ assert_equal_float -3.141, parse('-3141.0e-3')
90
+ assert_equal_float -3.141, parse('-3141e-3')
91
+ assert_raise(ParserError) { parse('NaN') }
92
+ assert parse('NaN', :allow_nan => true).nan?
93
+ assert_raise(ParserError) { parse('Infinity') }
94
+ assert_equal 1.0/0, parse('Infinity', :allow_nan => true)
95
+ assert_raise(ParserError) { parse('-Infinity') }
96
+ assert_equal -1.0/0, parse('-Infinity', :allow_nan => true)
97
+ end
98
+
99
+ if Array.method_defined?(:permutation)
100
+ def test_parse_more_complex_arrays
101
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
102
+ a.permutation.each do |perm|
103
+ json = pretty_generate(perm)
104
+ assert_equal perm, parse(json)
105
+ end
106
+ end
107
+
108
+ def test_parse_complex_objects
109
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
110
+ a.permutation.each do |perm|
111
+ s = "a"
112
+ orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
113
+ json = pretty_generate(orig_obj)
114
+ assert_equal orig_obj, parse(json)
115
+ end
116
+ end
117
+ end
118
+
119
+ def test_parse_arrays
120
+ assert_equal([1,2,3], parse('[1,2,3]'))
121
+ assert_equal([1.2,2,3], parse('[1.2,2,3]'))
122
+ assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
123
+ assert_equal([], parse('[]'))
124
+ assert_equal([], parse(' [ ] '))
125
+ assert_equal([1], parse('[1]'))
126
+ assert_equal([1], parse(' [ 1 ] '))
127
+ ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil],
128
+ [[1, -2, 3]], [false], [true]]
129
+ assert_equal(ary,
130
+ parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]'))
131
+ assert_equal(ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
132
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
133
+ end
134
+
135
+ def test_parse_json_primitive_values
136
+ assert_raise(JSON::ParserError) { parse('') }
137
+ assert_raise(TypeError) { parse(nil) }
138
+ assert_raise(JSON::ParserError) { parse(' /* foo */ ') }
139
+ assert_equal nil, parse('null')
140
+ assert_equal false, parse('false')
141
+ assert_equal true, parse('true')
142
+ assert_equal 23, parse('23')
143
+ assert_equal 1, parse('1')
144
+ assert_equal_float 3.141, parse('3.141'), 1E-3
145
+ assert_equal 2 ** 64, parse('18446744073709551616')
146
+ assert_equal 'foo', parse('"foo"')
147
+ assert parse('NaN', :allow_nan => true).nan?
148
+ assert parse('Infinity', :allow_nan => true).infinite?
149
+ assert parse('-Infinity', :allow_nan => true).infinite?
150
+ assert_raise(JSON::ParserError) { parse('[ 1, ]') }
151
+ end
152
+
153
+ def test_parse_some_strings
154
+ assert_equal([""], parse('[""]'))
155
+ assert_equal(["\\"], parse('["\\\\"]'))
156
+ assert_equal(['"'], parse('["\""]'))
157
+ assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
158
+ assert_equal(
159
+ ["\"\b\n\r\t\0\037"],
160
+ parse('["\"\b\n\r\t\u0000\u001f"]')
161
+ )
162
+ end
163
+
164
+ def test_parse_big_integers
165
+ json1 = JSON(orig = (1 << 31) - 1)
166
+ assert_equal orig, parse(json1)
167
+ json2 = JSON(orig = 1 << 31)
168
+ assert_equal orig, parse(json2)
169
+ json3 = JSON(orig = (1 << 62) - 1)
170
+ assert_equal orig, parse(json3)
171
+ json4 = JSON(orig = 1 << 62)
172
+ assert_equal orig, parse(json4)
173
+ json5 = JSON(orig = 1 << 64)
174
+ assert_equal orig, parse(json5)
175
+ end
176
+
177
+ def test_some_wrong_inputs
178
+ assert_raise(ParserError) { parse('[] bla') }
179
+ assert_raise(ParserError) { parse('[] 1') }
180
+ assert_raise(ParserError) { parse('[] []') }
181
+ assert_raise(ParserError) { parse('[] {}') }
182
+ assert_raise(ParserError) { parse('{} []') }
183
+ assert_raise(ParserError) { parse('{} {}') }
184
+ assert_raise(ParserError) { parse('[NULL]') }
185
+ assert_raise(ParserError) { parse('[FALSE]') }
186
+ assert_raise(ParserError) { parse('[TRUE]') }
187
+ assert_raise(ParserError) { parse('[07] ') }
188
+ assert_raise(ParserError) { parse('[0a]') }
189
+ assert_raise(ParserError) { parse('[1.]') }
190
+ assert_raise(ParserError) { parse(' ') }
191
+ end
192
+
193
+ def test_symbolize_names
194
+ assert_equal({ "foo" => "bar", "baz" => "quux" },
195
+ parse('{"foo":"bar", "baz":"quux"}'))
196
+ assert_equal({ :foo => "bar", :baz => "quux" },
197
+ parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
198
+ assert_raise(ArgumentError) do
199
+ parse('{}', :symbolize_names => true, :create_additions => true)
200
+ end
201
+ end
202
+
203
+ def test_parse_comments
204
+ json = <<EOT
205
+ {
206
+ "key1":"value1", // eol comment
207
+ "key2":"value2" /* multi line
208
+ * comment */,
209
+ "key3":"value3" /* multi line
210
+ // nested eol comment
211
+ * comment */
212
+ }
213
+ EOT
214
+ assert_equal(
215
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
216
+ parse(json))
217
+ json = <<EOT
218
+ {
219
+ "key1":"value1" /* multi line
220
+ // nested eol comment
221
+ /* illegal nested multi line comment */
222
+ * comment */
223
+ }
224
+ EOT
225
+ assert_raise(ParserError) { parse(json) }
226
+ json = <<EOT
227
+ {
228
+ "key1":"value1" /* multi line
229
+ // nested eol comment
230
+ closed multi comment */
231
+ and again, throw an Error */
232
+ }
233
+ EOT
234
+ assert_raise(ParserError) { parse(json) }
235
+ json = <<EOT
236
+ {
237
+ "key1":"value1" /*/*/
238
+ }
239
+ EOT
240
+ assert_equal({ "key1" => "value1" }, parse(json))
241
+ end
242
+
243
+ def test_nesting
244
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
245
+ too_deep_ary = eval too_deep
246
+ assert_raise(JSON::NestingError) { parse too_deep }
247
+ assert_raise(JSON::NestingError) { parse too_deep, :max_nesting => 100 }
248
+ ok = parse too_deep, :max_nesting => 101
249
+ assert_equal too_deep_ary, ok
250
+ ok = parse too_deep, :max_nesting => nil
251
+ assert_equal too_deep_ary, ok
252
+ ok = parse too_deep, :max_nesting => false
253
+ assert_equal too_deep_ary, ok
254
+ ok = parse too_deep, :max_nesting => 0
255
+ assert_equal too_deep_ary, ok
256
+ end
257
+
258
+ def test_backslash
259
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
260
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
261
+ assert_equal data, parse(json)
262
+ #
263
+ data = [ '\\"' ]
264
+ json = '["\\\\\""]'
265
+ assert_equal data, parse(json)
266
+ #
267
+ json = '["/"]'
268
+ data = [ '/' ]
269
+ assert_equal data, parse(json)
270
+ #
271
+ json = '["\""]'
272
+ data = ['"']
273
+ assert_equal data, parse(json)
274
+ #
275
+ json = '["\\\'"]'
276
+ data = ["'"]
277
+ assert_equal data, parse(json)
278
+ end
279
+
280
+
281
+ class SubArray < Array
282
+ def <<(v)
283
+ @shifted = true
284
+ super
285
+ end
286
+
287
+ def shifted?
288
+ @shifted
289
+ end
290
+ end
291
+
292
+ class SubArray2 < Array
293
+ def to_json(*a)
294
+ {
295
+ JSON.create_id => self.class.name,
296
+ 'ary' => to_a,
297
+ }.to_json(*a)
298
+ end
299
+
300
+ def self.json_create(o)
301
+ o.delete JSON.create_id
302
+ o['ary']
303
+ end
304
+ end
305
+
306
+ class SubArrayWrapper
307
+ def initialize
308
+ @data = []
309
+ end
310
+
311
+ attr_reader :data
312
+
313
+ def [](index)
314
+ @data[index]
315
+ end
316
+
317
+ def <<(value)
318
+ @data << value
319
+ @shifted = true
320
+ end
321
+
322
+ def shifted?
323
+ @shifted
324
+ end
325
+ end
326
+
327
+ def test_parse_array_custom_array_derived_class
328
+ res = parse('[1,2]', :array_class => SubArray)
329
+ assert_equal([1,2], res)
330
+ assert_equal(SubArray, res.class)
331
+ assert res.shifted?
332
+ end
333
+
334
+ def test_parse_array_custom_non_array_derived_class
335
+ res = parse('[1,2]', :array_class => SubArrayWrapper)
336
+ assert_equal([1,2], res.data)
337
+ assert_equal(SubArrayWrapper, res.class)
338
+ assert res.shifted?
339
+ end
340
+
341
+ def test_parse_object
342
+ assert_equal({}, parse('{}'))
343
+ assert_equal({}, parse(' { } '))
344
+ assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
345
+ assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
346
+ end
347
+
348
+ class SubHash < Hash
349
+ def []=(k, v)
350
+ @item_set = true
351
+ super
352
+ end
353
+
354
+ def item_set?
355
+ @item_set
356
+ end
357
+ end
358
+
359
+ class SubHash2 < Hash
360
+ def to_json(*a)
361
+ {
362
+ JSON.create_id => self.class.name,
363
+ }.merge(self).to_json(*a)
364
+ end
365
+
366
+ def self.json_create(o)
367
+ o.delete JSON.create_id
368
+ self[o]
369
+ end
370
+ end
371
+
372
+ class SubOpenStruct < OpenStruct
373
+ def [](k)
374
+ __send__(k)
375
+ end
376
+
377
+ def []=(k, v)
378
+ @item_set = true
379
+ __send__("#{k}=", v)
380
+ end
381
+
382
+ def item_set?
383
+ @item_set
384
+ end
385
+ end
386
+
387
+ def test_parse_object_custom_hash_derived_class
388
+ res = parse('{"foo":"bar"}', :object_class => SubHash)
389
+ assert_equal({"foo" => "bar"}, res)
390
+ assert_equal(SubHash, res.class)
391
+ assert res.item_set?
392
+ end
393
+
394
+ def test_parse_object_custom_non_hash_derived_class
395
+ res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
396
+ assert_equal "bar", res.foo
397
+ assert_equal(SubOpenStruct, res.class)
398
+ assert res.item_set?
399
+ end
400
+
401
+ def test_parse_generic_object
402
+ res = parse(
403
+ '{"foo":"bar", "baz":{}}',
404
+ :object_class => JSON::GenericObject
405
+ )
406
+ assert_equal(JSON::GenericObject, res.class)
407
+ assert_equal "bar", res.foo
408
+ assert_equal "bar", res["foo"]
409
+ assert_equal "bar", res[:foo]
410
+ assert_equal "bar", res.to_hash[:foo]
411
+ assert_equal(JSON::GenericObject, res.baz.class)
412
+ end
413
+
414
+ def test_generate_core_subclasses_with_new_to_json
415
+ obj = SubHash2["foo" => SubHash2["bar" => true]]
416
+ obj_json = JSON(obj)
417
+ obj_again = parse(obj_json, :create_additions => true)
418
+ assert_kind_of SubHash2, obj_again
419
+ assert_kind_of SubHash2, obj_again['foo']
420
+ assert obj_again['foo']['bar']
421
+ assert_equal obj, obj_again
422
+ assert_equal ["foo"],
423
+ JSON(JSON(SubArray2["foo"]), :create_additions => true)
424
+ end
425
+
426
+ def test_generate_core_subclasses_with_default_to_json
427
+ assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
428
+ assert_equal '["foo"]', JSON(SubArray["foo"])
429
+ end
430
+
431
+ def test_generate_of_core_subclasses
432
+ obj = SubHash["foo" => SubHash["bar" => true]]
433
+ obj_json = JSON(obj)
434
+ obj_again = JSON(obj_json)
435
+ assert_kind_of Hash, obj_again
436
+ assert_kind_of Hash, obj_again['foo']
437
+ assert obj_again['foo']['bar']
438
+ assert_equal obj, obj_again
439
+ end
440
+
441
+ private
442
+
443
+ def assert_equal_float(expected, actual, delta = 1e-2)
444
+ Array === expected and expected = expected.first
445
+ Array === actual and actual = actual.first
446
+ assert_in_delta(expected, actual, delta)
447
+ end
448
+ end