oj 3.13.23 → 3.16.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -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 +60 -92
  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 +51 -32
  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 +243 -212
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +94 -148
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +7 -8
  40. data/ext/oj/rails.c +70 -92
  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 +10 -9
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +45 -41
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +64 -38
  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. data/test/_test_active.rb +8 -9
  74. data/test/_test_active_mimic.rb +7 -8
  75. data/test/_test_mimic_rails.rb +17 -20
  76. data/test/activerecord/result_test.rb +5 -6
  77. data/test/activesupport6/encoding_test.rb +63 -28
  78. data/test/activesupport7/abstract_unit.rb +4 -1
  79. data/test/activesupport7/encoding_test.rb +72 -22
  80. data/test/files.rb +15 -15
  81. data/test/foo.rb +18 -69
  82. data/test/helper.rb +5 -8
  83. data/test/isolated/shared.rb +3 -2
  84. data/test/json_gem/json_addition_test.rb +2 -2
  85. data/test/json_gem/json_common_interface_test.rb +8 -6
  86. data/test/json_gem/json_encoding_test.rb +0 -0
  87. data/test/json_gem/json_ext_parser_test.rb +1 -0
  88. data/test/json_gem/json_fixtures_test.rb +3 -2
  89. data/test/json_gem/json_generator_test.rb +50 -33
  90. data/test/json_gem/json_generic_object_test.rb +11 -11
  91. data/test/json_gem/json_parser_test.rb +46 -46
  92. data/test/json_gem/json_string_matching_test.rb +9 -9
  93. data/test/mem.rb +13 -12
  94. data/test/perf.rb +21 -26
  95. data/test/perf_compat.rb +31 -33
  96. data/test/perf_dump.rb +28 -28
  97. data/test/perf_fast.rb +80 -82
  98. data/test/perf_file.rb +27 -29
  99. data/test/perf_object.rb +65 -69
  100. data/test/perf_once.rb +12 -11
  101. data/test/perf_parser.rb +42 -48
  102. data/test/perf_saj.rb +46 -54
  103. data/test/perf_scp.rb +57 -69
  104. data/test/perf_simple.rb +41 -39
  105. data/test/perf_strict.rb +68 -70
  106. data/test/perf_wab.rb +67 -69
  107. data/test/prec.rb +5 -5
  108. data/test/sample/change.rb +0 -1
  109. data/test/sample/dir.rb +0 -1
  110. data/test/sample/doc.rb +0 -1
  111. data/test/sample/file.rb +0 -1
  112. data/test/sample/group.rb +0 -1
  113. data/test/sample/hasprops.rb +0 -1
  114. data/test/sample/layer.rb +0 -1
  115. data/test/sample/rect.rb +0 -1
  116. data/test/sample/shape.rb +0 -1
  117. data/test/sample/text.rb +0 -1
  118. data/test/sample.rb +16 -16
  119. data/test/sample_json.rb +8 -8
  120. data/test/test_compat.rb +81 -54
  121. data/test/test_custom.rb +63 -52
  122. data/test/test_debian.rb +7 -10
  123. data/test/test_fast.rb +86 -90
  124. data/test/test_file.rb +24 -29
  125. data/test/test_gc.rb +5 -5
  126. data/test/test_generate.rb +5 -5
  127. data/test/test_hash.rb +4 -4
  128. data/test/test_integer_range.rb +9 -9
  129. data/test/test_null.rb +20 -20
  130. data/test/test_object.rb +92 -87
  131. data/test/test_parser.rb +4 -4
  132. data/test/test_parser_debug.rb +5 -5
  133. data/test/test_parser_saj.rb +27 -25
  134. data/test/test_parser_usual.rb +44 -6
  135. data/test/test_rails.rb +2 -2
  136. data/test/test_saj.rb +10 -8
  137. data/test/test_scp.rb +35 -35
  138. data/test/test_strict.rb +38 -32
  139. data/test/test_various.rb +146 -97
  140. data/test/test_wab.rb +46 -44
  141. data/test/test_writer.rb +63 -47
  142. data/test/tests.rb +7 -7
  143. data/test/tests_mimic.rb +6 -6
  144. data/test/tests_mimic_addition.rb +6 -6
  145. metadata +46 -26
  146. data/test/activesupport4/decoding_test.rb +0 -108
  147. data/test/activesupport4/encoding_test.rb +0 -531
  148. data/test/activesupport4/test_helper.rb +0 -41
  149. data/test/activesupport5/abstract_unit.rb +0 -45
  150. data/test/activesupport5/decoding_test.rb +0 -133
  151. data/test/activesupport5/encoding_test.rb +0 -500
  152. data/test/activesupport5/encoding_test_cases.rb +0 -98
  153. data/test/activesupport5/test_helper.rb +0 -72
  154. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  155. data/test/bar.rb +0 -11
  156. data/test/baz.rb +0 -16
  157. data/test/bug.rb +0 -16
  158. data/test/zoo.rb +0 -13
data/test/test_various.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: utf-8
2
+ # frozen_string_literal: false
3
3
 
4
- $: << File.dirname(__FILE__)
4
+ $LOAD_PATH << __dir__
5
5
 
6
6
  require 'helper'
7
7
 
8
8
  class Juice < Minitest::Test
9
- def gen_whitespaced_string(length = Random.new.rand(100))
10
- whitespace_chars = [" ", "\t", "\f", "\n", "\r"]
11
- result = ""
9
+ def gen_whitespaced_string(length=Random.new.rand(100))
10
+ whitespace_chars = [' ', "\t", "\f", "\n", "\r"]
11
+ result = ''
12
12
  length.times { result << whitespace_chars.sample }
13
13
  result
14
14
  end
@@ -32,59 +32,49 @@ class Juice < Minitest::Test
32
32
  end # Jam
33
33
 
34
34
  class Jeez < Jam
35
- def initialize(x, y)
36
- super
37
- end
38
35
 
39
- def to_json()
36
+ def to_json(*_args)
40
37
  %{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
41
38
  end
42
39
 
43
40
  def self.json_create(h)
44
- self.new(h['x'], h['y'])
41
+ new(h['x'], h['y'])
45
42
  end
46
43
  end # Jeez
47
44
 
48
45
  # contributed by sauliusg to fix as_json
49
46
  class Orange < Jam
50
- def initialize(x, y)
51
- super
52
- end
53
47
 
54
- def as_json()
48
+ def as_json
55
49
  { :json_class => self.class,
56
50
  :x => @x,
57
51
  :y => @y }
58
52
  end
59
53
 
60
54
  def self.json_create(h)
61
- self.new(h['x'], h['y'])
55
+ new(h['x'], h['y'])
62
56
  end
63
57
  end
64
58
 
65
59
  class Melon < Jam
66
- def initialize(x, y)
67
- super
68
- end
69
60
 
70
- def as_json(options)
61
+ def as_json(_options)
71
62
  "#{x} #{y}"
72
63
  end
73
64
 
74
65
  def self.json_create(h)
75
- self.new(h['x'], h['y'])
66
+ new(h['x'], h['y'])
76
67
  end
77
68
  end
78
69
 
79
70
  class Jazz < Jam
80
- def initialize(x, y)
81
- super
82
- end
83
- def to_hash()
71
+
72
+ def to_hash
84
73
  { 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
85
74
  end
75
+
86
76
  def self.json_create(h)
87
- self.new(h['x'], h['y'])
77
+ new(h['x'], h['y'])
88
78
  end
89
79
  end # Jazz
90
80
 
@@ -99,7 +89,7 @@ class Juice < Minitest::Test
99
89
  def test_set_options
100
90
  orig = Oj.default_options()
101
91
  alt ={
102
- indent: " - ",
92
+ indent: ' - ',
103
93
  second_precision: 5,
104
94
  circular: true,
105
95
  class_cache: false,
@@ -115,6 +105,7 @@ class Juice < Minitest::Test
115
105
  allow_gc: false,
116
106
  quirks_mode: false,
117
107
  allow_invalid_unicode: true,
108
+ float_format: '%0.13g',
118
109
  float_precision: 13,
119
110
  mode: :strict,
120
111
  escape_mode: :ascii,
@@ -139,17 +130,18 @@ class Juice < Minitest::Test
139
130
  ignore_under: true,
140
131
  trace: true,
141
132
  safe: true,
133
+ omit_null_byte: false,
142
134
  }
143
135
  Oj.default_options = alt
144
- #keys = alt.keys
145
- #Oj.default_options.keys.each { |k| puts k unless keys.include? k}
136
+ # keys = alt.keys
137
+ # Oj.default_options.keys.each { |k| puts k unless keys.include? k}
146
138
  opts = Oj.default_options()
147
- assert_equal(alt, opts);
139
+ assert_equal(alt, opts)
148
140
 
149
141
  Oj.default_options = orig # return to original
150
142
  # verify back to original
151
143
  opts = Oj.default_options()
152
- assert_equal(orig, opts);
144
+ assert_equal(orig, opts)
153
145
  end
154
146
 
155
147
  def test_nil
@@ -166,8 +158,8 @@ class Juice < Minitest::Test
166
158
 
167
159
  def test_fixnum
168
160
  dump_and_load(0, false)
169
- dump_and_load(12345, false)
170
- dump_and_load(-54321, false)
161
+ dump_and_load(12_345, false)
162
+ dump_and_load(-54_321, false)
171
163
  dump_and_load(1, false)
172
164
  end
173
165
 
@@ -175,11 +167,11 @@ class Juice < Minitest::Test
175
167
  Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
176
168
  n = Oj.load('0.00001234567890123456')
177
169
  assert_equal(Float, n.class)
178
- assert_equal('1.234567890123456e-05', "%0.15e" % [n])
170
+ assert_equal('1.234567890123456e-05', '%0.15e' % [n])
179
171
 
180
172
  n = Oj.load('-0.00001234567890123456')
181
173
  assert_equal(Float, n.class)
182
- assert_equal('-1.234567890123456e-05', "%0.15e" % [n])
174
+ assert_equal('-1.234567890123456e-05', '%0.15e' % [n])
183
175
 
184
176
  n = Oj.load('1000.0000123456789')
185
177
  assert_equal(BigDecimal, n.class)
@@ -227,12 +219,12 @@ class Juice < Minitest::Test
227
219
  def test_encode
228
220
  opts = Oj.default_options
229
221
  Oj.default_options = { :ascii_only => false }
230
- dump_and_load("ぴーたー", false)
222
+ dump_and_load('ぴーたー', false)
231
223
 
232
224
  Oj.default_options = { :ascii_only => true }
233
- json = Oj.dump("ぴーたー")
225
+ json = Oj.dump('ぴーたー')
234
226
  assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
235
- dump_and_load("ぴーたー", false)
227
+ dump_and_load('ぴーたー', false)
236
228
  Oj.default_options = opts
237
229
  end
238
230
 
@@ -253,7 +245,7 @@ class Juice < Minitest::Test
253
245
  assert(true)
254
246
  return
255
247
  end
256
- assert(false, "*** expected an exception")
248
+ assert(false, '*** expected an exception')
257
249
  end
258
250
 
259
251
  def test_invalid_unicode_ok
@@ -267,11 +259,11 @@ class Juice < Minitest::Test
267
259
  def test_dump_options
268
260
  json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
269
261
  :mode => :compat,
270
- :indent => "--",
262
+ :indent => '--',
271
263
  :array_nl => "\n",
272
264
  :object_nl => "#\n",
273
- :space => "*",
274
- :space_before => "~")
265
+ :space => '*',
266
+ :space_before => '~')
275
267
  assert(%{{#
276
268
  --"a"~:*1,#
277
269
  --"b"~:*[
@@ -286,7 +278,6 @@ class Juice < Minitest::Test
286
278
  --],#
287
279
  --"a"~:*1#
288
280
  }} == json)
289
-
290
281
  end
291
282
 
292
283
  def test_null_char
@@ -301,6 +292,7 @@ class Juice < Minitest::Test
301
292
  dump_and_load([[nil]], false)
302
293
  dump_and_load([[nil], 58], false)
303
294
  end
295
+
304
296
  def test_array_not_closed
305
297
  begin
306
298
  Oj.load('[')
@@ -308,7 +300,7 @@ class Juice < Minitest::Test
308
300
  assert(true)
309
301
  return
310
302
  end
311
- assert(false, "*** expected an exception")
303
+ assert(false, '*** expected an exception')
312
304
  end
313
305
 
314
306
  # multiple JSON in one string
@@ -319,7 +311,7 @@ class Juice < Minitest::Test
319
311
  }
320
312
  results = []
321
313
  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)
314
+ assert_equal([[{'a'=>1}, 0, 7], [[1, 2], 7, 6], [[3, 4], 13, 5], [{'b'=>2}, 18, 8]], results)
323
315
  end
324
316
 
325
317
  def test_multiple_json_no_callback
@@ -339,33 +331,39 @@ class Juice < Minitest::Test
339
331
  out = Oj.dump(hash)
340
332
  assert_equal(json, out)
341
333
  end
334
+
342
335
  def test_escapes_entities_by_default_when_configured_to_do_so
343
- hash = {'key' => "I <3 this"}
336
+ hash = {'key' => 'I <3 this'}
344
337
  Oj.default_options = {:escape_mode => :xss_safe}
345
338
  out = Oj.dump hash
346
339
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
347
340
  end
341
+
348
342
  def test_escapes_slashes_by_default_when_configured_to_do_so
349
- hash = {'key' => "I <3 this </script>"}
343
+ hash = {'key' => 'I <3 this </script>'}
350
344
  Oj.default_options = {:escape_mode => :slash}
351
345
  out = Oj.dump hash
352
346
  assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
353
347
  end
348
+
354
349
  def test_escapes_entities_when_asked_to
355
- hash = {'key' => "I <3 this"}
350
+ hash = {'key' => 'I <3 this'}
356
351
  out = Oj.dump(hash, :escape_mode => :xss_safe)
357
352
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
358
353
  end
354
+
359
355
  def test_does_not_escape_entities_when_not_asked_to
360
- hash = {'key' => "I <3 this"}
356
+ hash = {'key' => 'I <3 this'}
361
357
  out = Oj.dump(hash, :escape_mode => :json)
362
358
  assert_equal(%{{"key":"I <3 this"}}, out)
363
359
  end
360
+
364
361
  def test_escapes_common_xss_vectors
365
- hash = {'key' => "<script>alert(123) && formatHD()</script>"}
362
+ hash = {'key' => '<script>alert(123) && formatHD()</script>'}
366
363
  out = Oj.dump(hash, :escape_mode => :xss_safe)
367
364
  assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
368
365
  end
366
+
369
367
  def test_escape_newline_by_default
370
368
  Oj.default_options = { :escape_mode => :json }
371
369
  json = %{["one","two\\n2"]}
@@ -373,6 +371,7 @@ class Juice < Minitest::Test
373
371
  out = Oj.dump(x)
374
372
  assert_equal(json, out)
375
373
  end
374
+
376
375
  def test_does_not_escape_newline
377
376
  Oj.default_options = { :escape_mode => :newline }
378
377
  json = %{["one","two\n2"]}
@@ -380,6 +379,7 @@ class Juice < Minitest::Test
380
379
  out = Oj.dump(x)
381
380
  assert_equal(json, out)
382
381
  end
382
+
383
383
  def test_dump_invalid_utf8
384
384
  Oj.default_options = { :escape_mode => :ascii }
385
385
  assert_raises(EncodingError) {
@@ -401,14 +401,14 @@ class Juice < Minitest::Test
401
401
  end
402
402
 
403
403
  def test_time_neg
404
- t = Time.parse("1900-01-01 00:18:59 UTC")
404
+ t = Time.parse('1900-01-01 00:18:59 UTC')
405
405
  json = Oj.dump(t, :mode => :custom, :time_format => :unix)
406
406
  assert_equal('-2208987661.000000000', json)
407
407
  end
408
408
 
409
409
  def test_time_years
410
410
  (-2020..2020).each { |year|
411
- s = "%04d-03-01T15:14:13Z" % [year]
411
+ s = '%04d-03-01T15:14:13Z' % [year]
412
412
  json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
413
413
  assert_equal(s, json[1..-2])
414
414
 
@@ -417,6 +417,11 @@ class Juice < Minitest::Test
417
417
  }
418
418
  end
419
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
+
420
425
  # Class
421
426
  def test_class_null
422
427
  json = Oj.dump(Juice, :mode => :null)
@@ -437,7 +442,7 @@ class Juice < Minitest::Test
437
442
  assert(true)
438
443
  return
439
444
  end
440
- assert(false, "*** expected an exception")
445
+ assert(false, '*** expected an exception')
441
446
  end
442
447
 
443
448
  def test_hash_not_closed
@@ -447,7 +452,7 @@ class Juice < Minitest::Test
447
452
  assert(true)
448
453
  return
449
454
  end
450
- assert(false, "*** expected an exception")
455
+ assert(false, '*** expected an exception')
451
456
  end
452
457
 
453
458
  # Object with to_json()
@@ -457,7 +462,7 @@ class Juice < Minitest::Test
457
462
  assert_equal('null', json)
458
463
  end
459
464
 
460
- # Object with to_hash()
465
+ # Object with to_hash()
461
466
  def test_to_hash_object_null
462
467
  obj = Jazz.new(true, 58)
463
468
  json = Oj.dump(obj, :mode => :null)
@@ -505,7 +510,7 @@ class Juice < Minitest::Test
505
510
 
506
511
  def test_infinity
507
512
  n = Oj.load('Infinity', :mode => :object)
508
- assert_equal(BigDecimal('Infinity').to_f, n);
513
+ assert_equal(BigDecimal('Infinity').to_f, n)
509
514
  x = Oj.load('Infinity', :mode => :compat)
510
515
  assert_equal('Infinity', x.to_s)
511
516
  end
@@ -530,7 +535,7 @@ class Juice < Minitest::Test
530
535
  "y":58 }}
531
536
  obj = Oj.load(json, :mode => :object, :auto_define => true)
532
537
  assert_equal('Juice::Jem', obj.class.name)
533
- assert_equal(true, obj.x)
538
+ assert(obj.x)
534
539
  assert_equal(58, obj.y)
535
540
  end
536
541
 
@@ -538,19 +543,19 @@ class Juice < Minitest::Test
538
543
  def test_deep_nest_dump
539
544
  begin
540
545
  a = []
541
- 10000.times { a << [a] }
546
+ 10_000.times { a << [a] }
542
547
  Oj.dump(a)
543
548
  rescue Exception
544
549
  assert(true)
545
550
  return
546
551
  end
547
- assert(false, "*** expected an exception")
552
+ assert(false, '*** expected an exception')
548
553
  end
549
554
 
550
555
  # Stream IO
551
556
  def test_io_string
552
557
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
553
- output = StringIO.open("", "w+")
558
+ output = StringIO.open('', 'w+')
554
559
  Oj.to_stream(output, src)
555
560
 
556
561
  input = StringIO.new(output.string())
@@ -560,8 +565,8 @@ class Juice < Minitest::Test
560
565
 
561
566
  def test_io_file
562
567
  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|
568
+ filename = File.join(__dir__, 'open_file_test.json')
569
+ File.open(filename, 'w') { |f|
565
570
  Oj.to_stream(f, src)
566
571
  }
567
572
  f = File.new(filename)
@@ -575,26 +580,26 @@ class Juice < Minitest::Test
575
580
 
576
581
  IO.pipe do |r, w|
577
582
  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
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
586
591
  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)
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)
593
598
  end
594
599
  end
595
600
  end
596
601
 
597
- # comments
602
+ # comments
598
603
  def test_comment_slash
599
604
  json = %{{
600
605
  "x":true,//three
@@ -638,7 +643,7 @@ class Juice < Minitest::Test
638
643
  assert(true)
639
644
  return
640
645
  end
641
- assert(false, "*** expected an exception")
646
+ assert(false, '*** expected an exception')
642
647
  end
643
648
 
644
649
  def test_nilnil_true
@@ -661,27 +666,27 @@ class Juice < Minitest::Test
661
666
  assert(Oj::ParseError == e.class || EncodingError == e.class)
662
667
  return
663
668
  end
664
- assert(false, "*** expected an exception")
669
+ assert(false, '*** expected an exception')
665
670
  end
666
671
 
667
672
  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))
673
+ assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
674
+ assert_nil(Oj.load('null', :quirks_mode => true))
670
675
  end
671
676
 
672
677
  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))
678
+ assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
679
+ assert(Oj.load('true', :quirks_mode => true))
675
680
  end
676
681
 
677
682
  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))
683
+ assert_raises(Oj::ParseError) { Oj.load('123', :quirks_mode => false) }
684
+ assert_equal(123, Oj.load('123', :quirks_mode => true))
680
685
  end
681
686
 
682
687
  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))
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))
685
690
  end
686
691
 
687
692
  def test_quirks_string_mode
@@ -693,35 +698,33 @@ class Juice < Minitest::Test
693
698
  msg = ''
694
699
  assert_raises(Oj::ParseError) {
695
700
  begin
696
- Oj.load(%|{
701
+ Oj.load(%|{
697
702
  "first": [
698
703
  1, 2, { "third": 123x }
699
704
  ]
700
705
  }|)
701
706
  rescue Oj::ParseError => e
702
- msg = e.message
703
- raise e
707
+ msg = e.message
708
+ raise e
704
709
  end
705
710
  }
706
711
  assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
707
712
  end
708
713
 
709
714
  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
715
+ assert_raises Oj::ParseError do
716
+ Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
714
717
  end
715
718
  end
716
719
 
717
720
  def test_quirks_array_mode
718
- assert_equal([], Oj.load("[]", :quirks_mode => false))
719
- assert_equal([], Oj.load("[]", :quirks_mode => true))
721
+ assert_empty(Oj.load('[]', :quirks_mode => false))
722
+ assert_empty(Oj.load('[]', :quirks_mode => true))
720
723
  end
721
724
 
722
725
  def test_quirks_object_mode
723
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
724
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
726
+ assert_empty(Oj.load('{}', :quirks_mode => false))
727
+ assert_empty(Oj.load('{}', :quirks_mode => true))
725
728
  end
726
729
 
727
730
  def test_omit_nil
@@ -737,6 +740,52 @@ class Juice < Minitest::Test
737
740
  assert_equal(%|{"x":{"a":1}}|, json)
738
741
  end
739
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
+
740
789
  def dump_and_load(obj, trace=false)
741
790
  json = Oj.dump(obj, :indent => 2)
742
791
  puts json if trace