oj 3.14.2 → 3.15.0

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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +0 -1
  4. data/ext/oj/buf.h +2 -2
  5. data/ext/oj/cache.c +16 -16
  6. data/ext/oj/cache8.c +7 -7
  7. data/ext/oj/circarray.c +2 -1
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +2 -2
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +6 -14
  12. data/ext/oj/custom.c +6 -16
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +43 -18
  15. data/ext/oj/dump_compat.c +551 -576
  16. data/ext/oj/dump_leaf.c +3 -5
  17. data/ext/oj/dump_object.c +35 -36
  18. data/ext/oj/dump_strict.c +2 -4
  19. data/ext/oj/encoder.c +1 -1
  20. data/ext/oj/err.c +2 -13
  21. data/ext/oj/err.h +9 -12
  22. data/ext/oj/extconf.rb +1 -1
  23. data/ext/oj/fast.c +24 -38
  24. data/ext/oj/intern.c +38 -42
  25. data/ext/oj/intern.h +3 -7
  26. data/ext/oj/mem.c +211 -217
  27. data/ext/oj/mem.h +10 -10
  28. data/ext/oj/mimic_json.c +39 -24
  29. data/ext/oj/object.c +12 -26
  30. data/ext/oj/odd.c +2 -1
  31. data/ext/oj/odd.h +4 -4
  32. data/ext/oj/oj.c +80 -81
  33. data/ext/oj/oj.h +56 -54
  34. data/ext/oj/parse.c +55 -118
  35. data/ext/oj/parse.h +5 -10
  36. data/ext/oj/parser.c +7 -8
  37. data/ext/oj/parser.h +7 -8
  38. data/ext/oj/rails.c +28 -59
  39. data/ext/oj/reader.c +5 -9
  40. data/ext/oj/reader.h +1 -1
  41. data/ext/oj/resolve.c +3 -4
  42. data/ext/oj/rxclass.c +1 -1
  43. data/ext/oj/rxclass.h +1 -1
  44. data/ext/oj/saj.c +4 -4
  45. data/ext/oj/saj2.c +32 -49
  46. data/ext/oj/saj2.h +1 -1
  47. data/ext/oj/scp.c +3 -14
  48. data/ext/oj/sparse.c +18 -67
  49. data/ext/oj/stream_writer.c +5 -18
  50. data/ext/oj/strict.c +16 -40
  51. data/ext/oj/string_writer.c +6 -14
  52. data/ext/oj/trace.h +27 -16
  53. data/ext/oj/usual.c +62 -61
  54. data/ext/oj/usual.h +6 -6
  55. data/ext/oj/util.h +1 -1
  56. data/ext/oj/val_stack.h +4 -4
  57. data/ext/oj/wab.c +16 -36
  58. data/lib/oj/active_support_helper.rb +0 -1
  59. data/lib/oj/bag.rb +7 -1
  60. data/lib/oj/easy_hash.rb +4 -5
  61. data/lib/oj/error.rb +0 -1
  62. data/lib/oj/json.rb +4 -2
  63. data/lib/oj/mimic.rb +4 -2
  64. data/lib/oj/state.rb +8 -5
  65. data/lib/oj/version.rb +1 -2
  66. data/lib/oj.rb +2 -0
  67. data/pages/Options.md +4 -0
  68. data/test/_test_active.rb +8 -9
  69. data/test/_test_active_mimic.rb +7 -8
  70. data/test/_test_mimic_rails.rb +17 -20
  71. data/test/activerecord/result_test.rb +5 -6
  72. data/test/files.rb +15 -15
  73. data/test/foo.rb +9 -52
  74. data/test/helper.rb +5 -8
  75. data/test/isolated/shared.rb +3 -2
  76. data/test/json_gem/json_addition_test.rb +2 -2
  77. data/test/json_gem/json_common_interface_test.rb +4 -4
  78. data/test/json_gem/json_encoding_test.rb +0 -0
  79. data/test/json_gem/json_ext_parser_test.rb +1 -0
  80. data/test/json_gem/json_fixtures_test.rb +3 -2
  81. data/test/json_gem/json_generator_test.rb +43 -32
  82. data/test/json_gem/json_generic_object_test.rb +11 -11
  83. data/test/json_gem/json_parser_test.rb +46 -46
  84. data/test/json_gem/json_string_matching_test.rb +9 -9
  85. data/test/mem.rb +13 -12
  86. data/test/perf.rb +21 -26
  87. data/test/perf_compat.rb +31 -33
  88. data/test/perf_dump.rb +25 -25
  89. data/test/perf_fast.rb +80 -82
  90. data/test/perf_file.rb +27 -29
  91. data/test/perf_object.rb +65 -69
  92. data/test/perf_once.rb +12 -11
  93. data/test/perf_parser.rb +41 -48
  94. data/test/perf_saj.rb +46 -54
  95. data/test/perf_scp.rb +57 -69
  96. data/test/perf_simple.rb +41 -39
  97. data/test/perf_strict.rb +68 -70
  98. data/test/perf_wab.rb +67 -69
  99. data/test/prec.rb +3 -3
  100. data/test/sample/change.rb +0 -1
  101. data/test/sample/dir.rb +0 -1
  102. data/test/sample/doc.rb +0 -1
  103. data/test/sample/file.rb +0 -1
  104. data/test/sample/group.rb +0 -1
  105. data/test/sample/hasprops.rb +0 -1
  106. data/test/sample/layer.rb +0 -1
  107. data/test/sample/rect.rb +0 -1
  108. data/test/sample/shape.rb +0 -1
  109. data/test/sample/text.rb +0 -1
  110. data/test/sample.rb +16 -16
  111. data/test/sample_json.rb +8 -8
  112. data/test/test_compat.rb +52 -52
  113. data/test/test_custom.rb +61 -51
  114. data/test/test_debian.rb +7 -10
  115. data/test/test_fast.rb +86 -90
  116. data/test/test_file.rb +24 -29
  117. data/test/test_gc.rb +5 -5
  118. data/test/test_generate.rb +5 -5
  119. data/test/test_hash.rb +4 -4
  120. data/test/test_integer_range.rb +9 -9
  121. data/test/test_null.rb +20 -20
  122. data/test/test_object.rb +78 -87
  123. data/test/test_parser.rb +4 -4
  124. data/test/test_parser_debug.rb +4 -4
  125. data/test/test_parser_saj.rb +27 -25
  126. data/test/test_parser_usual.rb +6 -6
  127. data/test/test_rails.rb +2 -2
  128. data/test/test_saj.rb +10 -8
  129. data/test/test_scp.rb +35 -35
  130. data/test/test_strict.rb +28 -32
  131. data/test/test_various.rb +140 -97
  132. data/test/test_wab.rb +46 -44
  133. data/test/test_writer.rb +47 -47
  134. data/test/tests.rb +7 -7
  135. data/test/tests_mimic.rb +6 -6
  136. data/test/tests_mimic_addition.rb +6 -6
  137. metadata +18 -30
  138. data/test/activesupport4/decoding_test.rb +0 -108
  139. data/test/activesupport4/encoding_test.rb +0 -531
  140. data/test/activesupport4/test_helper.rb +0 -41
  141. data/test/activesupport5/abstract_unit.rb +0 -45
  142. data/test/activesupport5/decoding_test.rb +0 -133
  143. data/test/activesupport5/encoding_test.rb +0 -500
  144. data/test/activesupport5/encoding_test_cases.rb +0 -98
  145. data/test/activesupport5/test_helper.rb +0 -72
  146. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  147. data/test/bar.rb +0 -11
  148. data/test/baz.rb +0 -16
  149. data/test/bug.rb +0 -16
  150. 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,
@@ -139,17 +129,18 @@ class Juice < Minitest::Test
139
129
  ignore_under: true,
140
130
  trace: true,
141
131
  safe: true,
132
+ omit_null_byte: false,
142
133
  }
143
134
  Oj.default_options = alt
144
- #keys = alt.keys
145
- #Oj.default_options.keys.each { |k| puts k unless keys.include? k}
135
+ # keys = alt.keys
136
+ # Oj.default_options.keys.each { |k| puts k unless keys.include? k}
146
137
  opts = Oj.default_options()
147
- assert_equal(alt, opts);
138
+ assert_equal(alt, opts)
148
139
 
149
140
  Oj.default_options = orig # return to original
150
141
  # verify back to original
151
142
  opts = Oj.default_options()
152
- assert_equal(orig, opts);
143
+ assert_equal(orig, opts)
153
144
  end
154
145
 
155
146
  def test_nil
@@ -166,8 +157,8 @@ class Juice < Minitest::Test
166
157
 
167
158
  def test_fixnum
168
159
  dump_and_load(0, false)
169
- dump_and_load(12345, false)
170
- dump_and_load(-54321, false)
160
+ dump_and_load(12_345, false)
161
+ dump_and_load(-54_321, false)
171
162
  dump_and_load(1, false)
172
163
  end
173
164
 
@@ -175,11 +166,11 @@ class Juice < Minitest::Test
175
166
  Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
176
167
  n = Oj.load('0.00001234567890123456')
177
168
  assert_equal(Float, n.class)
178
- assert_equal('1.234567890123456e-05', "%0.15e" % [n])
169
+ assert_equal('1.234567890123456e-05', '%0.15e' % [n])
179
170
 
180
171
  n = Oj.load('-0.00001234567890123456')
181
172
  assert_equal(Float, n.class)
182
- assert_equal('-1.234567890123456e-05', "%0.15e" % [n])
173
+ assert_equal('-1.234567890123456e-05', '%0.15e' % [n])
183
174
 
184
175
  n = Oj.load('1000.0000123456789')
185
176
  assert_equal(BigDecimal, n.class)
@@ -227,12 +218,12 @@ class Juice < Minitest::Test
227
218
  def test_encode
228
219
  opts = Oj.default_options
229
220
  Oj.default_options = { :ascii_only => false }
230
- dump_and_load("ぴーたー", false)
221
+ dump_and_load('ぴーたー', false)
231
222
 
232
223
  Oj.default_options = { :ascii_only => true }
233
- json = Oj.dump("ぴーたー")
224
+ json = Oj.dump('ぴーたー')
234
225
  assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
235
- dump_and_load("ぴーたー", false)
226
+ dump_and_load('ぴーたー', false)
236
227
  Oj.default_options = opts
237
228
  end
238
229
 
@@ -253,7 +244,7 @@ class Juice < Minitest::Test
253
244
  assert(true)
254
245
  return
255
246
  end
256
- assert(false, "*** expected an exception")
247
+ assert(false, '*** expected an exception')
257
248
  end
258
249
 
259
250
  def test_invalid_unicode_ok
@@ -267,11 +258,11 @@ class Juice < Minitest::Test
267
258
  def test_dump_options
268
259
  json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
269
260
  :mode => :compat,
270
- :indent => "--",
261
+ :indent => '--',
271
262
  :array_nl => "\n",
272
263
  :object_nl => "#\n",
273
- :space => "*",
274
- :space_before => "~")
264
+ :space => '*',
265
+ :space_before => '~')
275
266
  assert(%{{#
276
267
  --"a"~:*1,#
277
268
  --"b"~:*[
@@ -286,7 +277,6 @@ class Juice < Minitest::Test
286
277
  --],#
287
278
  --"a"~:*1#
288
279
  }} == json)
289
-
290
280
  end
291
281
 
292
282
  def test_null_char
@@ -301,6 +291,7 @@ class Juice < Minitest::Test
301
291
  dump_and_load([[nil]], false)
302
292
  dump_and_load([[nil], 58], false)
303
293
  end
294
+
304
295
  def test_array_not_closed
305
296
  begin
306
297
  Oj.load('[')
@@ -308,7 +299,7 @@ class Juice < Minitest::Test
308
299
  assert(true)
309
300
  return
310
301
  end
311
- assert(false, "*** expected an exception")
302
+ assert(false, '*** expected an exception')
312
303
  end
313
304
 
314
305
  # multiple JSON in one string
@@ -319,7 +310,7 @@ class Juice < Minitest::Test
319
310
  }
320
311
  results = []
321
312
  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)
313
+ assert_equal([[{'a'=>1}, 0, 7], [[1, 2], 7, 6], [[3, 4], 13, 5], [{'b'=>2}, 18, 8]], results)
323
314
  end
324
315
 
325
316
  def test_multiple_json_no_callback
@@ -339,33 +330,39 @@ class Juice < Minitest::Test
339
330
  out = Oj.dump(hash)
340
331
  assert_equal(json, out)
341
332
  end
333
+
342
334
  def test_escapes_entities_by_default_when_configured_to_do_so
343
- hash = {'key' => "I <3 this"}
335
+ hash = {'key' => 'I <3 this'}
344
336
  Oj.default_options = {:escape_mode => :xss_safe}
345
337
  out = Oj.dump hash
346
338
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
347
339
  end
340
+
348
341
  def test_escapes_slashes_by_default_when_configured_to_do_so
349
- hash = {'key' => "I <3 this </script>"}
342
+ hash = {'key' => 'I <3 this </script>'}
350
343
  Oj.default_options = {:escape_mode => :slash}
351
344
  out = Oj.dump hash
352
345
  assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
353
346
  end
347
+
354
348
  def test_escapes_entities_when_asked_to
355
- hash = {'key' => "I <3 this"}
349
+ hash = {'key' => 'I <3 this'}
356
350
  out = Oj.dump(hash, :escape_mode => :xss_safe)
357
351
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
358
352
  end
353
+
359
354
  def test_does_not_escape_entities_when_not_asked_to
360
- hash = {'key' => "I <3 this"}
355
+ hash = {'key' => 'I <3 this'}
361
356
  out = Oj.dump(hash, :escape_mode => :json)
362
357
  assert_equal(%{{"key":"I <3 this"}}, out)
363
358
  end
359
+
364
360
  def test_escapes_common_xss_vectors
365
- hash = {'key' => "<script>alert(123) && formatHD()</script>"}
361
+ hash = {'key' => '<script>alert(123) && formatHD()</script>'}
366
362
  out = Oj.dump(hash, :escape_mode => :xss_safe)
367
363
  assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
368
364
  end
365
+
369
366
  def test_escape_newline_by_default
370
367
  Oj.default_options = { :escape_mode => :json }
371
368
  json = %{["one","two\\n2"]}
@@ -373,6 +370,7 @@ class Juice < Minitest::Test
373
370
  out = Oj.dump(x)
374
371
  assert_equal(json, out)
375
372
  end
373
+
376
374
  def test_does_not_escape_newline
377
375
  Oj.default_options = { :escape_mode => :newline }
378
376
  json = %{["one","two\n2"]}
@@ -380,6 +378,7 @@ class Juice < Minitest::Test
380
378
  out = Oj.dump(x)
381
379
  assert_equal(json, out)
382
380
  end
381
+
383
382
  def test_dump_invalid_utf8
384
383
  Oj.default_options = { :escape_mode => :ascii }
385
384
  assert_raises(EncodingError) {
@@ -401,14 +400,14 @@ class Juice < Minitest::Test
401
400
  end
402
401
 
403
402
  def test_time_neg
404
- t = Time.parse("1900-01-01 00:18:59 UTC")
403
+ t = Time.parse('1900-01-01 00:18:59 UTC')
405
404
  json = Oj.dump(t, :mode => :custom, :time_format => :unix)
406
405
  assert_equal('-2208987661.000000000', json)
407
406
  end
408
407
 
409
408
  def test_time_years
410
409
  (-2020..2020).each { |year|
411
- s = "%04d-03-01T15:14:13Z" % [year]
410
+ s = '%04d-03-01T15:14:13Z' % [year]
412
411
  json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
413
412
  assert_equal(s, json[1..-2])
414
413
 
@@ -437,7 +436,7 @@ class Juice < Minitest::Test
437
436
  assert(true)
438
437
  return
439
438
  end
440
- assert(false, "*** expected an exception")
439
+ assert(false, '*** expected an exception')
441
440
  end
442
441
 
443
442
  def test_hash_not_closed
@@ -447,7 +446,7 @@ class Juice < Minitest::Test
447
446
  assert(true)
448
447
  return
449
448
  end
450
- assert(false, "*** expected an exception")
449
+ assert(false, '*** expected an exception')
451
450
  end
452
451
 
453
452
  # Object with to_json()
@@ -457,7 +456,7 @@ class Juice < Minitest::Test
457
456
  assert_equal('null', json)
458
457
  end
459
458
 
460
- # Object with to_hash()
459
+ # Object with to_hash()
461
460
  def test_to_hash_object_null
462
461
  obj = Jazz.new(true, 58)
463
462
  json = Oj.dump(obj, :mode => :null)
@@ -505,7 +504,7 @@ class Juice < Minitest::Test
505
504
 
506
505
  def test_infinity
507
506
  n = Oj.load('Infinity', :mode => :object)
508
- assert_equal(BigDecimal('Infinity').to_f, n);
507
+ assert_equal(BigDecimal('Infinity').to_f, n)
509
508
  x = Oj.load('Infinity', :mode => :compat)
510
509
  assert_equal('Infinity', x.to_s)
511
510
  end
@@ -530,7 +529,7 @@ class Juice < Minitest::Test
530
529
  "y":58 }}
531
530
  obj = Oj.load(json, :mode => :object, :auto_define => true)
532
531
  assert_equal('Juice::Jem', obj.class.name)
533
- assert_equal(true, obj.x)
532
+ assert(obj.x)
534
533
  assert_equal(58, obj.y)
535
534
  end
536
535
 
@@ -538,19 +537,19 @@ class Juice < Minitest::Test
538
537
  def test_deep_nest_dump
539
538
  begin
540
539
  a = []
541
- 10000.times { a << [a] }
540
+ 10_000.times { a << [a] }
542
541
  Oj.dump(a)
543
542
  rescue Exception
544
543
  assert(true)
545
544
  return
546
545
  end
547
- assert(false, "*** expected an exception")
546
+ assert(false, '*** expected an exception')
548
547
  end
549
548
 
550
549
  # Stream IO
551
550
  def test_io_string
552
551
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
553
- output = StringIO.open("", "w+")
552
+ output = StringIO.open('', 'w+')
554
553
  Oj.to_stream(output, src)
555
554
 
556
555
  input = StringIO.new(output.string())
@@ -560,8 +559,8 @@ class Juice < Minitest::Test
560
559
 
561
560
  def test_io_file
562
561
  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|
562
+ filename = File.join(__dir__, 'open_file_test.json')
563
+ File.open(filename, 'w') { |f|
565
564
  Oj.to_stream(f, src)
566
565
  }
567
566
  f = File.new(filename)
@@ -575,26 +574,26 @@ class Juice < Minitest::Test
575
574
 
576
575
  IO.pipe do |r, w|
577
576
  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
577
+ r.close
578
+ # w.nonblock = false
579
+ a = []
580
+ 10_000.times do |i|
581
+ a << i
582
+ end
583
+ Oj.to_stream(w, a, indent: 2)
584
+ w.close
586
585
  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)
586
+ w.close
587
+ sleep(0.1) # to force a busy
588
+ cnt = 0
589
+ r.each_line { cnt += 1 }
590
+ r.close
591
+ Process.exit(0)
593
592
  end
594
593
  end
595
594
  end
596
595
 
597
- # comments
596
+ # comments
598
597
  def test_comment_slash
599
598
  json = %{{
600
599
  "x":true,//three
@@ -638,7 +637,7 @@ class Juice < Minitest::Test
638
637
  assert(true)
639
638
  return
640
639
  end
641
- assert(false, "*** expected an exception")
640
+ assert(false, '*** expected an exception')
642
641
  end
643
642
 
644
643
  def test_nilnil_true
@@ -661,27 +660,27 @@ class Juice < Minitest::Test
661
660
  assert(Oj::ParseError == e.class || EncodingError == e.class)
662
661
  return
663
662
  end
664
- assert(false, "*** expected an exception")
663
+ assert(false, '*** expected an exception')
665
664
  end
666
665
 
667
666
  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))
667
+ assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
668
+ assert_nil(Oj.load('null', :quirks_mode => true))
670
669
  end
671
670
 
672
671
  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))
672
+ assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
673
+ assert(Oj.load('true', :quirks_mode => true))
675
674
  end
676
675
 
677
676
  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))
677
+ assert_raises(Oj::ParseError) { Oj.load('123', :quirks_mode => false) }
678
+ assert_equal(123, Oj.load('123', :quirks_mode => true))
680
679
  end
681
680
 
682
681
  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))
682
+ assert_raises(Oj::ParseError) { Oj.load('123.45', :quirks_mode => false) }
683
+ assert_in_delta(123.45, Oj.load('123.45', :quirks_mode => true))
685
684
  end
686
685
 
687
686
  def test_quirks_string_mode
@@ -693,35 +692,33 @@ class Juice < Minitest::Test
693
692
  msg = ''
694
693
  assert_raises(Oj::ParseError) {
695
694
  begin
696
- Oj.load(%|{
695
+ Oj.load(%|{
697
696
  "first": [
698
697
  1, 2, { "third": 123x }
699
698
  ]
700
699
  }|)
701
700
  rescue Oj::ParseError => e
702
- msg = e.message
703
- raise e
701
+ msg = e.message
702
+ raise e
704
703
  end
705
704
  }
706
705
  assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
707
706
  end
708
707
 
709
708
  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
709
+ assert_raises Oj::ParseError do
710
+ Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
714
711
  end
715
712
  end
716
713
 
717
714
  def test_quirks_array_mode
718
- assert_equal([], Oj.load("[]", :quirks_mode => false))
719
- assert_equal([], Oj.load("[]", :quirks_mode => true))
715
+ assert_empty(Oj.load('[]', :quirks_mode => false))
716
+ assert_empty(Oj.load('[]', :quirks_mode => true))
720
717
  end
721
718
 
722
719
  def test_quirks_object_mode
723
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
724
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
720
+ assert_empty(Oj.load('{}', :quirks_mode => false))
721
+ assert_empty(Oj.load('{}', :quirks_mode => true))
725
722
  end
726
723
 
727
724
  def test_omit_nil
@@ -737,6 +734,52 @@ class Juice < Minitest::Test
737
734
  assert_equal(%|{"x":{"a":1}}|, json)
738
735
  end
739
736
 
737
+ def test_omit_null_byte
738
+ Oj.default_options = { :omit_null_byte => true }
739
+
740
+ json = Oj.dump({ "fo\x00o" => "b\x00ar" })
741
+ assert_equal(%|{"foo":"bar"}|, json)
742
+
743
+ json = Oj.dump({ "foo\x00" => "\x00bar" })
744
+ assert_equal(%|{"foo":"bar"}|, json)
745
+
746
+ json = Oj.dump({ "\x00foo" => "bar\x00" })
747
+ assert_equal(%|{"foo":"bar"}|, json)
748
+
749
+ json = Oj.dump({ "fo\0o" => "ba\0r" })
750
+ assert_equal(%|{"foo":"bar"}|, json)
751
+
752
+ json = Oj.dump({ "foo\0" => "\0bar" })
753
+ assert_equal(%|{"foo":"bar"}|, json)
754
+
755
+ json = Oj.dump({ "\0foo" => "bar\0" })
756
+ assert_equal(%|{"foo":"bar"}|, json)
757
+
758
+ json = Oj.dump({ "fo\u0000o" => "ba\u0000r" })
759
+ assert_equal(%|{"foo":"bar"}|, json)
760
+
761
+ json = Oj.dump({ "foo\u0000" => "\u0000bar" })
762
+ assert_equal(%|{"foo":"bar"}|, json)
763
+
764
+ json = Oj.dump({ "\u0000foo" => "bar\u0000" })
765
+ assert_equal(%|{"foo":"bar"}|, json)
766
+
767
+ json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => false)
768
+ assert_equal(%|{"\\u0000foo":"bar\\u0000"}|, json)
769
+
770
+ # no change from default set earlier so :omit_null_byte is still true
771
+ json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => nil)
772
+ assert_equal(%|{"foo":"bar"}|, json)
773
+
774
+ Oj.default_options = { :omit_null_byte => false }
775
+
776
+ json = Oj.dump({ "\x00foo" => "bar\x00" })
777
+ assert_equal(%|{"\\u0000foo":"bar\\u0000"}|, json)
778
+
779
+ json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => true)
780
+ assert_equal(%|{"foo":"bar"}|, json)
781
+ end
782
+
740
783
  def dump_and_load(obj, trace=false)
741
784
  json = Oj.dump(obj, :indent => 2)
742
785
  puts json if trace