oj 2.18.5 → 3.16.11

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.
Files changed (166) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1452 -0
  3. data/README.md +53 -221
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +54 -72
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +61 -63
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +38 -67
  11. data/ext/oj/circarray.h +16 -42
  12. data/ext/oj/code.c +214 -0
  13. data/ext/oj/code.h +40 -0
  14. data/ext/oj/compat.c +194 -110
  15. data/ext/oj/custom.c +1074 -0
  16. data/ext/oj/debug.c +126 -0
  17. data/ext/oj/dump.c +1276 -2494
  18. data/ext/oj/dump.h +110 -0
  19. data/ext/oj/dump_compat.c +897 -0
  20. data/ext/oj/dump_leaf.c +162 -0
  21. data/ext/oj/dump_object.c +710 -0
  22. data/ext/oj/dump_strict.c +399 -0
  23. data/ext/oj/encode.h +7 -42
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +28 -53
  26. data/ext/oj/err.h +49 -46
  27. data/ext/oj/extconf.rb +33 -32
  28. data/ext/oj/fast.c +1082 -1098
  29. data/ext/oj/intern.c +313 -0
  30. data/ext/oj/intern.h +22 -0
  31. data/ext/oj/mem.c +318 -0
  32. data/ext/oj/mem.h +53 -0
  33. data/ext/oj/mimic_json.c +919 -0
  34. data/ext/oj/object.c +545 -625
  35. data/ext/oj/odd.c +158 -168
  36. data/ext/oj/odd.h +32 -58
  37. data/ext/oj/oj.c +1727 -2080
  38. data/ext/oj/oj.h +334 -259
  39. data/ext/oj/parse.c +974 -753
  40. data/ext/oj/parse.h +97 -90
  41. data/ext/oj/parser.c +1600 -0
  42. data/ext/oj/parser.h +103 -0
  43. data/ext/oj/rails.c +1478 -0
  44. data/ext/oj/rails.h +18 -0
  45. data/ext/oj/reader.c +136 -163
  46. data/ext/oj/reader.h +76 -112
  47. data/ext/oj/resolve.c +45 -94
  48. data/ext/oj/resolve.h +7 -34
  49. data/ext/oj/rxclass.c +144 -0
  50. data/ext/oj/rxclass.h +26 -0
  51. data/ext/oj/saj.c +445 -511
  52. data/ext/oj/saj2.c +584 -0
  53. data/ext/oj/saj2.h +23 -0
  54. data/ext/oj/scp.c +82 -143
  55. data/ext/oj/simd.h +10 -0
  56. data/ext/oj/sparse.c +749 -644
  57. data/ext/oj/stream_writer.c +329 -0
  58. data/ext/oj/strict.c +114 -112
  59. data/ext/oj/string_writer.c +517 -0
  60. data/ext/oj/trace.c +72 -0
  61. data/ext/oj/trace.h +55 -0
  62. data/ext/oj/usual.c +1218 -0
  63. data/ext/oj/usual.h +69 -0
  64. data/ext/oj/util.c +136 -0
  65. data/ext/oj/util.h +20 -0
  66. data/ext/oj/val_stack.c +75 -72
  67. data/ext/oj/val_stack.h +94 -127
  68. data/ext/oj/validate.c +46 -0
  69. data/ext/oj/wab.c +586 -0
  70. data/lib/oj/active_support_helper.rb +1 -3
  71. data/lib/oj/bag.rb +8 -1
  72. data/lib/oj/easy_hash.rb +21 -13
  73. data/lib/oj/error.rb +10 -12
  74. data/lib/oj/json.rb +188 -0
  75. data/lib/oj/mimic.rb +165 -26
  76. data/lib/oj/saj.rb +20 -6
  77. data/lib/oj/schandler.rb +5 -4
  78. data/lib/oj/state.rb +135 -0
  79. data/lib/oj/version.rb +2 -3
  80. data/lib/oj.rb +3 -31
  81. data/pages/Advanced.md +22 -0
  82. data/pages/Compatibility.md +25 -0
  83. data/pages/Custom.md +23 -0
  84. data/pages/Encoding.md +65 -0
  85. data/pages/InstallOptions.md +20 -0
  86. data/pages/JsonGem.md +94 -0
  87. data/pages/Modes.md +161 -0
  88. data/pages/Options.md +337 -0
  89. data/pages/Parser.md +309 -0
  90. data/pages/Rails.md +167 -0
  91. data/pages/Security.md +20 -0
  92. data/pages/WAB.md +13 -0
  93. metadata +126 -163
  94. data/ext/oj/hash.c +0 -163
  95. data/ext/oj/hash.h +0 -46
  96. data/ext/oj/hash_test.c +0 -512
  97. data/test/_test_active.rb +0 -76
  98. data/test/_test_active_mimic.rb +0 -96
  99. data/test/_test_mimic_rails.rb +0 -126
  100. data/test/activesupport_datetime_test.rb +0 -23
  101. data/test/bug.rb +0 -51
  102. data/test/bug2.rb +0 -10
  103. data/test/bug3.rb +0 -46
  104. data/test/bug_fast.rb +0 -32
  105. data/test/bug_load.rb +0 -24
  106. data/test/crash.rb +0 -111
  107. data/test/curl/curl_oj.rb +0 -46
  108. data/test/curl/get_oj.rb +0 -24
  109. data/test/curl/just_curl.rb +0 -31
  110. data/test/curl/just_oj.rb +0 -51
  111. data/test/example.rb +0 -11
  112. data/test/files.rb +0 -29
  113. data/test/foo.rb +0 -24
  114. data/test/helper.rb +0 -27
  115. data/test/io.rb +0 -48
  116. data/test/isolated/shared.rb +0 -310
  117. data/test/isolated/test_mimic_after.rb +0 -13
  118. data/test/isolated/test_mimic_alone.rb +0 -12
  119. data/test/isolated/test_mimic_as_json.rb +0 -45
  120. data/test/isolated/test_mimic_before.rb +0 -13
  121. data/test/isolated/test_mimic_define.rb +0 -28
  122. data/test/isolated/test_mimic_rails_after.rb +0 -22
  123. data/test/isolated/test_mimic_rails_before.rb +0 -21
  124. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  125. data/test/isolated/test_mimic_redefine.rb +0 -15
  126. data/test/mod.rb +0 -16
  127. data/test/perf.rb +0 -107
  128. data/test/perf_compat.rb +0 -128
  129. data/test/perf_fast.rb +0 -164
  130. data/test/perf_file.rb +0 -64
  131. data/test/perf_object.rb +0 -138
  132. data/test/perf_saj.rb +0 -109
  133. data/test/perf_scp.rb +0 -151
  134. data/test/perf_simple.rb +0 -287
  135. data/test/perf_strict.rb +0 -128
  136. data/test/rails.rb +0 -50
  137. data/test/russian.rb +0 -18
  138. data/test/sample/change.rb +0 -14
  139. data/test/sample/dir.rb +0 -19
  140. data/test/sample/doc.rb +0 -36
  141. data/test/sample/file.rb +0 -48
  142. data/test/sample/group.rb +0 -16
  143. data/test/sample/hasprops.rb +0 -16
  144. data/test/sample/layer.rb +0 -12
  145. data/test/sample/line.rb +0 -20
  146. data/test/sample/oval.rb +0 -10
  147. data/test/sample/rect.rb +0 -10
  148. data/test/sample/shape.rb +0 -35
  149. data/test/sample/text.rb +0 -20
  150. data/test/sample.rb +0 -55
  151. data/test/sample_json.rb +0 -37
  152. data/test/struct.rb +0 -29
  153. data/test/test_compat.rb +0 -398
  154. data/test/test_debian.rb +0 -53
  155. data/test/test_fast.rb +0 -458
  156. data/test/test_file.rb +0 -245
  157. data/test/test_gc.rb +0 -49
  158. data/test/test_hash.rb +0 -29
  159. data/test/test_object.rb +0 -745
  160. data/test/test_saj.rb +0 -186
  161. data/test/test_scp.rb +0 -396
  162. data/test/test_serializer.rb +0 -59
  163. data/test/test_strict.rb +0 -254
  164. data/test/test_various.rb +0 -1383
  165. data/test/test_writer.rb +0 -308
  166. data/test/write_timebars.rb +0 -31
data/test/test_various.rb DELETED
@@ -1,1383 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- $: << File.dirname(__FILE__)
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
- def initialize(x, y)
36
- super
37
- end
38
-
39
- def to_json()
40
- %{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
41
- end
42
-
43
- def self.json_create(h)
44
- self.new(h['x'], h['y'])
45
- end
46
- end# Jeez
47
-
48
- # contributed by sauliusg to fix as_json
49
- class Orange < Jam
50
- def initialize(x, y)
51
- super
52
- end
53
-
54
- def as_json()
55
- { :json_class => self.class,
56
- :x => @x,
57
- :y => @y }
58
- end
59
-
60
- def self.json_create(h)
61
- self.new(h['x'], h['y'])
62
- end
63
- end
64
-
65
- class Melon < Jam
66
- def initialize(x, y)
67
- super
68
- end
69
-
70
- def as_json(options)
71
- "#{x} #{y}"
72
- end
73
-
74
- def self.json_create(h)
75
- self.new(h['x'], h['y'])
76
- end
77
- end
78
-
79
- class Jazz < Jam
80
- def initialize(x, y)
81
- super
82
- end
83
- def to_hash()
84
- { 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
85
- end
86
- def self.json_create(h)
87
- self.new(h['x'], h['y'])
88
- end
89
- end# Jazz
90
-
91
- def setup
92
- @default_options = Oj.default_options
93
- end
94
-
95
- def teardown
96
- Oj.default_options = @default_options
97
- end
98
-
99
- =begin
100
- # Depending on the order the values may have changed. The set_options sets
101
- # should cover the function itself.
102
- def test_get_options
103
- opts = Oj.default_options()
104
- assert_equal({ :indent=>0,
105
- :second_precision=>9,
106
- :circular=>false,
107
- :class_cache=>true,
108
- :auto_define=>false,
109
- :symbol_keys=>false,
110
- :bigdecimal_as_decimal=>true,
111
- :use_to_json=>true,
112
- :nilnil=>false,
113
- :allow_gc=>true,
114
- :quirks_mode=>true,
115
- :allow_invalid_unicode=>false,
116
- :float_precision=>15,
117
- :mode=>:object,
118
- :escape_mode=>:json,
119
- :time_format=>:unix_zone,
120
- :bigdecimal_load=>:auto,
121
- :create_id=>'json_class'}, opts)
122
- end
123
- =end
124
- def test_set_options
125
- orig = Oj.default_options()
126
- alt ={
127
- :indent=>" - ",
128
- :second_precision=>5,
129
- :circular=>true,
130
- :class_cache=>false,
131
- :auto_define=>true,
132
- :symbol_keys=>true,
133
- :bigdecimal_as_decimal=>false,
134
- :use_to_json=>false,
135
- :use_as_json=>false,
136
- :nilnil=>true,
137
- :empty_string=>true,
138
- :allow_gc=>false,
139
- :quirks_mode=>false,
140
- :allow_invalid_unicode=>true,
141
- :float_precision=>13,
142
- :mode=>:strict,
143
- :escape_mode=>:ascii,
144
- :time_format=>:unix_zone,
145
- :bigdecimal_load=>:float,
146
- :create_id=>'classy',
147
- :space=>'z',
148
- :array_nl=>'a',
149
- :object_nl=>'o',
150
- :space_before=>'b',
151
- :nan=>:huge,
152
- :hash_class=>Hash,
153
- :omit_nil=>false,
154
- }
155
- Oj.default_options = alt
156
- opts = Oj.default_options()
157
- assert_equal(alt, opts);
158
-
159
- Oj.default_options = orig # return to original
160
- # verify back to original
161
- opts = Oj.default_options()
162
- assert_equal(orig, opts);
163
- end
164
-
165
- def test_nil
166
- dump_and_load(nil, false)
167
- end
168
-
169
- def test_true
170
- dump_and_load(true, false)
171
- end
172
-
173
- def test_false
174
- dump_and_load(false, false)
175
- end
176
-
177
- def test_fixnum
178
- dump_and_load(0, false)
179
- dump_and_load(12345, false)
180
- dump_and_load(-54321, false)
181
- dump_and_load(1, false)
182
- end
183
-
184
- def test_float_parse
185
- Oj.default_options = { :float_precision => 16, :bigdecimal_load => :auto }
186
- n = Oj.load('0.00001234567890123456')
187
- assert_equal(Float, n.class)
188
- assert_equal('1.234567890123456e-05', "%0.15e" % [n])
189
-
190
- n = Oj.load('-0.00001234567890123456')
191
- assert_equal(Float, n.class)
192
- assert_equal('-1.234567890123456e-05', "%0.15e" % [n])
193
-
194
- n = Oj.load('1000.0000123456789')
195
- assert_equal(BigDecimal, n.class)
196
- assert_equal('0.10000000123456789E4', n.to_s)
197
-
198
- n = Oj.load('-0.000012345678901234567')
199
- assert_equal(BigDecimal, n.class)
200
- assert_equal('-0.12345678901234567E-4', n.to_s)
201
-
202
- end
203
-
204
- def test_float_dump
205
- Oj.default_options = { :float_precision => 16 }
206
- assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
207
- Oj.default_options = { :float_precision => 5 }
208
- assert_equal('1.4055', Oj.dump(1.405460727))
209
- Oj.default_options = { :float_precision => 0 }
210
- if RUBY_VERSION.start_with?('1.8')
211
- assert_equal('1405460727.72387', Oj.dump(1405460727.723866))
212
- else
213
- assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
214
- end
215
- Oj.default_options = { :float_precision => 15 }
216
- assert_equal('0.56', Oj.dump(0.56))
217
- assert_equal('0.5773', Oj.dump(0.5773))
218
- assert_equal('0.6768', Oj.dump(0.6768))
219
- assert_equal('0.685', Oj.dump(0.685))
220
- assert_equal('0.7032', Oj.dump(0.7032))
221
- assert_equal('0.7051', Oj.dump(0.7051))
222
- assert_equal('0.8274', Oj.dump(0.8274))
223
- assert_equal('0.9149', Oj.dump(0.9149))
224
- assert_equal('64.4', Oj.dump(64.4))
225
- assert_equal('71.6', Oj.dump(71.6))
226
- assert_equal('73.4', Oj.dump(73.4))
227
- assert_equal('80.6', Oj.dump(80.6))
228
- assert_equal('-95.640172', Oj.dump(-95.640172))
229
- end
230
-
231
- def test_nan_dump
232
- assert_equal('null', Oj.dump(0/0.0, :mode => :strict, :nan => :null))
233
- assert_equal('NaN', Oj.dump(0/0.0, :mode => :strict, :nan => :word))
234
- assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :mode => :strict, :nan => :huge))
235
- end
236
-
237
- def test_infinity_dump
238
- assert_equal('null', Oj.dump(1/0.0, :mode => :strict, :nan => :null))
239
- assert_equal('Infinity', Oj.dump(1/0.0, :mode => :strict, :nan => :word))
240
- assert_equal('3.0e14159265358979323846', Oj.dump(1/0.0, :mode => :strict, :nan => :huge))
241
- end
242
-
243
- def test_neg_infinity_dump
244
- assert_equal('null', Oj.dump(-1/0.0, :mode => :strict, :nan => :null))
245
- assert_equal('-Infinity', Oj.dump(-1/0.0, :mode => :strict, :nan => :word))
246
- assert_equal('-3.0e14159265358979323846', Oj.dump(-1/0.0, :mode => :strict, :nan => :huge))
247
- end
248
-
249
- def test_float
250
- mode = Oj.default_options()[:mode]
251
- Oj.default_options = {:mode => :object}
252
- dump_and_load(0.0, false)
253
- dump_and_load(12345.6789, false)
254
- dump_and_load(70.35, false)
255
- dump_and_load(-54321.012, false)
256
- dump_and_load(1.7775, false)
257
- dump_and_load(2.5024, false)
258
- dump_and_load(2.48e16, false)
259
- dump_and_load(2.48e100 * 1.0e10, false)
260
- dump_and_load(-2.48e100 * 1.0e10, false)
261
- dump_and_load(1/0.0, false)
262
- # NaN does not always == NaN
263
- json = Oj.dump(0/0.0)
264
- assert_equal('3.3e14159265358979323846', json)
265
- loaded = Oj.load(json);
266
- assert_equal(true, loaded.nan?)
267
- Oj.default_options = {:mode => mode}
268
- end
269
-
270
- def test_string
271
- dump_and_load('', false)
272
- dump_and_load('abc', false)
273
- dump_and_load("abc\ndef", false)
274
- dump_and_load("a\u0041", false)
275
- assert_equal("a\u0000a", dump_and_load("a\u0000a", false))
276
- end
277
-
278
- def test_string_object
279
- Oj.default_options = {:mode => :object}
280
- dump_and_load('abc', false)
281
- dump_and_load(':abc', false)
282
- end
283
-
284
- def test_encode
285
- opts = Oj.default_options
286
- Oj.default_options = { :ascii_only => false }
287
- dump_and_load("ぴーたー", false)
288
-
289
- Oj.default_options = { :ascii_only => true }
290
- json = Oj.dump("ぴーたー")
291
- assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
292
- dump_and_load("ぴーたー", false)
293
- Oj.default_options = opts
294
- end
295
-
296
- def test_unicode
297
- # hits the 3 normal ranges and one extended surrogate pair
298
- json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
299
- obj = Oj.load(json)
300
- json2 = Oj.dump(obj, :ascii_only => true)
301
- assert_equal(json, json2)
302
- end
303
-
304
- def test_invalid_unicode_raise
305
- # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
306
- json = %{"x\\ud83dy"}
307
- begin
308
- Oj.load(json)
309
- rescue Exception
310
- assert(true)
311
- return
312
- end
313
- assert(false, "*** expected an exception")
314
- end
315
-
316
- def test_invalid_unicode_ok
317
- # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
318
- json = %{"x\\ud83dy"}
319
- obj = Oj.load(json, :allow_invalid_unicode => true)
320
- # The same as what ruby would do with the invalid encoding.
321
- assert_equal("x\xED\xA0\xBDy", obj.to_s)
322
- end
323
-
324
- def test_dump_options
325
- json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
326
- :mode => :compat,
327
- :indent => "--",
328
- :array_nl => "\n",
329
- :object_nl => "#\n",
330
- :space => "*",
331
- :space_before => "~")
332
- assert(%{{#
333
- --"a"~:*1,#
334
- --"b"~:*[
335
- ----true,
336
- ----false
337
- --]#
338
- }} == json ||
339
- %{{#
340
- --"b"~:*[
341
- ----true,
342
- ----false
343
- --],#
344
- --"a"~:*1#
345
- }} == json)
346
-
347
- end
348
-
349
- def test_null_char
350
- assert_raises(Oj::ParseError) { Oj.load("\"\0\"") }
351
- assert_raises(Oj::ParseError) { Oj.load("\"\\\0\"") }
352
- end
353
-
354
- def test_array
355
- dump_and_load([], false)
356
- dump_and_load([true, false], false)
357
- dump_and_load(['a', 1, nil], false)
358
- dump_and_load([[nil]], false)
359
- dump_and_load([[nil], 58], false)
360
- end
361
- def test_array_not_closed
362
- begin
363
- Oj.load('[')
364
- rescue Exception
365
- assert(true)
366
- return
367
- end
368
- assert(false, "*** expected an exception")
369
- end
370
-
371
- # multiple JSON in one string
372
- def test_multiple_json_callback
373
- json = %{{"a":1}
374
- [1,2][3,4]
375
- {"b":2}
376
- }
377
- results = []
378
- Oj.load(json) { |x| results << x }
379
- assert_equal([{"a"=>1}, [1,2], [3,4], {"b"=>2}], results)
380
- end
381
-
382
- def test_multiple_json_no_callback
383
- json = %{{"a":1}
384
- [1,2][3,4]
385
- {"b":2}
386
- }
387
- assert_raises(Oj::ParseError) { Oj.load(json) }
388
- end
389
-
390
- # encoding tests
391
- def test_does_not_escape_entities_by_default
392
- Oj.default_options = { :escape_mode => :ascii } # set in mimic mode
393
- # use Oj to create the hash since some Rubies don't deal nicely with unicode.
394
- json = %{{"key":"I <3 this\\u2028space"}}
395
- hash = Oj.load(json)
396
- out = Oj.dump(hash)
397
- assert_equal(json, out)
398
- end
399
- def test_escapes_entities_by_default_when_configured_to_do_so
400
- hash = {'key' => "I <3 this"}
401
- Oj.default_options = {:escape_mode => :xss_safe}
402
- out = Oj.dump hash
403
- assert_equal(%{{"key":"I \\u003c3 this"}}, out)
404
- end
405
- def test_escapes_entities_when_asked_to
406
- hash = {'key' => "I <3 this"}
407
- out = Oj.dump(hash, :escape_mode => :xss_safe)
408
- assert_equal(%{{"key":"I \\u003c3 this"}}, out)
409
- end
410
- def test_does_not_escape_entities_when_not_asked_to
411
- hash = {'key' => "I <3 this"}
412
- out = Oj.dump(hash, :escape_mode => :json)
413
- assert_equal(%{{"key":"I <3 this"}}, out)
414
- end
415
- def test_escapes_common_xss_vectors
416
- hash = {'key' => "<script>alert(123) && formatHD()</script>"}
417
- out = Oj.dump(hash, :escape_mode => :xss_safe)
418
- assert_equal(%{{"key":"\\u003cscript\\u003ealert(123) \\u0026\\u0026 formatHD()\\u003c\\/script\\u003e"}}, out)
419
- end
420
- def test_escape_newline_by_default
421
- Oj.default_options = { :escape_mode => :json }
422
- json = %{["one","two\\n2"]}
423
- x = Oj.load(json)
424
- out = Oj.dump(x)
425
- assert_equal(json, out)
426
- end
427
- def test_does_not_escape_newline
428
- Oj.default_options = { :escape_mode => :newline }
429
- json = %{["one","two\n2"]}
430
- x = Oj.load(json)
431
- out = Oj.dump(x)
432
- assert_equal(json, out)
433
- end
434
-
435
- # Symbol
436
- def test_symbol_strict
437
- begin
438
- Oj.dump(:abc, :mode => :strict)
439
- rescue Exception
440
- assert(true)
441
- return
442
- end
443
- assert(false, "*** expected an exception")
444
- end
445
- def test_symbol_null
446
- json = Oj.dump(:abc, :mode => :null)
447
- assert_equal('null', json)
448
- end
449
- def test_symbol_compat
450
- json = Oj.dump(:abc, :mode => :compat)
451
- assert_equal('"abc"', json)
452
- end
453
- def test_symbol_object
454
- Oj.default_options = { :mode => :object }
455
- #dump_and_load(''.to_sym, false)
456
- dump_and_load(:abc, false)
457
- dump_and_load(':xyz'.to_sym, false)
458
- end
459
-
460
- # Time
461
- def test_time_strict
462
- t = Time.local(2012, 1, 5, 23, 58, 7)
463
- begin
464
- Oj.dump(t, :mode => :strict)
465
- rescue Exception
466
- assert(true)
467
- return
468
- end
469
- assert(false, "*** expected an exception")
470
- end
471
- def test_time_null
472
- t = Time.local(2012, 1, 5, 23, 58, 7)
473
- json = Oj.dump(t, :mode => :null)
474
- assert_equal('null', json)
475
- end
476
- def test_unix_time_compat
477
- t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
478
- #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
479
- json = Oj.dump(t, :mode => :compat, :time_format => :unix)
480
- assert_equal(%{1325775487.123456000}, json)
481
- end
482
- def test_unix_time_compat_precision
483
- t = Time.xmlschema("2012-01-05T23:58:07.123456789+09:00")
484
- #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
485
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
486
- assert_equal(%{1325775487.12346}, json)
487
- t = Time.xmlschema("2012-01-05T23:58:07.999600+09:00")
488
- json = Oj.dump(t, :mode => :compat, :second_precision => 3, :time_format => :unix)
489
- assert_equal(%{1325775488.000}, json)
490
- end
491
- def test_unix_time_compat_early
492
- t = Time.xmlschema("1954-01-05T00:00:00.123456789+00:00")
493
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
494
- assert_equal(%{-504575999.87654}, json)
495
- end
496
- def test_unix_time_compat_1970
497
- t = Time.xmlschema("1970-01-01T00:00:00.123456789+00:00")
498
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
499
- assert_equal(%{0.12346}, json)
500
- end
501
- def test_ruby_time_compat
502
- t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
503
- json = Oj.dump(t, :mode => :compat, :time_format => :ruby)
504
- #assert_equal(%{"2012-01-05 23:58:07 +0900"}, json)
505
- assert_equal(%{"#{t.to_s}"}, json)
506
- end
507
- def test_xml_time_compat
508
- begin
509
- t = Time.new(2012, 1, 5, 23, 58, 7.123456000, 34200)
510
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
511
- assert_equal(%{"2012-01-05T23:58:07.123456000+09:30"}, json)
512
- rescue Exception
513
- # some Rubies (1.8.7) do not allow the timezome to be set
514
- t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
515
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
516
- tz = t.utc_offset
517
- # Ruby does not handle a %+02d properly so...
518
- sign = '+'
519
- if 0 > tz
520
- sign = '-'
521
- tz = -tz
522
- end
523
- assert_equal(%{"2012-01-05T23:58:07.123456000%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
524
- end
525
- end
526
- def test_xml_time_compat_no_secs
527
- begin
528
- t = Time.new(2012, 1, 5, 23, 58, 7.0, 34200)
529
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
530
- assert_equal(%{"2012-01-05T23:58:07+09:30"}, json)
531
- rescue Exception
532
- # some Rubies (1.8.7) do not allow the timezome to be set
533
- t = Time.local(2012, 1, 5, 23, 58, 7, 0)
534
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
535
- tz = t.utc_offset
536
- # Ruby does not handle a %+02d properly so...
537
- sign = '+'
538
- if 0 > tz
539
- sign = '-'
540
- tz = -tz
541
- end
542
- assert_equal(%{"2012-01-05T23:58:07%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
543
- end
544
- end
545
- def test_xml_time_compat_precision
546
- begin
547
- t = Time.new(2012, 1, 5, 23, 58, 7.123456789, 32400)
548
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 5)
549
- assert_equal(%{"2012-01-05T23:58:07.12346+09:00"}, json)
550
- rescue Exception
551
- # some Rubies (1.8.7) do not allow the timezome to be set
552
- t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
553
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 5)
554
- tz = t.utc_offset
555
- # Ruby does not handle a %+02d properly so...
556
- sign = '+'
557
- if 0 > tz
558
- sign = '-'
559
- tz = -tz
560
- end
561
- assert_equal(%{"2012-01-05T23:58:07.12346%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
562
- end
563
- end
564
- def test_xml_time_compat_precision_round
565
- begin
566
- t = Time.new(2012, 1, 5, 23, 58, 7.9996, 32400)
567
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 3)
568
- assert_equal(%{"2012-01-05T23:58:08+09:00"}, json)
569
- rescue Exception
570
- # some Rubies (1.8.7) do not allow the timezome to be set
571
- t = Time.local(2012, 1, 5, 23, 58, 7, 999600)
572
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 3)
573
- tz = t.utc_offset
574
- # Ruby does not handle a %+02d properly so...
575
- sign = '+'
576
- if 0 > tz
577
- sign = '-'
578
- tz = -tz
579
- end
580
- assert_equal(%{"2012-01-05T23:58:08%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
581
- end
582
- end
583
- def test_xml_time_compat_zulu
584
- begin
585
- t = Time.new(2012, 1, 5, 23, 58, 7.0, 0)
586
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
587
- assert_equal(%{"2012-01-05T23:58:07Z"}, json)
588
- rescue Exception
589
- # some Rubies (1.8.7) do not allow the timezome to be set
590
- t = Time.utc(2012, 1, 5, 23, 58, 7, 0)
591
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
592
- #tz = t.utc_offset
593
- assert_equal(%{"2012-01-05T23:58:07Z"}, json)
594
- end
595
- end
596
-
597
- # Class
598
- def test_class_strict
599
- begin
600
- Oj.dump(Juice, :mode => :strict)
601
- rescue Exception
602
- assert(true)
603
- return
604
- end
605
- assert(false, "*** expected an exception")
606
- end
607
- def test_class_null
608
- json = Oj.dump(Juice, :mode => :null)
609
- assert_equal('null', json)
610
- end
611
- def test_class_compat
612
- json = Oj.dump(Juice, :mode => :compat)
613
- assert_equal(%{"Juice"}, json)
614
- end
615
- def test_class_object
616
- Oj.default_options = { :mode => :object }
617
- dump_and_load(Juice, false)
618
- end
619
-
620
- # Module
621
- def test_module_strict
622
- begin
623
- Oj.dump(TestModule, :mode => :strict)
624
- rescue Exception
625
- assert(true)
626
- return
627
- end
628
- assert(false, "*** expected an exception")
629
- end
630
- def test_module_null
631
- json = Oj.dump(TestModule, :mode => :null)
632
- assert_equal('null', json)
633
- end
634
- def test_module_compat
635
- json = Oj.dump(TestModule, :mode => :compat)
636
- assert_equal(%{"Juice::TestModule"}, json)
637
- end
638
- def test_module_object
639
- Oj.default_options = { :mode => :object }
640
- dump_and_load(TestModule, false)
641
- end
642
-
643
- # Hash
644
- def test_hash
645
- Oj.default_options = { :mode => :strict }
646
- dump_and_load({}, false)
647
- dump_and_load({ 'true' => true, 'false' => false}, false)
648
- dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
649
- end
650
- def test_non_str_hash_strict
651
- begin
652
- Oj.dump({ 1 => true, 0 => false }, :mode => :strict)
653
- rescue Exception
654
- assert(true)
655
- return
656
- end
657
- assert(false, "*** expected an exception")
658
- end
659
- def test_non_str_hash_null
660
- begin
661
- Oj.dump({ 1 => true, 0 => false }, :mode => :null)
662
- rescue Exception
663
- assert(true)
664
- return
665
- end
666
- assert(false, "*** expected an exception")
667
- end
668
- def test_non_str_hash_compat
669
- json = Oj.dump({ 1 => true, 0 => false }, :mode => :compat)
670
- h = Oj.load(json, :mode => :strict)
671
- assert_equal({ "1" => true, "0" => false }, h)
672
- end
673
- def test_non_str_hash_object
674
- Oj.default_options = { :mode => :object }
675
- json = Oj.dump({ 1 => true, :sim => nil })
676
- h = Oj.load(json, :mode => :strict)
677
- assert_equal({"^#1" => [1, true], ":sim" => nil}, h)
678
- h = Oj.load(json)
679
- assert_equal({ 1 => true, :sim => nil }, h)
680
- end
681
- def test_mixed_hash_object
682
- Oj.default_options = { :mode => :object }
683
- json = Oj.dump({ 1 => true, 'nil' => nil, :sim => 4 })
684
- h = Oj.load(json, :mode => :strict)
685
- assert_equal({"^#1" => [1, true], "nil" => nil, ":sim" => 4}, h)
686
- h = Oj.load(json)
687
- assert_equal({ 1 => true, 'nil' => nil, :sim => 4 }, h)
688
- end
689
- def test_hash_not_closed
690
- begin
691
- Oj.load('{')
692
- rescue Exception
693
- assert(true)
694
- return
695
- end
696
- assert(false, "*** expected an exception")
697
- end
698
-
699
- # Object with to_json()
700
- def test_json_object_strict
701
- obj = Jeez.new(true, 58)
702
- begin
703
- Oj.dump(obj, :mode => :strict)
704
- rescue Exception
705
- assert(true)
706
- return
707
- end
708
- assert(false, "*** expected an exception")
709
- end
710
- def test_json_object_null
711
- obj = Jeez.new(true, 58)
712
- json = Oj.dump(obj, :mode => :null)
713
- assert_equal('null', json)
714
- end
715
- def test_json_object_compat
716
- Oj.default_options = { :mode => :compat, :use_to_json => true }
717
- obj = Jeez.new(true, 58)
718
- json = Oj.dump(obj, :indent => 2)
719
- assert(%{{"json_class":"Juice::Jeez","x":true,"y":58}
720
- } == json ||
721
- %{{"json_class":"Juice::Jeez","y":58,"x":true}
722
- } == json)
723
- dump_and_load(obj, false)
724
- Oj.default_options = { :mode => :compat, :use_to_json => false }
725
- end
726
- def test_json_object_create_id
727
- Oj.default_options = { :mode => :compat, :create_id => 'kson_class' }
728
- expected = Jeez.new(true, 58)
729
- json = %{{"kson_class":"Juice::Jeez","x":true,"y":58}}
730
- obj = Oj.load(json)
731
- assert_equal(expected, obj)
732
- Oj.default_options = { :create_id => 'json_class' }
733
- end
734
- def test_json_object_object
735
- obj = Jeez.new(true, 58)
736
- json = Oj.dump(obj, :mode => :object, :indent => 2)
737
- assert(%{{
738
- "^o":"Juice::Jeez",
739
- "x":true,
740
- "y":58
741
- }
742
- } == json ||
743
- %{{
744
- "^o":"Juice::Jeez",
745
- "y":58,
746
- "x":true
747
- }
748
- } == json)
749
- obj2 = Oj.load(json, :mode => :object)
750
- assert_equal(obj, obj2)
751
- end
752
-
753
- # Object with to_hash()
754
- def test_to_hash_object_strict
755
- obj = Jazz.new(true, 58)
756
- begin
757
- Oj.dump(obj, :mode => :strict)
758
- rescue Exception
759
- assert(true)
760
- return
761
- end
762
- assert(false, "*** expected an exception")
763
- end
764
- def test_to_hash_object_null
765
- obj = Jazz.new(true, 58)
766
- json = Oj.dump(obj, :mode => :null)
767
- assert_equal('null', json)
768
- end
769
- def test_to_hash_object_compat
770
- Oj.default_options = { :use_to_json => true }
771
- obj = Jazz.new(true, 58)
772
- json = Oj.dump(obj, :mode => :compat, :indent => 2)
773
- h = Oj.load(json, :mode => :strict)
774
- assert_equal(obj.to_hash, h)
775
- end
776
- def test_to_hash_object_object
777
- obj = Jazz.new(true, 58)
778
- json = Oj.dump(obj, :mode => :object, :indent => 2)
779
- assert(%{{
780
- "^o":"Juice::Jazz",
781
- "x":true,
782
- "y":58
783
- }
784
- } == json ||
785
- %{{
786
- "^o":"Juice::Jazz",
787
- "y":58,
788
- "x":true
789
- }
790
- } == json)
791
- obj2 = Oj.load(json, :mode => :object)
792
- assert_equal(obj, obj2)
793
- end
794
-
795
- # Object with as_json() # contributed by sauliusg
796
- def test_as_json_object_strict
797
- obj = Orange.new(true, 58)
798
- begin
799
- Oj.dump(obj, :mode => :strict)
800
- rescue Exception
801
- assert(true)
802
- return
803
- end
804
- assert(false, "*** expected an exception")
805
- end
806
-
807
- def test_as_json_object_null
808
- obj = Orange.new(true, 58)
809
- json = Oj.dump(obj, :mode => :null)
810
- assert_equal('null', json)
811
- end
812
-
813
- def test_as_json_object_compat_hash
814
- Oj.default_options = { :mode => :compat, :use_as_json => true }
815
- obj = Orange.new(true, 58)
816
- json = Oj.dump(obj, :indent => 2)
817
- assert(!json.nil?)
818
- dump_and_load(obj, false)
819
- end
820
-
821
- def test_as_json_object_compat_non_hash
822
- Oj.default_options = { :mode => :compat, :use_as_json => true }
823
- obj = Melon.new(true, 58)
824
- json = Oj.dump(obj, :indent => 2)
825
- assert_equal(%{"true 58"}, json)
826
- end
827
-
828
- def test_as_json_object_object
829
- obj = Orange.new(true, 58)
830
- json = Oj.dump(obj, :mode => :object, :indent => 2)
831
- assert(%{{
832
- "^o":"Juice::Orange",
833
- "x":true,
834
- "y":58
835
- }
836
- } == json ||
837
- %{{
838
- "^o":"Juice::Orange",
839
- "y":58,
840
- "x":true
841
- }
842
- } == json)
843
- obj2 = Oj.load(json, :mode => :object)
844
- assert_equal(obj, obj2)
845
- end
846
-
847
- # Object without to_json() or to_hash()
848
- def test_object_strict
849
- obj = Jam.new(true, 58)
850
- begin
851
- Oj.dump(obj, :mode => :strict)
852
- rescue Exception
853
- assert(true)
854
- return
855
- end
856
- assert(false, "*** expected an exception")
857
- end
858
- def test_object_null
859
- obj = Jam.new(true, 58)
860
- json = Oj.dump(obj, :mode => :null)
861
- assert_equal('null', json)
862
- end
863
- def test_object_compat
864
- obj = Jam.new(true, 58)
865
- json = Oj.dump(obj, :mode => :compat, :indent => 2)
866
- assert(%{{
867
- "x":true,
868
- "y":58
869
- }
870
- } == json ||
871
- %{{
872
- "y":58,
873
- "x":true
874
- }
875
- } == json)
876
- end
877
- def test_object_object
878
- obj = Jam.new(true, 58)
879
- json = Oj.dump(obj, :mode => :object, :indent => 2)
880
- assert(%{{
881
- "^o":"Juice::Jam",
882
- "x":true,
883
- "y":58
884
- }
885
- } == json ||
886
- %{{
887
- "^o":"Juice::Jam",
888
- "y":58,
889
- "x":true
890
- }
891
- } == json)
892
- obj2 = Oj.load(json, :mode => :object)
893
- assert_equal(obj, obj2)
894
- end
895
-
896
- def test_object_object_no_cache
897
- obj = Jam.new(true, 58)
898
- json = Oj.dump(obj, :mode => :object, :indent => 2)
899
- assert(%{{
900
- "^o":"Juice::Jam",
901
- "x":true,
902
- "y":58
903
- }
904
- } == json ||
905
- %{{
906
- "^o":"Juice::Jam",
907
- "y":58,
908
- "x":true
909
- }
910
- } == json)
911
- obj2 = Oj.load(json, :mode => :object, :class_cache => false)
912
- assert_equal(obj, obj2)
913
- end
914
-
915
- # Exception
916
- def test_exception
917
- err = nil
918
- begin
919
- raise StandardError.new('A Message')
920
- rescue Exception => e
921
- err = e
922
- end
923
- json = Oj.dump(err, :mode => :object, :indent => 2)
924
- #puts "*** #{json}"
925
- e2 = Oj.load(json, :mode => :strict)
926
- assert_equal(err.class.to_s, e2['^o'])
927
- assert_equal(err.message, e2['~mesg'])
928
- assert_equal(err.backtrace, e2['~bt'])
929
- e2 = Oj.load(json, :mode => :object)
930
- if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby
931
- assert_equal(e.class, e2.class);
932
- assert_equal(e.message, e2.message);
933
- assert_equal(e.backtrace, e2.backtrace);
934
- else
935
- assert_equal(e, e2);
936
- end
937
- end
938
-
939
- # Range
940
- def test_range_strict
941
- begin
942
- Oj.dump(1..7, :mode => :strict)
943
- rescue Exception
944
- assert(true)
945
- return
946
- end
947
- assert(false, "*** expected an exception")
948
- end
949
- def test_range_null
950
- json = Oj.dump(1..7, :mode => :null)
951
- assert_equal('null', json)
952
- end
953
- def test_range_compat
954
- Oj.default_options = { :use_to_json => true }
955
- json = Oj.dump(1..7, :mode => :compat)
956
- h = Oj.load(json, :mode => :strict)
957
- assert_equal({'begin' => 1, 'end' => 7, 'exclude_end' => false}, h)
958
- json = Oj.dump(1...7, :mode => :compat)
959
- h = Oj.load(json, :mode => :strict)
960
- assert_equal({'begin' => 1, 'end' => 7, 'exclude_end' => true}, h)
961
- end
962
- def test_range_object
963
- unless RUBY_VERSION.start_with?('1.8')
964
- Oj.default_options = { :mode => :object }
965
- json = Oj.dump(1..7, :mode => :object, :indent => 0)
966
- if 'rubinius' == $ruby
967
- assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
968
- else
969
- assert_equal(%{{"^u":["Range",1,7,false]}}, json)
970
- end
971
- dump_and_load(1..7, false)
972
- dump_and_load(1..1, false)
973
- dump_and_load(1...7, false)
974
- end
975
- end
976
-
977
- # BigNum
978
- def test_bignum_strict
979
- json = Oj.dump(7 ** 55, :mode => :strict)
980
- assert_equal('30226801971775055948247051683954096612865741943', json)
981
- end
982
- def test_bignum_null
983
- json = Oj.dump(7 ** 55, :mode => :null)
984
- assert_equal('30226801971775055948247051683954096612865741943', json)
985
- end
986
- def test_bignum_compat
987
- json = Oj.dump(7 ** 55, :mode => :compat)
988
- b = Oj.load(json, :mode => :strict)
989
- assert_equal(30226801971775055948247051683954096612865741943, b)
990
- end
991
-
992
- def test_bignum_object
993
- dump_and_load(7 ** 55, false)
994
- dump_and_load(10 ** 19, false)
995
- end
996
-
997
- # BigDecimal
998
- def test_bigdecimal_strict
999
- mode = Oj.default_options[:mode]
1000
- Oj.default_options = {:mode => :strict}
1001
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
1002
- Oj.default_options = {:mode => mode}
1003
- end
1004
- def test_bigdecimal_null
1005
- mode = Oj.default_options[:mode]
1006
- Oj.default_options = {:mode => :null}
1007
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
1008
- Oj.default_options = {:mode => mode}
1009
- end
1010
- def test_bigdecimal_compat
1011
- orig = BigDecimal.new('80.51')
1012
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1013
- bg = Oj.load(json, :mode => :compat)
1014
- assert_equal(orig.to_s, bg)
1015
- orig = BigDecimal.new('3.14159265358979323846')
1016
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1017
- bg = Oj.load(json, :mode => :compat)
1018
- assert_equal(orig.to_s, bg)
1019
- end
1020
- def test_bigdecimal_load
1021
- orig = BigDecimal.new('80.51')
1022
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => true)
1023
- bg = Oj.load(json, :mode => :compat, :bigdecimal_load => true)
1024
- assert_equal(BigDecimal, bg.class)
1025
- assert_equal(orig, bg)
1026
- end
1027
- def test_float_load
1028
- orig = BigDecimal.new('80.51')
1029
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => true)
1030
- bg = Oj.load(json, :mode => :compat, :bigdecimal_load => :float)
1031
- assert_equal(Float, bg.class)
1032
- assert_equal(orig.to_f, bg)
1033
- end
1034
- def test_bigdecimal_compat_as_json
1035
- Oj.default_options = { :use_as_json => true }
1036
- orig = BigDecimal.new('80.51')
1037
- BigDecimal.send(:define_method, :as_json) do
1038
- %{this is big}
1039
- end
1040
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1041
- bg = Oj.load(json, :mode => :compat)
1042
- assert_equal("this is big", bg)
1043
- BigDecimal.send(:remove_method, :as_json) # cleanup
1044
- end
1045
- def test_bigdecimal_object
1046
- mode = Oj.default_options[:mode]
1047
- Oj.default_options = {:mode => :object}
1048
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
1049
- Oj.default_options = {:mode => mode}
1050
- # Infinity is the same for Float and BigDecimal
1051
- json = Oj.dump(BigDecimal.new('Infinity'), :mode => :object)
1052
- assert_equal('Infinity', json)
1053
- json = Oj.dump(BigDecimal.new('-Infinity'), :mode => :object)
1054
- assert_equal('-Infinity', json)
1055
- end
1056
-
1057
- def test_infinity
1058
- n = Oj.load('Infinity', :mode => :object)
1059
- assert_equal(BigDecimal.new('Infinity').to_f, n);
1060
- begin
1061
- Oj.load('Infinity', :mode => :strict)
1062
- fail()
1063
- rescue Oj::ParseError
1064
- assert(true)
1065
- end
1066
- x = Oj.load('Infinity', :mode => :compat)
1067
- assert_equal('Infinity', x.to_s)
1068
-
1069
- end
1070
-
1071
- # Date
1072
- def test_date_strict
1073
- begin
1074
- Oj.dump(Date.new(2012, 6, 19), :mode => :strict)
1075
- rescue Exception
1076
- assert(true)
1077
- return
1078
- end
1079
- assert(false, "*** expected an exception")
1080
- end
1081
- def test_date_null
1082
- json = Oj.dump(Date.new(2012, 6, 19), :mode => :null)
1083
- assert_equal('null', json)
1084
- end
1085
- def test_date_compat
1086
- orig = Date.new(2012, 6, 19)
1087
- json = Oj.dump(orig, :mode => :compat)
1088
- x = Oj.load(json, :mode => :compat)
1089
- # Some Rubies implement Date as data and some as a real Object. Either are
1090
- # okay for the test.
1091
- if x.is_a?(String)
1092
- assert_equal(orig.to_s, x)
1093
- else # better be a Hash
1094
- assert_equal({"year" => orig.year, "month" => orig.month, "day" => orig.day, "start" => orig.start}, x)
1095
- end
1096
- end
1097
- def test_date_object
1098
- Oj.default_options = {:mode => :object}
1099
- dump_and_load(Date.new(2012, 6, 19), false)
1100
- end
1101
-
1102
- # DateTime
1103
- def test_datetime_strict
1104
- begin
1105
- Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :strict)
1106
- rescue Exception
1107
- assert(true)
1108
- return
1109
- end
1110
- assert(false, "*** expected an exception")
1111
- end
1112
- def test_datetime_null
1113
- json = Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :null)
1114
- assert_equal('null', json)
1115
- end
1116
- def test_datetime_compat
1117
- orig = DateTime.new(2012, 6, 19, 20, 19, 27)
1118
- json = Oj.dump(orig, :mode => :compat)
1119
- x = Oj.load(json, :mode => :compat)
1120
- # Some Rubies implement Date as data and some as a real Object. Either are
1121
- # okay for the test.
1122
- assert_equal(orig.to_s, x)
1123
- end
1124
- def test_datetime_object
1125
- Oj.default_options = {:mode => :object}
1126
- dump_and_load(DateTime.new(2012, 6, 19), false)
1127
- end
1128
-
1129
- # autodefine Oj::Bag
1130
- def test_bag
1131
- json = %{{
1132
- "^o":"Juice::Jem",
1133
- "x":true,
1134
- "y":58 }}
1135
- obj = Oj.load(json, :mode => :object, :auto_define => true)
1136
- assert_equal('Juice::Jem', obj.class.name)
1137
- assert_equal(true, obj.x)
1138
- assert_equal(58, obj.y)
1139
- end
1140
-
1141
- # Circular
1142
- def test_circular_object
1143
- obj = Jam.new(nil, 58)
1144
- obj.x = obj
1145
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
1146
- assert(%{{
1147
- "^o":"Juice::Jam",
1148
- "^i":1,
1149
- "x":"^r1",
1150
- "y":58
1151
- }
1152
- } == json ||
1153
- %{{
1154
- "^o":"Juice::Jam",
1155
- "^i":1,
1156
- "y":58,
1157
- "x":"^r1"
1158
- }
1159
- } == json)
1160
- obj2 = Oj.load(json, :mode => :object, :circular => true)
1161
- assert_equal(obj2.x.__id__, obj2.__id__)
1162
- end
1163
-
1164
- def test_circular_hash
1165
- h = { 'a' => 7 }
1166
- h['b'] = h
1167
- json = Oj.dump(h, :mode => :object, :indent => 2, :circular => true)
1168
- ha = Oj.load(json, :mode => :strict)
1169
- assert_equal({'^i' => 1, 'a' => 7, 'b' => '^r1'}, ha)
1170
- Oj.load(json, :mode => :object, :circular => true)
1171
- assert_equal(h['b'].__id__, h.__id__)
1172
- end
1173
-
1174
- def test_circular_array
1175
- a = [7]
1176
- a << a
1177
- json = Oj.dump(a, :mode => :object, :indent => 2, :circular => true)
1178
- assert_equal(%{[
1179
- "^i1",
1180
- 7,
1181
- "^r1"
1182
- ]
1183
- }, json)
1184
- a2 = Oj.load(json, :mode => :object, :circular => true)
1185
- assert_equal(a2[1].__id__, a2.__id__)
1186
- end
1187
-
1188
- def test_circular
1189
- h = { 'a' => 7 }
1190
- obj = Jam.new(h, 58)
1191
- obj.x['b'] = obj
1192
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
1193
- ha = Oj.load(json, :mode => :strict)
1194
- assert_equal({'^o' => 'Juice::Jam', '^i' => 1, 'x' => { '^i' => 2, 'a' => 7, 'b' => '^r1' }, 'y' => 58 }, ha)
1195
- Oj.load(json, :mode => :object, :circular => true)
1196
- assert_equal(obj.x.__id__, h.__id__)
1197
- assert_equal(h['b'].__id__, obj.__id__)
1198
- end
1199
-
1200
- # Stream Deeply Nested
1201
- def test_deep_nest
1202
- begin
1203
- n = 10000
1204
- Oj.strict_load('[' * n + ']' * n)
1205
- rescue Exception => e
1206
- assert(false, e.message)
1207
- end
1208
- end
1209
-
1210
- def test_deep_nest_dump
1211
- begin
1212
- a = []
1213
- 10000.times { a << [a] }
1214
- Oj.dump(a)
1215
- rescue Exception
1216
- assert(true)
1217
- return
1218
- end
1219
- assert(false, "*** expected an exception")
1220
- end
1221
-
1222
- # Stream IO
1223
- def test_io_string
1224
- src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
1225
- output = StringIO.open("", "w+")
1226
- Oj.to_stream(output, src)
1227
-
1228
- input = StringIO.new(output.string())
1229
- obj = Oj.load(input, :mode => :strict)
1230
- assert_equal(src, obj)
1231
- end
1232
-
1233
- def test_io_file
1234
- src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
1235
- filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
1236
- File.open(filename, "w") { |f|
1237
- Oj.to_stream(f, src)
1238
- }
1239
- f = File.new(filename)
1240
- obj = Oj.load(f, :mode => :strict)
1241
- f.close()
1242
- assert_equal(src, obj)
1243
- end
1244
-
1245
- # symbol_keys option
1246
- def test_symbol_keys
1247
- json = %{{
1248
- "x":true,
1249
- "y":58,
1250
- "z": [1,2,3]
1251
- }
1252
- }
1253
- obj = Oj.load(json, :mode => :strict, :symbol_keys => true)
1254
- assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
1255
- end
1256
-
1257
- # comments
1258
- def test_comment_slash
1259
- json = %{{
1260
- "x":true,//three
1261
- "y":58,
1262
- "z": [1,2,
1263
- 3 // six
1264
- ]}
1265
- }
1266
- obj = Oj.load(json, :mode => :strict)
1267
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
1268
- end
1269
-
1270
- def test_comment_c
1271
- json = %{/*before*/
1272
- {
1273
- "x"/*one*/:/*two*/true,
1274
- "y":58,
1275
- "z": [1,2,3]}
1276
- }
1277
- obj = Oj.load(json, :mode => :strict)
1278
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
1279
- end
1280
-
1281
- def test_comment
1282
- json = %{{
1283
- "x"/*one*/:/*two*/true,//three
1284
- "y":58/*four*/,
1285
- "z": [1,2/*five*/,
1286
- 3 // six
1287
- ]
1288
- }
1289
- }
1290
- obj = Oj.load(json, :mode => :strict)
1291
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
1292
- end
1293
-
1294
- def test_nilnil_false
1295
- begin
1296
- Oj.load(nil)
1297
- rescue Exception
1298
- assert(true)
1299
- return
1300
- end
1301
- assert(false, "*** expected an exception")
1302
- end
1303
-
1304
- def test_nilnil_true
1305
- obj = Oj.load(nil, :nilnil => true)
1306
- assert_equal(nil, obj)
1307
- end
1308
-
1309
- def test_empty_string_true
1310
- 10.times do
1311
- result = Oj.load(gen_whitespaced_string, :empty_string => true)
1312
- assert_nil(result)
1313
- end
1314
- end
1315
-
1316
- def test_empty_string_false
1317
- 10.times do
1318
- assert_raises(Oj::ParseError) do
1319
- Oj.load(gen_whitespaced_string, :empty_string => false)
1320
- end
1321
- end
1322
- end
1323
-
1324
- def test_quirks_null_mode
1325
- assert_raises(Oj::ParseError) { Oj.load("null", :quirks_mode => false) }
1326
- assert_equal(nil, Oj.load("null", :quirks_mode => true))
1327
- end
1328
-
1329
- def test_quirks_bool_mode
1330
- assert_raises(Oj::ParseError) { Oj.load("true", :quirks_mode => false) }
1331
- assert_equal(true, Oj.load("true", :quirks_mode => true))
1332
- end
1333
-
1334
- def test_quirks_number_mode
1335
- assert_raises(Oj::ParseError) { Oj.load("123", :quirks_mode => false) }
1336
- assert_equal(123, Oj.load("123", :quirks_mode => true))
1337
- end
1338
-
1339
- def test_quirks_decimal_mode
1340
- assert_raises(Oj::ParseError) { Oj.load("123.45", :quirks_mode => false) }
1341
- assert_equal(123.45, Oj.load("123.45", :quirks_mode => true))
1342
- end
1343
-
1344
- def test_quirks_string_mode
1345
- assert_raises(Oj::ParseError) { Oj.load('"string"', :quirks_mode => false) }
1346
- assert_equal('string', Oj.load('"string"', :quirks_mode => true))
1347
- end
1348
-
1349
- def test_quirks_array_mode
1350
- assert_equal([], Oj.load("[]", :quirks_mode => false))
1351
- assert_equal([], Oj.load("[]", :quirks_mode => true))
1352
- end
1353
-
1354
- def test_quirks_object_mode
1355
- assert_equal({}, Oj.load("{}", :quirks_mode => false))
1356
- assert_equal({}, Oj.load("{}", :quirks_mode => true))
1357
- end
1358
-
1359
- def test_omit_nil
1360
- jam = Jam.new({'a' => 1, 'b' => nil }, nil)
1361
-
1362
- json = Oj.dump(jam, :omit_nil => true, :mode => :object)
1363
- assert_equal(%|{"^o":"Juice::Jam","x":{"a":1}}|, json)
1364
-
1365
- json = Oj.dump(jam, :omit_nil => true, :mode => :compat)
1366
- assert_equal(%|{"x":{"a":1}}|, json)
1367
-
1368
- json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :strict)
1369
- assert_equal(%|{"x":{"a":1}}|, json)
1370
-
1371
- json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :null)
1372
- assert_equal(%|{"x":{"a":1}}|, json)
1373
- end
1374
-
1375
- def dump_and_load(obj, trace=false)
1376
- json = Oj.dump(obj, :indent => 2)
1377
- puts json if trace
1378
- loaded = Oj.load(json)
1379
- assert_equal(obj, loaded)
1380
- loaded
1381
- end
1382
-
1383
- end