oj 2.18.3 → 3.13.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1324 -0
  3. data/README.md +51 -204
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +49 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -68
  11. data/ext/oj/circarray.h +16 -42
  12. data/ext/oj/code.c +221 -0
  13. data/ext/oj/code.h +40 -0
  14. data/ext/oj/compat.c +231 -107
  15. data/ext/oj/custom.c +1125 -0
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +935 -2513
  18. data/ext/oj/dump.h +108 -0
  19. data/ext/oj/dump_compat.c +936 -0
  20. data/ext/oj/dump_leaf.c +164 -0
  21. data/ext/oj/dump_object.c +761 -0
  22. data/ext/oj/dump_strict.c +410 -0
  23. data/ext/oj/encode.h +7 -42
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -54
  26. data/ext/oj/err.h +52 -46
  27. data/ext/oj/extconf.rb +21 -30
  28. data/ext/oj/fast.c +1097 -1080
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +893 -0
  32. data/ext/oj/object.c +549 -620
  33. data/ext/oj/odd.c +155 -167
  34. data/ext/oj/odd.h +37 -63
  35. data/ext/oj/oj.c +1661 -2063
  36. data/ext/oj/oj.h +341 -270
  37. data/ext/oj/parse.c +974 -737
  38. data/ext/oj/parse.h +105 -97
  39. data/ext/oj/parser.c +1526 -0
  40. data/ext/oj/parser.h +90 -0
  41. data/ext/oj/rails.c +1504 -0
  42. data/ext/oj/rails.h +18 -0
  43. data/ext/oj/reader.c +141 -163
  44. data/ext/oj/reader.h +75 -113
  45. data/ext/oj/resolve.c +45 -93
  46. data/ext/oj/resolve.h +7 -34
  47. data/ext/oj/rxclass.c +143 -0
  48. data/ext/oj/rxclass.h +26 -0
  49. data/ext/oj/saj.c +447 -511
  50. data/ext/oj/saj2.c +348 -0
  51. data/ext/oj/scp.c +91 -138
  52. data/ext/oj/sparse.c +793 -644
  53. data/ext/oj/stream_writer.c +331 -0
  54. data/ext/oj/strict.c +145 -109
  55. data/ext/oj/string_writer.c +493 -0
  56. data/ext/oj/trace.c +72 -0
  57. data/ext/oj/trace.h +28 -0
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +62 -70
  62. data/ext/oj/val_stack.h +95 -129
  63. data/ext/oj/validate.c +51 -0
  64. data/ext/oj/wab.c +622 -0
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +17 -8
  67. data/lib/oj/error.rb +10 -11
  68. data/lib/oj/json.rb +176 -0
  69. data/lib/oj/mimic.rb +158 -19
  70. data/lib/oj/state.rb +132 -0
  71. data/lib/oj/version.rb +2 -2
  72. data/lib/oj.rb +1 -31
  73. data/pages/Advanced.md +22 -0
  74. data/pages/Compatibility.md +25 -0
  75. data/pages/Custom.md +23 -0
  76. data/pages/Encoding.md +65 -0
  77. data/pages/JsonGem.md +94 -0
  78. data/pages/Modes.md +161 -0
  79. data/pages/Options.md +327 -0
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +167 -0
  82. data/pages/Security.md +20 -0
  83. data/pages/WAB.md +13 -0
  84. data/test/activerecord/result_test.rb +32 -0
  85. data/test/activesupport4/decoding_test.rb +108 -0
  86. data/test/activesupport4/encoding_test.rb +531 -0
  87. data/test/activesupport4/test_helper.rb +41 -0
  88. data/test/activesupport5/abstract_unit.rb +45 -0
  89. data/test/activesupport5/decoding_test.rb +133 -0
  90. data/test/activesupport5/encoding_test.rb +500 -0
  91. data/test/activesupport5/encoding_test_cases.rb +98 -0
  92. data/test/activesupport5/test_helper.rb +72 -0
  93. data/test/activesupport5/time_zone_test_helpers.rb +39 -0
  94. data/test/activesupport6/abstract_unit.rb +44 -0
  95. data/test/activesupport6/decoding_test.rb +133 -0
  96. data/test/activesupport6/encoding_test.rb +507 -0
  97. data/test/activesupport6/encoding_test_cases.rb +98 -0
  98. data/test/activesupport6/test_common.rb +17 -0
  99. data/test/activesupport6/test_helper.rb +163 -0
  100. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  101. data/test/activesupport7/abstract_unit.rb +49 -0
  102. data/test/activesupport7/decoding_test.rb +125 -0
  103. data/test/activesupport7/encoding_test.rb +486 -0
  104. data/test/activesupport7/encoding_test_cases.rb +104 -0
  105. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  106. data/test/bar.rb +9 -0
  107. data/test/baz.rb +16 -0
  108. data/test/bug.rb +11 -46
  109. data/test/foo.rb +69 -16
  110. data/test/helper.rb +10 -1
  111. data/test/isolated/shared.rb +12 -8
  112. data/test/isolated/test_mimic_rails_after.rb +3 -3
  113. data/test/isolated/test_mimic_rails_before.rb +3 -3
  114. data/test/json_gem/json_addition_test.rb +216 -0
  115. data/test/json_gem/json_common_interface_test.rb +153 -0
  116. data/test/json_gem/json_encoding_test.rb +107 -0
  117. data/test/json_gem/json_ext_parser_test.rb +20 -0
  118. data/test/json_gem/json_fixtures_test.rb +35 -0
  119. data/test/json_gem/json_generator_test.rb +397 -0
  120. data/test/json_gem/json_generic_object_test.rb +90 -0
  121. data/test/json_gem/json_parser_test.rb +470 -0
  122. data/test/json_gem/json_string_matching_test.rb +42 -0
  123. data/test/json_gem/test_helper.rb +26 -0
  124. data/test/mem.rb +33 -0
  125. data/test/perf.rb +1 -1
  126. data/test/perf_compat.rb +30 -28
  127. data/test/perf_dump.rb +50 -0
  128. data/test/perf_object.rb +1 -1
  129. data/test/perf_once.rb +58 -0
  130. data/test/perf_parser.rb +189 -0
  131. data/test/perf_scp.rb +11 -10
  132. data/test/perf_strict.rb +30 -19
  133. data/test/perf_wab.rb +131 -0
  134. data/test/prec.rb +23 -0
  135. data/test/sample.rb +0 -1
  136. data/test/sample_json.rb +1 -1
  137. data/test/test_compat.rb +219 -102
  138. data/test/test_custom.rb +533 -0
  139. data/test/test_fast.rb +107 -35
  140. data/test/test_file.rb +19 -25
  141. data/test/test_generate.rb +21 -0
  142. data/test/test_hash.rb +11 -1
  143. data/test/test_integer_range.rb +72 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +357 -70
  146. data/test/test_parser.rb +27 -0
  147. data/test/test_parser_saj.rb +245 -0
  148. data/test/test_parser_usual.rb +217 -0
  149. data/test/test_rails.rb +35 -0
  150. data/test/test_saj.rb +1 -1
  151. data/test/test_scp.rb +39 -2
  152. data/test/test_strict.rb +186 -7
  153. data/test/test_various.rb +160 -774
  154. data/test/test_wab.rb +307 -0
  155. data/test/test_writer.rb +90 -2
  156. data/test/tests.rb +24 -0
  157. data/test/tests_mimic.rb +14 -0
  158. data/test/tests_mimic_addition.rb +7 -0
  159. data/test/zoo.rb +13 -0
  160. metadata +194 -56
  161. data/ext/oj/hash.c +0 -163
  162. data/ext/oj/hash.h +0 -46
  163. data/ext/oj/hash_test.c +0 -512
  164. data/test/activesupport_datetime_test.rb +0 -23
  165. data/test/bug2.rb +0 -10
  166. data/test/bug3.rb +0 -46
  167. data/test/bug_fast.rb +0 -32
  168. data/test/bug_load.rb +0 -24
  169. data/test/crash.rb +0 -111
  170. data/test/curl/curl_oj.rb +0 -46
  171. data/test/curl/get_oj.rb +0 -24
  172. data/test/curl/just_curl.rb +0 -31
  173. data/test/curl/just_oj.rb +0 -51
  174. data/test/example.rb +0 -11
  175. data/test/io.rb +0 -48
  176. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  177. data/test/mod.rb +0 -16
  178. data/test/rails.rb +0 -50
  179. data/test/russian.rb +0 -18
  180. data/test/struct.rb +0 -29
  181. data/test/test_serializer.rb +0 -59
  182. data/test/write_timebars.rb +0 -31
data/test/test_object.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
2
+ # encoding: utf-8
3
3
 
4
4
  $: << File.dirname(__FILE__)
5
5
 
@@ -7,11 +7,12 @@ require 'helper'
7
7
 
8
8
  class ObjectJuice < Minitest::Test
9
9
  class Jeez
10
- attr_accessor :x, :y
10
+ attr_accessor :x, :y, :_z
11
11
 
12
12
  def initialize(x, y)
13
13
  @x = x
14
14
  @y = y
15
+ @_z = x.to_s
15
16
  end
16
17
 
17
18
  def eql?(o)
@@ -28,6 +29,49 @@ class ObjectJuice < Minitest::Test
28
29
  end
29
30
  end # Jeez
30
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
+
31
75
  module One
32
76
  module Two
33
77
  module Three
@@ -177,6 +221,13 @@ class ObjectJuice < Minitest::Test
177
221
 
178
222
  def teardown
179
223
  Oj.default_options = @default_options
224
+ #=begin
225
+ if '3.1.0' <= RUBY_VERSION && !(RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/)
226
+ #Oj::debug_odd("teardown before GC.verify_compaction_references")
227
+ GC.verify_compaction_references(double_heap: true, toward: :empty)
228
+ #Oj::debug_odd("teardown after GC.verify_compaction_references")
229
+ end
230
+ #=end
180
231
  end
181
232
 
182
233
  def test_nil
@@ -208,6 +259,12 @@ class ObjectJuice < Minitest::Test
208
259
  dump_and_load(2.48e16, false)
209
260
  dump_and_load(2.48e100 * 1.0e10, false)
210
261
  dump_and_load(-2.48e100 * 1.0e10, false)
262
+ dump_and_load(1/0.0, false)
263
+ # NaN does not always == NaN
264
+ json = Oj.dump(0/0.0, :mode => :object)
265
+ assert_equal('3.3e14159265358979323846', json)
266
+ loaded = Oj.load(json);
267
+ assert_equal(true, loaded.nan?)
211
268
  end
212
269
 
213
270
  def test_string
@@ -220,6 +277,7 @@ class ObjectJuice < Minitest::Test
220
277
  def test_symbol
221
278
  dump_and_load(:abc, false)
222
279
  dump_and_load(":abc", false)
280
+ dump_and_load(':xyz'.to_sym, false)
223
281
  end
224
282
 
225
283
  def test_encode
@@ -295,15 +353,20 @@ class ObjectJuice < Minitest::Test
295
353
 
296
354
  # BigDecimal
297
355
  def test_bigdecimal_object
298
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
356
+ dump_and_load(BigDecimal('3.14159265358979323846'), false)
299
357
  end
300
358
 
301
359
  def test_bigdecimal_load
302
- orig = BigDecimal.new('80.51')
360
+ orig = BigDecimal('80.51')
303
361
  json = Oj.dump(orig, :mode => :object, :bigdecimal_as_decimal => true)
304
362
  bg = Oj.load(json, :mode => :object, :bigdecimal_load => true)
305
363
  assert_equal(BigDecimal, bg.class)
306
364
  assert_equal(orig, bg)
365
+ # Infinity is the same for Float and BigDecimal
366
+ json = Oj.dump(BigDecimal('Infinity'), :mode => :object)
367
+ assert_equal('Infinity', json)
368
+ json = Oj.dump(BigDecimal('-Infinity'), :mode => :object)
369
+ assert_equal('-Infinity', json)
307
370
  end
308
371
 
309
372
  # Stream IO
@@ -345,6 +408,22 @@ class ObjectJuice < Minitest::Test
345
408
  assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
346
409
  end
347
410
 
411
+ def test_class_object
412
+ dump_and_load(ObjectJuice, false)
413
+ end
414
+
415
+ def test_module_object
416
+ dump_and_load(One, false)
417
+ end
418
+
419
+ def test_non_str_hash_object
420
+ json = Oj.dump({ 1 => true, :sim => nil }, :mode => :object)
421
+ h = Oj.load(json, :mode => :strict)
422
+ assert_equal({"^#1" => [1, true], ":sim" => nil}, h)
423
+ h = Oj.load(json, :mode => :object)
424
+ assert_equal({ 1 => true, :sim => nil }, h)
425
+ end
426
+
348
427
  # comments
349
428
  def test_comment_slash
350
429
  json = %{{
@@ -387,11 +466,7 @@ class ObjectJuice < Minitest::Test
387
466
  end
388
467
 
389
468
  def test_xml_time
390
- if RUBY_VERSION.start_with?('1.8')
391
- t = Time.parse('2015-01-05T21:37:07.123456789-08:00')
392
- else
393
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
394
- end
469
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
395
470
  # The fractional seconds are not always recreated exactly which causes a
396
471
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
397
472
  # separately along with utc.
@@ -409,11 +484,7 @@ class ObjectJuice < Minitest::Test
409
484
  end
410
485
 
411
486
  def test_xml_time_utc
412
- if RUBY_VERSION.start_with?('1.8')
413
- t = Time.parse('2015-01-05T21:37:07.123456789Z')
414
- else
415
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
416
- end
487
+ t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
417
488
  # The fractional seconds are not always recreated exactly which causes a
418
489
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
419
490
  # separately along with utc.
@@ -430,11 +501,7 @@ class ObjectJuice < Minitest::Test
430
501
  end
431
502
 
432
503
  def test_ruby_time
433
- if RUBY_VERSION.start_with?('1.8')
434
- t = Time.parse('2015-01-05T21:37:07.123456789-08:00')
435
- else
436
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
437
- end
504
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
438
505
  # The fractional seconds are not always recreated exactly which causes a
439
506
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
440
507
  # separately along with utc.
@@ -452,11 +519,7 @@ class ObjectJuice < Minitest::Test
452
519
  end
453
520
 
454
521
  def test_ruby_time_12345
455
- if RUBY_VERSION.start_with?('1.8')
456
- t = Time.parse('2015-01-05T21:37:07.123456789+03:25')
457
- else
458
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345/60*60)
459
- end
522
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345/60*60)
460
523
  # The fractional seconds are not always recreated exactly which causes a
461
524
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
462
525
  # separately along with utc.
@@ -475,11 +538,7 @@ class ObjectJuice < Minitest::Test
475
538
  end
476
539
 
477
540
  def test_ruby_time_utc
478
- if RUBY_VERSION.start_with?('1.8')
479
- t = Time.parse('2015-01-05T21:37:07.123456789Z')
480
- else
481
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
482
- end
541
+ t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
483
542
  # The fractional seconds are not always recreated exactly which causes a
484
543
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
485
544
  # separately along with utc.
@@ -497,11 +556,10 @@ class ObjectJuice < Minitest::Test
497
556
  end
498
557
 
499
558
  def test_time_early
500
- if RUBY_VERSION.start_with?('1.8')
501
- t = Time.parse('1954-01-05T21:37:07.123456789-08:00')
502
- else
503
- t = Time.new(1954, 1, 5, 21, 37, 7.123456789, -8 * 3600)
504
- end
559
+ # Windows does not support dates before 1970.
560
+ return if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
561
+
562
+ t = Time.new(1954, 1, 5, 21, 37, 7.123456789, -8 * 3600)
505
563
  # The fractional seconds are not always recreated exactly which causes a
506
564
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
507
565
  # separately along with utc.
@@ -519,11 +577,7 @@ class ObjectJuice < Minitest::Test
519
577
  end
520
578
 
521
579
  def test_time_unix_zone
522
- if RUBY_VERSION.start_with?('1.8')
523
- t = Time.parse('2015-01-05T21:37:07.123456789-08:00')
524
- else
525
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
526
- end
580
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456789, -8 * 3600)
527
581
  # The fractional seconds are not always recreated exactly which causes a
528
582
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
529
583
  # separately along with utc.
@@ -540,32 +594,26 @@ class ObjectJuice < Minitest::Test
540
594
  assert_equal(t.utc_offset, loaded.utc_offset)
541
595
  end
542
596
 
543
- unless RUBY_VERSION.start_with?('1.8')
544
- def test_time_unix_zone_12345
545
- t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345)
546
- # The fractional seconds are not always recreated exactly which causes a
547
- # mismatch so instead the seconds, nsecs, and gmt_offset are checked
548
- # separately along with utc.
549
- json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
550
- #puts json
551
- loaded = Oj.object_load(json);
552
- assert_equal(t.tv_sec, loaded.tv_sec)
553
- if t.respond_to?(:tv_nsec)
554
- assert_equal(t.tv_nsec, loaded.tv_nsec)
555
- else
556
- assert_equal(t.tv_usec, loaded.tv_usec)
557
- end
558
- assert_equal(t.utc?, loaded.utc?)
559
- assert_equal(t.utc_offset, loaded.utc_offset)
597
+ def test_time_unix_zone_12345
598
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456789, 12345)
599
+ # The fractional seconds are not always recreated exactly which causes a
600
+ # mismatch so instead the seconds, nsecs, and gmt_offset are checked
601
+ # separately along with utc.
602
+ json = Oj.dump(t, :mode => :object, :time_format => :unix_zone)
603
+ #puts json
604
+ loaded = Oj.object_load(json);
605
+ assert_equal(t.tv_sec, loaded.tv_sec)
606
+ if t.respond_to?(:tv_nsec)
607
+ assert_equal(t.tv_nsec, loaded.tv_nsec)
608
+ else
609
+ assert_equal(t.tv_usec, loaded.tv_usec)
560
610
  end
611
+ assert_equal(t.utc?, loaded.utc?)
612
+ assert_equal(t.utc_offset, loaded.utc_offset)
561
613
  end
562
614
 
563
615
  def test_time_unix_zone_utc
564
- if RUBY_VERSION.start_with?('1.8')
565
- t = Time.parse('2015-01-05T21:37:07.123456789Z')
566
- else
567
- t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
568
- end
616
+ t = Time.utc(2015, 1, 5, 21, 37, 7.123456789)
569
617
  # The fractional seconds are not always recreated exactly which causes a
570
618
  # mismatch so instead the seconds, nsecs, and gmt_offset are checked
571
619
  # separately along with utc.
@@ -597,7 +645,7 @@ class ObjectJuice < Minitest::Test
597
645
  begin
598
646
  Oj.object_load(json)
599
647
  rescue Exception => e
600
- assert_equal("Oj::ParseError", e.class().name)
648
+ assert_equal("ArgumentError", e.class().name)
601
649
  return
602
650
  end
603
651
  assert(false, "*** expected an exception")
@@ -645,6 +693,151 @@ class ObjectJuice < Minitest::Test
645
693
  assert_equal({ 1 => true, 'nil' => nil, :sim => 4 }, h)
646
694
  end
647
695
 
696
+ def test_json_object_object
697
+ obj = Jeez.new(true, 58)
698
+ json = Oj.dump(obj, mode: :object, indent: 2, ignore_under: true)
699
+ assert(%{{
700
+ "^o":"ObjectJuice::Jeez",
701
+ "x":true,
702
+ "y":58
703
+ }
704
+ } == json ||
705
+ %{{
706
+ "^o":"ObjectJuice::Jeez",
707
+ "y":58,
708
+ "x":true
709
+ }
710
+ } == json)
711
+ obj2 = Oj.load(json, :mode => :object)
712
+ assert_equal(obj, obj2)
713
+ end
714
+
715
+ def test_to_hash_object_object
716
+ obj = Jazz.new(true, 58)
717
+ json = Oj.dump(obj, :mode => :object, :indent => 2)
718
+ assert(%{{
719
+ "^o":"ObjectJuice::Jazz",
720
+ "x":true,
721
+ "y":58
722
+ }
723
+ } == json ||
724
+ %{{
725
+ "^o":"ObjectJuice::Jazz",
726
+ "y":58,
727
+ "x":true
728
+ }
729
+ } == json)
730
+ obj2 = Oj.load(json, :mode => :object)
731
+ assert_equal(obj, obj2)
732
+ end
733
+
734
+ def test_as_json_object_object
735
+ obj = Orange.new(true, 58)
736
+ json = Oj.dump(obj, :mode => :object, :indent => 2)
737
+ assert(%{{
738
+ "^o":"ObjectJuice::Orange",
739
+ "x":true,
740
+ "y":58
741
+ }
742
+ } == json ||
743
+ %{{
744
+ "^o":"ObjectJuice::Orange",
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
+ def test_object_object_no_cache
754
+ obj = Jam.new(true, 58)
755
+ json = Oj.dump(obj, :mode => :object, :indent => 2)
756
+ assert(%{{
757
+ "^o":"ObjectJuice::Jam",
758
+ "x":true,
759
+ "y":58
760
+ }
761
+ } == json ||
762
+ %{{
763
+ "^o":"ObjectJuice::Jam",
764
+ "y":58,
765
+ "x":true
766
+ }
767
+ } == json)
768
+ obj2 = Oj.load(json, :mode => :object, :class_cache => false)
769
+ assert_equal(obj, obj2)
770
+ end
771
+
772
+ def test_ignore
773
+ obj = Jeez.new(true, 58)
774
+ json = Oj.dump({ 'a' => 7, 'b' => obj }, :mode => :object, :indent => 2, :ignore => [ Jeez ])
775
+ assert_equal(%|{
776
+ "a":7
777
+ }
778
+ |, json)
779
+ end
780
+
781
+ def test_exception
782
+ err = nil
783
+ begin
784
+ raise StandardError.new('A Message')
785
+ rescue Exception => e
786
+ err = e
787
+ end
788
+ json = Oj.dump(err, :mode => :object, :indent => 2)
789
+ #puts "*** #{json}"
790
+ e2 = Oj.load(json, :mode => :strict)
791
+ assert_equal(err.class.to_s, e2['^o'])
792
+ assert_equal(err.message, e2['~mesg'])
793
+ assert_equal(err.backtrace, e2['~bt'])
794
+ e2 = Oj.load(json, :mode => :object)
795
+ if 'rubinius' == $ruby
796
+ assert_equal(e.class, e2.class);
797
+ assert_equal(e.message, e2.message);
798
+ assert_equal(e.backtrace, e2.backtrace);
799
+ else
800
+ assert_equal(e, e2);
801
+ end
802
+ end
803
+
804
+ class SubX < Exception
805
+ def initialize
806
+ super("sub")
807
+ @xyz = 123
808
+ end
809
+ end
810
+
811
+ def test_exception_subclass
812
+ err = nil
813
+ begin
814
+ raise SubX.new
815
+ rescue Exception => e
816
+ err = e
817
+ end
818
+ json = Oj.dump(err, :mode => :object, :indent => 2)
819
+ #puts "*** #{json}"
820
+ e2 = Oj.load(json, :mode => :strict)
821
+ assert_equal(err.class.to_s, e2['^o'])
822
+ assert_equal(err.message, e2['~mesg'])
823
+ assert_equal(err.backtrace, e2['~bt'])
824
+ e2 = Oj.load(json, :mode => :object)
825
+ assert_equal(e, e2);
826
+ end
827
+
828
+ def test_range_object
829
+ Oj.default_options = { :mode => :object }
830
+ json = Oj.dump(1..7, :mode => :object, :indent => 0)
831
+ if 'rubinius' == $ruby
832
+ assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
833
+ else
834
+ assert_equal(%{{"^u":["Range",1,7,false]}}, json)
835
+ end
836
+ dump_and_load(1..7, false)
837
+ dump_and_load(1..1, false)
838
+ dump_and_load(1...7, false)
839
+ end
840
+
648
841
  def test_circular_hash
649
842
  h = { 'a' => 7 }
650
843
  h['b'] = h
@@ -653,6 +846,14 @@ class ObjectJuice < Minitest::Test
653
846
  assert_equal(h2['b'].__id__, h2.__id__)
654
847
  end
655
848
 
849
+
850
+ def test_json_object_missing_fields
851
+ json = %{{ "^u": [ "ObjectJuice::Stuck",1]}}
852
+
853
+ obj = Oj.load(json, mode: :object)
854
+ assert_nil(obj['b'])
855
+ end
856
+
656
857
  def test_circular_array
657
858
  a = [7]
658
859
  a << a
@@ -661,6 +862,38 @@ class ObjectJuice < Minitest::Test
661
862
  assert_equal(a2[1].__id__, a2.__id__)
662
863
  end
663
864
 
865
+ def test_circular_array2
866
+ a = [7]
867
+ a << a
868
+ json = Oj.dump(a, :mode => :object, :indent => 2, :circular => true)
869
+ assert_equal(%{[
870
+ "^i1",
871
+ 7,
872
+ "^r1"
873
+ ]
874
+ }, json)
875
+ a2 = Oj.load(json, :mode => :object, :circular => true)
876
+ assert_equal(a2[1].__id__, a2.__id__)
877
+ end
878
+
879
+ def test_circular_array3
880
+ a = ['^r1']
881
+ json = Oj.dump(a, mode: :object, circular: true)
882
+ assert_equal(%{["^i1","\\u005er1"]}, json)
883
+ a2 = Oj.load(json, mode: :object, circular: true)
884
+ assert_equal(a, a2)
885
+ end
886
+
887
+ def test_circular_hash2
888
+ h = { 'a' => 7 }
889
+ h['b'] = h
890
+ json = Oj.dump(h, :mode => :object, :indent => 2, :circular => true)
891
+ ha = Oj.load(json, :mode => :strict)
892
+ assert_equal({'^i' => 1, 'a' => 7, 'b' => '^r1'}, ha)
893
+ Oj.load(json, :mode => :object, :circular => true)
894
+ assert_equal(h['b'].__id__, h.__id__)
895
+ end
896
+
664
897
  def test_circular_object
665
898
  obj = Jeez.new(nil, 58)
666
899
  obj.x = obj
@@ -669,6 +902,28 @@ class ObjectJuice < Minitest::Test
669
902
  assert_equal(obj2.x.__id__, obj2.__id__)
670
903
  end
671
904
 
905
+ def test_circular_object2
906
+ obj = Jam.new(nil, 58)
907
+ obj.x = obj
908
+ json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
909
+ assert(%{{
910
+ "^o":"ObjectJuice::Jam",
911
+ "^i":1,
912
+ "x":"^r1",
913
+ "y":58
914
+ }
915
+ } == json ||
916
+ %{{
917
+ "^o":"ObjectJuice::Jam",
918
+ "^i":1,
919
+ "y":58,
920
+ "x":"^r1"
921
+ }
922
+ } == json)
923
+ obj2 = Oj.load(json, :mode => :object, :circular => true)
924
+ assert_equal(obj2.x.__id__, obj2.__id__)
925
+ end
926
+
672
927
  def test_circular
673
928
  h = { 'a' => 7 }
674
929
  obj = Jeez.new(h, 58)
@@ -679,8 +934,32 @@ class ObjectJuice < Minitest::Test
679
934
  assert_equal(h['b'].__id__, obj.__id__)
680
935
  end
681
936
 
937
+ def test_circular2
938
+ h = { 'a' => 7 }
939
+ obj = Jam.new(h, 58)
940
+ obj.x['b'] = obj
941
+ json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
942
+ ha = Oj.load(json, :mode => :strict)
943
+ assert_equal({'^o' => 'ObjectJuice::Jam', '^i' => 1, 'x' => { '^i' => 2, 'a' => 7, 'b' => '^r1' }, 'y' => 58 }, ha)
944
+ Oj.load(json, :mode => :object, :circular => true)
945
+ assert_equal(obj.x.__id__, h.__id__)
946
+ assert_equal(h['b'].__id__, obj.__id__)
947
+ end
948
+
949
+ def test_omit_nil
950
+ jam = Jam.new({'a' => 1, 'b' => nil }, nil)
951
+
952
+ json = Oj.dump(jam, :omit_nil => true, :mode => :object)
953
+ assert_equal(%|{"^o":"ObjectJuice::Jam","x":{"a":1}}|, json)
954
+ end
955
+
682
956
  def test_odd_date
683
957
  dump_and_load(Date.new(2012, 6, 19), false)
958
+
959
+ Oj.register_odd(Date, Date, :jd, :jd)
960
+ json = Oj.dump(Date.new(2015, 3, 7), :mode => :object)
961
+ assert_equal(%|{"^O":"Date","jd":2457089}|, json)
962
+ dump_and_load(Date.new(2012, 6, 19), false)
684
963
  end
685
964
 
686
965
  def test_odd_datetime
@@ -688,19 +967,23 @@ class ObjectJuice < Minitest::Test
688
967
  dump_and_load(DateTime.new(2012, 6, 19, 13, 5, Rational(7123456789, 1000000000)), false)
689
968
  end
690
969
 
970
+ def test_bag
971
+ json = %{{
972
+ "^o":"ObjectJuice::Jem",
973
+ "x":true,
974
+ "y":58 }}
975
+ obj = Oj.load(json, :mode => :object, :auto_define => true)
976
+ assert_equal('ObjectJuice::Jem', obj.class.name)
977
+ assert_equal(true, obj.x)
978
+ assert_equal(58, obj.y)
979
+ end
980
+
691
981
  def test_odd_string
692
982
  Oj.register_odd(Strung, Strung, :create, :to_s, 'safe?')
693
983
  s = Strung.new("Pete", true)
694
984
  dump_and_load(s, false)
695
985
  end
696
986
 
697
- def test_odd_date_replaced
698
- Oj.register_odd(Date, Date, :jd, :jd)
699
- json = Oj.dump(Date.new(2015, 3, 7), :mode => :object)
700
- assert_equal(%|{"^O":"Date","jd":2457089}|, json)
701
- dump_and_load(Date.new(2012, 6, 19), false)
702
- end
703
-
704
987
  def test_odd_raw
705
988
  Oj.register_odd_raw(Raw, Raw, :create, :to_json)
706
989
  json = Oj.dump(Raw.new(%|{"a":1}|), :mode => :object)
@@ -738,7 +1021,11 @@ class ObjectJuice < Minitest::Test
738
1021
  json = Oj.dump(obj, :indent => 2, :mode => :object)
739
1022
  puts json if trace
740
1023
  loaded = Oj.object_load(json);
741
- assert_equal(obj, loaded)
1024
+ if obj.nil?
1025
+ assert_nil(loaded)
1026
+ else
1027
+ assert_equal(obj, loaded)
1028
+ end
742
1029
  loaded
743
1030
  end
744
1031
 
@@ -0,0 +1,27 @@
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 ParserJuice < Minitest::Test
18
+
19
+ def test_array
20
+ p = Oj::Parser.new(:debug)
21
+ out = p.parse(%|[true, false, null, 123, -1.23, "abc"]|)
22
+ puts out
23
+ out = p.parse(%|{"abc": []}|)
24
+ puts out
25
+ end
26
+
27
+ end