oj 3.13.9 → 3.16.1
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 +101 -0
- data/README.md +13 -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 +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +76 -155
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +203 -213
- 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 +59 -181
- data/ext/oj/dump_strict.c +24 -48
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +18 -7
- data/ext/oj/fast.c +83 -108
- 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 +104 -81
- data/ext/oj/object.c +50 -67
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +171 -106
- data/ext/oj/oj.h +96 -74
- data/ext/oj/parse.c +169 -189
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +20 -9
- data/ext/oj/rails.c +86 -151
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +12 -15
- 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 +21 -32
- 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 -22
- 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 +32 -69
- 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 +6 -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/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +10 -0
- data/pages/Rails.md +12 -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 +15 -15
- 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 +49 -37
- 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 +95 -43
- data/test/test_custom.rb +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +102 -87
- 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 +40 -32
- data/test/test_various.rb +163 -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 +34 -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,
|
@@ -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,27 +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
|
+
|
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
|
+
|
348
349
|
def test_escapes_entities_when_asked_to
|
349
|
-
hash = {'key' =>
|
350
|
+
hash = {'key' => 'I <3 this'}
|
350
351
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
351
352
|
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
352
353
|
end
|
354
|
+
|
353
355
|
def test_does_not_escape_entities_when_not_asked_to
|
354
|
-
hash = {'key' =>
|
356
|
+
hash = {'key' => 'I <3 this'}
|
355
357
|
out = Oj.dump(hash, :escape_mode => :json)
|
356
358
|
assert_equal(%{{"key":"I <3 this"}}, out)
|
357
359
|
end
|
360
|
+
|
358
361
|
def test_escapes_common_xss_vectors
|
359
|
-
hash = {'key' =>
|
362
|
+
hash = {'key' => '<script>alert(123) && formatHD()</script>'}
|
360
363
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
361
364
|
assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
|
362
365
|
end
|
366
|
+
|
363
367
|
def test_escape_newline_by_default
|
364
368
|
Oj.default_options = { :escape_mode => :json }
|
365
369
|
json = %{["one","two\\n2"]}
|
@@ -367,6 +371,7 @@ class Juice < Minitest::Test
|
|
367
371
|
out = Oj.dump(x)
|
368
372
|
assert_equal(json, out)
|
369
373
|
end
|
374
|
+
|
370
375
|
def test_does_not_escape_newline
|
371
376
|
Oj.default_options = { :escape_mode => :newline }
|
372
377
|
json = %{["one","two\n2"]}
|
@@ -374,6 +379,7 @@ class Juice < Minitest::Test
|
|
374
379
|
out = Oj.dump(x)
|
375
380
|
assert_equal(json, out)
|
376
381
|
end
|
382
|
+
|
377
383
|
def test_dump_invalid_utf8
|
378
384
|
Oj.default_options = { :escape_mode => :ascii }
|
379
385
|
assert_raises(EncodingError) {
|
@@ -395,14 +401,14 @@ class Juice < Minitest::Test
|
|
395
401
|
end
|
396
402
|
|
397
403
|
def test_time_neg
|
398
|
-
t = Time.parse(
|
404
|
+
t = Time.parse('1900-01-01 00:18:59 UTC')
|
399
405
|
json = Oj.dump(t, :mode => :custom, :time_format => :unix)
|
400
406
|
assert_equal('-2208987661.000000000', json)
|
401
407
|
end
|
402
408
|
|
403
409
|
def test_time_years
|
404
410
|
(-2020..2020).each { |year|
|
405
|
-
s =
|
411
|
+
s = '%04d-03-01T15:14:13Z' % [year]
|
406
412
|
json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
|
407
413
|
assert_equal(s, json[1..-2])
|
408
414
|
|
@@ -411,6 +417,11 @@ class Juice < Minitest::Test
|
|
411
417
|
}
|
412
418
|
end
|
413
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
|
+
|
414
425
|
# Class
|
415
426
|
def test_class_null
|
416
427
|
json = Oj.dump(Juice, :mode => :null)
|
@@ -431,7 +442,7 @@ class Juice < Minitest::Test
|
|
431
442
|
assert(true)
|
432
443
|
return
|
433
444
|
end
|
434
|
-
assert(false,
|
445
|
+
assert(false, '*** expected an exception')
|
435
446
|
end
|
436
447
|
|
437
448
|
def test_hash_not_closed
|
@@ -441,7 +452,7 @@ class Juice < Minitest::Test
|
|
441
452
|
assert(true)
|
442
453
|
return
|
443
454
|
end
|
444
|
-
assert(false,
|
455
|
+
assert(false, '*** expected an exception')
|
445
456
|
end
|
446
457
|
|
447
458
|
# Object with to_json()
|
@@ -451,7 +462,7 @@ class Juice < Minitest::Test
|
|
451
462
|
assert_equal('null', json)
|
452
463
|
end
|
453
464
|
|
454
|
-
# Object with to_hash()
|
465
|
+
# Object with to_hash()
|
455
466
|
def test_to_hash_object_null
|
456
467
|
obj = Jazz.new(true, 58)
|
457
468
|
json = Oj.dump(obj, :mode => :null)
|
@@ -499,7 +510,7 @@ class Juice < Minitest::Test
|
|
499
510
|
|
500
511
|
def test_infinity
|
501
512
|
n = Oj.load('Infinity', :mode => :object)
|
502
|
-
assert_equal(BigDecimal('Infinity').to_f, n)
|
513
|
+
assert_equal(BigDecimal('Infinity').to_f, n)
|
503
514
|
x = Oj.load('Infinity', :mode => :compat)
|
504
515
|
assert_equal('Infinity', x.to_s)
|
505
516
|
end
|
@@ -524,27 +535,27 @@ class Juice < Minitest::Test
|
|
524
535
|
"y":58 }}
|
525
536
|
obj = Oj.load(json, :mode => :object, :auto_define => true)
|
526
537
|
assert_equal('Juice::Jem', obj.class.name)
|
527
|
-
|
538
|
+
assert(obj.x)
|
528
539
|
assert_equal(58, obj.y)
|
529
540
|
end
|
530
541
|
|
531
|
-
# Stream Deeply Nested
|
542
|
+
# Stream Deeply Nested
|
532
543
|
def test_deep_nest_dump
|
533
544
|
begin
|
534
545
|
a = []
|
535
|
-
|
546
|
+
10_000.times { a << [a] }
|
536
547
|
Oj.dump(a)
|
537
548
|
rescue Exception
|
538
549
|
assert(true)
|
539
550
|
return
|
540
551
|
end
|
541
|
-
assert(false,
|
552
|
+
assert(false, '*** expected an exception')
|
542
553
|
end
|
543
554
|
|
544
|
-
# Stream IO
|
555
|
+
# Stream IO
|
545
556
|
def test_io_string
|
546
557
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
547
|
-
output = StringIO.open(
|
558
|
+
output = StringIO.open('', 'w+')
|
548
559
|
Oj.to_stream(output, src)
|
549
560
|
|
550
561
|
input = StringIO.new(output.string())
|
@@ -554,8 +565,8 @@ class Juice < Minitest::Test
|
|
554
565
|
|
555
566
|
def test_io_file
|
556
567
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
557
|
-
filename = File.join(
|
558
|
-
File.open(filename,
|
568
|
+
filename = File.join(__dir__, 'open_file_test.json')
|
569
|
+
File.open(filename, 'w') { |f|
|
559
570
|
Oj.to_stream(f, src)
|
560
571
|
}
|
561
572
|
f = File.new(filename)
|
@@ -564,7 +575,31 @@ class Juice < Minitest::Test
|
|
564
575
|
assert_equal(src, obj)
|
565
576
|
end
|
566
577
|
|
567
|
-
|
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
|
568
603
|
def test_comment_slash
|
569
604
|
json = %{{
|
570
605
|
"x":true,//three
|
@@ -608,7 +643,7 @@ class Juice < Minitest::Test
|
|
608
643
|
assert(true)
|
609
644
|
return
|
610
645
|
end
|
611
|
-
assert(false,
|
646
|
+
assert(false, '*** expected an exception')
|
612
647
|
end
|
613
648
|
|
614
649
|
def test_nilnil_true
|
@@ -631,27 +666,27 @@ class Juice < Minitest::Test
|
|
631
666
|
assert(Oj::ParseError == e.class || EncodingError == e.class)
|
632
667
|
return
|
633
668
|
end
|
634
|
-
assert(false,
|
669
|
+
assert(false, '*** expected an exception')
|
635
670
|
end
|
636
671
|
|
637
672
|
def test_quirks_null_mode
|
638
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
639
|
-
assert_nil(Oj.load(
|
673
|
+
assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
|
674
|
+
assert_nil(Oj.load('null', :quirks_mode => true))
|
640
675
|
end
|
641
676
|
|
642
677
|
def test_quirks_bool_mode
|
643
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
644
|
-
|
678
|
+
assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
|
679
|
+
assert(Oj.load('true', :quirks_mode => true))
|
645
680
|
end
|
646
681
|
|
647
682
|
def test_quirks_number_mode
|
648
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
649
|
-
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))
|
650
685
|
end
|
651
686
|
|
652
687
|
def test_quirks_decimal_mode
|
653
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
654
|
-
|
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))
|
655
690
|
end
|
656
691
|
|
657
692
|
def test_quirks_string_mode
|
@@ -663,35 +698,33 @@ class Juice < Minitest::Test
|
|
663
698
|
msg = ''
|
664
699
|
assert_raises(Oj::ParseError) {
|
665
700
|
begin
|
666
|
-
|
701
|
+
Oj.load(%|{
|
667
702
|
"first": [
|
668
703
|
1, 2, { "third": 123x }
|
669
704
|
]
|
670
705
|
}|)
|
671
706
|
rescue Oj::ParseError => e
|
672
|
-
|
673
|
-
|
707
|
+
msg = e.message
|
708
|
+
raise e
|
674
709
|
end
|
675
710
|
}
|
676
711
|
assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
|
677
712
|
end
|
678
713
|
|
679
714
|
def test_bad_bignum
|
680
|
-
|
681
|
-
|
682
|
-
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
683
|
-
end
|
715
|
+
assert_raises Oj::ParseError do
|
716
|
+
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
684
717
|
end
|
685
718
|
end
|
686
719
|
|
687
720
|
def test_quirks_array_mode
|
688
|
-
|
689
|
-
|
721
|
+
assert_empty(Oj.load('[]', :quirks_mode => false))
|
722
|
+
assert_empty(Oj.load('[]', :quirks_mode => true))
|
690
723
|
end
|
691
724
|
|
692
725
|
def test_quirks_object_mode
|
693
|
-
|
694
|
-
|
726
|
+
assert_empty(Oj.load('{}', :quirks_mode => false))
|
727
|
+
assert_empty(Oj.load('{}', :quirks_mode => true))
|
695
728
|
end
|
696
729
|
|
697
730
|
def test_omit_nil
|
@@ -707,6 +740,52 @@ class Juice < Minitest::Test
|
|
707
740
|
assert_equal(%|{"x":{"a":1}}|, json)
|
708
741
|
end
|
709
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
|
+
|
710
789
|
def dump_and_load(obj, trace=false)
|
711
790
|
json = Oj.dump(obj, :indent => 2)
|
712
791
|
puts json if trace
|