oj 3.11.5 → 3.16.5
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 +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
|