oj 3.14.3 → 3.15.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 +10 -0
- data/ext/oj/code.c +3 -10
- data/ext/oj/compat.c +5 -18
- data/ext/oj/custom.c +10 -28
- data/ext/oj/dump.c +40 -10
- data/ext/oj/dump.h +1 -4
- data/ext/oj/extconf.rb +4 -2
- data/ext/oj/fast.c +3 -6
- data/ext/oj/mimic_json.c +21 -1
- data/ext/oj/object.c +7 -21
- data/ext/oj/oj.c +24 -4
- data/ext/oj/oj.h +10 -6
- data/ext/oj/parse.c +3 -5
- data/ext/oj/parse.h +16 -14
- data/ext/oj/parser.h +2 -2
- data/ext/oj/reader.c +1 -3
- data/ext/oj/saj.c +1 -1
- data/ext/oj/strict.c +9 -27
- data/ext/oj/wab.c +9 -27
- data/lib/oj/active_support_helper.rb +2 -3
- data/lib/oj/json.rb +156 -149
- data/lib/oj/mimic.rb +3 -1
- 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 +15 -10
- 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 +27 -27
- 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
|