oj 3.16.9 → 3.16.10
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 +5 -0
- data/ext/oj/fast.c +3 -6
- data/ext/oj/mimic_json.c +3 -6
- data/ext/oj/oj.c +2 -4
- data/ext/oj/parse.c +15 -5
- data/ext/oj/parser.c +1 -1
- data/ext/oj/parser.h +2 -0
- data/ext/oj/rails.c +1 -2
- data/ext/oj/saj.c +3 -6
- data/ext/oj/scp.c +3 -6
- data/ext/oj/stream_writer.c +1 -7
- data/ext/oj/strict.c +2 -4
- data/ext/oj/string_writer.c +1 -3
- data/lib/oj/version.rb +1 -1
- metadata +3 -98
- data/test/_test_active.rb +0 -75
- data/test/_test_active_mimic.rb +0 -95
- data/test/_test_mimic_rails.rb +0 -123
- data/test/activerecord/result_test.rb +0 -31
- data/test/activesupport6/abstract_unit.rb +0 -44
- data/test/activesupport6/decoding_test.rb +0 -133
- data/test/activesupport6/encoding_test.rb +0 -542
- data/test/activesupport6/encoding_test_cases.rb +0 -98
- data/test/activesupport6/test_common.rb +0 -17
- data/test/activesupport6/test_helper.rb +0 -163
- data/test/activesupport6/time_zone_test_helpers.rb +0 -39
- data/test/activesupport7/abstract_unit.rb +0 -52
- data/test/activesupport7/decoding_test.rb +0 -125
- data/test/activesupport7/encoding_test.rb +0 -536
- data/test/activesupport7/encoding_test_cases.rb +0 -104
- data/test/activesupport7/time_zone_test_helpers.rb +0 -47
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -26
- data/test/helper.rb +0 -39
- data/test/isolated/shared.rb +0 -309
- data/test/isolated/test_mimic_after.rb +0 -13
- data/test/isolated/test_mimic_alone.rb +0 -12
- data/test/isolated/test_mimic_as_json.rb +0 -45
- data/test/isolated/test_mimic_before.rb +0 -13
- data/test/isolated/test_mimic_define.rb +0 -28
- data/test/isolated/test_mimic_rails_after.rb +0 -22
- data/test/isolated/test_mimic_rails_before.rb +0 -21
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/json_gem/json_addition_test.rb +0 -216
- data/test/json_gem/json_common_interface_test.rb +0 -155
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -21
- data/test/json_gem/json_fixtures_test.rb +0 -36
- data/test/json_gem/json_generator_test.rb +0 -413
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -477
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -30
- data/test/mem.rb +0 -34
- data/test/perf.rb +0 -102
- data/test/perf_compat.rb +0 -128
- data/test/perf_dump.rb +0 -50
- data/test/perf_fast.rb +0 -162
- data/test/perf_file.rb +0 -62
- data/test/perf_object.rb +0 -134
- data/test/perf_once.rb +0 -59
- data/test/perf_parser.rb +0 -183
- data/test/perf_saj.rb +0 -101
- data/test/perf_scp.rb +0 -140
- data/test/perf_simple.rb +0 -289
- data/test/perf_strict.rb +0 -137
- data/test/perf_wab.rb +0 -129
- data/test/prec.rb +0 -23
- data/test/sample/change.rb +0 -13
- data/test/sample/dir.rb +0 -18
- data/test/sample/doc.rb +0 -35
- data/test/sample/file.rb +0 -47
- data/test/sample/group.rb +0 -15
- data/test/sample/hasprops.rb +0 -15
- data/test/sample/layer.rb +0 -11
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -9
- data/test/sample/shape.rb +0 -34
- data/test/sample/text.rb +0 -19
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -567
- data/test/test_custom.rb +0 -555
- data/test/test_debian.rb +0 -50
- data/test/test_fast.rb +0 -526
- data/test/test_file.rb +0 -250
- data/test/test_gc.rb +0 -60
- data/test/test_generate.rb +0 -21
- data/test/test_hash.rb +0 -39
- data/test/test_integer_range.rb +0 -72
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1030
- data/test/test_parser.rb +0 -11
- data/test/test_parser_debug.rb +0 -27
- data/test/test_parser_saj.rb +0 -337
- data/test/test_parser_usual.rb +0 -255
- data/test/test_rails.rb +0 -35
- data/test/test_saj.rb +0 -188
- data/test/test_scp.rb +0 -431
- data/test/test_strict.rb +0 -441
- data/test/test_various.rb +0 -801
- data/test/test_wab.rb +0 -311
- data/test/test_writer.rb +0 -396
- data/test/tests.rb +0 -33
- data/test/tests_mimic.rb +0 -23
- data/test/tests_mimic_addition.rb +0 -16
data/test/test_various.rb
DELETED
@@ -1,801 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: false
|
3
|
-
|
4
|
-
$LOAD_PATH << __dir__
|
5
|
-
|
6
|
-
require 'helper'
|
7
|
-
|
8
|
-
class Juice < Minitest::Test
|
9
|
-
def gen_whitespaced_string(length=Random.new.rand(100))
|
10
|
-
whitespace_chars = [' ', "\t", "\f", "\n", "\r"]
|
11
|
-
result = ''
|
12
|
-
length.times { result << whitespace_chars.sample }
|
13
|
-
result
|
14
|
-
end
|
15
|
-
|
16
|
-
module TestModule
|
17
|
-
end
|
18
|
-
|
19
|
-
class Jam
|
20
|
-
attr_accessor :x, :y
|
21
|
-
|
22
|
-
def initialize(x, y)
|
23
|
-
@x = x
|
24
|
-
@y = y
|
25
|
-
end
|
26
|
-
|
27
|
-
def eql?(o)
|
28
|
-
self.class == o.class && @x == o.x && @y == o.y
|
29
|
-
end
|
30
|
-
alias == eql?
|
31
|
-
|
32
|
-
end # Jam
|
33
|
-
|
34
|
-
class Jeez < Jam
|
35
|
-
|
36
|
-
def to_json(*_args)
|
37
|
-
%{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.json_create(h)
|
41
|
-
new(h['x'], h['y'])
|
42
|
-
end
|
43
|
-
end # Jeez
|
44
|
-
|
45
|
-
# contributed by sauliusg to fix as_json
|
46
|
-
class Orange < Jam
|
47
|
-
|
48
|
-
def as_json
|
49
|
-
{ :json_class => self.class,
|
50
|
-
:x => @x,
|
51
|
-
:y => @y }
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.json_create(h)
|
55
|
-
new(h['x'], h['y'])
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class Melon < Jam
|
60
|
-
|
61
|
-
def as_json(_options)
|
62
|
-
"#{x} #{y}"
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.json_create(h)
|
66
|
-
new(h['x'], h['y'])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
class Jazz < Jam
|
71
|
-
|
72
|
-
def to_hash
|
73
|
-
{ 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.json_create(h)
|
77
|
-
new(h['x'], h['y'])
|
78
|
-
end
|
79
|
-
end # Jazz
|
80
|
-
|
81
|
-
def setup
|
82
|
-
@default_options = Oj.default_options
|
83
|
-
end
|
84
|
-
|
85
|
-
def teardown
|
86
|
-
Oj.default_options = @default_options
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_set_options
|
90
|
-
orig = Oj.default_options()
|
91
|
-
alt ={
|
92
|
-
indent: ' - ',
|
93
|
-
second_precision: 5,
|
94
|
-
circular: true,
|
95
|
-
class_cache: false,
|
96
|
-
auto_define: true,
|
97
|
-
symbol_keys: true,
|
98
|
-
bigdecimal_as_decimal: false,
|
99
|
-
use_to_json: false,
|
100
|
-
use_to_hash: false,
|
101
|
-
use_as_json: false,
|
102
|
-
use_raw_json: false,
|
103
|
-
nilnil: true,
|
104
|
-
empty_string: true,
|
105
|
-
allow_gc: false,
|
106
|
-
quirks_mode: false,
|
107
|
-
allow_invalid_unicode: true,
|
108
|
-
float_format: '%0.13g',
|
109
|
-
float_precision: 13,
|
110
|
-
mode: :strict,
|
111
|
-
escape_mode: :ascii,
|
112
|
-
time_format: :unix_zone,
|
113
|
-
bigdecimal_load: :float,
|
114
|
-
compat_bigdecimal: true,
|
115
|
-
create_id: 'classy',
|
116
|
-
create_additions: true,
|
117
|
-
cache_keys: false,
|
118
|
-
cache_str: 5,
|
119
|
-
space: 'z',
|
120
|
-
array_nl: 'a',
|
121
|
-
object_nl: 'o',
|
122
|
-
space_before: 'b',
|
123
|
-
nan: :huge,
|
124
|
-
hash_class: Hash,
|
125
|
-
omit_nil: false,
|
126
|
-
allow_nan: true,
|
127
|
-
integer_range: nil,
|
128
|
-
array_class: Array,
|
129
|
-
ignore: nil,
|
130
|
-
ignore_under: true,
|
131
|
-
trace: true,
|
132
|
-
safe: true,
|
133
|
-
omit_null_byte: false,
|
134
|
-
}
|
135
|
-
Oj.default_options = alt
|
136
|
-
# keys = alt.keys
|
137
|
-
# Oj.default_options.keys.each { |k| puts k unless keys.include? k}
|
138
|
-
opts = Oj.default_options()
|
139
|
-
assert_equal(alt, opts)
|
140
|
-
|
141
|
-
Oj.default_options = orig # return to original
|
142
|
-
# verify back to original
|
143
|
-
opts = Oj.default_options()
|
144
|
-
assert_equal(orig, opts)
|
145
|
-
end
|
146
|
-
|
147
|
-
def test_nil
|
148
|
-
dump_and_load(nil, false)
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_true
|
152
|
-
dump_and_load(true, false)
|
153
|
-
end
|
154
|
-
|
155
|
-
def test_false
|
156
|
-
dump_and_load(false, false)
|
157
|
-
end
|
158
|
-
|
159
|
-
def test_fixnum
|
160
|
-
dump_and_load(0, false)
|
161
|
-
dump_and_load(12_345, false)
|
162
|
-
dump_and_load(-54_321, false)
|
163
|
-
dump_and_load(1, false)
|
164
|
-
end
|
165
|
-
|
166
|
-
def test_float_parse
|
167
|
-
Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
|
168
|
-
n = Oj.load('0.00001234567890123456')
|
169
|
-
assert_equal(Float, n.class)
|
170
|
-
assert_equal('1.234567890123456e-05', '%0.15e' % [n])
|
171
|
-
|
172
|
-
n = Oj.load('-0.00001234567890123456')
|
173
|
-
assert_equal(Float, n.class)
|
174
|
-
assert_equal('-1.234567890123456e-05', '%0.15e' % [n])
|
175
|
-
|
176
|
-
n = Oj.load('1000.0000123456789')
|
177
|
-
assert_equal(BigDecimal, n.class)
|
178
|
-
assert_equal('0.10000000123456789E4', n.to_s.upcase)
|
179
|
-
|
180
|
-
n = Oj.load('-0.000012345678901234567')
|
181
|
-
assert_equal(BigDecimal, n.class)
|
182
|
-
assert_equal('-0.12345678901234567E-4', n.to_s.upcase)
|
183
|
-
end
|
184
|
-
|
185
|
-
=begin
|
186
|
-
# TBD move to custom
|
187
|
-
def test_float_dump
|
188
|
-
Oj.default_options = { :float_precision => 16 }
|
189
|
-
assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
|
190
|
-
Oj.default_options = { :float_precision => 5 }
|
191
|
-
assert_equal('1.4055', Oj.dump(1.405460727))
|
192
|
-
Oj.default_options = { :float_precision => 0 }
|
193
|
-
assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
|
194
|
-
Oj.default_options = { :float_precision => 15 }
|
195
|
-
assert_equal('0.56', Oj.dump(0.56))
|
196
|
-
assert_equal('0.5773', Oj.dump(0.5773))
|
197
|
-
assert_equal('0.6768', Oj.dump(0.6768))
|
198
|
-
assert_equal('0.685', Oj.dump(0.685))
|
199
|
-
assert_equal('0.7032', Oj.dump(0.7032))
|
200
|
-
assert_equal('0.7051', Oj.dump(0.7051))
|
201
|
-
assert_equal('0.8274', Oj.dump(0.8274))
|
202
|
-
assert_equal('0.9149', Oj.dump(0.9149))
|
203
|
-
assert_equal('64.4', Oj.dump(64.4))
|
204
|
-
assert_equal('71.6', Oj.dump(71.6))
|
205
|
-
assert_equal('73.4', Oj.dump(73.4))
|
206
|
-
assert_equal('80.6', Oj.dump(80.6))
|
207
|
-
assert_equal('-95.640172', Oj.dump(-95.640172))
|
208
|
-
end
|
209
|
-
=end
|
210
|
-
|
211
|
-
def test_string
|
212
|
-
dump_and_load('', false)
|
213
|
-
dump_and_load('abc', false)
|
214
|
-
dump_and_load("abc\ndef", false)
|
215
|
-
dump_and_load("a\u0041", false)
|
216
|
-
assert_equal("a\u0000a", dump_and_load("a\u0000a", false))
|
217
|
-
end
|
218
|
-
|
219
|
-
def test_encode
|
220
|
-
opts = Oj.default_options
|
221
|
-
Oj.default_options = { :ascii_only => false }
|
222
|
-
dump_and_load('ぴーたー', false)
|
223
|
-
|
224
|
-
Oj.default_options = { :ascii_only => true }
|
225
|
-
json = Oj.dump('ぴーたー')
|
226
|
-
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
227
|
-
dump_and_load('ぴーたー', false)
|
228
|
-
Oj.default_options = opts
|
229
|
-
end
|
230
|
-
|
231
|
-
def test_unicode
|
232
|
-
# hits the 3 normal ranges and one extended surrogate pair
|
233
|
-
json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
|
234
|
-
obj = Oj.load(json)
|
235
|
-
json2 = Oj.dump(obj, :ascii_only => true)
|
236
|
-
assert_equal(json, json2)
|
237
|
-
end
|
238
|
-
|
239
|
-
def test_invalid_unicode_raise
|
240
|
-
# validate that an invalid unicode raises unless the :allow_invalid_unicode is true
|
241
|
-
json = %{"x\\ud83dy"}
|
242
|
-
begin
|
243
|
-
Oj.load(json)
|
244
|
-
rescue Exception
|
245
|
-
assert(true)
|
246
|
-
return
|
247
|
-
end
|
248
|
-
assert(false, '*** expected an exception')
|
249
|
-
end
|
250
|
-
|
251
|
-
def test_invalid_unicode_ok
|
252
|
-
# validate that an invalid unicode raises unless the :allow_invalid_unicode is true
|
253
|
-
json = %{"x\\ud83dy"}
|
254
|
-
obj = Oj.load(json, :allow_invalid_unicode => true)
|
255
|
-
# The same as what ruby would do with the invalid encoding.
|
256
|
-
assert_equal("x\xED\xA0\xBDy", obj.to_s)
|
257
|
-
end
|
258
|
-
|
259
|
-
def test_dump_options
|
260
|
-
json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
|
261
|
-
:mode => :compat,
|
262
|
-
:indent => '--',
|
263
|
-
:array_nl => "\n",
|
264
|
-
:object_nl => "#\n",
|
265
|
-
:space => '*',
|
266
|
-
:space_before => '~')
|
267
|
-
assert(%{{#
|
268
|
-
--"a"~:*1,#
|
269
|
-
--"b"~:*[
|
270
|
-
----true,
|
271
|
-
----false
|
272
|
-
--]#
|
273
|
-
}} == json ||
|
274
|
-
%{{#
|
275
|
-
--"b"~:*[
|
276
|
-
----true,
|
277
|
-
----false
|
278
|
-
--],#
|
279
|
-
--"a"~:*1#
|
280
|
-
}} == json)
|
281
|
-
end
|
282
|
-
|
283
|
-
def test_null_char
|
284
|
-
assert_raises(Oj::ParseError) { Oj.load("\"\0\"") }
|
285
|
-
assert_raises(Oj::ParseError) { Oj.load("\"\\\0\"") }
|
286
|
-
end
|
287
|
-
|
288
|
-
def test_array
|
289
|
-
dump_and_load([], false)
|
290
|
-
dump_and_load([true, false], false)
|
291
|
-
dump_and_load(['a', 1, nil], false)
|
292
|
-
dump_and_load([[nil]], false)
|
293
|
-
dump_and_load([[nil], 58], false)
|
294
|
-
end
|
295
|
-
|
296
|
-
def test_array_not_closed
|
297
|
-
begin
|
298
|
-
Oj.load('[')
|
299
|
-
rescue Exception
|
300
|
-
assert(true)
|
301
|
-
return
|
302
|
-
end
|
303
|
-
assert(false, '*** expected an exception')
|
304
|
-
end
|
305
|
-
|
306
|
-
# multiple JSON in one string
|
307
|
-
def test_multiple_json_callback
|
308
|
-
json = %{{"a":1}
|
309
|
-
[1,2][3,4]
|
310
|
-
{"b":2}
|
311
|
-
}
|
312
|
-
results = []
|
313
|
-
Oj.load(json, :mode => :strict) { |x, start, len| results << [x, start, len] }
|
314
|
-
assert_equal([[{'a'=>1}, 0, 7], [[1, 2], 7, 6], [[3, 4], 13, 5], [{'b'=>2}, 18, 8]], results)
|
315
|
-
end
|
316
|
-
|
317
|
-
def test_multiple_json_no_callback
|
318
|
-
json = %{{"a":1}
|
319
|
-
[1,2][3,4]
|
320
|
-
{"b":2}
|
321
|
-
}
|
322
|
-
assert_raises(Oj::ParseError) { Oj.load(json) }
|
323
|
-
end
|
324
|
-
|
325
|
-
# encoding tests
|
326
|
-
def test_does_not_escape_entities_by_default
|
327
|
-
Oj.default_options = { :escape_mode => :ascii } # set in mimic mode
|
328
|
-
# use Oj to create the hash since some Rubies don't deal nicely with unicode.
|
329
|
-
json = %{{"key":"I <3 this\\u2028space"}}
|
330
|
-
hash = Oj.load(json)
|
331
|
-
out = Oj.dump(hash)
|
332
|
-
assert_equal(json, out)
|
333
|
-
end
|
334
|
-
|
335
|
-
def test_escapes_entities_by_default_when_configured_to_do_so
|
336
|
-
hash = {'key' => 'I <3 this'}
|
337
|
-
Oj.default_options = {:escape_mode => :xss_safe}
|
338
|
-
out = Oj.dump hash
|
339
|
-
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
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
|
-
|
349
|
-
def test_escapes_entities_when_asked_to
|
350
|
-
hash = {'key' => 'I <3 this'}
|
351
|
-
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
352
|
-
assert_equal(%{{"key":"I \\u003c3 this"}}, out)
|
353
|
-
end
|
354
|
-
|
355
|
-
def test_does_not_escape_entities_when_not_asked_to
|
356
|
-
hash = {'key' => 'I <3 this'}
|
357
|
-
out = Oj.dump(hash, :escape_mode => :json)
|
358
|
-
assert_equal(%{{"key":"I <3 this"}}, out)
|
359
|
-
end
|
360
|
-
|
361
|
-
def test_escapes_common_xss_vectors
|
362
|
-
hash = {'key' => '<script>alert(123) && formatHD()</script>'}
|
363
|
-
out = Oj.dump(hash, :escape_mode => :xss_safe)
|
364
|
-
assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
|
365
|
-
end
|
366
|
-
|
367
|
-
def test_escape_newline_by_default
|
368
|
-
Oj.default_options = { :escape_mode => :json }
|
369
|
-
json = %{["one","two\\n2"]}
|
370
|
-
x = Oj.load(json)
|
371
|
-
out = Oj.dump(x)
|
372
|
-
assert_equal(json, out)
|
373
|
-
end
|
374
|
-
|
375
|
-
def test_does_not_escape_newline
|
376
|
-
Oj.default_options = { :escape_mode => :newline }
|
377
|
-
json = %{["one","two\n2"]}
|
378
|
-
x = Oj.load(json)
|
379
|
-
out = Oj.dump(x)
|
380
|
-
assert_equal(json, out)
|
381
|
-
end
|
382
|
-
|
383
|
-
def test_dump_invalid_utf8
|
384
|
-
Oj.default_options = { :escape_mode => :ascii }
|
385
|
-
assert_raises(EncodingError) {
|
386
|
-
Oj.dump(["abc\xbe\x1f\x11"], mode: :strict)
|
387
|
-
}
|
388
|
-
end
|
389
|
-
|
390
|
-
# Symbol
|
391
|
-
def test_symbol_null
|
392
|
-
json = Oj.dump(:abc, :mode => :null)
|
393
|
-
assert_equal('"abc"', json)
|
394
|
-
end
|
395
|
-
|
396
|
-
# Time
|
397
|
-
def test_time_null
|
398
|
-
t = Time.local(2012, 1, 5, 23, 58, 7)
|
399
|
-
json = Oj.dump(t, :mode => :null)
|
400
|
-
assert_equal('null', json)
|
401
|
-
end
|
402
|
-
|
403
|
-
def test_time_neg
|
404
|
-
t = Time.parse('1900-01-01 00:18:59 UTC')
|
405
|
-
json = Oj.dump(t, :mode => :custom, :time_format => :unix)
|
406
|
-
assert_equal('-2208987661.000000000', json)
|
407
|
-
end
|
408
|
-
|
409
|
-
def test_time_years
|
410
|
-
(-2020..2020).each { |year|
|
411
|
-
s = '%04d-03-01T15:14:13Z' % [year]
|
412
|
-
json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
|
413
|
-
assert_equal(s, json[1..-2])
|
414
|
-
|
415
|
-
json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: 3)
|
416
|
-
assert_equal(s[0..-2] + '.000Z', json[1..-2])
|
417
|
-
}
|
418
|
-
end
|
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
|
-
|
425
|
-
# Class
|
426
|
-
def test_class_null
|
427
|
-
json = Oj.dump(Juice, :mode => :null)
|
428
|
-
assert_equal('null', json)
|
429
|
-
end
|
430
|
-
|
431
|
-
# Module
|
432
|
-
def test_module_null
|
433
|
-
json = Oj.dump(TestModule, :mode => :null)
|
434
|
-
assert_equal('null', json)
|
435
|
-
end
|
436
|
-
|
437
|
-
# Hash
|
438
|
-
def test_non_str_hash_null
|
439
|
-
begin
|
440
|
-
Oj.dump({ 1 => true, 0 => false }, :mode => :null)
|
441
|
-
rescue Exception
|
442
|
-
assert(true)
|
443
|
-
return
|
444
|
-
end
|
445
|
-
assert(false, '*** expected an exception')
|
446
|
-
end
|
447
|
-
|
448
|
-
def test_hash_not_closed
|
449
|
-
begin
|
450
|
-
Oj.load('{')
|
451
|
-
rescue Exception
|
452
|
-
assert(true)
|
453
|
-
return
|
454
|
-
end
|
455
|
-
assert(false, '*** expected an exception')
|
456
|
-
end
|
457
|
-
|
458
|
-
# Object with to_json()
|
459
|
-
def test_json_object_null
|
460
|
-
obj = Jeez.new(true, 58)
|
461
|
-
json = Oj.dump(obj, :mode => :null)
|
462
|
-
assert_equal('null', json)
|
463
|
-
end
|
464
|
-
|
465
|
-
# Object with to_hash()
|
466
|
-
def test_to_hash_object_null
|
467
|
-
obj = Jazz.new(true, 58)
|
468
|
-
json = Oj.dump(obj, :mode => :null)
|
469
|
-
assert_equal('null', json)
|
470
|
-
end
|
471
|
-
|
472
|
-
# Object with as_json() # contributed by sauliusg
|
473
|
-
def test_as_json_object_null
|
474
|
-
obj = Orange.new(true, 58)
|
475
|
-
json = Oj.dump(obj, :mode => :null)
|
476
|
-
assert_equal('null', json)
|
477
|
-
end
|
478
|
-
|
479
|
-
# Object without to_json() or to_hash()
|
480
|
-
def test_object_null
|
481
|
-
obj = Jam.new(true, 58)
|
482
|
-
json = Oj.dump(obj, :mode => :null)
|
483
|
-
assert_equal('null', json)
|
484
|
-
end
|
485
|
-
|
486
|
-
# Range
|
487
|
-
def test_range_null
|
488
|
-
json = Oj.dump(1..7, :mode => :null)
|
489
|
-
assert_equal('null', json)
|
490
|
-
end
|
491
|
-
|
492
|
-
# BigNum
|
493
|
-
def test_bignum_null
|
494
|
-
json = Oj.dump(7 ** 55, :mode => :null)
|
495
|
-
assert_equal('30226801971775055948247051683954096612865741943', json)
|
496
|
-
end
|
497
|
-
|
498
|
-
def test_bignum_object
|
499
|
-
dump_and_load(7 ** 55, false)
|
500
|
-
dump_and_load(10 ** 19, false)
|
501
|
-
end
|
502
|
-
|
503
|
-
# BigDecimal
|
504
|
-
def test_bigdecimal_null
|
505
|
-
mode = Oj.default_options[:mode]
|
506
|
-
Oj.default_options = {:mode => :null}
|
507
|
-
dump_and_load(BigDecimal('3.14159265358979323846'), false)
|
508
|
-
Oj.default_options = {:mode => mode}
|
509
|
-
end
|
510
|
-
|
511
|
-
def test_infinity
|
512
|
-
n = Oj.load('Infinity', :mode => :object)
|
513
|
-
assert_equal(BigDecimal('Infinity').to_f, n)
|
514
|
-
x = Oj.load('Infinity', :mode => :compat)
|
515
|
-
assert_equal('Infinity', x.to_s)
|
516
|
-
end
|
517
|
-
|
518
|
-
# Date
|
519
|
-
def test_date_null
|
520
|
-
json = Oj.dump(Date.new(2012, 6, 19), :mode => :null)
|
521
|
-
assert_equal('null', json)
|
522
|
-
end
|
523
|
-
|
524
|
-
# DateTime
|
525
|
-
def test_datetime_null
|
526
|
-
json = Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :null)
|
527
|
-
assert_equal('null', json)
|
528
|
-
end
|
529
|
-
|
530
|
-
# autodefine Oj::Bag
|
531
|
-
def test_bag
|
532
|
-
json = %{{
|
533
|
-
"^o":"Juice::Jem",
|
534
|
-
"x":true,
|
535
|
-
"y":58 }}
|
536
|
-
obj = Oj.load(json, :mode => :object, :auto_define => true)
|
537
|
-
assert_equal('Juice::Jem', obj.class.name)
|
538
|
-
assert(obj.x)
|
539
|
-
assert_equal(58, obj.y)
|
540
|
-
end
|
541
|
-
|
542
|
-
# Stream Deeply Nested
|
543
|
-
def test_deep_nest_dump
|
544
|
-
begin
|
545
|
-
a = []
|
546
|
-
10_000.times { a << [a] }
|
547
|
-
Oj.dump(a)
|
548
|
-
rescue Exception
|
549
|
-
assert(true)
|
550
|
-
return
|
551
|
-
end
|
552
|
-
assert(false, '*** expected an exception')
|
553
|
-
end
|
554
|
-
|
555
|
-
# Stream IO
|
556
|
-
def test_io_string
|
557
|
-
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
558
|
-
output = StringIO.open('', 'w+')
|
559
|
-
Oj.to_stream(output, src)
|
560
|
-
|
561
|
-
input = StringIO.new(output.string())
|
562
|
-
obj = Oj.load(input, :mode => :strict)
|
563
|
-
assert_equal(src, obj)
|
564
|
-
end
|
565
|
-
|
566
|
-
def test_io_file
|
567
|
-
src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
|
568
|
-
filename = File.join(__dir__, 'open_file_test.json')
|
569
|
-
File.open(filename, 'w') { |f|
|
570
|
-
Oj.to_stream(f, src)
|
571
|
-
}
|
572
|
-
f = File.new(filename)
|
573
|
-
obj = Oj.load(f, :mode => :strict)
|
574
|
-
f.close()
|
575
|
-
assert_equal(src, obj)
|
576
|
-
end
|
577
|
-
|
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
|
603
|
-
def test_comment_slash
|
604
|
-
json = %{{
|
605
|
-
"x":true,//three
|
606
|
-
"y":58,
|
607
|
-
"z": [1,2,
|
608
|
-
3 // six
|
609
|
-
]}
|
610
|
-
}
|
611
|
-
obj = Oj.load(json, :mode => :strict)
|
612
|
-
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
613
|
-
end
|
614
|
-
|
615
|
-
def test_comment_c
|
616
|
-
json = %{/*before*/
|
617
|
-
{
|
618
|
-
"x"/*one*/:/*two*/true,
|
619
|
-
"y":58,
|
620
|
-
"z": [1,2,3]}
|
621
|
-
}
|
622
|
-
obj = Oj.load(json, :mode => :strict)
|
623
|
-
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
624
|
-
end
|
625
|
-
|
626
|
-
def test_comment
|
627
|
-
json = %{{
|
628
|
-
"x"/*one*/:/*two*/true,//three
|
629
|
-
"y":58/*four*/,
|
630
|
-
"z": [1,2/*five*/,
|
631
|
-
3 // six
|
632
|
-
]
|
633
|
-
}
|
634
|
-
}
|
635
|
-
obj = Oj.load(json, :mode => :strict)
|
636
|
-
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
637
|
-
end
|
638
|
-
|
639
|
-
def test_nilnil_false
|
640
|
-
begin
|
641
|
-
Oj.load(nil, :nilnil => false)
|
642
|
-
rescue Exception
|
643
|
-
assert(true)
|
644
|
-
return
|
645
|
-
end
|
646
|
-
assert(false, '*** expected an exception')
|
647
|
-
end
|
648
|
-
|
649
|
-
def test_nilnil_true
|
650
|
-
obj = Oj.load(nil, :nilnil => true)
|
651
|
-
assert_nil(obj)
|
652
|
-
end
|
653
|
-
|
654
|
-
def test_empty_string_true
|
655
|
-
result = Oj.load(gen_whitespaced_string, :empty_string => true, mode: :strict)
|
656
|
-
assert_nil(result)
|
657
|
-
end
|
658
|
-
|
659
|
-
def test_empty_string_false
|
660
|
-
# Could be either a Oj::ParseError or an EncodingError depending on
|
661
|
-
# whether mimic_JSON has been called. Since we don't know when the test
|
662
|
-
# will be called either is okay.
|
663
|
-
begin
|
664
|
-
Oj.load(gen_whitespaced_string, :empty_string => false)
|
665
|
-
rescue Exception => e
|
666
|
-
assert(Oj::ParseError == e.class || EncodingError == e.class)
|
667
|
-
return
|
668
|
-
end
|
669
|
-
assert(false, '*** expected an exception')
|
670
|
-
end
|
671
|
-
|
672
|
-
def test_quirks_null_mode
|
673
|
-
assert_raises(Oj::ParseError) { Oj.load('null', :quirks_mode => false) }
|
674
|
-
assert_nil(Oj.load('null', :quirks_mode => true))
|
675
|
-
end
|
676
|
-
|
677
|
-
def test_quirks_bool_mode
|
678
|
-
assert_raises(Oj::ParseError) { Oj.load('true', :quirks_mode => false) }
|
679
|
-
assert(Oj.load('true', :quirks_mode => true))
|
680
|
-
end
|
681
|
-
|
682
|
-
def test_quirks_number_mode
|
683
|
-
assert_raises(Oj::ParseError) { Oj.load('123', :quirks_mode => false) }
|
684
|
-
assert_equal(123, Oj.load('123', :quirks_mode => true))
|
685
|
-
end
|
686
|
-
|
687
|
-
def test_quirks_decimal_mode
|
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))
|
690
|
-
end
|
691
|
-
|
692
|
-
def test_quirks_string_mode
|
693
|
-
assert_raises(Oj::ParseError) { Oj.load('"string"', :quirks_mode => false) }
|
694
|
-
assert_equal('string', Oj.load('"string"', :quirks_mode => true))
|
695
|
-
end
|
696
|
-
|
697
|
-
def test_error_path
|
698
|
-
msg = ''
|
699
|
-
assert_raises(Oj::ParseError) {
|
700
|
-
begin
|
701
|
-
Oj.load(%|{
|
702
|
-
"first": [
|
703
|
-
1, 2, { "third": 123x }
|
704
|
-
]
|
705
|
-
}|)
|
706
|
-
rescue Oj::ParseError => e
|
707
|
-
msg = e.message
|
708
|
-
raise e
|
709
|
-
end
|
710
|
-
}
|
711
|
-
assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
|
712
|
-
end
|
713
|
-
|
714
|
-
def test_bad_bignum
|
715
|
-
assert_raises Oj::ParseError do
|
716
|
-
Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
|
717
|
-
end
|
718
|
-
end
|
719
|
-
|
720
|
-
def test_quirks_array_mode
|
721
|
-
assert_empty(Oj.load('[]', :quirks_mode => false))
|
722
|
-
assert_empty(Oj.load('[]', :quirks_mode => true))
|
723
|
-
end
|
724
|
-
|
725
|
-
def test_quirks_object_mode
|
726
|
-
assert_empty(Oj.load('{}', :quirks_mode => false))
|
727
|
-
assert_empty(Oj.load('{}', :quirks_mode => true))
|
728
|
-
end
|
729
|
-
|
730
|
-
def test_omit_nil
|
731
|
-
jam = Jam.new({'a' => 1, 'b' => nil }, nil)
|
732
|
-
|
733
|
-
json = Oj.dump(jam, :omit_nil => true, :mode => :object)
|
734
|
-
assert_equal(%|{"^o":"Juice::Jam","x":{"a":1}}|, json)
|
735
|
-
|
736
|
-
json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :strict)
|
737
|
-
assert_equal(%|{"x":{"a":1}}|, json)
|
738
|
-
|
739
|
-
json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :null)
|
740
|
-
assert_equal(%|{"x":{"a":1}}|, json)
|
741
|
-
end
|
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
|
-
|
789
|
-
def dump_and_load(obj, trace=false)
|
790
|
-
json = Oj.dump(obj, :indent => 2)
|
791
|
-
puts json if trace
|
792
|
-
loaded = Oj.load(json)
|
793
|
-
if obj.nil?
|
794
|
-
assert_nil(loaded)
|
795
|
-
else
|
796
|
-
assert_equal(obj, loaded)
|
797
|
-
end
|
798
|
-
loaded
|
799
|
-
end
|
800
|
-
|
801
|
-
end
|