oj 3.13.23 → 3.16.10

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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +2 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +26 -59
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +103 -53
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -7
  25. data/ext/oj/fast.c +63 -98
  26. data/ext/oj/intern.c +62 -47
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +54 -38
  31. data/ext/oj/object.c +33 -43
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +245 -216
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +109 -153
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +9 -8
  40. data/ext/oj/rails.c +71 -94
  41. data/ext/oj/reader.c +9 -14
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +13 -15
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +6 -20
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +46 -48
  52. data/ext/oj/strict.c +22 -56
  53. data/ext/oj/string_writer.c +64 -40
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -114
  56. data/ext/oj/usual.h +7 -6
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +13 -2
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +7 -7
  67. data/lib/oj/schandler.rb +5 -4
  68. data/lib/oj/state.rb +8 -5
  69. data/lib/oj/version.rb +1 -2
  70. data/lib/oj.rb +2 -0
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +4 -0
  73. metadata +46 -121
  74. data/test/_test_active.rb +0 -76
  75. data/test/_test_active_mimic.rb +0 -96
  76. data/test/_test_mimic_rails.rb +0 -126
  77. data/test/activerecord/result_test.rb +0 -32
  78. data/test/activesupport4/decoding_test.rb +0 -108
  79. data/test/activesupport4/encoding_test.rb +0 -531
  80. data/test/activesupport4/test_helper.rb +0 -41
  81. data/test/activesupport5/abstract_unit.rb +0 -45
  82. data/test/activesupport5/decoding_test.rb +0 -133
  83. data/test/activesupport5/encoding_test.rb +0 -500
  84. data/test/activesupport5/encoding_test_cases.rb +0 -98
  85. data/test/activesupport5/test_helper.rb +0 -72
  86. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  87. data/test/activesupport6/abstract_unit.rb +0 -44
  88. data/test/activesupport6/decoding_test.rb +0 -133
  89. data/test/activesupport6/encoding_test.rb +0 -507
  90. data/test/activesupport6/encoding_test_cases.rb +0 -98
  91. data/test/activesupport6/test_common.rb +0 -17
  92. data/test/activesupport6/test_helper.rb +0 -163
  93. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  94. data/test/activesupport7/abstract_unit.rb +0 -49
  95. data/test/activesupport7/decoding_test.rb +0 -125
  96. data/test/activesupport7/encoding_test.rb +0 -486
  97. data/test/activesupport7/encoding_test_cases.rb +0 -104
  98. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  99. data/test/bar.rb +0 -11
  100. data/test/baz.rb +0 -16
  101. data/test/bug.rb +0 -16
  102. data/test/files.rb +0 -29
  103. data/test/foo.rb +0 -77
  104. data/test/helper.rb +0 -42
  105. data/test/isolated/shared.rb +0 -308
  106. data/test/isolated/test_mimic_after.rb +0 -13
  107. data/test/isolated/test_mimic_alone.rb +0 -12
  108. data/test/isolated/test_mimic_as_json.rb +0 -45
  109. data/test/isolated/test_mimic_before.rb +0 -13
  110. data/test/isolated/test_mimic_define.rb +0 -28
  111. data/test/isolated/test_mimic_rails_after.rb +0 -22
  112. data/test/isolated/test_mimic_rails_before.rb +0 -21
  113. data/test/isolated/test_mimic_redefine.rb +0 -15
  114. data/test/json_gem/json_addition_test.rb +0 -216
  115. data/test/json_gem/json_common_interface_test.rb +0 -153
  116. data/test/json_gem/json_encoding_test.rb +0 -107
  117. data/test/json_gem/json_ext_parser_test.rb +0 -20
  118. data/test/json_gem/json_fixtures_test.rb +0 -35
  119. data/test/json_gem/json_generator_test.rb +0 -396
  120. data/test/json_gem/json_generic_object_test.rb +0 -90
  121. data/test/json_gem/json_parser_test.rb +0 -477
  122. data/test/json_gem/json_string_matching_test.rb +0 -42
  123. data/test/json_gem/test_helper.rb +0 -30
  124. data/test/mem.rb +0 -33
  125. data/test/perf.rb +0 -107
  126. data/test/perf_compat.rb +0 -130
  127. data/test/perf_dump.rb +0 -50
  128. data/test/perf_fast.rb +0 -164
  129. data/test/perf_file.rb +0 -64
  130. data/test/perf_object.rb +0 -138
  131. data/test/perf_once.rb +0 -58
  132. data/test/perf_parser.rb +0 -189
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -152
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -139
  137. data/test/perf_wab.rb +0 -131
  138. data/test/prec.rb +0 -23
  139. data/test/sample/change.rb +0 -14
  140. data/test/sample/dir.rb +0 -19
  141. data/test/sample/doc.rb +0 -36
  142. data/test/sample/file.rb +0 -48
  143. data/test/sample/group.rb +0 -16
  144. data/test/sample/hasprops.rb +0 -16
  145. data/test/sample/layer.rb +0 -12
  146. data/test/sample/line.rb +0 -20
  147. data/test/sample/oval.rb +0 -10
  148. data/test/sample/rect.rb +0 -10
  149. data/test/sample/shape.rb +0 -35
  150. data/test/sample/text.rb +0 -20
  151. data/test/sample.rb +0 -54
  152. data/test/sample_json.rb +0 -37
  153. data/test/test_compat.rb +0 -540
  154. data/test/test_custom.rb +0 -544
  155. data/test/test_debian.rb +0 -53
  156. data/test/test_fast.rb +0 -530
  157. data/test/test_file.rb +0 -255
  158. data/test/test_gc.rb +0 -60
  159. data/test/test_generate.rb +0 -21
  160. data/test/test_hash.rb +0 -39
  161. data/test/test_integer_range.rb +0 -72
  162. data/test/test_null.rb +0 -376
  163. data/test/test_object.rb +0 -1025
  164. data/test/test_parser.rb +0 -11
  165. data/test/test_parser_debug.rb +0 -27
  166. data/test/test_parser_saj.rb +0 -335
  167. data/test/test_parser_usual.rb +0 -217
  168. data/test/test_rails.rb +0 -35
  169. data/test/test_saj.rb +0 -186
  170. data/test/test_scp.rb +0 -431
  171. data/test/test_strict.rb +0 -435
  172. data/test/test_various.rb +0 -752
  173. data/test/test_wab.rb +0 -309
  174. data/test/test_writer.rb +0 -380
  175. data/test/tests.rb +0 -33
  176. data/test/tests_mimic.rb +0 -23
  177. data/test/tests_mimic_addition.rb +0 -16
  178. data/test/zoo.rb +0 -13
data/test/test_various.rb DELETED
@@ -1,752 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- $: << File.dirname(__FILE__)
5
-
6
- require 'helper'
7
-
8
- class Juice < Minitest::Test
9
- def gen_whitespaced_string(length = Random.new.rand(100))
10
- whitespace_chars = [" ", "\t", "\f", "\n", "\r"]
11
- result = ""
12
- length.times { result << whitespace_chars.sample }
13
- result
14
- end
15
-
16
- module TestModule
17
- end
18
-
19
- class Jam
20
- attr_accessor :x, :y
21
-
22
- def initialize(x, y)
23
- @x = x
24
- @y = y
25
- end
26
-
27
- def eql?(o)
28
- self.class == o.class && @x == o.x && @y == o.y
29
- end
30
- alias == eql?
31
-
32
- end # Jam
33
-
34
- class Jeez < Jam
35
- def initialize(x, y)
36
- super
37
- end
38
-
39
- def to_json()
40
- %{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
41
- end
42
-
43
- def self.json_create(h)
44
- self.new(h['x'], h['y'])
45
- end
46
- end # Jeez
47
-
48
- # contributed by sauliusg to fix as_json
49
- class Orange < Jam
50
- def initialize(x, y)
51
- super
52
- end
53
-
54
- def as_json()
55
- { :json_class => self.class,
56
- :x => @x,
57
- :y => @y }
58
- end
59
-
60
- def self.json_create(h)
61
- self.new(h['x'], h['y'])
62
- end
63
- end
64
-
65
- class Melon < Jam
66
- def initialize(x, y)
67
- super
68
- end
69
-
70
- def as_json(options)
71
- "#{x} #{y}"
72
- end
73
-
74
- def self.json_create(h)
75
- self.new(h['x'], h['y'])
76
- end
77
- end
78
-
79
- class Jazz < Jam
80
- def initialize(x, y)
81
- super
82
- end
83
- def to_hash()
84
- { 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
85
- end
86
- def self.json_create(h)
87
- self.new(h['x'], h['y'])
88
- end
89
- end # Jazz
90
-
91
- def setup
92
- @default_options = Oj.default_options
93
- end
94
-
95
- def teardown
96
- Oj.default_options = @default_options
97
- end
98
-
99
- def test_set_options
100
- orig = Oj.default_options()
101
- alt ={
102
- indent: " - ",
103
- second_precision: 5,
104
- circular: true,
105
- class_cache: false,
106
- auto_define: true,
107
- symbol_keys: true,
108
- bigdecimal_as_decimal: false,
109
- use_to_json: false,
110
- use_to_hash: false,
111
- use_as_json: false,
112
- use_raw_json: false,
113
- nilnil: true,
114
- empty_string: true,
115
- allow_gc: false,
116
- quirks_mode: false,
117
- allow_invalid_unicode: true,
118
- float_precision: 13,
119
- mode: :strict,
120
- escape_mode: :ascii,
121
- time_format: :unix_zone,
122
- bigdecimal_load: :float,
123
- compat_bigdecimal: true,
124
- create_id: 'classy',
125
- create_additions: true,
126
- cache_keys: false,
127
- cache_str: 5,
128
- space: 'z',
129
- array_nl: 'a',
130
- object_nl: 'o',
131
- space_before: 'b',
132
- nan: :huge,
133
- hash_class: Hash,
134
- omit_nil: false,
135
- allow_nan: true,
136
- integer_range: nil,
137
- array_class: Array,
138
- ignore: nil,
139
- ignore_under: true,
140
- trace: true,
141
- safe: true,
142
- }
143
- Oj.default_options = alt
144
- #keys = alt.keys
145
- #Oj.default_options.keys.each { |k| puts k unless keys.include? k}
146
- opts = Oj.default_options()
147
- assert_equal(alt, opts);
148
-
149
- Oj.default_options = orig # return to original
150
- # verify back to original
151
- opts = Oj.default_options()
152
- assert_equal(orig, opts);
153
- end
154
-
155
- def test_nil
156
- dump_and_load(nil, false)
157
- end
158
-
159
- def test_true
160
- dump_and_load(true, false)
161
- end
162
-
163
- def test_false
164
- dump_and_load(false, false)
165
- end
166
-
167
- def test_fixnum
168
- dump_and_load(0, false)
169
- dump_and_load(12345, false)
170
- dump_and_load(-54321, false)
171
- dump_and_load(1, false)
172
- end
173
-
174
- def test_float_parse
175
- Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
176
- n = Oj.load('0.00001234567890123456')
177
- assert_equal(Float, n.class)
178
- assert_equal('1.234567890123456e-05', "%0.15e" % [n])
179
-
180
- n = Oj.load('-0.00001234567890123456')
181
- assert_equal(Float, n.class)
182
- assert_equal('-1.234567890123456e-05', "%0.15e" % [n])
183
-
184
- n = Oj.load('1000.0000123456789')
185
- assert_equal(BigDecimal, n.class)
186
- assert_equal('0.10000000123456789E4', n.to_s.upcase)
187
-
188
- n = Oj.load('-0.000012345678901234567')
189
- assert_equal(BigDecimal, n.class)
190
- assert_equal('-0.12345678901234567E-4', n.to_s.upcase)
191
- end
192
-
193
- =begin
194
- # TBD move to custom
195
- def test_float_dump
196
- Oj.default_options = { :float_precision => 16 }
197
- assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
198
- Oj.default_options = { :float_precision => 5 }
199
- assert_equal('1.4055', Oj.dump(1.405460727))
200
- Oj.default_options = { :float_precision => 0 }
201
- assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
202
- Oj.default_options = { :float_precision => 15 }
203
- assert_equal('0.56', Oj.dump(0.56))
204
- assert_equal('0.5773', Oj.dump(0.5773))
205
- assert_equal('0.6768', Oj.dump(0.6768))
206
- assert_equal('0.685', Oj.dump(0.685))
207
- assert_equal('0.7032', Oj.dump(0.7032))
208
- assert_equal('0.7051', Oj.dump(0.7051))
209
- assert_equal('0.8274', Oj.dump(0.8274))
210
- assert_equal('0.9149', Oj.dump(0.9149))
211
- assert_equal('64.4', Oj.dump(64.4))
212
- assert_equal('71.6', Oj.dump(71.6))
213
- assert_equal('73.4', Oj.dump(73.4))
214
- assert_equal('80.6', Oj.dump(80.6))
215
- assert_equal('-95.640172', Oj.dump(-95.640172))
216
- end
217
- =end
218
-
219
- def test_string
220
- dump_and_load('', false)
221
- dump_and_load('abc', false)
222
- dump_and_load("abc\ndef", false)
223
- dump_and_load("a\u0041", false)
224
- assert_equal("a\u0000a", dump_and_load("a\u0000a", false))
225
- end
226
-
227
- def test_encode
228
- opts = Oj.default_options
229
- Oj.default_options = { :ascii_only => false }
230
- dump_and_load("ぴーたー", false)
231
-
232
- Oj.default_options = { :ascii_only => true }
233
- json = Oj.dump("ぴーたー")
234
- assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
235
- dump_and_load("ぴーたー", false)
236
- Oj.default_options = opts
237
- end
238
-
239
- def test_unicode
240
- # hits the 3 normal ranges and one extended surrogate pair
241
- json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
242
- obj = Oj.load(json)
243
- json2 = Oj.dump(obj, :ascii_only => true)
244
- assert_equal(json, json2)
245
- end
246
-
247
- def test_invalid_unicode_raise
248
- # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
249
- json = %{"x\\ud83dy"}
250
- begin
251
- Oj.load(json)
252
- rescue Exception
253
- assert(true)
254
- return
255
- end
256
- assert(false, "*** expected an exception")
257
- end
258
-
259
- def test_invalid_unicode_ok
260
- # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
261
- json = %{"x\\ud83dy"}
262
- obj = Oj.load(json, :allow_invalid_unicode => true)
263
- # The same as what ruby would do with the invalid encoding.
264
- assert_equal("x\xED\xA0\xBDy", obj.to_s)
265
- end
266
-
267
- def test_dump_options
268
- json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
269
- :mode => :compat,
270
- :indent => "--",
271
- :array_nl => "\n",
272
- :object_nl => "#\n",
273
- :space => "*",
274
- :space_before => "~")
275
- assert(%{{#
276
- --"a"~:*1,#
277
- --"b"~:*[
278
- ----true,
279
- ----false
280
- --]#
281
- }} == json ||
282
- %{{#
283
- --"b"~:*[
284
- ----true,
285
- ----false
286
- --],#
287
- --"a"~:*1#
288
- }} == json)
289
-
290
- end
291
-
292
- def test_null_char
293
- assert_raises(Oj::ParseError) { Oj.load("\"\0\"") }
294
- assert_raises(Oj::ParseError) { Oj.load("\"\\\0\"") }
295
- end
296
-
297
- def test_array
298
- dump_and_load([], false)
299
- dump_and_load([true, false], false)
300
- dump_and_load(['a', 1, nil], false)
301
- dump_and_load([[nil]], false)
302
- dump_and_load([[nil], 58], false)
303
- end
304
- def test_array_not_closed
305
- begin
306
- Oj.load('[')
307
- rescue Exception
308
- assert(true)
309
- return
310
- end
311
- assert(false, "*** expected an exception")
312
- end
313
-
314
- # multiple JSON in one string
315
- def test_multiple_json_callback
316
- json = %{{"a":1}
317
- [1,2][3,4]
318
- {"b":2}
319
- }
320
- results = []
321
- Oj.load(json, :mode => :strict) { |x, start, len| results << [x, start, len] }
322
- assert_equal([[{"a"=>1}, 0, 7], [[1,2], 7, 6], [[3,4], 13, 5], [{"b"=>2}, 18, 8]], results)
323
- end
324
-
325
- def test_multiple_json_no_callback
326
- json = %{{"a":1}
327
- [1,2][3,4]
328
- {"b":2}
329
- }
330
- assert_raises(Oj::ParseError) { Oj.load(json) }
331
- end
332
-
333
- # encoding tests
334
- def test_does_not_escape_entities_by_default
335
- Oj.default_options = { :escape_mode => :ascii } # set in mimic mode
336
- # use Oj to create the hash since some Rubies don't deal nicely with unicode.
337
- json = %{{"key":"I <3 this\\u2028space"}}
338
- hash = Oj.load(json)
339
- out = Oj.dump(hash)
340
- assert_equal(json, out)
341
- end
342
- def test_escapes_entities_by_default_when_configured_to_do_so
343
- hash = {'key' => "I <3 this"}
344
- Oj.default_options = {:escape_mode => :xss_safe}
345
- out = Oj.dump hash
346
- assert_equal(%{{"key":"I \\u003c3 this"}}, out)
347
- end
348
- def test_escapes_slashes_by_default_when_configured_to_do_so
349
- hash = {'key' => "I <3 this </script>"}
350
- Oj.default_options = {:escape_mode => :slash}
351
- out = Oj.dump hash
352
- assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
353
- end
354
- def test_escapes_entities_when_asked_to
355
- hash = {'key' => "I <3 this"}
356
- out = Oj.dump(hash, :escape_mode => :xss_safe)
357
- assert_equal(%{{"key":"I \\u003c3 this"}}, out)
358
- end
359
- def test_does_not_escape_entities_when_not_asked_to
360
- hash = {'key' => "I <3 this"}
361
- out = Oj.dump(hash, :escape_mode => :json)
362
- assert_equal(%{{"key":"I <3 this"}}, out)
363
- end
364
- def test_escapes_common_xss_vectors
365
- hash = {'key' => "<script>alert(123) && formatHD()</script>"}
366
- out = Oj.dump(hash, :escape_mode => :xss_safe)
367
- assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
368
- end
369
- def test_escape_newline_by_default
370
- Oj.default_options = { :escape_mode => :json }
371
- json = %{["one","two\\n2"]}
372
- x = Oj.load(json)
373
- out = Oj.dump(x)
374
- assert_equal(json, out)
375
- end
376
- def test_does_not_escape_newline
377
- Oj.default_options = { :escape_mode => :newline }
378
- json = %{["one","two\n2"]}
379
- x = Oj.load(json)
380
- out = Oj.dump(x)
381
- assert_equal(json, out)
382
- end
383
- def test_dump_invalid_utf8
384
- Oj.default_options = { :escape_mode => :ascii }
385
- assert_raises(EncodingError) {
386
- Oj.dump(["abc\xbe\x1f\x11"], mode: :strict)
387
- }
388
- end
389
-
390
- # Symbol
391
- def test_symbol_null
392
- json = Oj.dump(:abc, :mode => :null)
393
- assert_equal('"abc"', json)
394
- end
395
-
396
- # Time
397
- def test_time_null
398
- t = Time.local(2012, 1, 5, 23, 58, 7)
399
- json = Oj.dump(t, :mode => :null)
400
- assert_equal('null', json)
401
- end
402
-
403
- def test_time_neg
404
- t = Time.parse("1900-01-01 00:18:59 UTC")
405
- json = Oj.dump(t, :mode => :custom, :time_format => :unix)
406
- assert_equal('-2208987661.000000000', json)
407
- end
408
-
409
- def test_time_years
410
- (-2020..2020).each { |year|
411
- s = "%04d-03-01T15:14:13Z" % [year]
412
- json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
413
- assert_equal(s, json[1..-2])
414
-
415
- json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: 3)
416
- assert_equal(s[0..-2] + '.000Z', json[1..-2])
417
- }
418
- end
419
-
420
- # Class
421
- def test_class_null
422
- json = Oj.dump(Juice, :mode => :null)
423
- assert_equal('null', json)
424
- end
425
-
426
- # Module
427
- def test_module_null
428
- json = Oj.dump(TestModule, :mode => :null)
429
- assert_equal('null', json)
430
- end
431
-
432
- # Hash
433
- def test_non_str_hash_null
434
- begin
435
- Oj.dump({ 1 => true, 0 => false }, :mode => :null)
436
- rescue Exception
437
- assert(true)
438
- return
439
- end
440
- assert(false, "*** expected an exception")
441
- end
442
-
443
- def test_hash_not_closed
444
- begin
445
- Oj.load('{')
446
- rescue Exception
447
- assert(true)
448
- return
449
- end
450
- assert(false, "*** expected an exception")
451
- end
452
-
453
- # Object with to_json()
454
- def test_json_object_null
455
- obj = Jeez.new(true, 58)
456
- json = Oj.dump(obj, :mode => :null)
457
- assert_equal('null', json)
458
- end
459
-
460
- # Object with to_hash()
461
- def test_to_hash_object_null
462
- obj = Jazz.new(true, 58)
463
- json = Oj.dump(obj, :mode => :null)
464
- assert_equal('null', json)
465
- end
466
-
467
- # Object with as_json() # contributed by sauliusg
468
- def test_as_json_object_null
469
- obj = Orange.new(true, 58)
470
- json = Oj.dump(obj, :mode => :null)
471
- assert_equal('null', json)
472
- end
473
-
474
- # Object without to_json() or to_hash()
475
- def test_object_null
476
- obj = Jam.new(true, 58)
477
- json = Oj.dump(obj, :mode => :null)
478
- assert_equal('null', json)
479
- end
480
-
481
- # Range
482
- def test_range_null
483
- json = Oj.dump(1..7, :mode => :null)
484
- assert_equal('null', json)
485
- end
486
-
487
- # BigNum
488
- def test_bignum_null
489
- json = Oj.dump(7 ** 55, :mode => :null)
490
- assert_equal('30226801971775055948247051683954096612865741943', json)
491
- end
492
-
493
- def test_bignum_object
494
- dump_and_load(7 ** 55, false)
495
- dump_and_load(10 ** 19, false)
496
- end
497
-
498
- # BigDecimal
499
- def test_bigdecimal_null
500
- mode = Oj.default_options[:mode]
501
- Oj.default_options = {:mode => :null}
502
- dump_and_load(BigDecimal('3.14159265358979323846'), false)
503
- Oj.default_options = {:mode => mode}
504
- end
505
-
506
- def test_infinity
507
- n = Oj.load('Infinity', :mode => :object)
508
- assert_equal(BigDecimal('Infinity').to_f, n);
509
- x = Oj.load('Infinity', :mode => :compat)
510
- assert_equal('Infinity', x.to_s)
511
- end
512
-
513
- # Date
514
- def test_date_null
515
- json = Oj.dump(Date.new(2012, 6, 19), :mode => :null)
516
- assert_equal('null', json)
517
- end
518
-
519
- # DateTime
520
- def test_datetime_null
521
- json = Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :null)
522
- assert_equal('null', json)
523
- end
524
-
525
- # autodefine Oj::Bag
526
- def test_bag
527
- json = %{{
528
- "^o":"Juice::Jem",
529
- "x":true,
530
- "y":58 }}
531
- obj = Oj.load(json, :mode => :object, :auto_define => true)
532
- assert_equal('Juice::Jem', obj.class.name)
533
- assert_equal(true, obj.x)
534
- assert_equal(58, obj.y)
535
- end
536
-
537
- # Stream Deeply Nested
538
- def test_deep_nest_dump
539
- begin
540
- a = []
541
- 10000.times { a << [a] }
542
- Oj.dump(a)
543
- rescue Exception
544
- assert(true)
545
- return
546
- end
547
- assert(false, "*** expected an exception")
548
- end
549
-
550
- # Stream IO
551
- def test_io_string
552
- src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
553
- output = StringIO.open("", "w+")
554
- Oj.to_stream(output, src)
555
-
556
- input = StringIO.new(output.string())
557
- obj = Oj.load(input, :mode => :strict)
558
- assert_equal(src, obj)
559
- end
560
-
561
- def test_io_file
562
- src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
563
- filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
564
- File.open(filename, "w") { |f|
565
- Oj.to_stream(f, src)
566
- }
567
- f = File.new(filename)
568
- obj = Oj.load(f, :mode => :strict)
569
- f.close()
570
- assert_equal(src, obj)
571
- end
572
-
573
- def test_io_stream
574
- skip 'needs fork' unless Process.respond_to?(:fork)
575
-
576
- IO.pipe do |r, w|
577
- if fork
578
- r.close
579
- #w.nonblock = false
580
- a = []
581
- 10_000.times do |i|
582
- a << i
583
- end
584
- Oj.to_stream(w, a, indent: 2)
585
- w.close
586
- else
587
- w.close
588
- sleep(0.1) # to force a busy
589
- cnt = 0
590
- r.each_line { cnt += 1 }
591
- r.close
592
- Process.exit(0)
593
- end
594
- end
595
- end
596
-
597
- # comments
598
- def test_comment_slash
599
- json = %{{
600
- "x":true,//three
601
- "y":58,
602
- "z": [1,2,
603
- 3 // six
604
- ]}
605
- }
606
- obj = Oj.load(json, :mode => :strict)
607
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
608
- end
609
-
610
- def test_comment_c
611
- json = %{/*before*/
612
- {
613
- "x"/*one*/:/*two*/true,
614
- "y":58,
615
- "z": [1,2,3]}
616
- }
617
- obj = Oj.load(json, :mode => :strict)
618
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
619
- end
620
-
621
- def test_comment
622
- json = %{{
623
- "x"/*one*/:/*two*/true,//three
624
- "y":58/*four*/,
625
- "z": [1,2/*five*/,
626
- 3 // six
627
- ]
628
- }
629
- }
630
- obj = Oj.load(json, :mode => :strict)
631
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
632
- end
633
-
634
- def test_nilnil_false
635
- begin
636
- Oj.load(nil, :nilnil => false)
637
- rescue Exception
638
- assert(true)
639
- return
640
- end
641
- assert(false, "*** expected an exception")
642
- end
643
-
644
- def test_nilnil_true
645
- obj = Oj.load(nil, :nilnil => true)
646
- assert_nil(obj)
647
- end
648
-
649
- def test_empty_string_true
650
- result = Oj.load(gen_whitespaced_string, :empty_string => true, mode: :strict)
651
- assert_nil(result)
652
- end
653
-
654
- def test_empty_string_false
655
- # Could be either a Oj::ParseError or an EncodingError depending on
656
- # whether mimic_JSON has been called. Since we don't know when the test
657
- # will be called either is okay.
658
- begin
659
- Oj.load(gen_whitespaced_string, :empty_string => false)
660
- rescue Exception => e
661
- assert(Oj::ParseError == e.class || EncodingError == e.class)
662
- return
663
- end
664
- assert(false, "*** expected an exception")
665
- end
666
-
667
- def test_quirks_null_mode
668
- assert_raises(Oj::ParseError) { Oj.load("null", :quirks_mode => false) }
669
- assert_nil(Oj.load("null", :quirks_mode => true))
670
- end
671
-
672
- def test_quirks_bool_mode
673
- assert_raises(Oj::ParseError) { Oj.load("true", :quirks_mode => false) }
674
- assert_equal(true, Oj.load("true", :quirks_mode => true))
675
- end
676
-
677
- def test_quirks_number_mode
678
- assert_raises(Oj::ParseError) { Oj.load("123", :quirks_mode => false) }
679
- assert_equal(123, Oj.load("123", :quirks_mode => true))
680
- end
681
-
682
- def test_quirks_decimal_mode
683
- assert_raises(Oj::ParseError) { Oj.load("123.45", :quirks_mode => false) }
684
- assert_equal(123.45, Oj.load("123.45", :quirks_mode => true))
685
- end
686
-
687
- def test_quirks_string_mode
688
- assert_raises(Oj::ParseError) { Oj.load('"string"', :quirks_mode => false) }
689
- assert_equal('string', Oj.load('"string"', :quirks_mode => true))
690
- end
691
-
692
- def test_error_path
693
- msg = ''
694
- assert_raises(Oj::ParseError) {
695
- begin
696
- Oj.load(%|{
697
- "first": [
698
- 1, 2, { "third": 123x }
699
- ]
700
- }|)
701
- rescue Oj::ParseError => e
702
- msg = e.message
703
- raise e
704
- end
705
- }
706
- assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
707
- end
708
-
709
- def test_bad_bignum
710
- if '2.4.0' < RUBY_VERSION
711
- assert_raises Oj::ParseError do
712
- Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
713
- end
714
- end
715
- end
716
-
717
- def test_quirks_array_mode
718
- assert_equal([], Oj.load("[]", :quirks_mode => false))
719
- assert_equal([], Oj.load("[]", :quirks_mode => true))
720
- end
721
-
722
- def test_quirks_object_mode
723
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
724
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
725
- end
726
-
727
- def test_omit_nil
728
- jam = Jam.new({'a' => 1, 'b' => nil }, nil)
729
-
730
- json = Oj.dump(jam, :omit_nil => true, :mode => :object)
731
- assert_equal(%|{"^o":"Juice::Jam","x":{"a":1}}|, json)
732
-
733
- json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :strict)
734
- assert_equal(%|{"x":{"a":1}}|, json)
735
-
736
- json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :null)
737
- assert_equal(%|{"x":{"a":1}}|, json)
738
- end
739
-
740
- def dump_and_load(obj, trace=false)
741
- json = Oj.dump(obj, :indent => 2)
742
- puts json if trace
743
- loaded = Oj.load(json)
744
- if obj.nil?
745
- assert_nil(loaded)
746
- else
747
- assert_equal(obj, loaded)
748
- end
749
- loaded
750
- end
751
-
752
- end