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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +74 -0
- data/README.md +4 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +17 -24
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +17 -44
- data/ext/oj/custom.c +70 -141
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +128 -118
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +564 -641
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +70 -199
- data/ext/oj/dump_strict.c +22 -46
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +14 -5
- data/ext/oj/fast.c +75 -103
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +75 -47
- data/ext/oj/object.c +49 -66
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +140 -99
- data/ext/oj/oj.h +80 -51
- data/ext/oj/parse.c +162 -184
- data/ext/oj/parse.h +7 -10
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +18 -7
- data/ext/oj/rails.c +82 -146
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -12
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +20 -31
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -21
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +31 -68
- data/lib/oj/active_support_helper.rb +0 -1
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +10 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +9 -71
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +4 -4
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +48 -36
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +76 -42
- data/test/test_custom.rb +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +30 -32
- data/test/test_various.rb +147 -99
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -4
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +33 -144
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/bar.rb +0 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/test/test_various.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# frozen_string_literal: false
|
3
3
|
|
4
|
-
|
4
|
+
$LOAD_PATH << __dir__
|
5
5
|
|
6
6
|
require 'helper'
|
7
7
|
|
8
8
|
class Juice < Minitest::Test
|
9
|
-
def gen_whitespaced_string(length
|
10
|
-
whitespace_chars = [
|
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
|
-
|
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
|
-
|
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(
|
61
|
+
def as_json(_options)
|
71
62
|
"#{x} #{y}"
|
72
63
|
end
|
73
64
|
|
74
65
|
def self.json_create(h)
|
75
|
-
|
66
|
+
new(h['x'], h['y'])
|
76
67
|
end
|
77
68
|
end
|
78
69
|
|
79
70
|
class Jazz < Jam
|
80
|
-
|
81
|
-
|
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
|
-
|
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(
|
170
|
-
dump_and_load(-
|
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',
|
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',
|
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(
|
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(
|
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,
|
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,
|
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([[{
|
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' =>
|
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' =>
|
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' =>
|
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' =>
|
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(
|
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 =
|
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,
|
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,
|
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
|
-
|
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
|
-
|
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,
|
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(
|
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(
|
561
|
-
File.open(filename,
|
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
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
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
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
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,
|
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,
|
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(
|
664
|
-
assert_nil(Oj.load(
|
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(
|
669
|
-
|
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(
|
674
|
-
assert_equal(123, Oj.load(
|
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(
|
679
|
-
|
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
|
-
|
695
|
+
Oj.load(%|{
|
692
696
|
"first": [
|
693
697
|
1, 2, { "third": 123x }
|
694
698
|
]
|
695
699
|
}|)
|
696
700
|
rescue Oj::ParseError => e
|
697
|
-
|
698
|
-
|
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
|
-
|
706
|
-
|
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
|
-
|
714
|
-
|
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
|
-
|
719
|
-
|
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
|