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