oj 3.8.1

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.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +104 -0
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +107 -0
  6. data/ext/oj/cache8.h +48 -0
  7. data/ext/oj/circarray.c +68 -0
  8. data/ext/oj/circarray.h +23 -0
  9. data/ext/oj/code.c +235 -0
  10. data/ext/oj/code.h +42 -0
  11. data/ext/oj/compat.c +299 -0
  12. data/ext/oj/custom.c +1191 -0
  13. data/ext/oj/dump.c +1252 -0
  14. data/ext/oj/dump.h +96 -0
  15. data/ext/oj/dump_compat.c +977 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +837 -0
  18. data/ext/oj/dump_strict.c +433 -0
  19. data/ext/oj/encode.h +45 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +47 -0
  23. data/ext/oj/fast.c +1771 -0
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +878 -0
  28. data/ext/oj/object.c +771 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1704 -0
  32. data/ext/oj/oj.h +385 -0
  33. data/ext/oj/parse.c +1086 -0
  34. data/ext/oj/parse.h +111 -0
  35. data/ext/oj/rails.c +1493 -0
  36. data/ext/oj/rails.h +21 -0
  37. data/ext/oj/reader.c +231 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +102 -0
  40. data/ext/oj/resolve.h +14 -0
  41. data/ext/oj/rxclass.c +147 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +714 -0
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +910 -0
  46. data/ext/oj/stream_writer.c +363 -0
  47. data/ext/oj/strict.c +212 -0
  48. data/ext/oj/string_writer.c +534 -0
  49. data/ext/oj/trace.c +79 -0
  50. data/ext/oj/trace.h +28 -0
  51. data/ext/oj/util.c +136 -0
  52. data/ext/oj/util.h +19 -0
  53. data/ext/oj/val_stack.c +118 -0
  54. data/ext/oj/val_stack.h +185 -0
  55. data/ext/oj/wab.c +631 -0
  56. data/lib/oj.rb +21 -0
  57. data/lib/oj/active_support_helper.rb +41 -0
  58. data/lib/oj/bag.rb +88 -0
  59. data/lib/oj/easy_hash.rb +52 -0
  60. data/lib/oj/error.rb +22 -0
  61. data/lib/oj/json.rb +176 -0
  62. data/lib/oj/mimic.rb +267 -0
  63. data/lib/oj/saj.rb +66 -0
  64. data/lib/oj/schandler.rb +142 -0
  65. data/lib/oj/state.rb +131 -0
  66. data/lib/oj/version.rb +5 -0
  67. data/pages/Advanced.md +22 -0
  68. data/pages/Compatibility.md +25 -0
  69. data/pages/Custom.md +23 -0
  70. data/pages/Encoding.md +65 -0
  71. data/pages/JsonGem.md +79 -0
  72. data/pages/Modes.md +155 -0
  73. data/pages/Options.md +283 -0
  74. data/pages/Rails.md +116 -0
  75. data/pages/Security.md +20 -0
  76. data/pages/WAB.md +13 -0
  77. data/test/_test_active.rb +76 -0
  78. data/test/_test_active_mimic.rb +96 -0
  79. data/test/_test_mimic_rails.rb +126 -0
  80. data/test/activerecord/result_test.rb +27 -0
  81. data/test/activesupport4/decoding_test.rb +108 -0
  82. data/test/activesupport4/encoding_test.rb +531 -0
  83. data/test/activesupport4/test_helper.rb +41 -0
  84. data/test/activesupport5/decoding_test.rb +125 -0
  85. data/test/activesupport5/encoding_test.rb +485 -0
  86. data/test/activesupport5/encoding_test_cases.rb +90 -0
  87. data/test/activesupport5/test_helper.rb +50 -0
  88. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  89. data/test/bar.rb +25 -0
  90. data/test/files.rb +29 -0
  91. data/test/foo.rb +167 -0
  92. data/test/helper.rb +26 -0
  93. data/test/isolated/shared.rb +308 -0
  94. data/test/isolated/test_mimic_after.rb +13 -0
  95. data/test/isolated/test_mimic_alone.rb +12 -0
  96. data/test/isolated/test_mimic_as_json.rb +45 -0
  97. data/test/isolated/test_mimic_before.rb +13 -0
  98. data/test/isolated/test_mimic_define.rb +28 -0
  99. data/test/isolated/test_mimic_rails_after.rb +22 -0
  100. data/test/isolated/test_mimic_rails_before.rb +21 -0
  101. data/test/isolated/test_mimic_redefine.rb +15 -0
  102. data/test/json_gem/json_addition_test.rb +216 -0
  103. data/test/json_gem/json_common_interface_test.rb +148 -0
  104. data/test/json_gem/json_encoding_test.rb +107 -0
  105. data/test/json_gem/json_ext_parser_test.rb +20 -0
  106. data/test/json_gem/json_fixtures_test.rb +35 -0
  107. data/test/json_gem/json_generator_test.rb +383 -0
  108. data/test/json_gem/json_generic_object_test.rb +90 -0
  109. data/test/json_gem/json_parser_test.rb +470 -0
  110. data/test/json_gem/json_string_matching_test.rb +42 -0
  111. data/test/json_gem/test_helper.rb +18 -0
  112. data/test/perf.rb +107 -0
  113. data/test/perf_compat.rb +130 -0
  114. data/test/perf_fast.rb +164 -0
  115. data/test/perf_file.rb +64 -0
  116. data/test/perf_object.rb +138 -0
  117. data/test/perf_saj.rb +109 -0
  118. data/test/perf_scp.rb +151 -0
  119. data/test/perf_simple.rb +287 -0
  120. data/test/perf_strict.rb +145 -0
  121. data/test/perf_wab.rb +131 -0
  122. data/test/sample.rb +54 -0
  123. data/test/sample/change.rb +14 -0
  124. data/test/sample/dir.rb +19 -0
  125. data/test/sample/doc.rb +36 -0
  126. data/test/sample/file.rb +48 -0
  127. data/test/sample/group.rb +16 -0
  128. data/test/sample/hasprops.rb +16 -0
  129. data/test/sample/layer.rb +12 -0
  130. data/test/sample/line.rb +20 -0
  131. data/test/sample/oval.rb +10 -0
  132. data/test/sample/rect.rb +10 -0
  133. data/test/sample/shape.rb +35 -0
  134. data/test/sample/text.rb +20 -0
  135. data/test/sample_json.rb +37 -0
  136. data/test/test_compat.rb +509 -0
  137. data/test/test_custom.rb +503 -0
  138. data/test/test_debian.rb +53 -0
  139. data/test/test_fast.rb +470 -0
  140. data/test/test_file.rb +239 -0
  141. data/test/test_gc.rb +49 -0
  142. data/test/test_hash.rb +29 -0
  143. data/test/test_integer_range.rb +73 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +1018 -0
  146. data/test/test_saj.rb +186 -0
  147. data/test/test_scp.rb +433 -0
  148. data/test/test_strict.rb +410 -0
  149. data/test/test_various.rb +741 -0
  150. data/test/test_wab.rb +307 -0
  151. data/test/test_writer.rb +380 -0
  152. data/test/tests.rb +24 -0
  153. data/test/tests_mimic.rb +14 -0
  154. data/test/tests_mimic_addition.rb +7 -0
  155. data/test/zoo.rb +13 -0
  156. metadata +359 -0
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ #frozen_string_literal: false
5
+
6
+ require 'json_gem/test_helper'
7
+
8
+ class JSONGenericObjectTest < Test::Unit::TestCase
9
+ include Test::Unit::TestCaseOmissionSupport
10
+
11
+ def setup
12
+ @go = JSON::GenericObject[ :a => 1, :b => 2 ]
13
+ end
14
+
15
+ def test_attributes
16
+ assert_equal 1, @go.a
17
+ assert_equal 1, @go[:a]
18
+ assert_equal 2, @go.b
19
+ assert_equal 2, @go[:b]
20
+ assert_nil @go.c
21
+ assert_nil @go[:c]
22
+ end
23
+
24
+ def test_generate_json
25
+ switch_json_creatable do
26
+ assert_equal @go, JSON(JSON(@go), :create_additions => true)
27
+ end
28
+ end
29
+
30
+ def test_parse_json
31
+ x = JSON(
32
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
33
+ :create_additions => true
34
+ )
35
+ assert_kind_of Hash,
36
+ JSON(
37
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
38
+ :create_additions => true
39
+ )
40
+ switch_json_creatable do
41
+ assert_equal @go, l =
42
+ JSON(
43
+ '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
44
+ :create_additions => true
45
+ )
46
+ assert_equal 1, l.a
47
+ assert_equal @go,
48
+ l = JSON('{ "a": 1, "b": 2 }', :object_class => JSON::GenericObject)
49
+ assert_equal 1, l.a
50
+ assert_equal JSON::GenericObject[:a => JSON::GenericObject[:b => 2]],
51
+ l = JSON('{ "a": { "b": 2 } }', :object_class => JSON::GenericObject)
52
+ assert_equal 2, l.a.b
53
+ end
54
+ end
55
+
56
+ def test_from_hash
57
+ result = JSON::GenericObject.from_hash(
58
+ :foo => { :bar => { :baz => true }, :quux => [ { :foobar => true } ] })
59
+ assert_kind_of JSON::GenericObject, result.foo
60
+ assert_kind_of JSON::GenericObject, result.foo.bar
61
+ assert_equal true, result.foo.bar.baz
62
+ assert_kind_of JSON::GenericObject, result.foo.quux.first
63
+ assert_equal true, result.foo.quux.first.foobar
64
+ assert_equal true, JSON::GenericObject.from_hash(true)
65
+ end
66
+
67
+ def test_json_generic_object_load
68
+ empty = JSON::GenericObject.load(nil)
69
+ assert_kind_of JSON::GenericObject, empty
70
+ simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}'
71
+ simple = JSON::GenericObject.load(simple_json)
72
+ assert_kind_of JSON::GenericObject, simple
73
+ assert_equal "world", simple.hello
74
+ converting = JSON::GenericObject.load('{ "hello": "world" }')
75
+ assert_kind_of JSON::GenericObject, converting
76
+ assert_equal "world", converting.hello
77
+
78
+ json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world'])
79
+ assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}')
80
+ end
81
+
82
+ private
83
+
84
+ def switch_json_creatable
85
+ JSON::GenericObject.json_creatable = true
86
+ yield
87
+ ensure
88
+ JSON::GenericObject.json_creatable = false
89
+ end
90
+ end
@@ -0,0 +1,470 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # frozen_string_literal: false
5
+
6
+ require 'json_gem/test_helper'
7
+
8
+ require 'stringio'
9
+ require 'tempfile'
10
+ require 'ostruct'
11
+
12
+ class JSONParserTest < Test::Unit::TestCase
13
+ include Test::Unit::TestCaseOmissionSupport
14
+
15
+ def test_construction
16
+ parser = JSON::Parser.new('test')
17
+ assert_equal 'test', parser.source
18
+ end
19
+
20
+ def test_argument_encoding
21
+ source = "{}".encode("UTF-16")
22
+ JSON::Parser.new(source)
23
+ assert_equal Encoding::UTF_16, source.encoding
24
+ end if defined?(Encoding::UTF_16)
25
+
26
+ def test_error_message_encoding
27
+ bug10705 = '[ruby-core:67386] [Bug #10705]'
28
+ json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
29
+ e = assert_raise(JSON::ParserError) {
30
+ JSON::Ext::Parser.new(json).parse
31
+ }
32
+ assert_equal(Encoding::UTF_8, e.message.encoding, bug10705)
33
+ assert_include(e.message, json, bug10705)
34
+ end if defined?(Encoding::UTF_8)
35
+
36
+ def test_parsing
37
+ parser = JSON::Parser.new('"test"')
38
+ assert_equal 'test', parser.parse
39
+ end
40
+
41
+ def test_parser_reset
42
+ parser = JSON::Parser.new('{"a":"b"}')
43
+ assert_equal({ 'a' => 'b' }, parser.parse)
44
+ assert_equal({ 'a' => 'b' }, parser.parse)
45
+ end
46
+
47
+ def test_parse_values
48
+ assert_equal(nil, JSON.parse('null'))
49
+ assert_equal(false, JSON.parse('false'))
50
+ assert_equal(true, JSON.parse('true'))
51
+ assert_equal(-23, JSON.parse('-23'))
52
+ assert_equal(23, JSON.parse('23'))
53
+ assert_in_delta(0.23, JSON.parse('0.23'), 1e-2)
54
+ assert_in_delta(0.0, JSON.parse('0e0'), 1e-2)
55
+ assert_equal("", JSON.parse('""'))
56
+ assert_equal("foobar", JSON.parse('"foobar"'))
57
+ end
58
+
59
+ def test_parse_simple_arrays
60
+ assert_equal([], JSON.parse('[]'))
61
+ assert_equal([], JSON.parse(' [ ] '))
62
+ assert_equal([ nil ], JSON.parse('[null]'))
63
+ assert_equal([ false ], JSON.parse('[false]'))
64
+ assert_equal([ true ], JSON.parse('[true]'))
65
+ assert_equal([ -23 ], JSON.parse('[-23]'))
66
+ assert_equal([ 23 ], JSON.parse('[23]'))
67
+ assert_equal_float([ 0.23 ], JSON.parse('[0.23]'))
68
+ assert_equal_float([ 0.0 ], JSON.parse('[0e0]'))
69
+ assert_equal([""], JSON.parse('[""]'))
70
+ assert_equal(["foobar"], JSON.parse('["foobar"]'))
71
+ assert_equal([{}], JSON.parse('[{}]'))
72
+ end
73
+
74
+ def test_parse_simple_objects
75
+ assert_equal({}, JSON.parse('{}'))
76
+ assert_equal({}, JSON.parse(' { } '))
77
+ assert_equal({ "a" => nil }, JSON.parse('{ "a" : null}'))
78
+ assert_equal({ "a" => nil }, JSON.parse('{"a":null}'))
79
+ assert_equal({ "a" => false }, JSON.parse('{ "a" : false } '))
80
+ assert_equal({ "a" => false }, JSON.parse('{"a":false}'))
81
+ assert_raise(JSON::ParserError) { JSON.parse('{false}') }
82
+ assert_equal({ "a" => true }, JSON.parse('{"a":true}'))
83
+ assert_equal({ "a" => true }, JSON.parse(' { "a" : true } '))
84
+ assert_equal({ "a" => -23 }, JSON.parse(' { "a" : -23 } '))
85
+ assert_equal({ "a" => -23 }, JSON.parse(' { "a" : -23 } '))
86
+ assert_equal({ "a" => 23 }, JSON.parse('{"a":23 } '))
87
+ assert_equal({ "a" => 23 }, JSON.parse(' { "a" : 23 } '))
88
+ assert_equal({ "a" => 0.23 }, JSON.parse(' { "a" : 0.23 } '))
89
+ assert_equal({ "a" => 0.23 }, JSON.parse(' { "a" : 0.23 } '))
90
+ end
91
+
92
+ def test_parse_numbers
93
+ assert_raise(JSON::ParserError) { JSON.parse('+23.2') }
94
+ assert_raise(JSON::ParserError) { JSON.parse('+23') }
95
+ assert_raise(JSON::ParserError) { JSON.parse('.23') }
96
+ assert_raise(JSON::ParserError) { JSON.parse('023') }
97
+ assert_equal 23, JSON.parse('23')
98
+ assert_equal -23, JSON.parse('-23')
99
+ assert_equal_float 3.141, JSON.parse('3.141')
100
+ assert_equal_float -3.141, JSON.parse('-3.141')
101
+ assert_equal_float 3.141, JSON.parse('3141e-3')
102
+ assert_equal_float 3.141, JSON.parse('3141.1e-3')
103
+ assert_equal_float 3.141, JSON.parse('3141E-3')
104
+ assert_equal_float 3.141, JSON.parse('3141.0E-3')
105
+ assert_equal_float -3.141, JSON.parse('-3141.0e-3')
106
+ assert_equal_float -3.141, JSON.parse('-3141e-3')
107
+ assert_raise(JSON::ParserError) { JSON.parse('NaN') }
108
+ assert JSON.parse('NaN', :allow_nan => true).nan?
109
+ assert_raise(JSON::ParserError) { JSON.parse('Infinity') }
110
+ assert_equal 1.0/0, JSON.parse('Infinity', :allow_nan => true)
111
+ assert_raise(JSON::ParserError) { JSON.parse('-Infinity') }
112
+ assert_equal -1.0/0, JSON.parse('-Infinity', :allow_nan => true)
113
+ end
114
+
115
+ if Array.method_defined?(:permutation)
116
+ def test_parse_more_complex_arrays
117
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
118
+ a.permutation.each do |perm|
119
+ json = JSON.pretty_generate(perm)
120
+ assert_equal perm, JSON.parse(json)
121
+ end
122
+ end
123
+
124
+ def test_parse_complex_objects
125
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
126
+ a.permutation.each do |perm|
127
+ s = "a"
128
+ orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
129
+ json = JSON.pretty_generate(orig_obj)
130
+ assert_equal orig_obj, JSON.parse(json)
131
+ end
132
+ end
133
+ end
134
+
135
+ def test_parse_arrays
136
+ assert_equal([1,2,3], JSON.parse('[1,2,3]'))
137
+ assert_equal([1.2,2,3], JSON.parse('[1.2,2,3]'))
138
+ assert_equal([[],[[],[]]], JSON.parse('[[],[[],[]]]'))
139
+ assert_equal([], JSON.parse('[]'))
140
+ assert_equal([], JSON.parse(' [ ] '))
141
+ assert_equal([1], JSON.parse('[1]'))
142
+ assert_equal([1], JSON.parse(' [ 1 ] '))
143
+ ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil],
144
+ [[1, -2, 3]], [false], [true]]
145
+ assert_equal(ary,
146
+ JSON.parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]'))
147
+ assert_equal(ary, JSON.parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
148
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
149
+ end
150
+
151
+ def test_parse_json_primitive_values
152
+ assert_raise(JSON::ParserError) { JSON.parse('') }
153
+ assert_raise(TypeError) { JSON.parse(nil) }
154
+ assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') }
155
+ assert_equal nil, JSON.parse('null')
156
+ assert_equal false, JSON.parse('false')
157
+ assert_equal true, JSON.parse('true')
158
+ assert_equal 23, JSON.parse('23')
159
+ assert_equal 1, JSON.parse('1')
160
+ assert_equal_float 3.141, JSON.parse('3.141'), 1E-3
161
+ assert_equal 2 ** 64, JSON.parse('18446744073709551616')
162
+ assert_equal 'foo', JSON.parse('"foo"')
163
+ assert JSON.parse('NaN', :allow_nan => true).nan?
164
+ assert JSON.parse('Infinity', :allow_nan => true).infinite?
165
+ assert JSON.parse('-Infinity', :allow_nan => true).infinite?
166
+ assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]') }
167
+ end
168
+
169
+ def test_parse_some_strings
170
+ assert_equal([""], JSON.parse('[""]'))
171
+ assert_equal(["\\"], JSON.parse('["\\\\"]'))
172
+ assert_equal(['"'], JSON.parse('["\""]'))
173
+ assert_equal(['\\"\\'], JSON.parse('["\\\\\\"\\\\"]'))
174
+ assert_equal(
175
+ ["\"\b\n\r\t\0\037"],
176
+ JSON.parse('["\"\b\n\r\t\u0000\u001f"]')
177
+ )
178
+ end
179
+
180
+ def test_parse_big_integers
181
+ json1 = JSON(orig = (1 << 31) - 1)
182
+ assert_equal orig, JSON.parse(json1)
183
+ json2 = JSON(orig = 1 << 31)
184
+ assert_equal orig, JSON.parse(json2)
185
+ json3 = JSON(orig = (1 << 62) - 1)
186
+ assert_equal orig, JSON.parse(json3)
187
+ json4 = JSON(orig = 1 << 62)
188
+ assert_equal orig, JSON.parse(json4)
189
+ json5 = JSON(orig = 1 << 64)
190
+ assert_equal orig, JSON.parse(json5)
191
+ end
192
+
193
+ def test_some_wrong_inputs
194
+ assert_raise(JSON::ParserError) { JSON.parse('[] bla') }
195
+ assert_raise(JSON::ParserError) { JSON.parse('[] 1') }
196
+ assert_raise(JSON::ParserError) { JSON.parse('[] []') }
197
+ assert_raise(JSON::ParserError) { JSON.parse('[] {}') }
198
+ assert_raise(JSON::ParserError) { JSON.parse('{} []') }
199
+ assert_raise(JSON::ParserError) { JSON.parse('{} {}') }
200
+ assert_raise(JSON::ParserError) { JSON.parse('[NULL]') }
201
+ assert_raise(JSON::ParserError) { JSON.parse('[FALSE]') }
202
+ assert_raise(JSON::ParserError) { JSON.parse('[TRUE]') }
203
+ assert_raise(JSON::ParserError) { JSON.parse('[07] ') }
204
+ assert_raise(JSON::ParserError) { JSON.parse('[0a]') }
205
+ assert_raise(JSON::ParserError) { JSON.parse('[1.]') }
206
+ assert_raise(JSON::ParserError) { JSON.parse(' ') }
207
+ end
208
+
209
+ def test_symbolize_names
210
+ assert_equal({ "foo" => "bar", "baz" => "quux" },
211
+ JSON.parse('{"foo":"bar", "baz":"quux"}'))
212
+ assert_equal({ :foo => "bar", :baz => "quux" },
213
+ JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
214
+ assert_raise(ArgumentError) do
215
+ JSON.parse('{}', :symbolize_names => true, :create_additions => true)
216
+ end
217
+ end
218
+
219
+ def test_parse_comments
220
+ json = <<EOT
221
+ {
222
+ "key1":"value1", // eol comment
223
+ "key2":"value2" /* multi line
224
+ * comment */,
225
+ "key3":"value3" /* multi line
226
+ // nested eol comment
227
+ * comment */
228
+ }
229
+ EOT
230
+ assert_equal(
231
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
232
+ JSON.parse(json))
233
+ json = <<EOT
234
+ {
235
+ "key1":"value1" /* multi line
236
+ // nested eol comment
237
+ /* illegal nested multi line comment */
238
+ * comment */
239
+ }
240
+ EOT
241
+ assert_raise(JSON::ParserError) { JSON.parse(json) }
242
+ json = <<EOT
243
+ {
244
+ "key1":"value1" /* multi line
245
+ // nested eol comment
246
+ closed multi comment */
247
+ and again, throw an Error */
248
+ }
249
+ EOT
250
+ assert_raise(JSON::ParserError) { JSON.parse(json) }
251
+ json = <<EOT
252
+ {
253
+ "key1":"value1" /*/*/
254
+ }
255
+ EOT
256
+ assert_equal({ "key1" => "value1" }, JSON.parse(json))
257
+ end
258
+
259
+ def test_nesting
260
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
261
+ too_deep_ary = eval too_deep
262
+ assert_raise(JSON::NestingError) { JSON.parse too_deep }
263
+ assert_raise(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 100 }
264
+ ok = JSON.parse too_deep, :max_nesting => 101
265
+ assert_equal too_deep_ary, ok
266
+ ok = JSON.parse too_deep, :max_nesting => nil
267
+ assert_equal too_deep_ary, ok
268
+ ok = JSON.parse too_deep, :max_nesting => false
269
+ assert_equal too_deep_ary, ok
270
+ ok = JSON.parse too_deep, :max_nesting => 0
271
+ assert_equal too_deep_ary, ok
272
+ end
273
+
274
+ def test_backslash
275
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
276
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
277
+ assert_equal data, JSON.parse(json)
278
+ #
279
+ data = [ '\\"' ]
280
+ json = '["\\\\\""]'
281
+ assert_equal data, JSON.parse(json)
282
+ #
283
+ json = '["/"]'
284
+ data = [ '/' ]
285
+ assert_equal data, JSON.parse(json)
286
+ #
287
+ json = '["\""]'
288
+ data = ['"']
289
+ assert_equal data, JSON.parse(json)
290
+ #
291
+ json = '["\\\'"]'
292
+ data = ["'"]
293
+ assert_equal data, JSON.parse(json)
294
+ end
295
+
296
+ class SubArray < Array
297
+ def <<(v)
298
+ @shifted = true
299
+ super
300
+ end
301
+
302
+ def shifted?
303
+ @shifted
304
+ end
305
+ end
306
+
307
+ class SubArray2 < Array
308
+ def to_json(*a)
309
+ {
310
+ JSON.create_id => self.class.name,
311
+ 'ary' => to_a,
312
+ }.to_json(*a)
313
+ end
314
+
315
+ def self.json_create(o)
316
+ o.delete JSON.create_id
317
+ o['ary']
318
+ end
319
+ end
320
+
321
+ class SubArrayWrapper
322
+ def initialize
323
+ @data = []
324
+ end
325
+
326
+ attr_reader :data
327
+
328
+ def [](index)
329
+ @data[index]
330
+ end
331
+
332
+ def <<(value)
333
+ @data << value
334
+ @shifted = true
335
+ end
336
+
337
+ def shifted?
338
+ @shifted
339
+ end
340
+ end
341
+
342
+ def test_parse_array_custom_array_derived_class
343
+ res = JSON.parse('[1,2]', :array_class => SubArray)
344
+ assert_equal([1,2], res)
345
+ assert_equal(SubArray, res.class)
346
+ assert res.shifted?
347
+ end
348
+
349
+ def test_parse_array_custom_non_array_derived_class
350
+ res = JSON.parse('[1,2]', :array_class => SubArrayWrapper)
351
+ assert_equal(SubArrayWrapper, res.class)
352
+ assert_equal([1,2], res.data)
353
+ assert res.shifted?
354
+ end
355
+
356
+ def test_parse_object
357
+ assert_equal({}, JSON.parse('{}'))
358
+ assert_equal({}, JSON.parse(' { } '))
359
+ assert_equal({'foo'=>'bar'}, JSON.parse('{"foo":"bar"}'))
360
+ assert_equal({'foo'=>'bar'}, JSON.parse(' { "foo" : "bar" } '))
361
+ end
362
+
363
+ class SubHash < Hash
364
+ def []=(k, v)
365
+ @item_set = true
366
+ super
367
+ end
368
+
369
+ def item_set?
370
+ @item_set
371
+ end
372
+ end
373
+
374
+ class SubHash2 < Hash
375
+ def to_json(*a)
376
+ {
377
+ JSON.create_id => self.class.name,
378
+ }.merge(self).to_json(*a)
379
+ end
380
+
381
+ def self.json_create(o)
382
+ o.delete JSON.create_id
383
+ self[o]
384
+ end
385
+ end
386
+
387
+ class SubOpenStruct < OpenStruct
388
+ def [](k)
389
+ __send__(k)
390
+ end
391
+
392
+ def []=(k, v)
393
+ @item_set = true
394
+ __send__("#{k}=", v)
395
+ end
396
+
397
+ def item_set?
398
+ @item_set
399
+ end
400
+ end
401
+
402
+ def test_parse_object_custom_hash_derived_class
403
+ res = JSON.parse('{"foo":"bar"}', :object_class => SubHash)
404
+ assert_equal(SubHash, res.class)
405
+ assert_equal({"foo" => "bar"}, res)
406
+ assert res.item_set?
407
+ end
408
+
409
+ def test_parse_object_custom_non_hash_derived_class
410
+ res = JSON.parse('{"foo":"bar"}', :object_class => SubOpenStruct)
411
+ assert_equal(SubOpenStruct, res.class)
412
+ assert_equal "bar", res.foo
413
+ assert res.item_set?
414
+ end
415
+
416
+ def test_parse_generic_object
417
+ res = JSON.parse(
418
+ '{"foo":"bar", "baz":{}}',
419
+ :object_class => JSON::GenericObject
420
+ )
421
+ assert_equal(JSON::GenericObject, res.class)
422
+ assert_equal "bar", res.foo
423
+ assert_equal "bar", res["foo"]
424
+ assert_equal "bar", res[:foo]
425
+ assert_equal "bar", res.to_hash[:foo]
426
+ assert_equal(JSON::GenericObject, res.baz.class)
427
+ end if defined?(JSON::GenericObject)
428
+
429
+ def test_generate_core_subclasses_with_new_to_json
430
+ obj = SubHash2["foo" => SubHash2["bar" => true]]
431
+ obj_json = JSON(obj)
432
+ obj_again = JSON.parse(obj_json, :create_additions => true)
433
+ assert_kind_of SubHash2, obj_again
434
+ assert_kind_of SubHash2, obj_again['foo']
435
+ assert obj_again['foo']['bar']
436
+ assert_equal obj, obj_again
437
+ assert_equal ["foo"],
438
+ JSON(JSON(SubArray2["foo"]), :create_additions => true)
439
+ end
440
+
441
+ def test_generate_core_subclasses_with_default_to_json
442
+ assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
443
+ assert_equal '["foo"]', JSON(SubArray["foo"])
444
+ end
445
+
446
+ def test_generate_of_core_subclasses
447
+ obj = SubHash["foo" => SubHash["bar" => true]]
448
+ obj_json = JSON(obj)
449
+ obj_again = JSON(obj_json)
450
+ assert_kind_of Hash, obj_again
451
+ assert_kind_of Hash, obj_again['foo']
452
+ assert obj_again['foo']['bar']
453
+ assert_equal obj, obj_again
454
+ end
455
+
456
+ def test_parsing_frozen_ascii8bit_string
457
+ assert_equal(
458
+ { 'foo' => 'bar' },
459
+ JSON('{ "foo": "bar" }'.force_encoding(Encoding::ASCII_8BIT).freeze)
460
+ )
461
+ end
462
+
463
+ private
464
+
465
+ def assert_equal_float(expected, actual, delta = 1e-2)
466
+ Array === expected and expected = expected.first
467
+ Array === actual and actual = actual.first
468
+ assert_in_delta(expected, actual, delta)
469
+ end
470
+ end