oj 3.13.23 → 3.16.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +81 -0
- data/README.md +2 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +26 -59
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +103 -53
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- 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 +16 -7
- data/ext/oj/fast.c +60 -92
- data/ext/oj/intern.c +62 -47
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +51 -32
- data/ext/oj/object.c +33 -43
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +243 -212
- data/ext/oj/oj.h +83 -81
- data/ext/oj/parse.c +94 -148
- data/ext/oj/parse.h +21 -24
- data/ext/oj/parser.c +80 -67
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +70 -92
- data/ext/oj/reader.c +9 -14
- 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 +10 -9
- data/ext/oj/saj2.c +37 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +45 -41
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +64 -38
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -114
- data/ext/oj/usual.h +7 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +13 -2
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- 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 +162 -150
- data/lib/oj/mimic.rb +7 -7
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +4 -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/activesupport6/encoding_test.rb +63 -28
- data/test/activesupport7/abstract_unit.rb +4 -1
- data/test/activesupport7/encoding_test.rb +72 -22
- data/test/files.rb +15 -15
- data/test/foo.rb +18 -69
- data/test/helper.rb +5 -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 +8 -6
- 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 +50 -33
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +46 -46
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +28 -28
- 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 +5 -5
- 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 +81 -54
- data/test/test_custom.rb +63 -52
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +24 -29
- data/test/test_gc.rb +5 -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 +92 -87
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +5 -5
- data/test/test_parser_saj.rb +27 -25
- data/test/test_parser_usual.rb +44 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +35 -35
- data/test/test_strict.rb +38 -32
- data/test/test_various.rb +146 -97
- data/test/test_wab.rb +46 -44
- data/test/test_writer.rb +63 -47
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +46 -26
- 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/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/bar.rb +0 -11
- 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,
|
@@ -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(
|
170
|
-
dump_and_load(-
|
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',
|
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',
|
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(
|
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(
|
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,
|
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,
|
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([[{
|
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' =>
|
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' =>
|
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' =>
|
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' =>
|
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' =>
|
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(
|
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 =
|
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,
|
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,
|
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
|
-
|
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
|
-
|
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,
|
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(
|
558
|
+
output = StringIO.open('', 'w+')
|
554
559
|
Oj.to_stream(output, src)
|
555
560
|
|
556
561
|
input = StringIO.new(output.string())
|
@@ -560,8 +565,8 @@ class Juice < Minitest::Test
|
|
560
565
|
|
561
566
|
def test_io_file
|
562
567
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
563
|
-
filename = File.join(
|
564
|
-
File.open(filename,
|
568
|
+
filename = File.join(__dir__, 'open_file_test.json')
|
569
|
+
File.open(filename, 'w') { |f|
|
565
570
|
Oj.to_stream(f, src)
|
566
571
|
}
|
567
572
|
f = File.new(filename)
|
@@ -575,26 +580,26 @@ class Juice < Minitest::Test
|
|
575
580
|
|
576
581
|
IO.pipe do |r, w|
|
577
582
|
if fork
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
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
|
586
591
|
else
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
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)
|
593
598
|
end
|
594
599
|
end
|
595
600
|
end
|
596
601
|
|
597
|
-
# comments
|
602
|
+
# comments
|
598
603
|
def test_comment_slash
|
599
604
|
json = %{{
|
600
605
|
"x":true,//three
|
@@ -638,7 +643,7 @@ class Juice < Minitest::Test
|
|
638
643
|
assert(true)
|
639
644
|
return
|
640
645
|
end
|
641
|
-
assert(false,
|
646
|
+
assert(false, '*** expected an exception')
|
642
647
|
end
|
643
648
|
|
644
649
|
def test_nilnil_true
|
@@ -661,27 +666,27 @@ class Juice < Minitest::Test
|
|
661
666
|
assert(Oj::ParseError == e.class || EncodingError == e.class)
|
662
667
|
return
|
663
668
|
end
|
664
|
-
assert(false,
|
669
|
+
assert(false, '*** expected an exception')
|
665
670
|
end
|
666
671
|
|
667
672
|
def test_quirks_null_mode
|
668
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
669
|
-
assert_nil(Oj.load(
|
673
|
+
assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
|
674
|
+
assert_nil(Oj.load('null', :quirks_mode => true))
|
670
675
|
end
|
671
676
|
|
672
677
|
def test_quirks_bool_mode
|
673
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
674
|
-
|
678
|
+
assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
|
679
|
+
assert(Oj.load('true', :quirks_mode => true))
|
675
680
|
end
|
676
681
|
|
677
682
|
def test_quirks_number_mode
|
678
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
679
|
-
assert_equal(123, Oj.load(
|
683
|
+
assert_raises(Oj::ParseError) { Oj.load('123', :quirks_mode => false) }
|
684
|
+
assert_equal(123, Oj.load('123', :quirks_mode => true))
|
680
685
|
end
|
681
686
|
|
682
687
|
def test_quirks_decimal_mode
|
683
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
684
|
-
|
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))
|
685
690
|
end
|
686
691
|
|
687
692
|
def test_quirks_string_mode
|
@@ -693,35 +698,33 @@ class Juice < Minitest::Test
|
|
693
698
|
msg = ''
|
694
699
|
assert_raises(Oj::ParseError) {
|
695
700
|
begin
|
696
|
-
|
701
|
+
Oj.load(%|{
|
697
702
|
"first": [
|
698
703
|
1, 2, { "third": 123x }
|
699
704
|
]
|
700
705
|
}|)
|
701
706
|
rescue Oj::ParseError => e
|
702
|
-
|
703
|
-
|
707
|
+
msg = e.message
|
708
|
+
raise e
|
704
709
|
end
|
705
710
|
}
|
706
711
|
assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
|
707
712
|
end
|
708
713
|
|
709
714
|
def test_bad_bignum
|
710
|
-
|
711
|
-
|
712
|
-
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
713
|
-
end
|
715
|
+
assert_raises Oj::ParseError do
|
716
|
+
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
714
717
|
end
|
715
718
|
end
|
716
719
|
|
717
720
|
def test_quirks_array_mode
|
718
|
-
|
719
|
-
|
721
|
+
assert_empty(Oj.load('[]', :quirks_mode => false))
|
722
|
+
assert_empty(Oj.load('[]', :quirks_mode => true))
|
720
723
|
end
|
721
724
|
|
722
725
|
def test_quirks_object_mode
|
723
|
-
|
724
|
-
|
726
|
+
assert_empty(Oj.load('{}', :quirks_mode => false))
|
727
|
+
assert_empty(Oj.load('{}', :quirks_mode => true))
|
725
728
|
end
|
726
729
|
|
727
730
|
def test_omit_nil
|
@@ -737,6 +740,52 @@ class Juice < Minitest::Test
|
|
737
740
|
assert_equal(%|{"x":{"a":1}}|, json)
|
738
741
|
end
|
739
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
|
+
|
740
789
|
def dump_and_load(obj, trace=false)
|
741
790
|
json = Oj.dump(obj, :indent => 2)
|
742
791
|
puts json if trace
|