oj 2.18.5 → 3.0.0
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/README.md +33 -226
- data/ext/oj/circarray.c +0 -25
- data/ext/oj/circarray.h +0 -25
- data/ext/oj/code.c +227 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +126 -38
- data/ext/oj/custom.c +1097 -0
- data/ext/oj/dump.c +658 -2376
- data/ext/oj/dump.h +92 -0
- data/ext/oj/dump_compat.c +937 -0
- data/ext/oj/dump_leaf.c +254 -0
- data/ext/oj/dump_object.c +810 -0
- data/ext/oj/dump_rails.c +329 -0
- data/ext/oj/dump_strict.c +416 -0
- data/ext/oj/err.c +0 -25
- data/ext/oj/err.h +8 -2
- data/ext/oj/fast.c +24 -24
- data/ext/oj/mimic_json.c +817 -0
- data/ext/oj/mimic_rails.c +806 -0
- data/ext/oj/mimic_rails.h +17 -0
- data/ext/oj/object.c +18 -72
- data/ext/oj/odd.c +0 -25
- data/ext/oj/odd.h +2 -27
- data/ext/oj/oj.c +655 -1503
- data/ext/oj/oj.h +93 -40
- data/ext/oj/parse.c +99 -46
- data/ext/oj/parse.h +12 -26
- data/ext/oj/reader.c +1 -25
- data/ext/oj/reader.h +3 -25
- data/ext/oj/resolve.c +9 -11
- data/ext/oj/resolve.h +2 -2
- data/ext/oj/rxclass.c +133 -0
- data/ext/oj/rxclass.h +27 -0
- data/ext/oj/saj.c +4 -25
- data/ext/oj/scp.c +3 -25
- data/ext/oj/sparse.c +89 -13
- data/ext/oj/stream_writer.c +301 -0
- data/ext/oj/strict.c +4 -27
- data/ext/oj/string_writer.c +480 -0
- data/ext/oj/val_stack.h +6 -2
- data/lib/oj.rb +1 -23
- data/lib/oj/easy_hash.rb +12 -4
- data/lib/oj/json.rb +172 -0
- data/lib/oj/mimic.rb +123 -18
- data/lib/oj/state.rb +131 -0
- data/lib/oj/version.rb +1 -1
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/JsonGem.md +79 -0
- data/pages/Modes.md +140 -0
- data/pages/Options.md +250 -0
- data/pages/Rails.md +60 -0
- data/pages/Security.md +20 -0
- data/test/activesupport4/decoding_test.rb +105 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/decoding_test.rb +125 -0
- data/test/activesupport5/encoding_test.rb +483 -0
- data/test/activesupport5/encoding_test_cases.rb +90 -0
- data/test/activesupport5/test_helper.rb +50 -0
- data/test/activesupport5/time_zone_test_helpers.rb +24 -0
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +143 -0
- data/test/json_gem/json_encoding_test.rb +109 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +383 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +18 -0
- data/test/perf_compat.rb +30 -28
- data/test/perf_object.rb +1 -1
- data/test/perf_strict.rb +18 -1
- data/test/sample.rb +0 -1
- data/test/test_compat.rb +169 -93
- data/test/test_custom.rb +355 -0
- data/test/test_file.rb +0 -8
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +268 -3
- data/test/test_scp.rb +22 -1
- data/test/test_strict.rb +160 -4
- data/test/test_various.rb +52 -620
- data/test/tests.rb +14 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- metadata +89 -47
- data/test/activesupport_datetime_test.rb +0 -23
- data/test/bug.rb +0 -51
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/foo.rb +0 -24
- data/test/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/test/test_custom.rb
ADDED
@@ -0,0 +1,355 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
$oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
6
|
+
%w(lib ext).each do |dir|
|
7
|
+
$: << File.join($oj_dir, dir)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'minitest'
|
11
|
+
require 'minitest/autorun'
|
12
|
+
require 'stringio'
|
13
|
+
require 'date'
|
14
|
+
require 'bigdecimal'
|
15
|
+
require 'oj'
|
16
|
+
|
17
|
+
class CustomJuice < Minitest::Test
|
18
|
+
|
19
|
+
module TestModule
|
20
|
+
end
|
21
|
+
|
22
|
+
class Jeez
|
23
|
+
attr_accessor :x, :y
|
24
|
+
|
25
|
+
def initialize(x, y)
|
26
|
+
@x = x
|
27
|
+
@y = y
|
28
|
+
end
|
29
|
+
def ==(o)
|
30
|
+
self.class == o.class && @x == o.x && @y = o.y
|
31
|
+
end
|
32
|
+
def to_json(*args)
|
33
|
+
%|{"xx":#{@x},"yy":#{y}}|
|
34
|
+
end
|
35
|
+
def as_json(*args)
|
36
|
+
{'a' => @x, :b => @y }
|
37
|
+
end
|
38
|
+
def to_hash()
|
39
|
+
{'b' => @x, 'n' => @y }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup
|
44
|
+
@default_options = Oj.default_options
|
45
|
+
Oj.default_options = { :mode => :custom }
|
46
|
+
end
|
47
|
+
|
48
|
+
def teardown
|
49
|
+
Oj.default_options = @default_options
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_nil
|
53
|
+
dump_and_load(nil, false)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_true
|
57
|
+
dump_and_load(true, false)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_false
|
61
|
+
dump_and_load(false, false)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_fixnum
|
65
|
+
dump_and_load(0, false)
|
66
|
+
dump_and_load(12345, false)
|
67
|
+
dump_and_load(-54321, false)
|
68
|
+
dump_and_load(1, false)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_float
|
72
|
+
dump_and_load(0.0, false)
|
73
|
+
dump_and_load(12345.6789, false)
|
74
|
+
dump_and_load(70.35, false)
|
75
|
+
dump_and_load(-54321.012, false)
|
76
|
+
dump_and_load(1.7775, false)
|
77
|
+
dump_and_load(2.5024, false)
|
78
|
+
dump_and_load(2.48e16, false)
|
79
|
+
dump_and_load(2.48e100 * 1.0e10, false)
|
80
|
+
dump_and_load(-2.48e100 * 1.0e10, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_nan_dump
|
84
|
+
assert_equal('null', Oj.dump(0/0.0, :nan => :null))
|
85
|
+
assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :nan => :huge))
|
86
|
+
assert_equal('NaN', Oj.dump(0/0.0, :nan => :word))
|
87
|
+
begin
|
88
|
+
Oj.dump(0/0.0, :nan => :raise)
|
89
|
+
rescue Exception
|
90
|
+
assert(true)
|
91
|
+
return
|
92
|
+
end
|
93
|
+
assert(false, "*** expected an exception")
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_infinity_dump
|
97
|
+
assert_equal('null', Oj.dump(1/0.0, :nan => :null))
|
98
|
+
assert_equal('3.0e14159265358979323846', Oj.dump(1/0.0, :nan => :huge))
|
99
|
+
assert_equal('Infinity', Oj.dump(1/0.0, :nan => :word))
|
100
|
+
begin
|
101
|
+
Oj.dump(1/0.0, :nan => :raise)
|
102
|
+
rescue Exception
|
103
|
+
assert(true)
|
104
|
+
return
|
105
|
+
end
|
106
|
+
assert(false, "*** expected an exception")
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_neg_infinity_dump
|
110
|
+
assert_equal('null', Oj.dump(-1/0.0, :nan => :null))
|
111
|
+
assert_equal('-3.0e14159265358979323846', Oj.dump(-1/0.0, :nan => :huge))
|
112
|
+
assert_equal('-Infinity', Oj.dump(-1/0.0, :nan => :word))
|
113
|
+
begin
|
114
|
+
Oj.dump(-1/0.0, :nan => :raise)
|
115
|
+
rescue Exception
|
116
|
+
assert(true)
|
117
|
+
return
|
118
|
+
end
|
119
|
+
assert(false, "*** expected an exception")
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_string
|
123
|
+
dump_and_load('', false)
|
124
|
+
dump_and_load('abc', false)
|
125
|
+
dump_and_load("abc\ndef", false)
|
126
|
+
dump_and_load("a\u0041", false)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_string_ascii
|
130
|
+
json = Oj.dump("ぴーたー", :escape_mode => :ascii)
|
131
|
+
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
132
|
+
dump_and_load("ぴーたー", false, :escape_mode => :ascii)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_string_json
|
136
|
+
json = Oj.dump("ぴーたー", :escape_mode => :json)
|
137
|
+
assert_equal(%{"ぴーたー"}, json)
|
138
|
+
dump_and_load("ぴーたー", false, :escape_mode => :json)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_array
|
142
|
+
dump_and_load([], false)
|
143
|
+
dump_and_load([true, false], false)
|
144
|
+
dump_and_load(['a', 1, nil], false)
|
145
|
+
dump_and_load([[nil]], false)
|
146
|
+
dump_and_load([[nil], 58], false)
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_array_deep
|
150
|
+
dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_deep_nest
|
154
|
+
begin
|
155
|
+
n = 10000
|
156
|
+
Oj.strict_load('[' * n + ']' * n)
|
157
|
+
rescue Exception => e
|
158
|
+
assert(false, e.message)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_hash
|
163
|
+
dump_and_load({}, false)
|
164
|
+
dump_and_load({ 'true' => true, 'false' => false}, false)
|
165
|
+
dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_hash_deep
|
169
|
+
dump_and_load({'1' => {
|
170
|
+
'2' => {
|
171
|
+
'3' => {
|
172
|
+
'4' => {
|
173
|
+
'5' => {
|
174
|
+
'6' => {
|
175
|
+
'7' => {
|
176
|
+
'8' => {
|
177
|
+
'9' => {
|
178
|
+
'10' => {
|
179
|
+
'11' => {
|
180
|
+
'12' => {
|
181
|
+
'13' => {
|
182
|
+
'14' => {
|
183
|
+
'15' => {
|
184
|
+
'16' => {
|
185
|
+
'17' => {
|
186
|
+
'18' => {
|
187
|
+
'19' => {
|
188
|
+
'20' => {}}}}}}}}}}}}}}}}}}}}}, false)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_hash_escaped_key
|
192
|
+
json = %{{"a\nb":true,"c\td":false}}
|
193
|
+
obj = Oj.load(json)
|
194
|
+
assert_equal({"a\nb" => true, "c\td" => false}, obj)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_hash_non_string_key
|
198
|
+
assert_equal(%|{"1":true}|, Oj.dump({ 1 => true }, :indent => 0))
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_bignum_object
|
202
|
+
dump_and_load(7 ** 55, false)
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_bigdecimal
|
206
|
+
assert_equal('0.314159265358979323846e1', Oj.dump(BigDecimal.new('3.14159265358979323846'), :bigdecimal_load => true))
|
207
|
+
dump_and_load(BigDecimal.new('3.14159265358979323846'), false, :bigdecimal_load => true)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_object
|
211
|
+
obj = Jeez.new(true, 58)
|
212
|
+
json = Oj.dump(obj, :create_id => "^o", :use_to_json => false, :use_as_json => false, :use_to_hash => false)
|
213
|
+
#puts "*** #{json}"
|
214
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_object_to_json
|
218
|
+
obj = Jeez.new(true, 58)
|
219
|
+
json = Oj.dump(obj, :use_to_json => true, :use_as_json => false, :use_to_hash => false)
|
220
|
+
assert_equal(%|{"xx":true,"yy":58}|, json)
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_object_as_json
|
224
|
+
obj = Jeez.new(true, 58)
|
225
|
+
json = Oj.dump(obj, :use_to_json => false, :use_as_json => true, :use_to_hash => false)
|
226
|
+
assert_equal(%|{"a":true,"b":58}|, json)
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_object_to_hash
|
230
|
+
obj = Jeez.new(true, 58)
|
231
|
+
json = Oj.dump(obj, :use_to_json => false, :use_as_json => false, :use_to_hash => true)
|
232
|
+
assert_equal(%|{"b":true,"n":58}|, json)
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_symbol
|
236
|
+
json = Oj.dump(:abc)
|
237
|
+
assert_equal('"abc"', json)
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_class
|
241
|
+
assert_equal(%|"CustomJuice"|, Oj.dump(CustomJuice))
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_module
|
245
|
+
assert_equal(%|"CustomJuice::TestModule"|, Oj.dump(TestModule))
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_symbol_keys
|
249
|
+
json = %|{
|
250
|
+
"x":true,
|
251
|
+
"y":58,
|
252
|
+
"z": [1,2,3]
|
253
|
+
}
|
254
|
+
|
|
255
|
+
obj = Oj.load(json, :symbol_keys => true)
|
256
|
+
assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_double
|
260
|
+
json = %{{ "x": 1}{ "y": 2}}
|
261
|
+
results = []
|
262
|
+
Oj.load(json, :mode => :strict) { |x| results << x }
|
263
|
+
|
264
|
+
assert_equal([{ 'x' => 1 }, { 'y' => 2 }], results)
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_circular_hash
|
268
|
+
h = { 'a' => 7 }
|
269
|
+
h['b'] = h
|
270
|
+
json = Oj.dump(h, :indent => 2, :circular => true)
|
271
|
+
assert_equal(%|{
|
272
|
+
"a":7,
|
273
|
+
"b":null
|
274
|
+
}
|
275
|
+
|, json)
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_omit_nil
|
279
|
+
json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true)
|
280
|
+
assert_equal(%|{"x":{"a":1}}|, json)
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_complex
|
284
|
+
obj = Complex(2, 9)
|
285
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_rational
|
289
|
+
obj = Rational(2, 9)
|
290
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_range
|
294
|
+
obj = 3..8
|
295
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_date
|
299
|
+
obj = Date.new(2017, 1, 5)
|
300
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_datetime
|
304
|
+
obj = DateTime.new(2017, 1, 5, 10, 20, 30)
|
305
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_regexp
|
309
|
+
# this notation must be used to get an == match later
|
310
|
+
obj = /(?ix-m:^yes$)/
|
311
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_openstruct
|
315
|
+
obj = OpenStruct.new(:a => 1, 'b' => 2)
|
316
|
+
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_time
|
320
|
+
obj = Time.now()
|
321
|
+
dump_and_load(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
|
322
|
+
dump_and_load_inspect(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
|
323
|
+
dump_and_load_inspect(obj, false, :time_format => :xmlschema, :create_id => "^o", :create_additions => true)
|
324
|
+
dump_and_load_inspect(obj, false, :time_format => :ruby, :create_id => "^o", :create_additions => true)
|
325
|
+
end
|
326
|
+
|
327
|
+
def dump_and_load(obj, trace=false, options={})
|
328
|
+
options = options.merge(:indent => 2, :mode => :custom)
|
329
|
+
json = Oj.dump(obj, options)
|
330
|
+
puts json if trace
|
331
|
+
|
332
|
+
loaded = Oj.load(json, options);
|
333
|
+
if obj.nil?
|
334
|
+
assert_nil(loaded)
|
335
|
+
else
|
336
|
+
assert_equal(obj, loaded)
|
337
|
+
end
|
338
|
+
loaded
|
339
|
+
end
|
340
|
+
|
341
|
+
def dump_and_load_inspect(obj, trace=false, options={})
|
342
|
+
options = options.merge(:indent => 2, :mode => :custom)
|
343
|
+
json = Oj.dump(obj, options)
|
344
|
+
puts json if trace
|
345
|
+
|
346
|
+
loaded = Oj.load(json, options);
|
347
|
+
if obj.nil?
|
348
|
+
assert_nil(loaded)
|
349
|
+
else
|
350
|
+
assert_equal(obj.inspect, loaded.inspect)
|
351
|
+
end
|
352
|
+
loaded
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
data/test/test_file.rb
CHANGED
@@ -156,14 +156,6 @@ class FileJuice < Minitest::Test
|
|
156
156
|
Oj.default_options = { :mode => :compat, :use_to_json => false }
|
157
157
|
end
|
158
158
|
|
159
|
-
def test_as_json_object_compat_hash
|
160
|
-
Oj.default_options = { :mode => :compat, :use_as_json => true }
|
161
|
-
obj = Orange.new(true, 58)
|
162
|
-
json = Oj.dump(obj, :indent => 2)
|
163
|
-
assert(!json.nil?)
|
164
|
-
dump_and_load(obj, false)
|
165
|
-
end
|
166
|
-
|
167
159
|
# Range
|
168
160
|
def test_range_object
|
169
161
|
unless RUBY_VERSION.start_with?('1.8')
|
data/test/test_null.rb
ADDED
@@ -0,0 +1,376 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
$oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
6
|
+
%w(lib ext).each do |dir|
|
7
|
+
$: << File.join($oj_dir, dir)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'minitest'
|
11
|
+
require 'minitest/autorun'
|
12
|
+
require 'stringio'
|
13
|
+
require 'date'
|
14
|
+
require 'bigdecimal'
|
15
|
+
require 'oj'
|
16
|
+
|
17
|
+
class NullJuice < Minitest::Test
|
18
|
+
|
19
|
+
module TestModule
|
20
|
+
end
|
21
|
+
|
22
|
+
class Jeez
|
23
|
+
attr_accessor :x, :y
|
24
|
+
|
25
|
+
def initialize(x, y)
|
26
|
+
@x = x
|
27
|
+
@y = y
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@default_options = Oj.default_options
|
33
|
+
# in null mode other options other than the number formats are not used.
|
34
|
+
Oj.default_options = { :mode => :null }
|
35
|
+
end
|
36
|
+
|
37
|
+
def teardown
|
38
|
+
Oj.default_options = @default_options
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_nil
|
42
|
+
dump_and_load(nil, false)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_true
|
46
|
+
dump_and_load(true, false)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_false
|
50
|
+
dump_and_load(false, false)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_fixnum
|
54
|
+
dump_and_load(0, false)
|
55
|
+
dump_and_load(12345, false)
|
56
|
+
dump_and_load(-54321, false)
|
57
|
+
dump_and_load(1, false)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_float
|
61
|
+
dump_and_load(0.0, false)
|
62
|
+
dump_and_load(12345.6789, false)
|
63
|
+
dump_and_load(70.35, false)
|
64
|
+
dump_and_load(-54321.012, false)
|
65
|
+
dump_and_load(1.7775, false)
|
66
|
+
dump_and_load(2.5024, false)
|
67
|
+
dump_and_load(2.48e16, false)
|
68
|
+
dump_and_load(2.48e100 * 1.0e10, false)
|
69
|
+
dump_and_load(-2.48e100 * 1.0e10, false)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_nan_dump
|
73
|
+
assert_equal('null', Oj.dump(0/0.0, :nan => :null))
|
74
|
+
assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :nan => :huge))
|
75
|
+
begin
|
76
|
+
Oj.dump(0/0.0, :nan => :word)
|
77
|
+
rescue Exception
|
78
|
+
assert(true)
|
79
|
+
return
|
80
|
+
end
|
81
|
+
assert(false, "*** expected an exception")
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_infinity_dump
|
85
|
+
assert_equal('null', Oj.dump(1/0.0, :nan => :null))
|
86
|
+
assert_equal('3.0e14159265358979323846', Oj.dump(1/0.0, :nan => :huge))
|
87
|
+
begin
|
88
|
+
Oj.dump(1/0.0, :nan => :word)
|
89
|
+
rescue Exception
|
90
|
+
assert(true)
|
91
|
+
return
|
92
|
+
end
|
93
|
+
assert(false, "*** expected an exception")
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_neg_infinity_dump
|
97
|
+
assert_equal('null', Oj.dump(-1/0.0, :nan => :null))
|
98
|
+
assert_equal('-3.0e14159265358979323846', Oj.dump(-1/0.0, :nan => :huge))
|
99
|
+
begin
|
100
|
+
Oj.dump(-1/0.0, :nan => :word)
|
101
|
+
rescue Exception
|
102
|
+
assert(true)
|
103
|
+
return
|
104
|
+
end
|
105
|
+
assert(false, "*** expected an exception")
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_string
|
109
|
+
dump_and_load('', false)
|
110
|
+
dump_and_load('abc', false)
|
111
|
+
dump_and_load("abc\ndef", false)
|
112
|
+
dump_and_load("a\u0041", false)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_encode
|
116
|
+
opts = Oj.default_options
|
117
|
+
Oj.default_options = { :ascii_only => false }
|
118
|
+
unless 'jruby' == $ruby
|
119
|
+
dump_and_load("ぴーたー", false)
|
120
|
+
end
|
121
|
+
Oj.default_options = { :ascii_only => true }
|
122
|
+
json = Oj.dump("ぴーたー")
|
123
|
+
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
124
|
+
unless 'jruby' == $ruby
|
125
|
+
dump_and_load("ぴーたー", false)
|
126
|
+
end
|
127
|
+
Oj.default_options = opts
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_unicode
|
131
|
+
# hits the 3 normal ranges and one extended surrogate pair
|
132
|
+
json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
|
133
|
+
obj = Oj.load(json)
|
134
|
+
json2 = Oj.dump(obj, :ascii_only => true)
|
135
|
+
assert_equal(json, json2)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_unicode_long
|
139
|
+
# tests buffer overflow
|
140
|
+
json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e #{'x' * 2000}"}
|
141
|
+
obj = Oj.load(json)
|
142
|
+
json2 = Oj.dump(obj, :ascii_only => true)
|
143
|
+
assert_equal(json, json2)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_array
|
147
|
+
dump_and_load([], false)
|
148
|
+
dump_and_load([true, false], false)
|
149
|
+
dump_and_load(['a', 1, nil], false)
|
150
|
+
dump_and_load([[nil]], false)
|
151
|
+
dump_and_load([[nil], 58], false)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_array_deep
|
155
|
+
dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Hash
|
159
|
+
def test_hash
|
160
|
+
dump_and_load({}, false)
|
161
|
+
dump_and_load({ 'true' => true, 'false' => false}, false)
|
162
|
+
dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_hash_deep
|
166
|
+
dump_and_load({'1' => {
|
167
|
+
'2' => {
|
168
|
+
'3' => {
|
169
|
+
'4' => {
|
170
|
+
'5' => {
|
171
|
+
'6' => {
|
172
|
+
'7' => {
|
173
|
+
'8' => {
|
174
|
+
'9' => {
|
175
|
+
'10' => {
|
176
|
+
'11' => {
|
177
|
+
'12' => {
|
178
|
+
'13' => {
|
179
|
+
'14' => {
|
180
|
+
'15' => {
|
181
|
+
'16' => {
|
182
|
+
'17' => {
|
183
|
+
'18' => {
|
184
|
+
'19' => {
|
185
|
+
'20' => {}}}}}}}}}}}}}}}}}}}}}, false)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_hash_escaped_key
|
189
|
+
json = %{{"a\nb":true,"c\td":false}}
|
190
|
+
obj = Oj.strict_load(json)
|
191
|
+
assert_equal({"a\nb" => true, "c\td" => false}, obj)
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_non_str_hash
|
195
|
+
begin
|
196
|
+
Oj.dump({ 1 => true, 0 => false })
|
197
|
+
rescue Exception
|
198
|
+
assert(true)
|
199
|
+
return
|
200
|
+
end
|
201
|
+
assert(false, "*** expected an exception")
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_bignum_object
|
205
|
+
dump_and_load(7 ** 55, false)
|
206
|
+
end
|
207
|
+
|
208
|
+
# BigDecimal
|
209
|
+
def test_bigdecimal_strict
|
210
|
+
Oj.default_options = { :bigdecimal_load => true}
|
211
|
+
dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_bigdecimal_load
|
215
|
+
orig = BigDecimal.new('80.51')
|
216
|
+
json = Oj.dump(orig, :mode => :strict, :bigdecimal_as_decimal => true)
|
217
|
+
bg = Oj.load(json, :mode => :strict, :bigdecimal_load => true)
|
218
|
+
assert_equal(BigDecimal, bg.class)
|
219
|
+
assert_equal(orig, bg)
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_json_object
|
223
|
+
obj = Jeez.new(true, 58)
|
224
|
+
json = Oj.dump(obj)
|
225
|
+
assert_equal('null', json)
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_range
|
229
|
+
json = Oj.dump(1..7)
|
230
|
+
assert_equal('null', json)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Stream IO
|
234
|
+
def test_io_string
|
235
|
+
json = %{{
|
236
|
+
"x":true,
|
237
|
+
"y":58,
|
238
|
+
"z": [1,2,3]
|
239
|
+
}
|
240
|
+
}
|
241
|
+
input = StringIO.new(json)
|
242
|
+
obj = Oj.strict_load(input)
|
243
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_io_file
|
247
|
+
filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
|
248
|
+
File.open(filename, 'w') { |f| f.write(%{{
|
249
|
+
"x":true,
|
250
|
+
"y":58,
|
251
|
+
"z": [1,2,3]
|
252
|
+
}
|
253
|
+
}) }
|
254
|
+
f = File.new(filename)
|
255
|
+
obj = Oj.strict_load(f)
|
256
|
+
f.close()
|
257
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_symbol
|
261
|
+
json = Oj.dump(:abc)
|
262
|
+
assert_equal('"abc"', json)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_time
|
266
|
+
t = Time.local(2012, 1, 5, 23, 58, 7)
|
267
|
+
json = Oj.dump(t)
|
268
|
+
assert_equal('null', json)
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_class
|
272
|
+
json = Oj.dump(NullJuice)
|
273
|
+
assert_equal('null', json)
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_module
|
277
|
+
json = Oj.dump(TestModule)
|
278
|
+
assert_equal('null', json)
|
279
|
+
end
|
280
|
+
|
281
|
+
# symbol_keys option
|
282
|
+
def test_symbol_keys
|
283
|
+
json = %{{
|
284
|
+
"x":true,
|
285
|
+
"y":58,
|
286
|
+
"z": [1,2,3]
|
287
|
+
}
|
288
|
+
}
|
289
|
+
obj = Oj.strict_load(json, :symbol_keys => true)
|
290
|
+
assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_symbol_keys_safe
|
294
|
+
json = %{{
|
295
|
+
"x":true,
|
296
|
+
"y":58,
|
297
|
+
"z": [1,2,3]
|
298
|
+
}
|
299
|
+
}
|
300
|
+
obj = Oj.safe_load(json)
|
301
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
302
|
+
end
|
303
|
+
|
304
|
+
# comments
|
305
|
+
def test_comment_slash
|
306
|
+
json = %{{
|
307
|
+
"x":true,//three
|
308
|
+
"y":58,
|
309
|
+
"z": [1,2,
|
310
|
+
3 // six
|
311
|
+
]}
|
312
|
+
}
|
313
|
+
obj = Oj.strict_load(json)
|
314
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_comment_c
|
318
|
+
json = %{{
|
319
|
+
"x"/*one*/:/*two*/true,
|
320
|
+
"y":58,
|
321
|
+
"z": [1,2,3]}
|
322
|
+
}
|
323
|
+
obj = Oj.strict_load(json)
|
324
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_comment
|
328
|
+
json = %{{
|
329
|
+
"x"/*one*/:/*two*/true,//three
|
330
|
+
"y":58/*four*/,
|
331
|
+
"z": [1,2/*five*/,
|
332
|
+
3 // six
|
333
|
+
]
|
334
|
+
}
|
335
|
+
}
|
336
|
+
obj = Oj.strict_load(json)
|
337
|
+
assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_double
|
341
|
+
json = %{{ "x": 1}{ "y": 2}}
|
342
|
+
results = []
|
343
|
+
Oj.load(json, :mode => :strict) { |x| results << x }
|
344
|
+
|
345
|
+
assert_equal([{ 'x' => 1 }, { 'y' => 2 }], results)
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_circular_hash
|
349
|
+
h = { 'a' => 7 }
|
350
|
+
h['b'] = h
|
351
|
+
json = Oj.dump(h, :indent => 2, :circular => true, :mode => :null)
|
352
|
+
assert_equal(%|{
|
353
|
+
"a":7,
|
354
|
+
"b":null
|
355
|
+
}
|
356
|
+
|, json)
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_omit_nil
|
360
|
+
json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true)
|
361
|
+
assert_equal(%|{"x":{"a":1}}|, json)
|
362
|
+
end
|
363
|
+
|
364
|
+
def dump_and_load(obj, trace=false)
|
365
|
+
json = Oj.dump(obj, :indent => 2)
|
366
|
+
puts json if trace
|
367
|
+
loaded = Oj.strict_load(json);
|
368
|
+
if obj.nil?
|
369
|
+
assert_nil(loaded)
|
370
|
+
else
|
371
|
+
assert_equal(obj, loaded)
|
372
|
+
end
|
373
|
+
loaded
|
374
|
+
end
|
375
|
+
|
376
|
+
end
|