oj 3.13.11 → 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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +4 -2
  4. data/ext/oj/buf.h +11 -6
  5. data/ext/oj/cache.c +25 -24
  6. data/ext/oj/cache8.c +10 -9
  7. data/ext/oj/circarray.c +8 -6
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +17 -24
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +17 -44
  12. data/ext/oj/custom.c +70 -141
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +128 -118
  15. data/ext/oj/dump.h +12 -8
  16. data/ext/oj/dump_compat.c +564 -641
  17. data/ext/oj/dump_leaf.c +17 -63
  18. data/ext/oj/dump_object.c +70 -199
  19. data/ext/oj/dump_strict.c +22 -46
  20. data/ext/oj/encoder.c +1 -1
  21. data/ext/oj/err.c +2 -13
  22. data/ext/oj/err.h +9 -12
  23. data/ext/oj/extconf.rb +14 -5
  24. data/ext/oj/fast.c +75 -103
  25. data/ext/oj/intern.c +52 -50
  26. data/ext/oj/intern.h +4 -8
  27. data/ext/oj/mem.c +318 -0
  28. data/ext/oj/mem.h +53 -0
  29. data/ext/oj/mimic_json.c +75 -47
  30. data/ext/oj/object.c +49 -66
  31. data/ext/oj/odd.c +89 -67
  32. data/ext/oj/odd.h +15 -15
  33. data/ext/oj/oj.c +140 -99
  34. data/ext/oj/oj.h +80 -51
  35. data/ext/oj/parse.c +162 -184
  36. data/ext/oj/parse.h +7 -10
  37. data/ext/oj/parser.c +89 -34
  38. data/ext/oj/parser.h +18 -7
  39. data/ext/oj/rails.c +82 -146
  40. data/ext/oj/rails.h +1 -1
  41. data/ext/oj/reader.c +11 -12
  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 +20 -31
  47. data/ext/oj/saj2.c +329 -93
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +26 -70
  51. data/ext/oj/stream_writer.c +12 -22
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +21 -21
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +105 -150
  56. data/ext/oj/usual.h +68 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +1 -1
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/validate.c +21 -26
  61. data/ext/oj/wab.c +31 -68
  62. data/lib/oj/active_support_helper.rb +0 -1
  63. data/lib/oj/bag.rb +7 -1
  64. data/lib/oj/easy_hash.rb +4 -5
  65. data/lib/oj/error.rb +0 -1
  66. data/lib/oj/json.rb +4 -2
  67. data/lib/oj/mimic.rb +4 -2
  68. data/lib/oj/saj.rb +20 -6
  69. data/lib/oj/state.rb +9 -6
  70. data/lib/oj/version.rb +1 -2
  71. data/lib/oj.rb +2 -0
  72. data/pages/Compatibility.md +1 -1
  73. data/pages/InstallOptions.md +20 -0
  74. data/pages/Options.md +10 -0
  75. data/test/_test_active.rb +8 -9
  76. data/test/_test_active_mimic.rb +7 -8
  77. data/test/_test_mimic_rails.rb +17 -20
  78. data/test/activerecord/result_test.rb +5 -6
  79. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  80. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  81. data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
  82. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  83. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  84. data/test/files.rb +15 -15
  85. data/test/foo.rb +9 -71
  86. data/test/helper.rb +11 -8
  87. data/test/isolated/shared.rb +3 -2
  88. data/test/json_gem/json_addition_test.rb +2 -2
  89. data/test/json_gem/json_common_interface_test.rb +4 -4
  90. data/test/json_gem/json_encoding_test.rb +0 -0
  91. data/test/json_gem/json_ext_parser_test.rb +1 -0
  92. data/test/json_gem/json_fixtures_test.rb +3 -2
  93. data/test/json_gem/json_generator_test.rb +48 -36
  94. data/test/json_gem/json_generic_object_test.rb +11 -11
  95. data/test/json_gem/json_parser_test.rb +54 -47
  96. data/test/json_gem/json_string_matching_test.rb +9 -9
  97. data/test/json_gem/test_helper.rb +7 -3
  98. data/test/mem.rb +13 -12
  99. data/test/perf.rb +21 -26
  100. data/test/perf_compat.rb +31 -33
  101. data/test/perf_dump.rb +50 -0
  102. data/test/perf_fast.rb +80 -82
  103. data/test/perf_file.rb +27 -29
  104. data/test/perf_object.rb +65 -69
  105. data/test/perf_once.rb +12 -11
  106. data/test/perf_parser.rb +42 -48
  107. data/test/perf_saj.rb +46 -54
  108. data/test/perf_scp.rb +57 -69
  109. data/test/perf_simple.rb +41 -39
  110. data/test/perf_strict.rb +68 -70
  111. data/test/perf_wab.rb +67 -69
  112. data/test/prec.rb +3 -3
  113. data/test/sample/change.rb +0 -1
  114. data/test/sample/dir.rb +0 -1
  115. data/test/sample/doc.rb +0 -1
  116. data/test/sample/file.rb +0 -1
  117. data/test/sample/group.rb +0 -1
  118. data/test/sample/hasprops.rb +0 -1
  119. data/test/sample/layer.rb +0 -1
  120. data/test/sample/rect.rb +0 -1
  121. data/test/sample/shape.rb +0 -1
  122. data/test/sample/text.rb +0 -1
  123. data/test/sample.rb +16 -16
  124. data/test/sample_json.rb +8 -8
  125. data/test/test_compat.rb +76 -42
  126. data/test/test_custom.rb +72 -51
  127. data/test/test_debian.rb +7 -10
  128. data/test/test_fast.rb +86 -90
  129. data/test/test_file.rb +41 -30
  130. data/test/test_gc.rb +16 -5
  131. data/test/test_generate.rb +5 -5
  132. data/test/test_hash.rb +4 -4
  133. data/test/test_integer_range.rb +9 -9
  134. data/test/test_null.rb +20 -20
  135. data/test/test_object.rb +85 -96
  136. data/test/test_parser.rb +6 -22
  137. data/test/test_parser_debug.rb +27 -0
  138. data/test/test_parser_saj.rb +115 -23
  139. data/test/test_parser_usual.rb +6 -6
  140. data/test/test_rails.rb +2 -2
  141. data/test/test_saj.rb +10 -8
  142. data/test/test_scp.rb +37 -39
  143. data/test/test_strict.rb +30 -32
  144. data/test/test_various.rb +147 -99
  145. data/test/test_wab.rb +48 -44
  146. data/test/test_writer.rb +47 -47
  147. data/test/tests.rb +13 -4
  148. data/test/tests_mimic.rb +12 -3
  149. data/test/tests_mimic_addition.rb +12 -3
  150. metadata +33 -144
  151. data/test/activesupport4/decoding_test.rb +0 -108
  152. data/test/activesupport4/encoding_test.rb +0 -531
  153. data/test/activesupport4/test_helper.rb +0 -41
  154. data/test/activesupport5/test_helper.rb +0 -72
  155. data/test/bar.rb +0 -16
  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,
@@ -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,27 +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
+
341
+ def test_escapes_slashes_by_default_when_configured_to_do_so
342
+ hash = {'key' => 'I <3 this </script>'}
343
+ Oj.default_options = {:escape_mode => :slash}
344
+ out = Oj.dump hash
345
+ assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
346
+ end
347
+
348
348
  def test_escapes_entities_when_asked_to
349
- hash = {'key' => "I <3 this"}
349
+ hash = {'key' => 'I <3 this'}
350
350
  out = Oj.dump(hash, :escape_mode => :xss_safe)
351
351
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
352
352
  end
353
+
353
354
  def test_does_not_escape_entities_when_not_asked_to
354
- hash = {'key' => "I <3 this"}
355
+ hash = {'key' => 'I <3 this'}
355
356
  out = Oj.dump(hash, :escape_mode => :json)
356
357
  assert_equal(%{{"key":"I <3 this"}}, out)
357
358
  end
359
+
358
360
  def test_escapes_common_xss_vectors
359
- hash = {'key' => "<script>alert(123) && formatHD()</script>"}
361
+ hash = {'key' => '<script>alert(123) && formatHD()</script>'}
360
362
  out = Oj.dump(hash, :escape_mode => :xss_safe)
361
363
  assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
362
364
  end
365
+
363
366
  def test_escape_newline_by_default
364
367
  Oj.default_options = { :escape_mode => :json }
365
368
  json = %{["one","two\\n2"]}
@@ -367,6 +370,7 @@ class Juice < Minitest::Test
367
370
  out = Oj.dump(x)
368
371
  assert_equal(json, out)
369
372
  end
373
+
370
374
  def test_does_not_escape_newline
371
375
  Oj.default_options = { :escape_mode => :newline }
372
376
  json = %{["one","two\n2"]}
@@ -374,6 +378,7 @@ class Juice < Minitest::Test
374
378
  out = Oj.dump(x)
375
379
  assert_equal(json, out)
376
380
  end
381
+
377
382
  def test_dump_invalid_utf8
378
383
  Oj.default_options = { :escape_mode => :ascii }
379
384
  assert_raises(EncodingError) {
@@ -395,14 +400,14 @@ class Juice < Minitest::Test
395
400
  end
396
401
 
397
402
  def test_time_neg
398
- t = Time.parse("1900-01-01 00:18:59 UTC")
403
+ t = Time.parse('1900-01-01 00:18:59 UTC')
399
404
  json = Oj.dump(t, :mode => :custom, :time_format => :unix)
400
405
  assert_equal('-2208987661.000000000', json)
401
406
  end
402
407
 
403
408
  def test_time_years
404
409
  (-2020..2020).each { |year|
405
- s = "%04d-03-01T15:14:13Z" % [year]
410
+ s = '%04d-03-01T15:14:13Z' % [year]
406
411
  json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
407
412
  assert_equal(s, json[1..-2])
408
413
 
@@ -431,7 +436,7 @@ class Juice < Minitest::Test
431
436
  assert(true)
432
437
  return
433
438
  end
434
- assert(false, "*** expected an exception")
439
+ assert(false, '*** expected an exception')
435
440
  end
436
441
 
437
442
  def test_hash_not_closed
@@ -441,7 +446,7 @@ class Juice < Minitest::Test
441
446
  assert(true)
442
447
  return
443
448
  end
444
- assert(false, "*** expected an exception")
449
+ assert(false, '*** expected an exception')
445
450
  end
446
451
 
447
452
  # Object with to_json()
@@ -451,7 +456,7 @@ class Juice < Minitest::Test
451
456
  assert_equal('null', json)
452
457
  end
453
458
 
454
- # Object with to_hash()
459
+ # Object with to_hash()
455
460
  def test_to_hash_object_null
456
461
  obj = Jazz.new(true, 58)
457
462
  json = Oj.dump(obj, :mode => :null)
@@ -499,7 +504,7 @@ class Juice < Minitest::Test
499
504
 
500
505
  def test_infinity
501
506
  n = Oj.load('Infinity', :mode => :object)
502
- assert_equal(BigDecimal('Infinity').to_f, n);
507
+ assert_equal(BigDecimal('Infinity').to_f, n)
503
508
  x = Oj.load('Infinity', :mode => :compat)
504
509
  assert_equal('Infinity', x.to_s)
505
510
  end
@@ -524,7 +529,7 @@ class Juice < Minitest::Test
524
529
  "y":58 }}
525
530
  obj = Oj.load(json, :mode => :object, :auto_define => true)
526
531
  assert_equal('Juice::Jem', obj.class.name)
527
- assert_equal(true, obj.x)
532
+ assert(obj.x)
528
533
  assert_equal(58, obj.y)
529
534
  end
530
535
 
@@ -532,19 +537,19 @@ class Juice < Minitest::Test
532
537
  def test_deep_nest_dump
533
538
  begin
534
539
  a = []
535
- 10000.times { a << [a] }
540
+ 10_000.times { a << [a] }
536
541
  Oj.dump(a)
537
542
  rescue Exception
538
543
  assert(true)
539
544
  return
540
545
  end
541
- assert(false, "*** expected an exception")
546
+ assert(false, '*** expected an exception')
542
547
  end
543
548
 
544
549
  # Stream IO
545
550
  def test_io_string
546
551
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
547
- output = StringIO.open("", "w+")
552
+ output = StringIO.open('', 'w+')
548
553
  Oj.to_stream(output, src)
549
554
 
550
555
  input = StringIO.new(output.string())
@@ -553,12 +558,9 @@ class Juice < Minitest::Test
553
558
  end
554
559
 
555
560
  def test_io_file
556
- # Windows does not support fork
557
- return if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
558
-
559
561
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
560
- filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
561
- File.open(filename, "w") { |f|
562
+ filename = File.join(__dir__, 'open_file_test.json')
563
+ File.open(filename, 'w') { |f|
562
564
  Oj.to_stream(f, src)
563
565
  }
564
566
  f = File.new(filename)
@@ -568,28 +570,30 @@ class Juice < Minitest::Test
568
570
  end
569
571
 
570
572
  def test_io_stream
573
+ skip 'needs fork' unless Process.respond_to?(:fork)
574
+
571
575
  IO.pipe do |r, w|
572
576
  if fork
573
- r.close
574
- #w.nonblock = false
575
- a = []
576
- 10_000.times do |i|
577
- a << i
578
- end
579
- Oj.to_stream(w, a, indent: 2)
580
- 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
581
585
  else
582
- w.close
583
- sleep(0.1) # to force a busy
584
- cnt = 0
585
- r.each_line { cnt += 1 }
586
- r.close
587
- 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)
588
592
  end
589
593
  end
590
594
  end
591
595
 
592
- # comments
596
+ # comments
593
597
  def test_comment_slash
594
598
  json = %{{
595
599
  "x":true,//three
@@ -633,7 +637,7 @@ class Juice < Minitest::Test
633
637
  assert(true)
634
638
  return
635
639
  end
636
- assert(false, "*** expected an exception")
640
+ assert(false, '*** expected an exception')
637
641
  end
638
642
 
639
643
  def test_nilnil_true
@@ -656,27 +660,27 @@ class Juice < Minitest::Test
656
660
  assert(Oj::ParseError == e.class || EncodingError == e.class)
657
661
  return
658
662
  end
659
- assert(false, "*** expected an exception")
663
+ assert(false, '*** expected an exception')
660
664
  end
661
665
 
662
666
  def test_quirks_null_mode
663
- assert_raises(Oj::ParseError) { Oj.load("null", :quirks_mode => false) }
664
- 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))
665
669
  end
666
670
 
667
671
  def test_quirks_bool_mode
668
- assert_raises(Oj::ParseError) { Oj.load("true", :quirks_mode => false) }
669
- 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))
670
674
  end
671
675
 
672
676
  def test_quirks_number_mode
673
- assert_raises(Oj::ParseError) { Oj.load("123", :quirks_mode => false) }
674
- 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))
675
679
  end
676
680
 
677
681
  def test_quirks_decimal_mode
678
- assert_raises(Oj::ParseError) { Oj.load("123.45", :quirks_mode => false) }
679
- 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))
680
684
  end
681
685
 
682
686
  def test_quirks_string_mode
@@ -688,35 +692,33 @@ class Juice < Minitest::Test
688
692
  msg = ''
689
693
  assert_raises(Oj::ParseError) {
690
694
  begin
691
- Oj.load(%|{
695
+ Oj.load(%|{
692
696
  "first": [
693
697
  1, 2, { "third": 123x }
694
698
  ]
695
699
  }|)
696
700
  rescue Oj::ParseError => e
697
- msg = e.message
698
- raise e
701
+ msg = e.message
702
+ raise e
699
703
  end
700
704
  }
701
705
  assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
702
706
  end
703
707
 
704
708
  def test_bad_bignum
705
- if '2.4.0' < RUBY_VERSION
706
- assert_raises Oj::ParseError do
707
- Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
708
- end
709
+ assert_raises Oj::ParseError do
710
+ Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
709
711
  end
710
712
  end
711
713
 
712
714
  def test_quirks_array_mode
713
- assert_equal([], Oj.load("[]", :quirks_mode => false))
714
- assert_equal([], Oj.load("[]", :quirks_mode => true))
715
+ assert_empty(Oj.load('[]', :quirks_mode => false))
716
+ assert_empty(Oj.load('[]', :quirks_mode => true))
715
717
  end
716
718
 
717
719
  def test_quirks_object_mode
718
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
719
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
720
+ assert_empty(Oj.load('{}', :quirks_mode => false))
721
+ assert_empty(Oj.load('{}', :quirks_mode => true))
720
722
  end
721
723
 
722
724
  def test_omit_nil
@@ -732,6 +734,52 @@ class Juice < Minitest::Test
732
734
  assert_equal(%|{"x":{"a":1}}|, json)
733
735
  end
734
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
+
735
783
  def dump_and_load(obj, trace=false)
736
784
  json = Oj.dump(obj, :indent => 2)
737
785
  puts json if trace