oj 3.14.3 → 3.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/oj/custom.c +5 -15
- data/ext/oj/dump.c +27 -2
- data/ext/oj/mimic_json.c +21 -0
- data/ext/oj/object.c +7 -21
- data/ext/oj/oj.c +20 -0
- data/ext/oj/oj.h +3 -0
- data/ext/oj/strict.c +9 -27
- data/ext/oj/wab.c +9 -27
- data/lib/oj/version.rb +1 -1
- data/lib/oj.rb +3 -0
- data/pages/Options.md +4 -0
- data/test/_test_active.rb +8 -8
- data/test/_test_active_mimic.rb +7 -7
- data/test/_test_mimic_rails.rb +17 -19
- data/test/files.rb +14 -14
- data/test/foo.rb +5 -5
- data/test/helper.rb +4 -4
- data/test/mem.rb +8 -7
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +30 -32
- data/test/perf_dump.rb +25 -25
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -68
- data/test/perf_once.rb +8 -7
- data/test/perf_parser.rb +40 -46
- data/test/perf_saj.rb +46 -53
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +40 -38
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample.rb +16 -15
- data/test/sample_json.rb +8 -7
- data/test/test_compat.rb +44 -46
- data/test/test_custom.rb +56 -42
- data/test/test_debian.rb +6 -9
- data/test/test_fast.rb +78 -72
- data/test/test_file.rb +16 -21
- 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 +18 -20
- data/test/test_object.rb +76 -86
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +4 -4
- data/test/test_parser_saj.rb +31 -31
- data/test/test_parser_usual.rb +3 -3
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +8 -8
- data/test/test_scp.rb +29 -29
- data/test/test_strict.rb +25 -31
- data/test/test_various.rb +121 -75
- data/test/test_wab.rb +43 -42
- data/test/test_writer.rb +46 -46
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +3 -6
- 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
36
|
def to_json(*_args)
|
40
37
|
%{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
|
41
38
|
end
|
42
39
|
|
43
40
|
def self.json_create(h)
|
44
|
-
|
41
|
+
new(h['x'], h['y'])
|
45
42
|
end
|
46
43
|
end # Jeez
|
47
44
|
|
48
45
|
# contributed by sauliusg to fix as_json
|
49
46
|
class Orange < Jam
|
50
|
-
def initialize(x, y)
|
51
|
-
super
|
52
|
-
end
|
53
47
|
|
54
|
-
def as_json
|
48
|
+
def as_json
|
55
49
|
{ :json_class => self.class,
|
56
50
|
:x => @x,
|
57
51
|
:y => @y }
|
58
52
|
end
|
59
53
|
|
60
54
|
def self.json_create(h)
|
61
|
-
|
55
|
+
new(h['x'], h['y'])
|
62
56
|
end
|
63
57
|
end
|
64
58
|
|
65
59
|
class Melon < Jam
|
66
|
-
def initialize(x, y)
|
67
|
-
super
|
68
|
-
end
|
69
60
|
|
70
|
-
def as_json(
|
61
|
+
def as_json(_options)
|
71
62
|
"#{x} #{y}"
|
72
63
|
end
|
73
64
|
|
74
65
|
def self.json_create(h)
|
75
|
-
|
66
|
+
new(h['x'], h['y'])
|
76
67
|
end
|
77
68
|
end
|
78
69
|
|
79
70
|
class Jazz < Jam
|
80
|
-
|
81
|
-
|
82
|
-
end
|
83
|
-
def to_hash()
|
71
|
+
|
72
|
+
def to_hash
|
84
73
|
{ 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
|
85
74
|
end
|
75
|
+
|
86
76
|
def self.json_create(h)
|
87
|
-
|
77
|
+
new(h['x'], h['y'])
|
88
78
|
end
|
89
79
|
end # Jazz
|
90
80
|
|
@@ -99,7 +89,7 @@ class Juice < Minitest::Test
|
|
99
89
|
def test_set_options
|
100
90
|
orig = Oj.default_options()
|
101
91
|
alt ={
|
102
|
-
indent:
|
92
|
+
indent: ' - ',
|
103
93
|
second_precision: 5,
|
104
94
|
circular: true,
|
105
95
|
class_cache: false,
|
@@ -139,17 +129,18 @@ class Juice < Minitest::Test
|
|
139
129
|
ignore_under: true,
|
140
130
|
trace: true,
|
141
131
|
safe: true,
|
132
|
+
omit_null_byte: false,
|
142
133
|
}
|
143
134
|
Oj.default_options = alt
|
144
|
-
#keys = alt.keys
|
145
|
-
#Oj.default_options.keys.each { |k| puts k unless keys.include? k}
|
135
|
+
# keys = alt.keys
|
136
|
+
# Oj.default_options.keys.each { |k| puts k unless keys.include? k}
|
146
137
|
opts = Oj.default_options()
|
147
|
-
assert_equal(alt, opts)
|
138
|
+
assert_equal(alt, opts)
|
148
139
|
|
149
140
|
Oj.default_options = orig # return to original
|
150
141
|
# verify back to original
|
151
142
|
opts = Oj.default_options()
|
152
|
-
assert_equal(orig, opts)
|
143
|
+
assert_equal(orig, opts)
|
153
144
|
end
|
154
145
|
|
155
146
|
def test_nil
|
@@ -166,8 +157,8 @@ class Juice < Minitest::Test
|
|
166
157
|
|
167
158
|
def test_fixnum
|
168
159
|
dump_and_load(0, false)
|
169
|
-
dump_and_load(
|
170
|
-
dump_and_load(-
|
160
|
+
dump_and_load(12_345, false)
|
161
|
+
dump_and_load(-54_321, false)
|
171
162
|
dump_and_load(1, false)
|
172
163
|
end
|
173
164
|
|
@@ -175,11 +166,11 @@ class Juice < Minitest::Test
|
|
175
166
|
Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
|
176
167
|
n = Oj.load('0.00001234567890123456')
|
177
168
|
assert_equal(Float, n.class)
|
178
|
-
assert_equal('1.234567890123456e-05',
|
169
|
+
assert_equal('1.234567890123456e-05', '%0.15e' % [n])
|
179
170
|
|
180
171
|
n = Oj.load('-0.00001234567890123456')
|
181
172
|
assert_equal(Float, n.class)
|
182
|
-
assert_equal('-1.234567890123456e-05',
|
173
|
+
assert_equal('-1.234567890123456e-05', '%0.15e' % [n])
|
183
174
|
|
184
175
|
n = Oj.load('1000.0000123456789')
|
185
176
|
assert_equal(BigDecimal, n.class)
|
@@ -227,12 +218,12 @@ class Juice < Minitest::Test
|
|
227
218
|
def test_encode
|
228
219
|
opts = Oj.default_options
|
229
220
|
Oj.default_options = { :ascii_only => false }
|
230
|
-
dump_and_load(
|
221
|
+
dump_and_load('ぴーたー', false)
|
231
222
|
|
232
223
|
Oj.default_options = { :ascii_only => true }
|
233
|
-
json = Oj.dump(
|
224
|
+
json = Oj.dump('ぴーたー')
|
234
225
|
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
235
|
-
dump_and_load(
|
226
|
+
dump_and_load('ぴーたー', false)
|
236
227
|
Oj.default_options = opts
|
237
228
|
end
|
238
229
|
|
@@ -253,7 +244,7 @@ class Juice < Minitest::Test
|
|
253
244
|
assert(true)
|
254
245
|
return
|
255
246
|
end
|
256
|
-
assert(false,
|
247
|
+
assert(false, '*** expected an exception')
|
257
248
|
end
|
258
249
|
|
259
250
|
def test_invalid_unicode_ok
|
@@ -267,11 +258,11 @@ class Juice < Minitest::Test
|
|
267
258
|
def test_dump_options
|
268
259
|
json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
|
269
260
|
:mode => :compat,
|
270
|
-
:indent =>
|
261
|
+
:indent => '--',
|
271
262
|
:array_nl => "\n",
|
272
263
|
:object_nl => "#\n",
|
273
|
-
:space =>
|
274
|
-
:space_before =>
|
264
|
+
:space => '*',
|
265
|
+
:space_before => '~')
|
275
266
|
assert(%{{#
|
276
267
|
--"a"~:*1,#
|
277
268
|
--"b"~:*[
|
@@ -300,6 +291,7 @@ class Juice < Minitest::Test
|
|
300
291
|
dump_and_load([[nil]], false)
|
301
292
|
dump_and_load([[nil], 58], false)
|
302
293
|
end
|
294
|
+
|
303
295
|
def test_array_not_closed
|
304
296
|
begin
|
305
297
|
Oj.load('[')
|
@@ -307,7 +299,7 @@ class Juice < Minitest::Test
|
|
307
299
|
assert(true)
|
308
300
|
return
|
309
301
|
end
|
310
|
-
assert(false,
|
302
|
+
assert(false, '*** expected an exception')
|
311
303
|
end
|
312
304
|
|
313
305
|
# multiple JSON in one string
|
@@ -318,7 +310,7 @@ class Juice < Minitest::Test
|
|
318
310
|
}
|
319
311
|
results = []
|
320
312
|
Oj.load(json, :mode => :strict) { |x, start, len| results << [x, start, len] }
|
321
|
-
assert_equal([[{
|
313
|
+
assert_equal([[{'a'=>1}, 0, 7], [[1, 2], 7, 6], [[3, 4], 13, 5], [{'b'=>2}, 18, 8]], results)
|
322
314
|
end
|
323
315
|
|
324
316
|
def test_multiple_json_no_callback
|
@@ -338,33 +330,39 @@ class Juice < Minitest::Test
|
|
338
330
|
out = Oj.dump(hash)
|
339
331
|
assert_equal(json, out)
|
340
332
|
end
|
333
|
+
|
341
334
|
def test_escapes_entities_by_default_when_configured_to_do_so
|
342
|
-
hash = {'key' =>
|
335
|
+
hash = {'key' => 'I <3 this'}
|
343
336
|
Oj.default_options = {:escape_mode => :xss_safe}
|
344
337
|
out = Oj.dump hash
|
345
338
|
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
346
339
|
end
|
340
|
+
|
347
341
|
def test_escapes_slashes_by_default_when_configured_to_do_so
|
348
|
-
hash = {'key' =>
|
342
|
+
hash = {'key' => 'I <3 this </script>'}
|
349
343
|
Oj.default_options = {:escape_mode => :slash}
|
350
344
|
out = Oj.dump hash
|
351
345
|
assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
|
352
346
|
end
|
347
|
+
|
353
348
|
def test_escapes_entities_when_asked_to
|
354
|
-
hash = {'key' =>
|
349
|
+
hash = {'key' => 'I <3 this'}
|
355
350
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
356
351
|
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
357
352
|
end
|
353
|
+
|
358
354
|
def test_does_not_escape_entities_when_not_asked_to
|
359
|
-
hash = {'key' =>
|
355
|
+
hash = {'key' => 'I <3 this'}
|
360
356
|
out = Oj.dump(hash, :escape_mode => :json)
|
361
357
|
assert_equal(%{{"key":"I <3 this"}}, out)
|
362
358
|
end
|
359
|
+
|
363
360
|
def test_escapes_common_xss_vectors
|
364
|
-
hash = {'key' =>
|
361
|
+
hash = {'key' => '<script>alert(123) && formatHD()</script>'}
|
365
362
|
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
366
363
|
assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
|
367
364
|
end
|
365
|
+
|
368
366
|
def test_escape_newline_by_default
|
369
367
|
Oj.default_options = { :escape_mode => :json }
|
370
368
|
json = %{["one","two\\n2"]}
|
@@ -372,6 +370,7 @@ class Juice < Minitest::Test
|
|
372
370
|
out = Oj.dump(x)
|
373
371
|
assert_equal(json, out)
|
374
372
|
end
|
373
|
+
|
375
374
|
def test_does_not_escape_newline
|
376
375
|
Oj.default_options = { :escape_mode => :newline }
|
377
376
|
json = %{["one","two\n2"]}
|
@@ -379,6 +378,7 @@ class Juice < Minitest::Test
|
|
379
378
|
out = Oj.dump(x)
|
380
379
|
assert_equal(json, out)
|
381
380
|
end
|
381
|
+
|
382
382
|
def test_dump_invalid_utf8
|
383
383
|
Oj.default_options = { :escape_mode => :ascii }
|
384
384
|
assert_raises(EncodingError) {
|
@@ -400,14 +400,14 @@ class Juice < Minitest::Test
|
|
400
400
|
end
|
401
401
|
|
402
402
|
def test_time_neg
|
403
|
-
t = Time.parse(
|
403
|
+
t = Time.parse('1900-01-01 00:18:59 UTC')
|
404
404
|
json = Oj.dump(t, :mode => :custom, :time_format => :unix)
|
405
405
|
assert_equal('-2208987661.000000000', json)
|
406
406
|
end
|
407
407
|
|
408
408
|
def test_time_years
|
409
409
|
(-2020..2020).each { |year|
|
410
|
-
s =
|
410
|
+
s = '%04d-03-01T15:14:13Z' % [year]
|
411
411
|
json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
|
412
412
|
assert_equal(s, json[1..-2])
|
413
413
|
|
@@ -436,7 +436,7 @@ class Juice < Minitest::Test
|
|
436
436
|
assert(true)
|
437
437
|
return
|
438
438
|
end
|
439
|
-
assert(false,
|
439
|
+
assert(false, '*** expected an exception')
|
440
440
|
end
|
441
441
|
|
442
442
|
def test_hash_not_closed
|
@@ -446,7 +446,7 @@ class Juice < Minitest::Test
|
|
446
446
|
assert(true)
|
447
447
|
return
|
448
448
|
end
|
449
|
-
assert(false,
|
449
|
+
assert(false, '*** expected an exception')
|
450
450
|
end
|
451
451
|
|
452
452
|
# Object with to_json()
|
@@ -456,7 +456,7 @@ class Juice < Minitest::Test
|
|
456
456
|
assert_equal('null', json)
|
457
457
|
end
|
458
458
|
|
459
|
-
# Object with to_hash()
|
459
|
+
# Object with to_hash()
|
460
460
|
def test_to_hash_object_null
|
461
461
|
obj = Jazz.new(true, 58)
|
462
462
|
json = Oj.dump(obj, :mode => :null)
|
@@ -504,7 +504,7 @@ class Juice < Minitest::Test
|
|
504
504
|
|
505
505
|
def test_infinity
|
506
506
|
n = Oj.load('Infinity', :mode => :object)
|
507
|
-
assert_equal(BigDecimal('Infinity').to_f, n)
|
507
|
+
assert_equal(BigDecimal('Infinity').to_f, n)
|
508
508
|
x = Oj.load('Infinity', :mode => :compat)
|
509
509
|
assert_equal('Infinity', x.to_s)
|
510
510
|
end
|
@@ -529,7 +529,7 @@ class Juice < Minitest::Test
|
|
529
529
|
"y":58 }}
|
530
530
|
obj = Oj.load(json, :mode => :object, :auto_define => true)
|
531
531
|
assert_equal('Juice::Jem', obj.class.name)
|
532
|
-
|
532
|
+
assert(obj.x)
|
533
533
|
assert_equal(58, obj.y)
|
534
534
|
end
|
535
535
|
|
@@ -537,19 +537,19 @@ class Juice < Minitest::Test
|
|
537
537
|
def test_deep_nest_dump
|
538
538
|
begin
|
539
539
|
a = []
|
540
|
-
|
540
|
+
10_000.times { a << [a] }
|
541
541
|
Oj.dump(a)
|
542
542
|
rescue Exception
|
543
543
|
assert(true)
|
544
544
|
return
|
545
545
|
end
|
546
|
-
assert(false,
|
546
|
+
assert(false, '*** expected an exception')
|
547
547
|
end
|
548
548
|
|
549
549
|
# Stream IO
|
550
550
|
def test_io_string
|
551
551
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
552
|
-
output = StringIO.open(
|
552
|
+
output = StringIO.open('', 'w+')
|
553
553
|
Oj.to_stream(output, src)
|
554
554
|
|
555
555
|
input = StringIO.new(output.string())
|
@@ -559,8 +559,8 @@ class Juice < Minitest::Test
|
|
559
559
|
|
560
560
|
def test_io_file
|
561
561
|
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
562
|
-
filename = File.join(
|
563
|
-
File.open(filename,
|
562
|
+
filename = File.join(__dir__, 'open_file_test.json')
|
563
|
+
File.open(filename, 'w') { |f|
|
564
564
|
Oj.to_stream(f, src)
|
565
565
|
}
|
566
566
|
f = File.new(filename)
|
@@ -575,7 +575,7 @@ class Juice < Minitest::Test
|
|
575
575
|
IO.pipe do |r, w|
|
576
576
|
if fork
|
577
577
|
r.close
|
578
|
-
#w.nonblock = false
|
578
|
+
# w.nonblock = false
|
579
579
|
a = []
|
580
580
|
10_000.times do |i|
|
581
581
|
a << i
|
@@ -593,7 +593,7 @@ class Juice < Minitest::Test
|
|
593
593
|
end
|
594
594
|
end
|
595
595
|
|
596
|
-
# comments
|
596
|
+
# comments
|
597
597
|
def test_comment_slash
|
598
598
|
json = %{{
|
599
599
|
"x":true,//three
|
@@ -637,7 +637,7 @@ class Juice < Minitest::Test
|
|
637
637
|
assert(true)
|
638
638
|
return
|
639
639
|
end
|
640
|
-
assert(false,
|
640
|
+
assert(false, '*** expected an exception')
|
641
641
|
end
|
642
642
|
|
643
643
|
def test_nilnil_true
|
@@ -660,27 +660,27 @@ class Juice < Minitest::Test
|
|
660
660
|
assert(Oj::ParseError == e.class || EncodingError == e.class)
|
661
661
|
return
|
662
662
|
end
|
663
|
-
assert(false,
|
663
|
+
assert(false, '*** expected an exception')
|
664
664
|
end
|
665
665
|
|
666
666
|
def test_quirks_null_mode
|
667
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
668
|
-
assert_nil(Oj.load(
|
667
|
+
assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
|
668
|
+
assert_nil(Oj.load('null', :quirks_mode => true))
|
669
669
|
end
|
670
670
|
|
671
671
|
def test_quirks_bool_mode
|
672
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
673
|
-
|
672
|
+
assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
|
673
|
+
assert(Oj.load('true', :quirks_mode => true))
|
674
674
|
end
|
675
675
|
|
676
676
|
def test_quirks_number_mode
|
677
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
678
|
-
assert_equal(123, Oj.load(
|
677
|
+
assert_raises(Oj::ParseError) { Oj.load('123', :quirks_mode => false) }
|
678
|
+
assert_equal(123, Oj.load('123', :quirks_mode => true))
|
679
679
|
end
|
680
680
|
|
681
681
|
def test_quirks_decimal_mode
|
682
|
-
assert_raises(Oj::ParseError) { Oj.load(
|
683
|
-
|
682
|
+
assert_raises(Oj::ParseError) { Oj.load('123.45', :quirks_mode => false) }
|
683
|
+
assert_in_delta(123.45, Oj.load('123.45', :quirks_mode => true))
|
684
684
|
end
|
685
685
|
|
686
686
|
def test_quirks_string_mode
|
@@ -712,13 +712,13 @@ class Juice < Minitest::Test
|
|
712
712
|
end
|
713
713
|
|
714
714
|
def test_quirks_array_mode
|
715
|
-
|
716
|
-
|
715
|
+
assert_empty(Oj.load('[]', :quirks_mode => false))
|
716
|
+
assert_empty(Oj.load('[]', :quirks_mode => true))
|
717
717
|
end
|
718
718
|
|
719
719
|
def test_quirks_object_mode
|
720
|
-
|
721
|
-
|
720
|
+
assert_empty(Oj.load('{}', :quirks_mode => false))
|
721
|
+
assert_empty(Oj.load('{}', :quirks_mode => true))
|
722
722
|
end
|
723
723
|
|
724
724
|
def test_omit_nil
|
@@ -734,6 +734,52 @@ class Juice < Minitest::Test
|
|
734
734
|
assert_equal(%|{"x":{"a":1}}|, json)
|
735
735
|
end
|
736
736
|
|
737
|
+
def test_omit_null_byte
|
738
|
+
Oj.default_options = { :omit_null_byte => true }
|
739
|
+
|
740
|
+
json = Oj.dump({ "fo\x00o" => "b\x00ar" })
|
741
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
742
|
+
|
743
|
+
json = Oj.dump({ "foo\x00" => "\x00bar" })
|
744
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
745
|
+
|
746
|
+
json = Oj.dump({ "\x00foo" => "bar\x00" })
|
747
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
748
|
+
|
749
|
+
json = Oj.dump({ "fo\0o" => "ba\0r" })
|
750
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
751
|
+
|
752
|
+
json = Oj.dump({ "foo\0" => "\0bar" })
|
753
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
754
|
+
|
755
|
+
json = Oj.dump({ "\0foo" => "bar\0" })
|
756
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
757
|
+
|
758
|
+
json = Oj.dump({ "fo\u0000o" => "ba\u0000r" })
|
759
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
760
|
+
|
761
|
+
json = Oj.dump({ "foo\u0000" => "\u0000bar" })
|
762
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
763
|
+
|
764
|
+
json = Oj.dump({ "\u0000foo" => "bar\u0000" })
|
765
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
766
|
+
|
767
|
+
json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => false)
|
768
|
+
assert_equal(%|{"\\u0000foo":"bar\\u0000"}|, json)
|
769
|
+
|
770
|
+
# no change from default set earlier so :omit_null_byte is still true
|
771
|
+
json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => nil)
|
772
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
773
|
+
|
774
|
+
Oj.default_options = { :omit_null_byte => false }
|
775
|
+
|
776
|
+
json = Oj.dump({ "\x00foo" => "bar\x00" })
|
777
|
+
assert_equal(%|{"\\u0000foo":"bar\\u0000"}|, json)
|
778
|
+
|
779
|
+
json = Oj.dump({ "\x00foo" => "bar\x00" }, :omit_null_byte => true)
|
780
|
+
assert_equal(%|{"foo":"bar"}|, json)
|
781
|
+
end
|
782
|
+
|
737
783
|
def dump_and_load(obj, trace=false)
|
738
784
|
json = Oj.dump(obj, :indent => 2)
|
739
785
|
puts json if trace
|
data/test/test_wab.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
$LOAD_PATH << __dir__
|
5
|
+
@oj_dir = File.dirname(File.expand_path(__dir__))
|
6
6
|
%w(lib ext).each do |dir|
|
7
|
-
|
7
|
+
$LOAD_PATH << File.join(@oj_dir, dir)
|
8
8
|
end
|
9
9
|
|
10
10
|
require 'minitest'
|
@@ -19,13 +19,16 @@ require 'oj'
|
|
19
19
|
module WAB
|
20
20
|
class UUID
|
21
21
|
attr_reader :id
|
22
|
+
|
22
23
|
def initialize(id)
|
23
24
|
@id = id.downcase
|
24
|
-
raise
|
25
|
+
raise StandardError.new('Invalid UUID format.') if /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.match(@id).nil?
|
25
26
|
end
|
27
|
+
|
26
28
|
def to_s
|
27
29
|
@id
|
28
30
|
end
|
31
|
+
|
29
32
|
def ==(other)
|
30
33
|
other.is_a?(self.class) && @id == other.id
|
31
34
|
end
|
@@ -51,16 +54,16 @@ class WabJuice < Minitest::Test
|
|
51
54
|
|
52
55
|
def test_fixnum
|
53
56
|
dump_and_load(0, false)
|
54
|
-
dump_and_load(
|
55
|
-
dump_and_load(-
|
57
|
+
dump_and_load(12_345, false)
|
58
|
+
dump_and_load(-54_321, false)
|
56
59
|
dump_and_load(1, false)
|
57
60
|
end
|
58
61
|
|
59
62
|
def test_float
|
60
63
|
dump_and_load(0.0, false)
|
61
|
-
dump_and_load(
|
64
|
+
dump_and_load(12_345.6789, false)
|
62
65
|
dump_and_load(70.35, false)
|
63
|
-
dump_and_load(-
|
66
|
+
dump_and_load(-54_321.012, false)
|
64
67
|
dump_and_load(1.7775, false)
|
65
68
|
dump_and_load(2.5024, false)
|
66
69
|
dump_and_load(2.48e16, false)
|
@@ -88,7 +91,7 @@ class WabJuice < Minitest::Test
|
|
88
91
|
end
|
89
92
|
|
90
93
|
def test_encode
|
91
|
-
dump_and_load(
|
94
|
+
dump_and_load('ぴーたー', false)
|
92
95
|
end
|
93
96
|
|
94
97
|
def test_array
|
@@ -107,18 +110,18 @@ class WabJuice < Minitest::Test
|
|
107
110
|
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
108
111
|
|
109
112
|
begin
|
110
|
-
n =
|
113
|
+
n = 10_000
|
111
114
|
Oj.wab_load(('[' * n) + (']' * n))
|
112
115
|
rescue Exception => e
|
113
|
-
|
116
|
+
refute(e.message)
|
114
117
|
end
|
115
118
|
end
|
116
119
|
|
117
120
|
# Hash
|
118
121
|
def test_hash
|
119
122
|
dump_and_load({}, false)
|
120
|
-
dump_and_load({
|
121
|
-
dump_and_load({
|
123
|
+
dump_and_load({ tru: true, fals: false}, false)
|
124
|
+
dump_and_load({ tru: true, array: [], hash: {}}, false)
|
122
125
|
end
|
123
126
|
|
124
127
|
def test_hash_non_sym_keys
|
@@ -127,25 +130,25 @@ class WabJuice < Minitest::Test
|
|
127
130
|
|
128
131
|
def test_hash_deep
|
129
132
|
dump_and_load({x1: {
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
133
|
+
x2: {
|
134
|
+
x3: {
|
135
|
+
x4: {
|
136
|
+
x5: {
|
137
|
+
x6: {
|
138
|
+
x7: {
|
139
|
+
x8: {
|
140
|
+
x9: {
|
141
|
+
x10: {
|
142
|
+
x11: {
|
143
|
+
x12: {
|
144
|
+
x13: {
|
145
|
+
x14: {
|
146
|
+
x15: {
|
147
|
+
x16: {
|
148
|
+
x17: {
|
149
|
+
x18: {
|
150
|
+
x19: {
|
151
|
+
x20: {}}}}}}}}}}}}}}}}}}}}}, false)
|
149
152
|
end
|
150
153
|
|
151
154
|
def test_non_str_hash
|
@@ -153,7 +156,7 @@ class WabJuice < Minitest::Test
|
|
153
156
|
end
|
154
157
|
|
155
158
|
def test_bignum_object
|
156
|
-
dump_and_load(7
|
159
|
+
dump_and_load(7**55, false)
|
157
160
|
end
|
158
161
|
|
159
162
|
# BigDecimal
|
@@ -187,15 +190,13 @@ class WabJuice < Minitest::Test
|
|
187
190
|
end
|
188
191
|
|
189
192
|
def test_io_file
|
190
|
-
filename = File.join(
|
191
|
-
File.
|
192
|
-
f.write(%{{
|
193
|
+
filename = File.join(__dir__, 'open_file_test.json')
|
194
|
+
File.write(filename, %{{
|
193
195
|
"x":true,
|
194
196
|
"y":58,
|
195
197
|
"z": [1,2,3]
|
196
198
|
}
|
197
199
|
})
|
198
|
-
}
|
199
200
|
f = File.new(filename)
|
200
201
|
obj = Oj.wab_load(f)
|
201
202
|
f.close()
|
@@ -208,13 +209,13 @@ class WabJuice < Minitest::Test
|
|
208
209
|
end
|
209
210
|
|
210
211
|
def test_time
|
211
|
-
t = Time.gm(2017, 1, 5, 23, 58, 7,
|
212
|
+
t = Time.gm(2017, 1, 5, 23, 58, 7, 123_456.789)
|
212
213
|
json = Oj.dump(t, mode: :wab)
|
213
214
|
assert_equal('"2017-01-05T23:58:07.123456789Z"', json)
|
214
215
|
# must load and convert to json as the Time#== does not match identical
|
215
216
|
# times due to the way it tracks fractional seconds.
|
216
|
-
loaded = Oj.wab_load(json)
|
217
|
-
assert_equal(json, Oj.dump(loaded, mode: :wab),
|
217
|
+
loaded = Oj.wab_load(json)
|
218
|
+
assert_equal(json, Oj.dump(loaded, mode: :wab), 'json mismatch after load')
|
218
219
|
end
|
219
220
|
|
220
221
|
def test_uuid
|
@@ -298,7 +299,7 @@ class WabJuice < Minitest::Test
|
|
298
299
|
def dump_and_load(obj, trace=false)
|
299
300
|
json = Oj.dump(obj, mode: :wab, indent: 2)
|
300
301
|
puts json if trace
|
301
|
-
loaded = Oj.wab_load(json)
|
302
|
+
loaded = Oj.wab_load(json)
|
302
303
|
if obj.nil?
|
303
304
|
assert_nil(loaded)
|
304
305
|
else
|