oj 3.14.2 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
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