oj 3.13.17 → 3.16.3

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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +4 -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 +44 -96
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +69 -39
  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 -6
  25. data/ext/oj/fast.c +76 -106
  26. data/ext/oj/intern.c +63 -51
  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 +43 -30
  31. data/ext/oj/object.c +61 -70
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +243 -205
  35. data/ext/oj/oj.h +82 -78
  36. data/ext/oj/parse.c +123 -188
  37. data/ext/oj/parse.h +23 -24
  38. data/ext/oj/parser.c +103 -63
  39. data/ext/oj/parser.h +19 -9
  40. data/ext/oj/rails.c +68 -92
  41. data/ext/oj/reader.c +10 -15
  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 +74 -92
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +43 -35
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +60 -34
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -150
  56. data/ext/oj/usual.h +69 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +14 -3
  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 +6 -2
  67. data/lib/oj/state.rb +9 -6
  68. data/lib/oj/version.rb +1 -2
  69. data/lib/oj.rb +2 -0
  70. data/pages/Compatibility.md +1 -1
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +10 -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/files.rb +15 -15
  78. data/test/foo.rb +9 -72
  79. data/test/helper.rb +11 -8
  80. data/test/isolated/shared.rb +3 -2
  81. data/test/json_gem/json_addition_test.rb +2 -2
  82. data/test/json_gem/json_common_interface_test.rb +8 -6
  83. data/test/json_gem/json_encoding_test.rb +0 -0
  84. data/test/json_gem/json_ext_parser_test.rb +1 -0
  85. data/test/json_gem/json_fixtures_test.rb +3 -2
  86. data/test/json_gem/json_generator_test.rb +53 -37
  87. data/test/json_gem/json_generic_object_test.rb +11 -11
  88. data/test/json_gem/json_parser_test.rb +47 -47
  89. data/test/json_gem/json_string_matching_test.rb +9 -9
  90. data/test/json_gem/test_helper.rb +7 -3
  91. data/test/mem.rb +13 -12
  92. data/test/perf.rb +21 -26
  93. data/test/perf_compat.rb +31 -33
  94. data/test/perf_dump.rb +28 -28
  95. data/test/perf_fast.rb +80 -82
  96. data/test/perf_file.rb +27 -29
  97. data/test/perf_object.rb +65 -69
  98. data/test/perf_once.rb +12 -11
  99. data/test/perf_parser.rb +42 -48
  100. data/test/perf_saj.rb +46 -54
  101. data/test/perf_scp.rb +57 -69
  102. data/test/perf_simple.rb +41 -39
  103. data/test/perf_strict.rb +68 -70
  104. data/test/perf_wab.rb +67 -69
  105. data/test/prec.rb +5 -5
  106. data/test/sample/change.rb +0 -1
  107. data/test/sample/dir.rb +0 -1
  108. data/test/sample/doc.rb +0 -1
  109. data/test/sample/file.rb +0 -1
  110. data/test/sample/group.rb +0 -1
  111. data/test/sample/hasprops.rb +0 -1
  112. data/test/sample/layer.rb +0 -1
  113. data/test/sample/rect.rb +0 -1
  114. data/test/sample/shape.rb +0 -1
  115. data/test/sample/text.rb +0 -1
  116. data/test/sample.rb +16 -16
  117. data/test/sample_json.rb +8 -8
  118. data/test/test_compat.rb +80 -53
  119. data/test/test_custom.rb +73 -51
  120. data/test/test_debian.rb +7 -10
  121. data/test/test_fast.rb +86 -90
  122. data/test/test_file.rb +28 -35
  123. data/test/test_gc.rb +16 -5
  124. data/test/test_generate.rb +5 -5
  125. data/test/test_hash.rb +4 -4
  126. data/test/test_integer_range.rb +9 -9
  127. data/test/test_null.rb +20 -20
  128. data/test/test_object.rb +94 -96
  129. data/test/test_parser.rb +6 -22
  130. data/test/test_parser_debug.rb +27 -0
  131. data/test/test_parser_saj.rb +61 -22
  132. data/test/test_parser_usual.rb +16 -6
  133. data/test/test_rails.rb +2 -2
  134. data/test/test_saj.rb +10 -8
  135. data/test/test_scp.rb +37 -39
  136. data/test/test_strict.rb +40 -32
  137. data/test/test_various.rb +148 -100
  138. data/test/test_wab.rb +48 -44
  139. data/test/test_writer.rb +47 -47
  140. data/test/tests.rb +13 -4
  141. data/test/tests_mimic.rb +12 -3
  142. data/test/tests_mimic_addition.rb +12 -3
  143. metadata +36 -27
  144. data/test/activesupport4/decoding_test.rb +0 -108
  145. data/test/activesupport4/encoding_test.rb +0 -531
  146. data/test/activesupport4/test_helper.rb +0 -41
  147. data/test/activesupport5/abstract_unit.rb +0 -45
  148. data/test/activesupport5/decoding_test.rb +0 -133
  149. data/test/activesupport5/encoding_test.rb +0 -500
  150. data/test/activesupport5/encoding_test_cases.rb +0 -98
  151. data/test/activesupport5/test_helper.rb +0 -72
  152. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  153. data/test/bar.rb +0 -11
  154. data/test/baz.rb +0 -16
  155. data/test/bug.rb +0 -16
  156. 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())
@@ -559,12 +564,9 @@ class Juice < Minitest::Test
559
564
  end
560
565
 
561
566
  def test_io_file
562
- # Windows does not support fork
563
- return if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
564
-
565
567
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
566
- filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
567
- File.open(filename, "w") { |f|
568
+ filename = File.join(__dir__, 'open_file_test.json')
569
+ File.open(filename, 'w') { |f|
568
570
  Oj.to_stream(f, src)
569
571
  }
570
572
  f = File.new(filename)
@@ -574,28 +576,30 @@ class Juice < Minitest::Test
574
576
  end
575
577
 
576
578
  def test_io_stream
579
+ skip 'needs fork' unless Process.respond_to?(:fork)
580
+
577
581
  IO.pipe do |r, w|
578
582
  if fork
579
- r.close
580
- #w.nonblock = false
581
- a = []
582
- 10_000.times do |i|
583
- a << i
584
- end
585
- Oj.to_stream(w, a, indent: 2)
586
- 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
587
591
  else
588
- w.close
589
- sleep(0.1) # to force a busy
590
- cnt = 0
591
- r.each_line { cnt += 1 }
592
- r.close
593
- 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)
594
598
  end
595
599
  end
596
600
  end
597
601
 
598
- # comments
602
+ # comments
599
603
  def test_comment_slash
600
604
  json = %{{
601
605
  "x":true,//three
@@ -639,7 +643,7 @@ class Juice < Minitest::Test
639
643
  assert(true)
640
644
  return
641
645
  end
642
- assert(false, "*** expected an exception")
646
+ assert(false, '*** expected an exception')
643
647
  end
644
648
 
645
649
  def test_nilnil_true
@@ -662,27 +666,27 @@ class Juice < Minitest::Test
662
666
  assert(Oj::ParseError == e.class || EncodingError == e.class)
663
667
  return
664
668
  end
665
- assert(false, "*** expected an exception")
669
+ assert(false, '*** expected an exception')
666
670
  end
667
671
 
668
672
  def test_quirks_null_mode
669
- assert_raises(Oj::ParseError) { Oj.load("null", :quirks_mode => false) }
670
- 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))
671
675
  end
672
676
 
673
677
  def test_quirks_bool_mode
674
- assert_raises(Oj::ParseError) { Oj.load("true", :quirks_mode => false) }
675
- 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))
676
680
  end
677
681
 
678
682
  def test_quirks_number_mode
679
- assert_raises(Oj::ParseError) { Oj.load("123", :quirks_mode => false) }
680
- 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))
681
685
  end
682
686
 
683
687
  def test_quirks_decimal_mode
684
- assert_raises(Oj::ParseError) { Oj.load("123.45", :quirks_mode => false) }
685
- 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))
686
690
  end
687
691
 
688
692
  def test_quirks_string_mode
@@ -694,35 +698,33 @@ class Juice < Minitest::Test
694
698
  msg = ''
695
699
  assert_raises(Oj::ParseError) {
696
700
  begin
697
- Oj.load(%|{
701
+ Oj.load(%|{
698
702
  "first": [
699
703
  1, 2, { "third": 123x }
700
704
  ]
701
705
  }|)
702
706
  rescue Oj::ParseError => e
703
- msg = e.message
704
- raise e
707
+ msg = e.message
708
+ raise e
705
709
  end
706
710
  }
707
711
  assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
708
712
  end
709
713
 
710
714
  def test_bad_bignum
711
- if '2.4.0' < RUBY_VERSION
712
- assert_raises Oj::ParseError do
713
- Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
714
- end
715
+ assert_raises Oj::ParseError do
716
+ Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
715
717
  end
716
718
  end
717
719
 
718
720
  def test_quirks_array_mode
719
- assert_equal([], Oj.load("[]", :quirks_mode => false))
720
- assert_equal([], Oj.load("[]", :quirks_mode => true))
721
+ assert_empty(Oj.load('[]', :quirks_mode => false))
722
+ assert_empty(Oj.load('[]', :quirks_mode => true))
721
723
  end
722
724
 
723
725
  def test_quirks_object_mode
724
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
725
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
726
+ assert_empty(Oj.load('{}', :quirks_mode => false))
727
+ assert_empty(Oj.load('{}', :quirks_mode => true))
726
728
  end
727
729
 
728
730
  def test_omit_nil
@@ -738,6 +740,52 @@ class Juice < Minitest::Test
738
740
  assert_equal(%|{"x":{"a":1}}|, json)
739
741
  end
740
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
+
741
789
  def dump_and_load(obj, trace=false)
742
790
  json = Oj.dump(obj, :indent => 2)
743
791
  puts json if trace