oj 3.13.23 → 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.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +2 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +26 -59
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +103 -53
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -7
  25. data/ext/oj/fast.c +63 -98
  26. data/ext/oj/intern.c +62 -47
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +54 -38
  31. data/ext/oj/object.c +33 -43
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +245 -216
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +109 -153
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +9 -8
  40. data/ext/oj/rails.c +71 -94
  41. data/ext/oj/reader.c +9 -14
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +13 -15
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +6 -20
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +46 -48
  52. data/ext/oj/strict.c +22 -56
  53. data/ext/oj/string_writer.c +64 -40
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -114
  56. data/ext/oj/usual.h +7 -6
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +13 -2
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +7 -7
  67. data/lib/oj/schandler.rb +5 -4
  68. data/lib/oj/state.rb +8 -5
  69. data/lib/oj/version.rb +1 -2
  70. data/lib/oj.rb +2 -0
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +4 -0
  73. metadata +46 -121
  74. data/test/_test_active.rb +0 -76
  75. data/test/_test_active_mimic.rb +0 -96
  76. data/test/_test_mimic_rails.rb +0 -126
  77. data/test/activerecord/result_test.rb +0 -32
  78. data/test/activesupport4/decoding_test.rb +0 -108
  79. data/test/activesupport4/encoding_test.rb +0 -531
  80. data/test/activesupport4/test_helper.rb +0 -41
  81. data/test/activesupport5/abstract_unit.rb +0 -45
  82. data/test/activesupport5/decoding_test.rb +0 -133
  83. data/test/activesupport5/encoding_test.rb +0 -500
  84. data/test/activesupport5/encoding_test_cases.rb +0 -98
  85. data/test/activesupport5/test_helper.rb +0 -72
  86. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  87. data/test/activesupport6/abstract_unit.rb +0 -44
  88. data/test/activesupport6/decoding_test.rb +0 -133
  89. data/test/activesupport6/encoding_test.rb +0 -507
  90. data/test/activesupport6/encoding_test_cases.rb +0 -98
  91. data/test/activesupport6/test_common.rb +0 -17
  92. data/test/activesupport6/test_helper.rb +0 -163
  93. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  94. data/test/activesupport7/abstract_unit.rb +0 -49
  95. data/test/activesupport7/decoding_test.rb +0 -125
  96. data/test/activesupport7/encoding_test.rb +0 -486
  97. data/test/activesupport7/encoding_test_cases.rb +0 -104
  98. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  99. data/test/bar.rb +0 -11
  100. data/test/baz.rb +0 -16
  101. data/test/bug.rb +0 -16
  102. data/test/files.rb +0 -29
  103. data/test/foo.rb +0 -77
  104. data/test/helper.rb +0 -42
  105. data/test/isolated/shared.rb +0 -308
  106. data/test/isolated/test_mimic_after.rb +0 -13
  107. data/test/isolated/test_mimic_alone.rb +0 -12
  108. data/test/isolated/test_mimic_as_json.rb +0 -45
  109. data/test/isolated/test_mimic_before.rb +0 -13
  110. data/test/isolated/test_mimic_define.rb +0 -28
  111. data/test/isolated/test_mimic_rails_after.rb +0 -22
  112. data/test/isolated/test_mimic_rails_before.rb +0 -21
  113. data/test/isolated/test_mimic_redefine.rb +0 -15
  114. data/test/json_gem/json_addition_test.rb +0 -216
  115. data/test/json_gem/json_common_interface_test.rb +0 -153
  116. data/test/json_gem/json_encoding_test.rb +0 -107
  117. data/test/json_gem/json_ext_parser_test.rb +0 -20
  118. data/test/json_gem/json_fixtures_test.rb +0 -35
  119. data/test/json_gem/json_generator_test.rb +0 -396
  120. data/test/json_gem/json_generic_object_test.rb +0 -90
  121. data/test/json_gem/json_parser_test.rb +0 -477
  122. data/test/json_gem/json_string_matching_test.rb +0 -42
  123. data/test/json_gem/test_helper.rb +0 -30
  124. data/test/mem.rb +0 -33
  125. data/test/perf.rb +0 -107
  126. data/test/perf_compat.rb +0 -130
  127. data/test/perf_dump.rb +0 -50
  128. data/test/perf_fast.rb +0 -164
  129. data/test/perf_file.rb +0 -64
  130. data/test/perf_object.rb +0 -138
  131. data/test/perf_once.rb +0 -58
  132. data/test/perf_parser.rb +0 -189
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -152
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -139
  137. data/test/perf_wab.rb +0 -131
  138. data/test/prec.rb +0 -23
  139. data/test/sample/change.rb +0 -14
  140. data/test/sample/dir.rb +0 -19
  141. data/test/sample/doc.rb +0 -36
  142. data/test/sample/file.rb +0 -48
  143. data/test/sample/group.rb +0 -16
  144. data/test/sample/hasprops.rb +0 -16
  145. data/test/sample/layer.rb +0 -12
  146. data/test/sample/line.rb +0 -20
  147. data/test/sample/oval.rb +0 -10
  148. data/test/sample/rect.rb +0 -10
  149. data/test/sample/shape.rb +0 -35
  150. data/test/sample/text.rb +0 -20
  151. data/test/sample.rb +0 -54
  152. data/test/sample_json.rb +0 -37
  153. data/test/test_compat.rb +0 -540
  154. data/test/test_custom.rb +0 -544
  155. data/test/test_debian.rb +0 -53
  156. data/test/test_fast.rb +0 -530
  157. data/test/test_file.rb +0 -255
  158. data/test/test_gc.rb +0 -60
  159. data/test/test_generate.rb +0 -21
  160. data/test/test_hash.rb +0 -39
  161. data/test/test_integer_range.rb +0 -72
  162. data/test/test_null.rb +0 -376
  163. data/test/test_object.rb +0 -1025
  164. data/test/test_parser.rb +0 -11
  165. data/test/test_parser_debug.rb +0 -27
  166. data/test/test_parser_saj.rb +0 -335
  167. data/test/test_parser_usual.rb +0 -217
  168. data/test/test_rails.rb +0 -35
  169. data/test/test_saj.rb +0 -186
  170. data/test/test_scp.rb +0 -431
  171. data/test/test_strict.rb +0 -435
  172. data/test/test_various.rb +0 -752
  173. data/test/test_wab.rb +0 -309
  174. data/test/test_writer.rb +0 -380
  175. data/test/tests.rb +0 -33
  176. data/test/tests_mimic.rb +0 -23
  177. data/test/tests_mimic_addition.rb +0 -16
  178. data/test/zoo.rb +0 -13
data/test/test_object.rb DELETED
@@ -1,1025 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- $: << File.dirname(__FILE__)
5
-
6
- require 'helper'
7
-
8
- class ObjectJuice < Minitest::Test
9
- class Jeez
10
- attr_accessor :x, :y, :_z
11
-
12
- def initialize(x, y)
13
- @x = x
14
- @y = y
15
- @_z = x.to_s
16
- end
17
-
18
- def eql?(o)
19
- self.class == o.class && @x == o.x && @y == o.y
20
- end
21
- alias == eql?
22
-
23
- def to_json(*a)
24
- %{{"json_class":"#{self.class}","x":#{@x},"y":#{@y}}}
25
- end
26
-
27
- def self.json_create(h)
28
- self.new(h['x'], h['y'])
29
- end
30
- end # Jeez
31
-
32
- class Jam
33
- attr_accessor :x, :y
34
-
35
- def initialize(x, y)
36
- @x = x
37
- @y = y
38
- end
39
-
40
- def eql?(o)
41
- self.class == o.class && @x == o.x && @y == o.y
42
- end
43
- alias == eql?
44
-
45
- end # Jam
46
-
47
- class Jazz < Jam
48
- def initialize(x, y)
49
- super
50
- end
51
- def to_hash()
52
- { 'json_class' => self.class.to_s, 'x' => @x, 'y' => @y }
53
- end
54
- def self.json_create(h)
55
- self.new(h['x'], h['y'])
56
- end
57
- end # Jazz
58
-
59
- class Orange < Jam
60
- def initialize(x, y)
61
- super
62
- end
63
-
64
- def as_json()
65
- { :json_class => self.class,
66
- :x => @x,
67
- :y => @y }
68
- end
69
-
70
- def self.json_create(h)
71
- self.new(h['x'], h['y'])
72
- end
73
- end
74
-
75
- module One
76
- module Two
77
- module Three
78
- class Deep
79
-
80
- def initialize()
81
- end
82
-
83
- def eql?(o)
84
- self.class == o.class
85
- end
86
- alias == eql?
87
-
88
- def to_hash()
89
- {'json_class' => "#{self.class.name}"}
90
- end
91
-
92
- def to_json(*a)
93
- %{{"json_class":"#{self.class.name}"}}
94
- end
95
-
96
- def self.json_create(h)
97
- self.new()
98
- end
99
- end # Deep
100
- end # Three
101
- end # Two
102
-
103
- class Stuck2 < Struct.new(:a, :b)
104
- end
105
-
106
- end # One
107
-
108
- class Stuck < Struct.new(:a, :b)
109
- end
110
-
111
- class Strung < String
112
-
113
- def initialize(str, safe)
114
- super(str)
115
- @safe = safe
116
- end
117
-
118
- def safe?()
119
- @safe
120
- end
121
-
122
- def self.create(str, safe)
123
- new(str, safe)
124
- end
125
-
126
- def eql?(o)
127
- super && self.class == o.class && @safe == o.safe?
128
- end
129
- alias == eql?
130
-
131
- def inspect()
132
- return super + '(' + @safe + ')'
133
- end
134
- end
135
-
136
- class AutoStrung < String
137
- attr_accessor :safe
138
-
139
- def initialize(str, safe)
140
- super(str)
141
- @safe = safe
142
- end
143
-
144
- def eql?(o)
145
- self.class == o.class && super(o) && @safe == o.safe
146
- end
147
- alias == eql?
148
- end
149
-
150
- class AutoArray < Array
151
- attr_accessor :safe
152
-
153
- def initialize(a, safe)
154
- super(a)
155
- @safe = safe
156
- end
157
-
158
- def eql?(o)
159
- self.class == o.class && super(o) && @safe == o.safe
160
- end
161
- alias == eql?
162
- end
163
-
164
- class AutoHash < Hash
165
- attr_accessor :safe
166
-
167
- def initialize(h, safe)
168
- super(h)
169
- @safe = safe
170
- end
171
-
172
- def eql?(o)
173
- self.class == o.class && super(o) && @safe == o.safe
174
- end
175
- alias == eql?
176
- end
177
-
178
- class Raw
179
- attr_accessor :json
180
-
181
- def initialize(j)
182
- @json = j
183
- end
184
-
185
- def to_json(*a)
186
- @json
187
- end
188
-
189
- def self.create(h)
190
- h
191
- end
192
- end # Raw
193
-
194
- module Ichi
195
- module Ni
196
- def self.direct(h)
197
- h
198
- end
199
-
200
- module San
201
- class Shi
202
-
203
- attr_accessor :hash
204
-
205
- def initialize(h)
206
- @hash = h
207
- end
208
-
209
- def dump()
210
- @hash
211
- end
212
-
213
- end # Shi
214
- end # San
215
- end # Ni
216
- end # Ichi
217
-
218
- def setup
219
- @default_options = Oj.default_options
220
- end
221
-
222
- def teardown
223
- Oj.default_options = @default_options
224
- end
225
-
226
- def test_nil
227
- dump_and_load(nil, false)
228
- end
229
-
230
- def test_true
231
- dump_and_load(true, false)
232
- end
233
-
234
- def test_false
235
- dump_and_load(false, false)
236
- end
237
-
238
- def test_fixnum
239
- dump_and_load(0, false)
240
- dump_and_load(12345, false)
241
- dump_and_load(-54321, false)
242
- dump_and_load(1, false)
243
- end
244
-
245
- def test_float
246
- dump_and_load(0.0, false)
247
- dump_and_load(12345.6789, false)
248
- dump_and_load(70.35, false)
249
- dump_and_load(-54321.012, false)
250
- dump_and_load(1.7775, false)
251
- dump_and_load(2.5024, false)
252
- dump_and_load(2.48e16, false)
253
- dump_and_load(2.48e100 * 1.0e10, false)
254
- dump_and_load(-2.48e100 * 1.0e10, false)
255
- dump_and_load(1/0.0, false)
256
- # NaN does not always == NaN
257
- json = Oj.dump(0/0.0, :mode => :object)
258
- assert_equal('3.3e14159265358979323846', json)
259
- loaded = Oj.load(json);
260
- assert_equal(true, loaded.nan?)
261
- end
262
-
263
- def test_string
264
- dump_and_load('', false)
265
- dump_and_load('abc', false)
266
- dump_and_load("abc\ndef", false)
267
- dump_and_load("a\u0041", false)
268
- end
269
-
270
- def test_symbol
271
- dump_and_load(:abc, false)
272
- dump_and_load(":abc", false)
273
- dump_and_load(':xyz'.to_sym, false)
274
- end
275
-
276
- def test_encode
277
- opts = Oj.default_options
278
- Oj.default_options = { :ascii_only => false }
279
- dump_and_load("ぴーたー", false)
280
- Oj.default_options = { :ascii_only => true }
281
- json = Oj.dump("ぴーたー")
282
- assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
283
- dump_and_load("ぴーたー", false)
284
- Oj.default_options = opts
285
- end
286
-
287
- def test_unicode
288
- # hits the 3 normal ranges and one extended surrogate pair
289
- json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
290
- obj = Oj.load(json)
291
- json2 = Oj.dump(obj, :ascii_only => true)
292
- assert_equal(json, json2)
293
- end
294
-
295
- def test_array
296
- dump_and_load([], false)
297
- dump_and_load([true, false], false)
298
- dump_and_load(['a', 1, nil], false)
299
- dump_and_load([[nil]], false)
300
- dump_and_load([[nil], 58], false)
301
- end
302
-
303
- def test_array_deep
304
- dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
305
- end
306
-
307
- # Hash
308
- def test_hash
309
- dump_and_load({}, false)
310
- dump_and_load({ 'true' => true, 'false' => false}, false)
311
- dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
312
- end
313
-
314
- def test_hash_deep
315
- dump_and_load({'1' => {
316
- '2' => {
317
- '3' => {
318
- '4' => {
319
- '5' => {
320
- '6' => {
321
- '7' => {
322
- '8' => {
323
- '9' => {
324
- '10' => {
325
- '11' => {
326
- '12' => {
327
- '13' => {
328
- '14' => {
329
- '15' => {
330
- '16' => {
331
- '17' => {
332
- '18' => {
333
- '19' => {
334
- '20' => {}}}}}}}}}}}}}}}}}}}}}, false)
335
- end
336
-
337
- def test_hash_escaped_key
338
- json = %{{"a\nb":true,"c\td":false}}
339
- obj = Oj.object_load(json)
340
- assert_equal({"a\nb" => true, "c\td" => false}, obj)
341
- end
342
-
343
- def test_bignum_object
344
- dump_and_load(7 ** 55, false)
345
- end
346
-
347
- # BigDecimal
348
- def test_bigdecimal_object
349
- dump_and_load(BigDecimal('3.14159265358979323846'), false)
350
- end
351
-
352
- def test_bigdecimal_load
353
- orig = BigDecimal('80.51')
354
- json = Oj.dump(orig, :mode => :object, :bigdecimal_as_decimal => true)
355
- bg = Oj.load(json, :mode => :object, :bigdecimal_load => true)
356
- assert_equal(BigDecimal, bg.class)
357
- assert_equal(orig, bg)
358
- # Infinity is the same for Float and BigDecimal
359
- json = Oj.dump(BigDecimal('Infinity'), :mode => :object)
360
- assert_equal('Infinity', json)
361
- json = Oj.dump(BigDecimal('-Infinity'), :mode => :object)
362
- assert_equal('-Infinity', json)
363
- end
364
-
365
- # Stream IO
366
- def test_io_string
367
- json = %{{
368
- "x":true,
369
- "y":58,
370
- "z": [1,2,3]
371
- }
372
- }
373
- input = StringIO.new(json)
374
- obj = Oj.object_load(input)
375
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
376
- end
377
-
378
- def test_io_file
379
- filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
380
- File.open(filename, 'w') { |f| f.write(%{{
381
- "x":true,
382
- "y":58,
383
- "z": [1,2,3]
384
- }
385
- }) }
386
- f = File.new(filename)
387
- obj = Oj.object_load(f)
388
- f.close()
389
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
390
- end
391
-
392
- # symbol_keys option
393
- def test_symbol_keys
394
- json = %{{
395
- "x":true,
396
- "y":58,
397
- "z": [1,2,3]
398
- }
399
- }
400
- obj = Oj.object_load(json, :symbol_keys => true)
401
- assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
402
- end
403
-
404
- def test_class_object
405
- dump_and_load(ObjectJuice, false)
406
- end
407
-
408
- def test_module_object
409
- dump_and_load(One, false)
410
- end
411
-
412
- def test_non_str_hash_object
413
- json = Oj.dump({ 1 => true, :sim => nil }, :mode => :object)
414
- h = Oj.load(json, :mode => :strict)
415
- assert_equal({"^#1" => [1, true], ":sim" => nil}, h)
416
- h = Oj.load(json, :mode => :object)
417
- assert_equal({ 1 => true, :sim => nil }, h)
418
- end
419
-
420
- # comments
421
- def test_comment_slash
422
- json = %{{
423
- "x":true,//three
424
- "y":58,
425
- "z": [1,2,
426
- 3 // six
427
- ]}
428
- }
429
- obj = Oj.object_load(json)
430
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
431
- end
432
-
433
- def test_comment_c
434
- json = %{{
435
- "x"/*one*/:/*two*/true,
436
- "y":58,
437
- "z": [1,2,3]}
438
- }
439
- obj = Oj.object_load(json)
440
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
441
- end
442
-
443
- def test_comment
444
- json = %{{
445
- "x"/*one*/:/*two*/true,//three
446
- "y":58/*four*/,
447
- "z": [1,2/*five*/,
448
- 3 // six
449
- ]
450
- }
451
- }
452
- obj = Oj.object_load(json)
453
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
454
- end
455
-
456
- def test_json_module_object
457
- obj = One::Two::Three::Deep.new()
458
- dump_and_load(obj, false)
459
- end
460
-
461
- def test_xml_time
462
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
463
- # The fractional seconds are not always recreated exactly which causes a
464
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
465
- # separately along with utc.
466
- json = Oj.dump(t, :mode => :object, :time_format => :xmlschema)
467
- #puts "*** json for test_xml_time '#{json}'"
468
- loaded = Oj.object_load(json);
469
- assert_equal(t.tv_sec, loaded.tv_sec)
470
- if t.respond_to?(:tv_nsec)
471
- assert_equal(t.tv_nsec, loaded.tv_nsec)
472
- else
473
- assert_equal(t.tv_usec, loaded.tv_usec)
474
- end
475
- assert_equal(t.utc?, loaded.utc?)
476
- assert_equal(t.utc_offset, loaded.utc_offset)
477
- end
478
-
479
- def test_xml_time_utc
480
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
481
- # The fractional seconds are not always recreated exactly which causes a
482
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
483
- # separately along with utc.
484
- json = Oj.dump(t, :mode => :object, :time_format => :xmlschema)
485
- loaded = Oj.object_load(json);
486
- assert_equal(t.tv_sec, loaded.tv_sec)
487
- if t.respond_to?(:tv_nsec)
488
- assert_equal(t.tv_nsec, loaded.tv_nsec)
489
- else
490
- assert_equal(t.tv_usec, loaded.tv_usec)
491
- end
492
- assert_equal(t.utc?, loaded.utc?)
493
- assert_equal(t.utc_offset, loaded.utc_offset)
494
- end
495
-
496
- def test_ruby_time
497
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
498
- # The fractional seconds are not always recreated exactly which causes a
499
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
500
- # separately along with utc.
501
- json = Oj.dump(t, :mode => :object, :time_format => :ruby)
502
- #puts "*** json for test_ruby_time '#{json}'"
503
- loaded = Oj.object_load(json);
504
- assert_equal(t.tv_sec, loaded.tv_sec)
505
- if t.respond_to?(:tv_nsec)
506
- assert_equal(t.tv_nsec, loaded.tv_nsec)
507
- else
508
- assert_equal(t.tv_usec, loaded.tv_usec)
509
- end
510
- assert_equal(t.utc?, loaded.utc?)
511
- assert_equal(t.utc_offset, loaded.utc_offset)
512
- end
513
-
514
- def test_ruby_time_12345
515
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345/60*60)
516
- # The fractional seconds are not always recreated exactly which causes a
517
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
518
- # separately along with utc.
519
- json = Oj.dump(t, :mode => :object, :time_format => :ruby)
520
- #puts "*** json for test_ruby_time '#{json}'"
521
- loaded = Oj.object_load(json);
522
- #puts "*** loaded: #{loaded}"
523
- assert_equal(t.tv_sec, loaded.tv_sec)
524
- if t.respond_to?(:tv_nsec)
525
- assert_equal(t.tv_nsec, loaded.tv_nsec)
526
- else
527
- assert_equal(t.tv_usec, loaded.tv_usec)
528
- end
529
- assert_equal(t.utc?, loaded.utc?)
530
- assert_equal(t.utc_offset, loaded.utc_offset)
531
- end
532
-
533
- def test_ruby_time_utc
534
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
535
- # The fractional seconds are not always recreated exactly which causes a
536
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
537
- # separately along with utc.
538
- json = Oj.dump(t, :mode => :object, :time_format => :ruby)
539
- #puts json
540
- loaded = Oj.object_load(json);
541
- assert_equal(t.tv_sec, loaded.tv_sec)
542
- if t.respond_to?(:tv_nsec)
543
- assert_equal(t.tv_nsec, loaded.tv_nsec)
544
- else
545
- assert_equal(t.tv_usec, loaded.tv_usec)
546
- end
547
- assert_equal(t.utc?, loaded.utc?)
548
- assert_equal(t.utc_offset, loaded.utc_offset)
549
- end
550
-
551
- def test_time_early
552
- # Windows does not support dates before 1970.
553
- return if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
554
-
555
- t = Time.new(1954, 1, 5, 21, 37, 7.123456789, -8 * 3600)
556
- # The fractional seconds are not always recreated exactly which causes a
557
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
558
- # separately along with utc.
559
- json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
560
- #puts json
561
- loaded = Oj.object_load(json);
562
- assert_equal(t.tv_sec, loaded.tv_sec)
563
- if t.respond_to?(:tv_nsec)
564
- assert_equal(t.tv_nsec, loaded.tv_nsec)
565
- else
566
- assert_equal(t.tv_usec, loaded.tv_usec)
567
- end
568
- assert_equal(t.utc?, loaded.utc?)
569
- assert_equal(t.utc_offset, loaded.utc_offset)
570
- end
571
-
572
- def test_time_unix_zone
573
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
574
- # The fractional seconds are not always recreated exactly which causes a
575
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
576
- # separately along with utc.
577
- json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
578
- #puts json
579
- loaded = Oj.object_load(json);
580
- assert_equal(t.tv_sec, loaded.tv_sec)
581
- if t.respond_to?(:tv_nsec)
582
- assert_equal(t.tv_nsec, loaded.tv_nsec)
583
- else
584
- assert_equal(t.tv_usec, loaded.tv_usec)
585
- end
586
- assert_equal(t.utc?, loaded.utc?)
587
- assert_equal(t.utc_offset, loaded.utc_offset)
588
- end
589
-
590
- def test_time_unix_zone_12345
591
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345)
592
- # The fractional seconds are not always recreated exactly which causes a
593
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
594
- # separately along with utc.
595
- json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
596
- #puts json
597
- loaded = Oj.object_load(json);
598
- assert_equal(t.tv_sec, loaded.tv_sec)
599
- if t.respond_to?(:tv_nsec)
600
- assert_equal(t.tv_nsec, loaded.tv_nsec)
601
- else
602
- assert_equal(t.tv_usec, loaded.tv_usec)
603
- end
604
- assert_equal(t.utc?, loaded.utc?)
605
- assert_equal(t.utc_offset, loaded.utc_offset)
606
- end
607
-
608
- def test_time_unix_zone_utc
609
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
610
- # The fractional seconds are not always recreated exactly which causes a
611
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
612
- # separately along with utc.
613
- json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
614
- #puts json
615
- loaded = Oj.object_load(json);
616
- assert_equal(t.tv_sec, loaded.tv_sec)
617
- if t.respond_to?(:tv_nsec)
618
- assert_equal(t.tv_nsec, loaded.tv_nsec)
619
- else
620
- assert_equal(t.tv_usec, loaded.tv_usec)
621
- end
622
- assert_equal(t.utc?, loaded.utc?)
623
- assert_equal(t.utc_offset, loaded.utc_offset)
624
- end
625
-
626
- def test_json_object
627
- obj = Jeez.new(true, 58)
628
- dump_and_load(obj, false)
629
- end
630
-
631
- def test_json_object_create_deep
632
- obj = One::Two::Three::Deep.new()
633
- dump_and_load(obj, false)
634
- end
635
-
636
- def test_json_object_bad
637
- json = %{{"^o":"Junk","x":true}}
638
- begin
639
- Oj.object_load(json)
640
- rescue Exception => e
641
- assert_equal("ArgumentError", e.class().name)
642
- return
643
- end
644
- assert(false, "*** expected an exception")
645
- end
646
-
647
- def test_json_object_not_hat_hash
648
- json = %{{"^#x":[1,2]}}
649
- h = Oj.object_load(json)
650
- assert_equal({1 => 2}, h);
651
-
652
- json = %{{"~#x":[1,2]}}
653
- h = Oj.object_load(json)
654
- assert_equal({'~#x' => [1,2]}, h);
655
- end
656
-
657
- def test_json_struct
658
- obj = Stuck.new(false, 7)
659
- dump_and_load(obj, false)
660
- end
661
-
662
- def test_json_struct2
663
- obj = One::Stuck2.new(false, 7)
664
- dump_and_load(obj, false)
665
- end
666
-
667
- def test_json_anonymous_struct
668
- s = Struct.new(:x, :y)
669
- obj = s.new(1, 2)
670
- json = Oj.dump(obj, :indent => 2, :mode => :object)
671
- #puts json
672
- loaded = Oj.object_load(json);
673
- assert_equal(obj.members, loaded.members)
674
- assert_equal(obj.values, loaded.values)
675
- end
676
-
677
- def test_json_non_str_hash
678
- obj = { 59 => "young", false => true }
679
- dump_and_load(obj, false)
680
- end
681
-
682
- def test_mixed_hash_object
683
- Oj.default_options = { :mode => :object }
684
- json = Oj.dump({ 1 => true, 'nil' => nil, :sim => 4 })
685
- h = Oj.object_load(json)
686
- assert_equal({ 1 => true, 'nil' => nil, :sim => 4 }, h)
687
- end
688
-
689
- def test_json_object_object
690
- obj = Jeez.new(true, 58)
691
- json = Oj.dump(obj, mode: :object, indent: 2, ignore_under: true)
692
- assert(%{{
693
- "^o":"ObjectJuice::Jeez",
694
- "x":true,
695
- "y":58
696
- }
697
- } == json ||
698
- %{{
699
- "^o":"ObjectJuice::Jeez",
700
- "y":58,
701
- "x":true
702
- }
703
- } == json)
704
- obj2 = Oj.load(json, :mode => :object)
705
- assert_equal(obj, obj2)
706
- end
707
-
708
- def test_to_hash_object_object
709
- obj = Jazz.new(true, 58)
710
- json = Oj.dump(obj, :mode => :object, :indent => 2)
711
- assert(%{{
712
- "^o":"ObjectJuice::Jazz",
713
- "x":true,
714
- "y":58
715
- }
716
- } == json ||
717
- %{{
718
- "^o":"ObjectJuice::Jazz",
719
- "y":58,
720
- "x":true
721
- }
722
- } == json)
723
- obj2 = Oj.load(json, :mode => :object)
724
- assert_equal(obj, obj2)
725
- end
726
-
727
- def test_as_json_object_object
728
- obj = Orange.new(true, 58)
729
- json = Oj.dump(obj, :mode => :object, :indent => 2)
730
- assert(%{{
731
- "^o":"ObjectJuice::Orange",
732
- "x":true,
733
- "y":58
734
- }
735
- } == json ||
736
- %{{
737
- "^o":"ObjectJuice::Orange",
738
- "y":58,
739
- "x":true
740
- }
741
- } == json)
742
- obj2 = Oj.load(json, :mode => :object)
743
- assert_equal(obj, obj2)
744
- end
745
-
746
- def test_object_object_no_cache
747
- obj = Jam.new(true, 58)
748
- json = Oj.dump(obj, :mode => :object, :indent => 2)
749
- assert(%{{
750
- "^o":"ObjectJuice::Jam",
751
- "x":true,
752
- "y":58
753
- }
754
- } == json ||
755
- %{{
756
- "^o":"ObjectJuice::Jam",
757
- "y":58,
758
- "x":true
759
- }
760
- } == json)
761
- obj2 = Oj.load(json, :mode => :object, :class_cache => false)
762
- assert_equal(obj, obj2)
763
- end
764
-
765
- def test_ignore
766
- obj = Jeez.new(true, 58)
767
- json = Oj.dump({ 'a' => 7, 'b' => obj }, :mode => :object, :indent => 2, :ignore => [ Jeez ])
768
- assert_equal(%|{
769
- "a":7
770
- }
771
- |, json)
772
- end
773
-
774
- def test_exception
775
- err = nil
776
- begin
777
- raise StandardError.new('A Message')
778
- rescue Exception => e
779
- err = e
780
- end
781
- json = Oj.dump(err, :mode => :object, :indent => 2)
782
- #puts "*** #{json}"
783
- e2 = Oj.load(json, :mode => :strict)
784
- assert_equal(err.class.to_s, e2['^o'])
785
- assert_equal(err.message, e2['~mesg'])
786
- assert_equal(err.backtrace, e2['~bt'])
787
- e2 = Oj.load(json, :mode => :object)
788
- if 'rubinius' == $ruby
789
- assert_equal(e.class, e2.class);
790
- assert_equal(e.message, e2.message);
791
- assert_equal(e.backtrace, e2.backtrace);
792
- else
793
- assert_equal(e, e2);
794
- end
795
- end
796
-
797
- class SubX < Exception
798
- def initialize
799
- super("sub")
800
- @xyz = 123
801
- end
802
- end
803
-
804
- def test_exception_subclass
805
- err = nil
806
- begin
807
- raise SubX.new
808
- rescue Exception => e
809
- err = e
810
- end
811
- json = Oj.dump(err, :mode => :object, :indent => 2)
812
- #puts "*** #{json}"
813
- e2 = Oj.load(json, :mode => :strict)
814
- assert_equal(err.class.to_s, e2['^o'])
815
- assert_equal(err.message, e2['~mesg'])
816
- assert_equal(err.backtrace, e2['~bt'])
817
- e2 = Oj.load(json, :mode => :object)
818
- assert_equal(e, e2);
819
- end
820
-
821
- def test_range_object
822
- Oj.default_options = { :mode => :object }
823
- json = Oj.dump(1..7, :mode => :object, :indent => 0)
824
- if 'ruby' == $ruby
825
- assert_equal(%{{"^u":["Range",1,7,false]}}, json)
826
- else
827
- assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
828
- end
829
- dump_and_load(1..7, false)
830
- dump_and_load(1..1, false)
831
- dump_and_load(1...7, false)
832
- end
833
-
834
- def test_circular_hash
835
- h = { 'a' => 7 }
836
- h['b'] = h
837
- json = Oj.dump(h, :mode => :object, :indent => 2, :circular => true)
838
- h2 = Oj.object_load(json, :circular => true)
839
- assert_equal(h2['b'].__id__, h2.__id__)
840
- end
841
-
842
-
843
- def test_json_object_missing_fields
844
- json = %{{ "^u": [ "ObjectJuice::Stuck",1]}}
845
-
846
- obj = Oj.load(json, mode: :object)
847
- assert_nil(obj['b'])
848
- end
849
-
850
- def test_circular_array
851
- a = [7]
852
- a << a
853
- json = Oj.dump(a, :mode => :object, :indent => 2, :circular => true)
854
- a2 = Oj.object_load(json, :circular => true)
855
- assert_equal(a2[1].__id__, a2.__id__)
856
- end
857
-
858
- def test_circular_array2
859
- a = [7]
860
- a << a
861
- json = Oj.dump(a, :mode => :object, :indent => 2, :circular => true)
862
- assert_equal(%{[
863
- "^i1",
864
- 7,
865
- "^r1"
866
- ]
867
- }, json)
868
- a2 = Oj.load(json, :mode => :object, :circular => true)
869
- assert_equal(a2[1].__id__, a2.__id__)
870
- end
871
-
872
- def test_circular_array3
873
- a = ['^r1']
874
- json = Oj.dump(a, mode: :object, circular: true)
875
- assert_equal(%{["^i1","\\u005er1"]}, json)
876
- a2 = Oj.load(json, mode: :object, circular: true)
877
- assert_equal(a, a2)
878
- end
879
-
880
- def test_circular_hash2
881
- h = { 'a' => 7 }
882
- h['b'] = h
883
- json = Oj.dump(h, :mode => :object, :indent => 2, :circular => true)
884
- ha = Oj.load(json, :mode => :strict)
885
- assert_equal({'^i' => 1, 'a' => 7, 'b' => '^r1'}, ha)
886
- Oj.load(json, :mode => :object, :circular => true)
887
- assert_equal(h['b'].__id__, h.__id__)
888
- end
889
-
890
- def test_circular_object
891
- obj = Jeez.new(nil, 58)
892
- obj.x = obj
893
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
894
- obj2 = Oj.object_load(json, :circular => true)
895
- assert_equal(obj2.x.__id__, obj2.__id__)
896
- end
897
-
898
- def test_circular_object2
899
- obj = Jam.new(nil, 58)
900
- obj.x = obj
901
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
902
- assert(%{{
903
- "^o":"ObjectJuice::Jam",
904
- "^i":1,
905
- "x":"^r1",
906
- "y":58
907
- }
908
- } == json ||
909
- %{{
910
- "^o":"ObjectJuice::Jam",
911
- "^i":1,
912
- "y":58,
913
- "x":"^r1"
914
- }
915
- } == json)
916
- obj2 = Oj.load(json, :mode => :object, :circular => true)
917
- assert_equal(obj2.x.__id__, obj2.__id__)
918
- end
919
-
920
- def test_circular
921
- h = { 'a' => 7 }
922
- obj = Jeez.new(h, 58)
923
- obj.x['b'] = obj
924
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
925
- Oj.object_load(json, :circular => true)
926
- assert_equal(obj.x.__id__, h.__id__)
927
- assert_equal(h['b'].__id__, obj.__id__)
928
- end
929
-
930
- def test_circular2
931
- h = { 'a' => 7 }
932
- obj = Jam.new(h, 58)
933
- obj.x['b'] = obj
934
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
935
- ha = Oj.load(json, :mode => :strict)
936
- assert_equal({'^o' => 'ObjectJuice::Jam', '^i' => 1, 'x' => { '^i' => 2, 'a' => 7, 'b' => '^r1' }, 'y' => 58 }, ha)
937
- Oj.load(json, :mode => :object, :circular => true)
938
- assert_equal(obj.x.__id__, h.__id__)
939
- assert_equal(h['b'].__id__, obj.__id__)
940
- end
941
-
942
- def test_omit_nil
943
- jam = Jam.new({'a' => 1, 'b' => nil }, nil)
944
-
945
- json = Oj.dump(jam, :omit_nil => true, :mode => :object)
946
- assert_equal(%|{"^o":"ObjectJuice::Jam","x":{"a":1}}|, json)
947
- end
948
-
949
- def test_odd_date
950
- dump_and_load(Date.new(2012, 6, 19), false)
951
-
952
- Oj.register_odd(Date, Date, :jd, :jd)
953
- json = Oj.dump(Date.new(2015, 3, 7), :mode => :object)
954
- assert_equal(%|{"^O":"Date","jd":2457089}|, json)
955
- dump_and_load(Date.new(2012, 6, 19), false)
956
- end
957
-
958
- def test_odd_datetime
959
- dump_and_load(DateTime.new(2012, 6, 19, 13, 5, Rational(4, 3)), false)
960
- dump_and_load(DateTime.new(2012, 6, 19, 13, 5, Rational(7123456789, 1000000000)), false)
961
- end
962
-
963
- def test_bag
964
- json = %{{
965
- "^o":"ObjectJuice::Jem",
966
- "x":true,
967
- "y":58 }}
968
- obj = Oj.load(json, :mode => :object, :auto_define => true)
969
- assert_equal('ObjectJuice::Jem', obj.class.name)
970
- assert_equal(true, obj.x)
971
- assert_equal(58, obj.y)
972
- end
973
-
974
- def test_odd_string
975
- Oj.register_odd(Strung, Strung, :create, :to_s, 'safe?')
976
- s = Strung.new("Pete", true)
977
- dump_and_load(s, false)
978
- end
979
-
980
- def test_odd_raw
981
- Oj.register_odd_raw(Raw, Raw, :create, :to_json)
982
- json = Oj.dump(Raw.new(%|{"a":1}|), :mode => :object)
983
- assert_equal(%|{"^O":"ObjectJuice::Raw","to_json":{"a":1}}|, json)
984
- h = Oj.load(json, :mode => :object)
985
- assert_equal({'a' => 1}, h)
986
- end
987
-
988
- def test_odd_mod
989
- Oj.register_odd(Ichi::Ni, Ichi::Ni, :direct, :dump)
990
- json = Oj.dump(Ichi::Ni::San::Shi.new({'a' => 1}), :mode => :object)
991
- assert_equal(%|{"^O":"ObjectJuice::Ichi::Ni::San::Shi","dump":{"a":1}}|, json)
992
- h = Oj.load(json, :mode => :object)
993
- assert_equal({'a' => 1}, h)
994
- end
995
-
996
- def test_auto_string
997
- s = AutoStrung.new("Pete", true)
998
- dump_and_load(s, false)
999
- end
1000
-
1001
- def test_auto_array
1002
- a = AutoArray.new([1, 'abc', nil], true)
1003
- dump_and_load(a, false)
1004
- end
1005
-
1006
- def test_auto_hash
1007
- h = AutoHash.new(nil, true)
1008
- h['a'] = 1
1009
- h['b'] = 2
1010
- dump_and_load(h, false)
1011
- end
1012
-
1013
- def dump_and_load(obj, trace=false)
1014
- json = Oj.dump(obj, :indent => 2, :mode => :object)
1015
- puts json if trace
1016
- loaded = Oj.object_load(json);
1017
- if obj.nil?
1018
- assert_nil(loaded)
1019
- else
1020
- assert_equal(obj, loaded)
1021
- end
1022
- loaded
1023
- end
1024
-
1025
- end