oj 3.11.5 → 3.16.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1421 -0
- data/README.md +19 -5
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +20 -6
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- 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 +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +27 -77
- data/ext/oj/custom.c +86 -179
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +256 -249
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +65 -187
- data/ext/oj/dump_strict.c +27 -51
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +24 -8
- data/ext/oj/extconf.rb +21 -6
- data/ext/oj/fast.c +149 -149
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +121 -106
- data/ext/oj/object.c +85 -162
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +542 -411
- data/ext/oj/oj.h +99 -73
- data/ext/oj/parse.c +175 -187
- data/ext/oj/parse.h +26 -24
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +101 -0
- data/ext/oj/rails.c +112 -159
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +5 -24
- data/ext/oj/rxclass.c +7 -6
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +22 -33
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +5 -28
- data/ext/oj/sparse.c +28 -72
- data/ext/oj/stream_writer.c +50 -40
- data/ext/oj/strict.c +56 -61
- data/ext/oj/string_writer.c +72 -39
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +63 -88
- 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 +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +9 -7
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- 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/JsonGem.md +15 -0
- data/pages/Modes.md +8 -3
- data/pages/Options.md +43 -5
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +14 -2
- 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/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
- 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 +16 -45
- 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 +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 +56 -38
- 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 +34 -0
- data/test/perf.rb +22 -27
- 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 +59 -0
- data/test/perf_parser.rb +183 -0
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +58 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +74 -82
- 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 +95 -43
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +135 -79
- 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 +5 -5
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +99 -96
- data/test/test_parser.rb +11 -0
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +337 -0
- data/test/test_parser_usual.rb +251 -0
- 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 +40 -32
- data/test/test_various.rb +165 -84
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -5
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +74 -128
- data/ext/oj/hash.c +0 -131
- data/ext/oj/hash.h +0 -19
- data/ext/oj/hash_test.c +0 -491
- 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 -35
- data/test/baz.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,
|
@@ -123,6 +114,8 @@ class Juice < Minitest::Test
|
|
123
114
|
compat_bigdecimal: true,
|
124
115
|
create_id: 'classy',
|
125
116
|
create_additions: true,
|
117
|
+
cache_keys: false,
|
118
|
+
cache_str: 5,
|
126
119
|
space: 'z',
|
127
120
|
array_nl: 'a',
|
128
121
|
object_nl: 'o',
|
@@ -137,17 +130,18 @@ class Juice < Minitest::Test
|
|
137
130
|
ignore_under: true,
|
138
131
|
trace: true,
|
139
132
|
safe: true,
|
133
|
+
omit_null_byte: false,
|
140
134
|
}
|
141
135
|
Oj.default_options = alt
|
142
|
-
#keys = alt.keys
|
143
|
-
#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}
|
144
138
|
opts = Oj.default_options()
|
145
|
-
assert_equal(alt, opts)
|
139
|
+
assert_equal(alt, opts)
|
146
140
|
|
147
141
|
Oj.default_options = orig # return to original
|
148
142
|
# verify back to original
|
149
143
|
opts = Oj.default_options()
|
150
|
-
assert_equal(orig, opts)
|
144
|
+
assert_equal(orig, opts)
|
151
145
|
end
|
152
146
|
|
153
147
|
def test_nil
|
@@ -164,8 +158,8 @@ class Juice < Minitest::Test
|
|
164
158
|
|
165
159
|
def test_fixnum
|
166
160
|
dump_and_load(0, false)
|
167
|
-
dump_and_load(
|
168
|
-
dump_and_load(-
|
161
|
+
dump_and_load(12_345, false)
|
162
|
+
dump_and_load(-54_321, false)
|
169
163
|
dump_and_load(1, false)
|
170
164
|
end
|
171
165
|
|
@@ -173,11 +167,11 @@ class Juice < Minitest::Test
|
|
173
167
|
Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
|
174
168
|
n = Oj.load('0.00001234567890123456')
|
175
169
|
assert_equal(Float, n.class)
|
176
|
-
assert_equal('1.234567890123456e-05',
|
170
|
+
assert_equal('1.234567890123456e-05', '%0.15e' % [n])
|
177
171
|
|
178
172
|
n = Oj.load('-0.00001234567890123456')
|
179
173
|
assert_equal(Float, n.class)
|
180
|
-
assert_equal('-1.234567890123456e-05',
|
174
|
+
assert_equal('-1.234567890123456e-05', '%0.15e' % [n])
|
181
175
|
|
182
176
|
n = Oj.load('1000.0000123456789')
|
183
177
|
assert_equal(BigDecimal, n.class)
|
@@ -225,12 +219,12 @@ class Juice < Minitest::Test
|
|
225
219
|
def test_encode
|
226
220
|
opts = Oj.default_options
|
227
221
|
Oj.default_options = { :ascii_only => false }
|
228
|
-
dump_and_load(
|
222
|
+
dump_and_load('ぴーたー', false)
|
229
223
|
|
230
224
|
Oj.default_options = { :ascii_only => true }
|
231
|
-
json = Oj.dump(
|
225
|
+
json = Oj.dump('ぴーたー')
|
232
226
|
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
233
|
-
dump_and_load(
|
227
|
+
dump_and_load('ぴーたー', false)
|
234
228
|
Oj.default_options = opts
|
235
229
|
end
|
236
230
|
|
@@ -251,7 +245,7 @@ class Juice < Minitest::Test
|
|
251
245
|
assert(true)
|
252
246
|
return
|
253
247
|
end
|
254
|
-
assert(false,
|
248
|
+
assert(false, '*** expected an exception')
|
255
249
|
end
|
256
250
|
|
257
251
|
def test_invalid_unicode_ok
|
@@ -265,11 +259,11 @@ class Juice < Minitest::Test
|
|
265
259
|
def test_dump_options
|
266
260
|
json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
|
267
261
|
:mode => :compat,
|
268
|
-
:indent =>
|
262
|
+
:indent => '--',
|
269
263
|
:array_nl => "\n",
|
270
264
|
:object_nl => "#\n",
|
271
|
-
:space =>
|
272
|
-
:space_before =>
|
265
|
+
:space => '*',
|
266
|
+
:space_before => '~')
|
273
267
|
assert(%{{#
|
274
268
|
--"a"~:*1,#
|
275
269
|
--"b"~:*[
|
@@ -284,7 +278,6 @@ class Juice < Minitest::Test
|
|
284
278
|
--],#
|
285
279
|
--"a"~:*1#
|
286
280
|
}} == json)
|
287
|
-
|
288
281
|
end
|
289
282
|
|
290
283
|
def test_null_char
|
@@ -299,6 +292,7 @@ class Juice < Minitest::Test
|
|
299
292
|
dump_and_load([[nil]], false)
|
300
293
|
dump_and_load([[nil], 58], false)
|
301
294
|
end
|
295
|
+
|
302
296
|
def test_array_not_closed
|
303
297
|
begin
|
304
298
|
Oj.load('[')
|
@@ -306,7 +300,7 @@ class Juice < Minitest::Test
|
|
306
300
|
assert(true)
|
307
301
|
return
|
308
302
|
end
|
309
|
-
assert(false,
|
303
|
+
assert(false, '*** expected an exception')
|
310
304
|
end
|
311
305
|
|
312
306
|
# multiple JSON in one string
|
@@ -317,7 +311,7 @@ class Juice < Minitest::Test
|
|
317
311
|
}
|
318
312
|
results = []
|
319
313
|
Oj.load(json, :mode => :strict) { |x, start, len| results << [x, start, len] }
|
320
|
-
assert_equal([[{
|
314
|
+
assert_equal([[{'a'=>1}, 0, 7], [[1, 2], 7, 6], [[3, 4], 13, 5], [{'b'=>2}, 18, 8]], results)
|
321
315
|
end
|
322
316
|
|
323
317
|
def test_multiple_json_no_callback
|
@@ -337,27 +331,39 @@ class Juice < Minitest::Test
|
|
337
331
|
out = Oj.dump(hash)
|
338
332
|
assert_equal(json, out)
|
339
333
|
end
|
334
|
+
|
340
335
|
def test_escapes_entities_by_default_when_configured_to_do_so
|
341
|
-
hash = {'key' =>
|
336
|
+
hash = {'key' => 'I <3 this'}
|
342
337
|
Oj.default_options = {:escape_mode => :xss_safe}
|
343
338
|
out = Oj.dump hash
|
344
339
|
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
345
340
|
end
|
341
|
+
|
342
|
+
def test_escapes_slashes_by_default_when_configured_to_do_so
|
343
|
+
hash = {'key' => 'I <3 this </script>'}
|
344
|
+
Oj.default_options = {:escape_mode => :slash}
|
345
|
+
out = Oj.dump hash
|
346
|
+
assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
|
347
|
+
end
|
348
|
+
|
346
349
|
def test_escapes_entities_when_asked_to
|
347
|
-
hash = {'key' =>
|
350
|
+
hash = {'key' => 'I <3 this'}
|
348
351
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
349
352
|
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
350
353
|
end
|
354
|
+
|
351
355
|
def test_does_not_escape_entities_when_not_asked_to
|
352
|
-
hash = {'key' =>
|
356
|
+
hash = {'key' => 'I <3 this'}
|
353
357
|
out = Oj.dump(hash, :escape_mode => :json)
|
354
358
|
assert_equal(%{{"key":"I <3 this"}}, out)
|
355
359
|
end
|
360
|
+
|
356
361
|
def test_escapes_common_xss_vectors
|
357
|
-
hash = {'key' =>
|
362
|
+
hash = {'key' => '<script>alert(123) && formatHD()</script>'}
|
358
363
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
359
364
|
assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
|
360
365
|
end
|
366
|
+
|
361
367
|
def test_escape_newline_by_default
|
362
368
|
Oj.default_options = { :escape_mode => :json }
|
363
369
|
json = %{["one","two\\n2"]}
|
@@ -365,6 +371,7 @@ class Juice < Minitest::Test
|
|
365
371
|
out = Oj.dump(x)
|
366
372
|
assert_equal(json, out)
|
367
373
|
end
|
374
|
+
|
368
375
|
def test_does_not_escape_newline
|
369
376
|
Oj.default_options = { :escape_mode => :newline }
|
370
377
|
json = %{["one","two\n2"]}
|
@@ -372,6 +379,7 @@ class Juice < Minitest::Test
|
|
372
379
|
out = Oj.dump(x)
|
373
380
|
assert_equal(json, out)
|
374
381
|
end
|
382
|
+
|
375
383
|
def test_dump_invalid_utf8
|
376
384
|
Oj.default_options = { :escape_mode => :ascii }
|
377
385
|
assert_raises(EncodingError) {
|
@@ -393,14 +401,14 @@ class Juice < Minitest::Test
|
|
393
401
|
end
|
394
402
|
|
395
403
|
def test_time_neg
|
396
|
-
t = Time.parse(
|
404
|
+
t = Time.parse('1900-01-01 00:18:59 UTC')
|
397
405
|
json = Oj.dump(t, :mode => :custom, :time_format => :unix)
|
398
406
|
assert_equal('-2208987661.000000000', json)
|
399
407
|
end
|
400
408
|
|
401
409
|
def test_time_years
|
402
410
|
(-2020..2020).each { |year|
|
403
|
-
s =
|
411
|
+
s = '%04d-03-01T15:14:13Z' % [year]
|
404
412
|
json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
|
405
413
|
assert_equal(s, json[1..-2])
|
406
414
|
|
@@ -409,6 +417,11 @@ class Juice < Minitest::Test
|
|
409
417
|
}
|
410
418
|
end
|
411
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
|
+
|
412
425
|
# Class
|
413
426
|
def test_class_null
|
414
427
|
json = Oj.dump(Juice, :mode => :null)
|
@@ -429,7 +442,7 @@ class Juice < Minitest::Test
|
|
429
442
|
assert(true)
|
430
443
|
return
|
431
444
|
end
|
432
|
-
assert(false,
|
445
|
+
assert(false, '*** expected an exception')
|
433
446
|
end
|
434
447
|
|
435
448
|
def test_hash_not_closed
|
@@ -439,7 +452,7 @@ class Juice < Minitest::Test
|
|
439
452
|
assert(true)
|
440
453
|
return
|
441
454
|
end
|
442
|
-
assert(false,
|
455
|
+
assert(false, '*** expected an exception')
|
443
456
|
end
|
444
457
|
|
445
458
|
# Object with to_json()
|
@@ -449,7 +462,7 @@ class Juice < Minitest::Test
|
|
449
462
|
assert_equal('null', json)
|
450
463
|
end
|
451
464
|
|
452
|
-
# Object with to_hash()
|
465
|
+
# Object with to_hash()
|
453
466
|
def test_to_hash_object_null
|
454
467
|
obj = Jazz.new(true, 58)
|
455
468
|
json = Oj.dump(obj, :mode => :null)
|
@@ -497,7 +510,7 @@ class Juice < Minitest::Test
|
|
497
510
|
|
498
511
|
def test_infinity
|
499
512
|
n = Oj.load('Infinity', :mode => :object)
|
500
|
-
assert_equal(BigDecimal('Infinity').to_f, n)
|
513
|
+
assert_equal(BigDecimal('Infinity').to_f, n)
|
501
514
|
x = Oj.load('Infinity', :mode => :compat)
|
502
515
|
assert_equal('Infinity', x.to_s)
|
503
516
|
end
|
@@ -522,27 +535,27 @@ class Juice < Minitest::Test
|
|
522
535
|
"y":58 }}
|
523
536
|
obj = Oj.load(json, :mode => :object, :auto_define => true)
|
524
537
|
assert_equal('Juice::Jem', obj.class.name)
|
525
|
-
|
538
|
+
assert(obj.x)
|
526
539
|
assert_equal(58, obj.y)
|
527
540
|
end
|
528
541
|
|
529
|
-
# Stream Deeply Nested
|
542
|
+
# Stream Deeply Nested
|
530
543
|
def test_deep_nest_dump
|
531
544
|
begin
|
532
545
|
a = []
|
533
|
-
|
546
|
+
10_000.times { a << [a] }
|
534
547
|
Oj.dump(a)
|
535
548
|
rescue Exception
|
536
549
|
assert(true)
|
537
550
|
return
|
538
551
|
end
|
539
|
-
assert(false,
|
552
|
+
assert(false, '*** expected an exception')
|
540
553
|
end
|
541
554
|
|
542
|
-
# Stream IO
|
555
|
+
# Stream IO
|
543
556
|
def test_io_string
|
544
557
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
545
|
-
output = StringIO.open(
|
558
|
+
output = StringIO.open('', 'w+')
|
546
559
|
Oj.to_stream(output, src)
|
547
560
|
|
548
561
|
input = StringIO.new(output.string())
|
@@ -552,8 +565,8 @@ class Juice < Minitest::Test
|
|
552
565
|
|
553
566
|
def test_io_file
|
554
567
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
555
|
-
filename = File.join(
|
556
|
-
File.open(filename,
|
568
|
+
filename = File.join(__dir__, 'open_file_test.json')
|
569
|
+
File.open(filename, 'w') { |f|
|
557
570
|
Oj.to_stream(f, src)
|
558
571
|
}
|
559
572
|
f = File.new(filename)
|
@@ -562,7 +575,31 @@ class Juice < Minitest::Test
|
|
562
575
|
assert_equal(src, obj)
|
563
576
|
end
|
564
577
|
|
565
|
-
|
578
|
+
def test_io_stream
|
579
|
+
skip 'needs fork' unless Process.respond_to?(:fork)
|
580
|
+
|
581
|
+
IO.pipe do |r, w|
|
582
|
+
if fork
|
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
|
591
|
+
else
|
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)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
# comments
|
566
603
|
def test_comment_slash
|
567
604
|
json = %{{
|
568
605
|
"x":true,//three
|
@@ -606,7 +643,7 @@ class Juice < Minitest::Test
|
|
606
643
|
assert(true)
|
607
644
|
return
|
608
645
|
end
|
609
|
-
assert(false,
|
646
|
+
assert(false, '*** expected an exception')
|
610
647
|
end
|
611
648
|
|
612
649
|
def test_nilnil_true
|
@@ -629,27 +666,27 @@ class Juice < Minitest::Test
|
|
629
666
|
assert(Oj::ParseError == e.class || EncodingError == e.class)
|
630
667
|
return
|
631
668
|
end
|
632
|
-
assert(false,
|
669
|
+
assert(false, '*** expected an exception')
|
633
670
|
end
|
634
671
|
|
635
672
|
def test_quirks_null_mode
|
636
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
637
|
-
assert_nil(Oj.load(
|
673
|
+
assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
|
674
|
+
assert_nil(Oj.load('null', :quirks_mode => true))
|
638
675
|
end
|
639
676
|
|
640
677
|
def test_quirks_bool_mode
|
641
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
642
|
-
|
678
|
+
assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
|
679
|
+
assert(Oj.load('true', :quirks_mode => true))
|
643
680
|
end
|
644
681
|
|
645
682
|
def test_quirks_number_mode
|
646
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
647
|
-
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))
|
648
685
|
end
|
649
686
|
|
650
687
|
def test_quirks_decimal_mode
|
651
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
652
|
-
|
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))
|
653
690
|
end
|
654
691
|
|
655
692
|
def test_quirks_string_mode
|
@@ -661,35 +698,33 @@ class Juice < Minitest::Test
|
|
661
698
|
msg = ''
|
662
699
|
assert_raises(Oj::ParseError) {
|
663
700
|
begin
|
664
|
-
|
701
|
+
Oj.load(%|{
|
665
702
|
"first": [
|
666
703
|
1, 2, { "third": 123x }
|
667
704
|
]
|
668
705
|
}|)
|
669
706
|
rescue Oj::ParseError => e
|
670
|
-
|
671
|
-
|
707
|
+
msg = e.message
|
708
|
+
raise e
|
672
709
|
end
|
673
710
|
}
|
674
711
|
assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
|
675
712
|
end
|
676
713
|
|
677
714
|
def test_bad_bignum
|
678
|
-
|
679
|
-
|
680
|
-
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
681
|
-
end
|
715
|
+
assert_raises Oj::ParseError do
|
716
|
+
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
682
717
|
end
|
683
718
|
end
|
684
719
|
|
685
720
|
def test_quirks_array_mode
|
686
|
-
|
687
|
-
|
721
|
+
assert_empty(Oj.load('[]', :quirks_mode => false))
|
722
|
+
assert_empty(Oj.load('[]', :quirks_mode => true))
|
688
723
|
end
|
689
724
|
|
690
725
|
def test_quirks_object_mode
|
691
|
-
|
692
|
-
|
726
|
+
assert_empty(Oj.load('{}', :quirks_mode => false))
|
727
|
+
assert_empty(Oj.load('{}', :quirks_mode => true))
|
693
728
|
end
|
694
729
|
|
695
730
|
def test_omit_nil
|
@@ -705,6 +740,52 @@ class Juice < Minitest::Test
|
|
705
740
|
assert_equal(%|{"x":{"a":1}}|, json)
|
706
741
|
end
|
707
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
|
+
|
708
789
|
def dump_and_load(obj, trace=false)
|
709
790
|
json = Oj.dump(obj, :indent => 2)
|
710
791
|
puts json if trace
|