oj 2.18.5 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -226
  3. data/ext/oj/circarray.c +0 -25
  4. data/ext/oj/circarray.h +0 -25
  5. data/ext/oj/code.c +227 -0
  6. data/ext/oj/code.h +40 -0
  7. data/ext/oj/compat.c +126 -38
  8. data/ext/oj/custom.c +1097 -0
  9. data/ext/oj/dump.c +658 -2376
  10. data/ext/oj/dump.h +92 -0
  11. data/ext/oj/dump_compat.c +937 -0
  12. data/ext/oj/dump_leaf.c +254 -0
  13. data/ext/oj/dump_object.c +810 -0
  14. data/ext/oj/dump_rails.c +329 -0
  15. data/ext/oj/dump_strict.c +416 -0
  16. data/ext/oj/err.c +0 -25
  17. data/ext/oj/err.h +8 -2
  18. data/ext/oj/fast.c +24 -24
  19. data/ext/oj/mimic_json.c +817 -0
  20. data/ext/oj/mimic_rails.c +806 -0
  21. data/ext/oj/mimic_rails.h +17 -0
  22. data/ext/oj/object.c +18 -72
  23. data/ext/oj/odd.c +0 -25
  24. data/ext/oj/odd.h +2 -27
  25. data/ext/oj/oj.c +655 -1503
  26. data/ext/oj/oj.h +93 -40
  27. data/ext/oj/parse.c +99 -46
  28. data/ext/oj/parse.h +12 -26
  29. data/ext/oj/reader.c +1 -25
  30. data/ext/oj/reader.h +3 -25
  31. data/ext/oj/resolve.c +9 -11
  32. data/ext/oj/resolve.h +2 -2
  33. data/ext/oj/rxclass.c +133 -0
  34. data/ext/oj/rxclass.h +27 -0
  35. data/ext/oj/saj.c +4 -25
  36. data/ext/oj/scp.c +3 -25
  37. data/ext/oj/sparse.c +89 -13
  38. data/ext/oj/stream_writer.c +301 -0
  39. data/ext/oj/strict.c +4 -27
  40. data/ext/oj/string_writer.c +480 -0
  41. data/ext/oj/val_stack.h +6 -2
  42. data/lib/oj.rb +1 -23
  43. data/lib/oj/easy_hash.rb +12 -4
  44. data/lib/oj/json.rb +172 -0
  45. data/lib/oj/mimic.rb +123 -18
  46. data/lib/oj/state.rb +131 -0
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Advanced.md +22 -0
  49. data/pages/Compatibility.md +25 -0
  50. data/pages/Custom.md +23 -0
  51. data/pages/Encoding.md +65 -0
  52. data/pages/JsonGem.md +79 -0
  53. data/pages/Modes.md +140 -0
  54. data/pages/Options.md +250 -0
  55. data/pages/Rails.md +60 -0
  56. data/pages/Security.md +20 -0
  57. data/test/activesupport4/decoding_test.rb +105 -0
  58. data/test/activesupport4/encoding_test.rb +531 -0
  59. data/test/activesupport4/test_helper.rb +41 -0
  60. data/test/activesupport5/decoding_test.rb +125 -0
  61. data/test/activesupport5/encoding_test.rb +483 -0
  62. data/test/activesupport5/encoding_test_cases.rb +90 -0
  63. data/test/activesupport5/test_helper.rb +50 -0
  64. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  65. data/test/json_gem/json_addition_test.rb +216 -0
  66. data/test/json_gem/json_common_interface_test.rb +143 -0
  67. data/test/json_gem/json_encoding_test.rb +109 -0
  68. data/test/json_gem/json_ext_parser_test.rb +20 -0
  69. data/test/json_gem/json_fixtures_test.rb +35 -0
  70. data/test/json_gem/json_generator_test.rb +383 -0
  71. data/test/json_gem/json_generic_object_test.rb +90 -0
  72. data/test/json_gem/json_parser_test.rb +470 -0
  73. data/test/json_gem/json_string_matching_test.rb +42 -0
  74. data/test/json_gem/test_helper.rb +18 -0
  75. data/test/perf_compat.rb +30 -28
  76. data/test/perf_object.rb +1 -1
  77. data/test/perf_strict.rb +18 -1
  78. data/test/sample.rb +0 -1
  79. data/test/test_compat.rb +169 -93
  80. data/test/test_custom.rb +355 -0
  81. data/test/test_file.rb +0 -8
  82. data/test/test_null.rb +376 -0
  83. data/test/test_object.rb +268 -3
  84. data/test/test_scp.rb +22 -1
  85. data/test/test_strict.rb +160 -4
  86. data/test/test_various.rb +52 -620
  87. data/test/tests.rb +14 -0
  88. data/test/tests_mimic.rb +14 -0
  89. data/test/tests_mimic_addition.rb +7 -0
  90. metadata +89 -47
  91. data/test/activesupport_datetime_test.rb +0 -23
  92. data/test/bug.rb +0 -51
  93. data/test/bug2.rb +0 -10
  94. data/test/bug3.rb +0 -46
  95. data/test/bug_fast.rb +0 -32
  96. data/test/bug_load.rb +0 -24
  97. data/test/crash.rb +0 -111
  98. data/test/curl/curl_oj.rb +0 -46
  99. data/test/curl/get_oj.rb +0 -24
  100. data/test/curl/just_curl.rb +0 -31
  101. data/test/curl/just_oj.rb +0 -51
  102. data/test/example.rb +0 -11
  103. data/test/foo.rb +0 -24
  104. data/test/io.rb +0 -48
  105. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  106. data/test/mod.rb +0 -16
  107. data/test/rails.rb +0 -50
  108. data/test/russian.rb +0 -18
  109. data/test/struct.rb +0 -29
  110. data/test/test_serializer.rb +0 -59
  111. data/test/write_timebars.rb +0 -31
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ #frozen_string_literal: false
4
+
5
+ require 'json_gem/test_helper'
6
+
7
+ require 'time'
8
+
9
+ class JSONStringMatchingTest < Test::Unit::TestCase
10
+ include Test::Unit::TestCaseOmissionSupport
11
+
12
+ class TestTime < ::Time
13
+ def self.json_create(string)
14
+ Time.parse(string)
15
+ end
16
+
17
+ def to_json(*)
18
+ %{"#{strftime('%FT%T%z')}"}
19
+ end
20
+
21
+ def ==(other)
22
+ to_i == other.to_i
23
+ end
24
+ end
25
+
26
+ def test_match_date
27
+ t = TestTime.new
28
+ t_json = [ t ].to_json
29
+ time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
30
+ assert_equal [ t ],
31
+ JSON.parse(
32
+ t_json,
33
+ :create_additions => true,
34
+ :match_string => { time_regexp => TestTime }
35
+ )
36
+ assert_equal [ t.strftime('%FT%T%z') ],
37
+ JSON.parse(
38
+ t_json,
39
+ :match_string => { time_regexp => TestTime }
40
+ )
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ $: << File.dirname(__FILE__)
2
+ $oj_dir = File.dirname(File.dirname(File.expand_path(File.dirname(__FILE__))))
3
+ %w(lib ext).each do |dir|
4
+ $: << File.join($oj_dir, dir)
5
+ end
6
+
7
+ require 'test/unit'
8
+ REAL_JSON_GEM = !!ENV['REAL_JSON_GEM']
9
+
10
+ if ENV['REAL_JSON_GEM']
11
+ require 'json'
12
+ else
13
+ require 'oj'
14
+ Oj.mimic_JSON
15
+ end
16
+
17
+ NaN = JSON::NaN if defined?(JSON::NaN)
18
+ NaN = 0.0/0 unless defined?(NaN)
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -wW1
1
+ #!/usr/bin/env ruby
2
2
  # encoding: UTF-8
3
3
 
4
4
  $: << '.'
@@ -12,8 +12,6 @@ require 'oj'
12
12
  $verbose = false
13
13
  $indent = 0
14
14
  $iter = 20000
15
- $with_bignum = false
16
- $with_nums = true
17
15
  $size = 0
18
16
 
19
17
  opts = OptionParser.new
@@ -24,25 +22,48 @@ opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
24
22
  opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
25
23
  files = opts.parse(ARGV)
26
24
 
25
+ def capture_error(tag, orig, load_key, dump_key, &blk)
26
+ begin
27
+ obj = blk.call(orig)
28
+ puts obj unless orig == obj
29
+ raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
30
+ rescue Exception => e
31
+ $failed[tag] = "#{e.class}: #{e.message}"
32
+ end
33
+ end
34
+
35
+ # Verify that all packages dump and load correctly and return the same Object as the original.
36
+ capture_error('Oj:compat', $obj, 'load', 'dump') { |o| Oj.compat_load(Oj.dump(o, :mode => :compat)) }
37
+ capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
38
+ require 'json'
39
+ require 'json/ext'
40
+ JSON.generator = JSON::Ext::Generator
41
+ JSON.parser = JSON::Ext::Parser
42
+ JSON.load(JSON.generate(o))
43
+ }
44
+
27
45
  module One
28
46
  module Two
29
47
  module Three
30
48
  class Empty
31
49
 
32
50
  def initialize()
51
+ @a = 1
52
+ @b = 2
53
+ @c = 3
33
54
  end
34
55
 
35
56
  def eql?(o)
36
- self.class == o.class
57
+ self.class == o.class && @a == o.a && @b = o.b && @c = o.c
37
58
  end
38
59
  alias == eql?
39
60
 
40
- def to_hash()
41
- {'json_class' => "#{self.class.name}"}
61
+ def as_json(*a)
62
+ {JSON.create_id => self.class.name, 'a' => @a, 'b' => @b, 'c' => @c }
42
63
  end
43
-
64
+
44
65
  def to_json(*a)
45
- %{{"json_class":"#{self.class.name}"}}
66
+ JSON.generate(as_json())
46
67
  end
47
68
 
48
69
  def self.json_create(h)
@@ -65,7 +86,7 @@ $obj = {
65
86
  'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
66
87
  }
67
88
 
68
- Oj.default_options = { :indent => $indent, :mode => :compat }
89
+ Oj.default_options = { :indent => $indent, :mode => :compat, :use_to_json => true, :create_additions => true, :create_id => '^o' }
69
90
 
70
91
  if 0 < $size
71
92
  s = Oj.dump($obj).size + 1
@@ -80,25 +101,6 @@ end
80
101
  $json = Oj.dump($obj)
81
102
  $failed = {} # key is same as String used in tests later
82
103
 
83
- def capture_error(tag, orig, load_key, dump_key, &blk)
84
- begin
85
- obj = blk.call(orig)
86
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
87
- rescue Exception => e
88
- $failed[tag] = "#{e.class}: #{e.message}"
89
- end
90
- end
91
-
92
- # Verify that all packages dump and load correctly and return the same Object as the original.
93
- capture_error('Oj:compat', $obj, 'load', 'dump') { |o| Oj.compat_load(Oj.dump(o, :mode => :compat)) }
94
- capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
95
- require 'json'
96
- require 'json/ext'
97
- JSON.generator = JSON::Ext::Generator
98
- JSON.parser = JSON::Ext::Parser
99
- JSON.load(JSON.generate(o))
100
- }
101
-
102
104
  if $verbose
103
105
  puts "size: #{$json.size}"
104
106
  puts "json:\n#{$json}\n"
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -wW1
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  $: << '.'
4
4
  $: << '../lib'
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -wW1
1
+ #!/usr/bin/env ruby
2
2
  # encoding: UTF-8
3
3
 
4
4
  $: << '.'
@@ -118,6 +118,23 @@ end
118
118
  perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
119
119
  perf.run($iter)
120
120
 
121
+ puts '-' * 80
122
+ puts "Strict Dump Performance"
123
+ perf = Perf.new()
124
+ unless $failed.has_key?('JSON::Ext')
125
+ perf.add('JSON::Ext', 'dump') { JSON.generate($obj) }
126
+ perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
127
+ end
128
+ unless $failed.has_key?('JSON::Pure')
129
+ perf.add('JSON::Pure', 'generate') { JSON.generate($obj) }
130
+ perf.before('JSON::Pure') { JSON.generator = JSON::Pure::Generator }
131
+ end
132
+ unless $failed.has_key?('Oj:strict')
133
+ perf.add('Oj:strict', 'dump') { Oj.dump($obj, :mode => :strict) }
134
+ end
135
+ perf.add('Yajl', 'encode') { Yajl::Encoder.encode($obj) } unless $failed.has_key?('Yajl')
136
+ perf.run($iter)
137
+
121
138
  puts
122
139
  puts '-' * 80
123
140
  puts
@@ -10,7 +10,6 @@ end
10
10
  require 'pp'
11
11
  require 'sample/doc'
12
12
 
13
-
14
13
  def sample_doc(size=3)
15
14
  colors = [ :black, :gray, :white, :red, :blue, :yellow, :green, :purple, :orange ]
16
15
 
@@ -2,8 +2,17 @@
2
2
  # encoding: UTF-8
3
3
 
4
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
5
9
 
6
- require 'helper'
10
+ require 'minitest'
11
+ require 'minitest/autorun'
12
+ require 'stringio'
13
+ require 'date'
14
+ require 'bigdecimal'
15
+ require 'oj'
7
16
 
8
17
  class CompatJuice < Minitest::Test
9
18
 
@@ -20,8 +29,8 @@ class CompatJuice < Minitest::Test
20
29
  end
21
30
  alias == eql?
22
31
 
23
- def as_json()
24
- {"json_class" => self.class.to_s,"x" => @x,"y" => @y}
32
+ def to_json()
33
+ %|{"json_class":"#{self.class.to_s}","x":#{@x},"y":#{@y}}|
25
34
  end
26
35
 
27
36
  def self.json_create(h)
@@ -42,12 +51,8 @@ class CompatJuice < Minitest::Test
42
51
  end
43
52
  alias == eql?
44
53
 
45
- def to_hash()
46
- {'json_class' => "#{self.class.name}"}
47
- end
48
-
49
54
  def to_json(*a)
50
- %{{"json_class":"#{self.class.name}"}}
55
+ %|{"json_class":"#{self.class.name}"}|
51
56
  end
52
57
 
53
58
  def self.json_create(h)
@@ -60,6 +65,9 @@ class CompatJuice < Minitest::Test
60
65
 
61
66
  def setup
62
67
  @default_options = Oj.default_options
68
+ # in compat mode other options other than the JSON gem globals and options
69
+ # are not used.
70
+ Oj.default_options = { :mode => :compat }
63
71
  end
64
72
 
65
73
  def teardown
@@ -87,6 +95,8 @@ class CompatJuice < Minitest::Test
87
95
 
88
96
  def test_float
89
97
  dump_and_load(0.0, false)
98
+ dump_and_load(0.56, false)
99
+ dump_and_load(3.0, false)
90
100
  dump_and_load(12345.6789, false)
91
101
  dump_and_load(70.35, false)
92
102
  dump_and_load(-54321.012, false)
@@ -95,6 +105,19 @@ class CompatJuice < Minitest::Test
95
105
  dump_and_load(2.48e16, false)
96
106
  dump_and_load(2.48e100 * 1.0e10, false)
97
107
  dump_and_load(-2.48e100 * 1.0e10, false)
108
+ dump_and_load(1405460727.723866, false)
109
+ dump_and_load(0.5773, false)
110
+ dump_and_load(0.6768, false)
111
+ dump_and_load(0.685, false)
112
+ dump_and_load(0.7032, false)
113
+ dump_and_load(0.7051, false)
114
+ dump_and_load(0.8274, false)
115
+ dump_and_load(0.9149, false)
116
+ dump_and_load(64.4, false)
117
+ dump_and_load(71.6, false)
118
+ dump_and_load(73.4, false)
119
+ dump_and_load(80.6, false)
120
+ dump_and_load(-95.640172, false)
98
121
  end
99
122
 
100
123
  def test_string
@@ -139,7 +162,34 @@ class CompatJuice < Minitest::Test
139
162
  dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
140
163
  end
141
164
 
165
+ def test_symbol
166
+ json = Oj.dump(:abc, :mode => :compat)
167
+ assert_equal('"abc"', json)
168
+ end
169
+
170
+ def test_time
171
+ t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
172
+ #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
173
+ json = Oj.dump(t, :mode => :compat)
174
+ assert_equal(%{"2012-01-05 23:58:07 +0900"}, json)
175
+ end
176
+
177
+ def test_class
178
+ json = Oj.dump(CompatJuice, :mode => :compat)
179
+ assert_equal(%{"CompatJuice"}, json)
180
+ end
181
+
182
+ def test_module
183
+ json = Oj.dump(One::Two, :mode => :compat)
184
+ assert_equal(%{"CompatJuice::One::Two"}, json)
185
+ end
186
+
142
187
  # Hash
188
+ def test_non_str_hash
189
+ json = Oj.dump({ 1 => true, 0 => false }, :mode => :compat)
190
+ h = Oj.load(json, :mode => :strict)
191
+ assert_equal({ "1" => true, "0" => false }, h)
192
+ end
143
193
  def test_hash
144
194
  dump_and_load({}, false)
145
195
  dump_and_load({ 'true' => true, 'false' => false}, false)
@@ -179,79 +229,82 @@ class CompatJuice < Minitest::Test
179
229
  dump_and_load(7 ** 55, false)
180
230
  end
181
231
 
182
- # BigDecimal
183
- def test_bigdecimal_compat
184
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
232
+ def test_json_object
233
+ obj = Jeez.new(true, 58)
234
+ json = Oj.to_json(obj)
235
+ assert(%|{"json_class":"CompatJuice::Jeez","x":true,"y":58}| == json ||
236
+ %|{"json_class":"CompatJuice::Jeez","y":58,"x":true}| == json)
237
+ dump_to_json_and_load(obj, false)
185
238
  end
186
239
 
187
- def test_bigdecimal_load
188
- orig = BigDecimal.new('80.51')
189
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => true)
190
- bg = Oj.load(json, :mode => :compat, :bigdecimal_load => true)
191
- assert_equal(BigDecimal, bg.class)
192
- assert_equal(orig, bg)
240
+ def test_json_object_create_id
241
+ Oj.default_options = { :create_id => 'kson_class', :create_additions => true}
242
+ expected = Jeez.new(true, 58)
243
+ json = %{{"kson_class":"CompatJuice::Jeez","x":true,"y":58}}
244
+ obj = Oj.load(json)
245
+ assert_equal(expected, obj)
246
+ Oj.default_options = { :create_id => 'json_class' }
193
247
  end
194
248
 
195
- # Time
196
- def test_time_ruby
197
- if RUBY_VERSION.start_with?('1.8')
198
- t = Time.parse('2015-01-05T21:37:07.123456-08:00')
199
- else
200
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
201
- end
202
- expect = '"' + t.to_s + '"'
203
- json = Oj.dump(t, :mode => :compat, :time_format => :ruby)
204
- assert_equal(expect, json)
249
+ def test_bignum_compat
250
+ json = Oj.dump(7 ** 55, :mode => :compat)
251
+ b = Oj.load(json, :mode => :strict)
252
+ assert_equal(30226801971775055948247051683954096612865741943, b)
205
253
  end
206
- def test_time_xml
207
- if RUBY_VERSION.start_with?('1.8')
208
- t = Time.parse('2015-01-05T21:37:07.123456-08:00')
254
+
255
+ # BigDecimal
256
+ def test_bigdecimal
257
+ # BigDecimals are dumped as strings and can not be restored to the
258
+ # original value.
259
+ json = Oj.dump(BigDecimal.new('3.14159265358979323846'))
260
+ if RUBY_VERSION == '2.4.0'
261
+ # 2.4.0 changes the exponent to lowercase
262
+ assert_equal('"0.314159265358979323846e1"', json)
209
263
  else
210
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
211
- end
212
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 6)
213
- assert_equal('"2015-01-05T21:37:07.123456-08:00"', json)
214
- end
215
- unless RUBY_VERSION.start_with?('1.8')
216
- def test_time_xml_12345
217
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, 12345)
218
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 6)
219
- assert_equal('"2015-01-05T21:37:07.123456+03:25"', json)
264
+ assert_equal('"0.314159265358979323846E1"', json)
220
265
  end
221
266
  end
222
- def test_time_unix
223
- if RUBY_VERSION.start_with?('1.8')
224
- t = Time.parse('2015-01-05T21:37:07.123456-08:00')
225
- else
226
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
267
+
268
+ def test_infinity
269
+ begin
270
+ Oj.load('Infinity', :mode => :strict)
271
+ fail()
272
+ rescue Oj::ParseError
273
+ assert(true)
227
274
  end
228
- json = Oj.dump(t, :mode => :compat, :time_format => :unix, :second_precision => 6)
229
- assert_equal('1420522627.123456', json)
275
+ x = Oj.load('Infinity', :mode => :compat)
276
+ assert_equal('Infinity', x.to_s)
277
+
230
278
  end
231
- def test_time_unix_zone
232
- if RUBY_VERSION.start_with?('1.8')
233
- t = Time.parse('2015-01-05T21:37:07.123456-08:00')
234
- else
235
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
236
- end
237
- json = Oj.dump(t, :mode => :compat, :time_format => :unix_zone, :second_precision => 6)
238
- assert_equal('1420522627.123456e-28800', json)
239
- end
240
- unless RUBY_VERSION.start_with?('1.8')
241
- def test_time_unix_zone_12345
242
- t = Time.new(2015, 1, 5, 21, 37, 7.123456, 12345)
243
- json = Oj.dump(t, :mode => :compat, :time_format => :unix_zone, :second_precision => 6)
244
- assert_equal('1420481482.123456e12345', json)
245
- end
279
+
280
+ # Time
281
+ def test_time
282
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
283
+ expect = '"' + t.to_s + '"'
284
+ json = Oj.dump(t)
285
+ assert_equal(expect, json)
246
286
  end
247
- def test_time_unix_zone_early
248
- if RUBY_VERSION.start_with?('1.8')
249
- t = Time.parse('1954-01-05T21:37:07.123456-08:00')
250
- else
251
- t = Time.new(1954, 1, 5, 21, 37, 7.123456, -8 * 3600)
287
+
288
+ def test_date_compat
289
+ orig = Date.new(2012, 6, 19)
290
+ json = Oj.dump(orig, :mode => :compat)
291
+ x = Oj.load(json, :mode => :compat)
292
+ # Some Rubies implement Date as data and some as a real Object. Either are
293
+ # okay for the test.
294
+ if x.is_a?(String)
295
+ assert_equal(orig.to_s, x)
296
+ else # better be a Hash
297
+ assert_equal({"year" => orig.year, "month" => orig.month, "day" => orig.day, "start" => orig.start}, x)
252
298
  end
253
- json = Oj.dump(t, :mode => :compat, :time_format => :unix_zone, :second_precision => 6)
254
- assert_equal('-504469372.876544e-28800', json)
299
+ end
300
+
301
+ def test_datetime_compat
302
+ orig = DateTime.new(2012, 6, 19, 20, 19, 27)
303
+ json = Oj.dump(orig, :mode => :compat)
304
+ x = Oj.load(json, :mode => :compat)
305
+ # Some Rubies implement Date as data and some as a real Object. Either are
306
+ # okay for the test.
307
+ assert_equal(orig.to_s, x)
255
308
  end
256
309
 
257
310
  # Stream IO
@@ -329,69 +382,92 @@ class CompatJuice < Minitest::Test
329
382
  assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
330
383
  end
331
384
 
332
- def test_json_object_compat
385
+ # If mimic_JSON has not been called then Oj.dump will call to_json on the
386
+ # top level object only.
387
+ def test_json_object_top
333
388
  obj = Jeez.new(true, 58)
334
- Oj.default_options = { :mode => :compat, :use_as_json => true, :use_to_json => true }
335
- dump_and_load(obj, false)
389
+ dump_to_json_and_load(obj, false)
390
+ end
391
+
392
+ # A child to_json should not be called.
393
+ def test_json_object_child
394
+ obj = { "child" => Jeez.new(true, 58) }
395
+ assert_equal('{"child":{"json_class":"CompatJuice::Jeez","x":true,"y":58}}', Oj.dump(obj))
336
396
  end
337
397
 
338
398
  def test_json_module_object
339
- Oj.default_options = { :mode => :compat, :use_as_json => true, :use_to_json => true }
340
399
  obj = One::Two::Three::Deep.new()
341
- dump_and_load(obj, false)
400
+ dump_to_json_and_load(obj, false)
342
401
  end
343
402
 
344
- def test_json_object_create_id
345
- Oj.default_options = { :mode => :compat, :use_as_json => false, :use_to_json => false }
403
+ def test_json_object_dump_create_id
346
404
  expected = Jeez.new(true, 58)
347
- json = Oj.dump(expected, :indent => 2, :mode => :compat, :use_to_json => true, :use_as_json => true)
348
- obj = Oj.compat_load(json)
405
+ json = Oj.to_json(expected)
406
+ obj = Oj.compat_load(json, :create_additions => true)
349
407
  assert_equal(expected, obj)
350
408
  end
351
409
 
352
410
  def test_json_object_bad
353
411
  json = %{{"json_class":"CompatJuice::Junk","x":true}}
354
412
  begin
355
- Oj.compat_load(json)
413
+ Oj.compat_load(json, :create_additions => true)
356
414
  rescue Exception => e
357
- assert_equal("Oj::ParseError", e.class().name)
415
+ assert_equal("ArgumentError", e.class().name)
358
416
  return
359
417
  end
360
418
  assert(false, "*** expected an exception")
361
419
  end
362
420
 
363
421
  def test_json_object_create_cache
364
- Oj.default_options = { :mode => :compat, :use_as_json => true, :use_to_json => true }
365
422
  expected = Jeez.new(true, 58)
366
- json = Oj.dump(expected, :indent => 2, :mode => :compat, :use_to_json => true)
367
- obj = Oj.compat_load(json, :class_cache => true)
423
+ json = Oj.to_json(expected)
424
+ obj = Oj.compat_load(json, :class_cache => true, :create_additions => true)
368
425
  assert_equal(expected, obj)
369
- obj = Oj.compat_load(json, :class_cache => false)
426
+ obj = Oj.compat_load(json, :class_cache => false, :create_additions => true)
370
427
  assert_equal(expected, obj)
371
428
  end
372
429
 
373
430
  def test_json_object_create_id_other
374
- Oj.default_options = { :mode => :compat, :use_as_json => false, :use_to_json => false }
375
431
  expected = Jeez.new(true, 58)
376
- json = Oj.dump(expected, :indent => 2, :mode => :compat, :use_as_json => true)
432
+ json = Oj.to_json(expected)
377
433
  json.gsub!('json_class', '_class_')
378
- obj = Oj.compat_load(json, :create_id => "_class_")
434
+ obj = Oj.compat_load(json, :create_id => "_class_", :create_additions => true)
379
435
  assert_equal(expected, obj)
380
436
  end
381
437
 
382
438
  def test_json_object_create_deep
383
- Oj.default_options = { :mode => :compat, :use_as_json => true, :use_to_json => true }
384
439
  expected = One::Two::Three::Deep.new()
385
- json = Oj.dump(expected, :indent => 2, :mode => :compat)
386
- obj = Oj.compat_load(json)
440
+ json = Oj.to_json(expected)
441
+ obj = Oj.compat_load(json, :create_additions => true)
387
442
  assert_equal(expected, obj)
388
443
  end
389
444
 
445
+ def test_range
446
+ json = Oj.dump(1..7)
447
+ assert_equal('"1..7"', json)
448
+ end
449
+
390
450
  def dump_and_load(obj, trace=false)
391
- json = Oj.dump(obj, :indent => 2, :mode => :compat)
451
+ json = Oj.dump(obj)
452
+ puts json if trace
453
+ loaded = Oj.compat_load(json, :create_additions => true);
454
+ if obj.nil?
455
+ assert_nil(loaded)
456
+ else
457
+ assert_equal(obj, loaded)
458
+ end
459
+ loaded
460
+ end
461
+
462
+ def dump_to_json_and_load(obj, trace=false)
463
+ json = Oj.to_json(obj, :indent => ' ')
392
464
  puts json if trace
393
- loaded = Oj.compat_load(json);
394
- assert_equal(obj, loaded)
465
+ loaded = Oj.compat_load(json, :create_additions => true);
466
+ if obj.nil?
467
+ assert_nil(loaded)
468
+ else
469
+ assert_equal(obj, loaded)
470
+ end
395
471
  loaded
396
472
  end
397
473