oj 2.18.3 → 3.13.14

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 (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_various.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
2
+ # encoding: utf-8
3
3
 
4
4
  $: << File.dirname(__FILE__)
5
5
 
6
6
  require 'helper'
7
7
 
8
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
9
15
 
10
16
  module TestModule
11
17
  end
@@ -23,7 +29,7 @@ class Juice < Minitest::Test
23
29
  end
24
30
  alias == eql?
25
31
 
26
- end# Jam
32
+ end # Jam
27
33
 
28
34
  class Jeez < Jam
29
35
  def initialize(x, y)
@@ -37,7 +43,7 @@ class Juice < Minitest::Test
37
43
  def self.json_create(h)
38
44
  self.new(h['x'], h['y'])
39
45
  end
40
- end# Jeez
46
+ end # Jeez
41
47
 
42
48
  # contributed by sauliusg to fix as_json
43
49
  class Orange < Jam
@@ -80,7 +86,7 @@ class Juice < Minitest::Test
80
86
  def self.json_create(h)
81
87
  self.new(h['x'], h['y'])
82
88
  end
83
- end# Jazz
89
+ end # Jazz
84
90
 
85
91
  def setup
86
92
  @default_options = Oj.default_options
@@ -90,62 +96,53 @@ class Juice < Minitest::Test
90
96
  Oj.default_options = @default_options
91
97
  end
92
98
 
93
- =begin
94
- # Depending on the order the values may have changed. The set_options sets
95
- # should cover the function itself.
96
- def test_get_options
97
- opts = Oj.default_options()
98
- assert_equal({ :indent=>0,
99
- :second_precision=>9,
100
- :circular=>false,
101
- :class_cache=>true,
102
- :auto_define=>false,
103
- :symbol_keys=>false,
104
- :bigdecimal_as_decimal=>true,
105
- :use_to_json=>true,
106
- :nilnil=>false,
107
- :allow_gc=>true,
108
- :quirks_mode=>true,
109
- :allow_invalid_unicode=>false,
110
- :float_precision=>15,
111
- :mode=>:object,
112
- :escape_mode=>:json,
113
- :time_format=>:unix_zone,
114
- :bigdecimal_load=>:auto,
115
- :create_id=>'json_class'}, opts)
116
- end
117
- =end
118
99
  def test_set_options
119
100
  orig = Oj.default_options()
120
101
  alt ={
121
- :indent=>" - ",
122
- :second_precision=>5,
123
- :circular=>true,
124
- :class_cache=>false,
125
- :auto_define=>true,
126
- :symbol_keys=>true,
127
- :bigdecimal_as_decimal=>false,
128
- :use_to_json=>false,
129
- :use_as_json=>false,
130
- :nilnil=>true,
131
- :allow_gc=>false,
132
- :quirks_mode=>false,
133
- :allow_invalid_unicode=>true,
134
- :float_precision=>13,
135
- :mode=>:strict,
136
- :escape_mode=>:ascii,
137
- :time_format=>:unix_zone,
138
- :bigdecimal_load=>:float,
139
- :create_id=>'classy',
140
- :space=>'z',
141
- :array_nl=>'a',
142
- :object_nl=>'o',
143
- :space_before=>'b',
144
- :nan=>:huge,
145
- :hash_class=>Hash,
146
- :omit_nil=>false,
102
+ indent: " - ",
103
+ second_precision: 5,
104
+ circular: true,
105
+ class_cache: false,
106
+ auto_define: true,
107
+ symbol_keys: true,
108
+ bigdecimal_as_decimal: false,
109
+ use_to_json: false,
110
+ use_to_hash: false,
111
+ use_as_json: false,
112
+ use_raw_json: false,
113
+ nilnil: true,
114
+ empty_string: true,
115
+ allow_gc: false,
116
+ quirks_mode: false,
117
+ allow_invalid_unicode: true,
118
+ float_precision: 13,
119
+ mode: :strict,
120
+ escape_mode: :ascii,
121
+ time_format: :unix_zone,
122
+ bigdecimal_load: :float,
123
+ compat_bigdecimal: true,
124
+ create_id: 'classy',
125
+ create_additions: true,
126
+ cache_keys: false,
127
+ cache_str: 5,
128
+ space: 'z',
129
+ array_nl: 'a',
130
+ object_nl: 'o',
131
+ space_before: 'b',
132
+ nan: :huge,
133
+ hash_class: Hash,
134
+ omit_nil: false,
135
+ allow_nan: true,
136
+ integer_range: nil,
137
+ array_class: Array,
138
+ ignore: nil,
139
+ ignore_under: true,
140
+ trace: true,
141
+ safe: true,
147
142
  }
148
143
  Oj.default_options = alt
144
+ #keys = alt.keys
145
+ #Oj.default_options.keys.each { |k| puts k unless keys.include? k}
149
146
  opts = Oj.default_options()
150
147
  assert_equal(alt, opts);
151
148
 
@@ -186,25 +183,22 @@ class Juice < Minitest::Test
186
183
 
187
184
  n = Oj.load('1000.0000123456789')
188
185
  assert_equal(BigDecimal, n.class)
189
- assert_equal('0.10000000123456789E4', n.to_s)
186
+ assert_equal('0.10000000123456789E4', n.to_s.upcase)
190
187
 
191
188
  n = Oj.load('-0.000012345678901234567')
192
189
  assert_equal(BigDecimal, n.class)
193
- assert_equal('-0.12345678901234567E-4', n.to_s)
194
-
190
+ assert_equal('-0.12345678901234567E-4', n.to_s.upcase)
195
191
  end
196
192
 
193
+ =begin
194
+ # TBD move to custom
197
195
  def test_float_dump
198
196
  Oj.default_options = { :float_precision => 16 }
199
197
  assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
200
198
  Oj.default_options = { :float_precision => 5 }
201
199
  assert_equal('1.4055', Oj.dump(1.405460727))
202
200
  Oj.default_options = { :float_precision => 0 }
203
- if RUBY_VERSION.start_with?('1.8')
204
- assert_equal('1405460727.72387', Oj.dump(1405460727.723866))
205
- else
206
- assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
207
- end
201
+ assert_equal('1405460727.723866', Oj.dump(1405460727.723866))
208
202
  Oj.default_options = { :float_precision => 15 }
209
203
  assert_equal('0.56', Oj.dump(0.56))
210
204
  assert_equal('0.5773', Oj.dump(0.5773))
@@ -220,45 +214,7 @@ class Juice < Minitest::Test
220
214
  assert_equal('80.6', Oj.dump(80.6))
221
215
  assert_equal('-95.640172', Oj.dump(-95.640172))
222
216
  end
223
-
224
- def test_nan_dump
225
- assert_equal('null', Oj.dump(0/0.0, :mode => :strict, :nan => :null))
226
- assert_equal('NaN', Oj.dump(0/0.0, :mode => :strict, :nan => :word))
227
- assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :mode => :strict, :nan => :huge))
228
- end
229
-
230
- def test_infinity_dump
231
- assert_equal('null', Oj.dump(1/0.0, :mode => :strict, :nan => :null))
232
- assert_equal('Infinity', Oj.dump(1/0.0, :mode => :strict, :nan => :word))
233
- assert_equal('3.0e14159265358979323846', Oj.dump(1/0.0, :mode => :strict, :nan => :huge))
234
- end
235
-
236
- def test_neg_infinity_dump
237
- assert_equal('null', Oj.dump(-1/0.0, :mode => :strict, :nan => :null))
238
- assert_equal('-Infinity', Oj.dump(-1/0.0, :mode => :strict, :nan => :word))
239
- assert_equal('-3.0e14159265358979323846', Oj.dump(-1/0.0, :mode => :strict, :nan => :huge))
240
- end
241
-
242
- def test_float
243
- mode = Oj.default_options()[:mode]
244
- Oj.default_options = {:mode => :object}
245
- dump_and_load(0.0, false)
246
- dump_and_load(12345.6789, false)
247
- dump_and_load(70.35, false)
248
- dump_and_load(-54321.012, false)
249
- dump_and_load(1.7775, false)
250
- dump_and_load(2.5024, false)
251
- dump_and_load(2.48e16, false)
252
- dump_and_load(2.48e100 * 1.0e10, false)
253
- dump_and_load(-2.48e100 * 1.0e10, false)
254
- dump_and_load(1/0.0, false)
255
- # NaN does not always == NaN
256
- json = Oj.dump(0/0.0)
257
- assert_equal('3.3e14159265358979323846', json)
258
- loaded = Oj.load(json);
259
- assert_equal(true, loaded.nan?)
260
- Oj.default_options = {:mode => mode}
261
- end
217
+ =end
262
218
 
263
219
  def test_string
264
220
  dump_and_load('', false)
@@ -268,12 +224,6 @@ class Juice < Minitest::Test
268
224
  assert_equal("a\u0000a", dump_and_load("a\u0000a", false))
269
225
  end
270
226
 
271
- def test_string_object
272
- Oj.default_options = {:mode => :object}
273
- dump_and_load('abc', false)
274
- dump_and_load(':abc', false)
275
- end
276
-
277
227
  def test_encode
278
228
  opts = Oj.default_options
279
229
  Oj.default_options = { :ascii_only => false }
@@ -368,8 +318,8 @@ class Juice < Minitest::Test
368
318
  {"b":2}
369
319
  }
370
320
  results = []
371
- Oj.load(json) { |x| results << x }
372
- assert_equal([{"a"=>1}, [1,2], [3,4], {"b"=>2}], results)
321
+ Oj.load(json, :mode => :strict) { |x, start, len| results << [x, start, len] }
322
+ assert_equal([[{"a"=>1}, 0, 7], [[1,2], 7, 6], [[3,4], 13, 5], [{"b"=>2}, 18, 8]], results)
373
323
  end
374
324
 
375
325
  def test_multiple_json_no_callback
@@ -424,231 +374,56 @@ class Juice < Minitest::Test
424
374
  out = Oj.dump(x)
425
375
  assert_equal(json, out)
426
376
  end
377
+ def test_dump_invalid_utf8
378
+ Oj.default_options = { :escape_mode => :ascii }
379
+ assert_raises(EncodingError) {
380
+ Oj.dump(["abc\xbe\x1f\x11"], mode: :strict)
381
+ }
382
+ end
427
383
 
428
384
  # Symbol
429
- def test_symbol_strict
430
- begin
431
- Oj.dump(:abc, :mode => :strict)
432
- rescue Exception
433
- assert(true)
434
- return
435
- end
436
- assert(false, "*** expected an exception")
437
- end
438
385
  def test_symbol_null
439
386
  json = Oj.dump(:abc, :mode => :null)
440
- assert_equal('null', json)
441
- end
442
- def test_symbol_compat
443
- json = Oj.dump(:abc, :mode => :compat)
444
387
  assert_equal('"abc"', json)
445
388
  end
446
- def test_symbol_object
447
- Oj.default_options = { :mode => :object }
448
- #dump_and_load(''.to_sym, false)
449
- dump_and_load(:abc, false)
450
- dump_and_load(':xyz'.to_sym, false)
451
- end
452
389
 
453
390
  # Time
454
- def test_time_strict
455
- t = Time.local(2012, 1, 5, 23, 58, 7)
456
- begin
457
- Oj.dump(t, :mode => :strict)
458
- rescue Exception
459
- assert(true)
460
- return
461
- end
462
- assert(false, "*** expected an exception")
463
- end
464
391
  def test_time_null
465
392
  t = Time.local(2012, 1, 5, 23, 58, 7)
466
393
  json = Oj.dump(t, :mode => :null)
467
394
  assert_equal('null', json)
468
395
  end
469
- def test_unix_time_compat
470
- t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
471
- #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
472
- json = Oj.dump(t, :mode => :compat, :time_format => :unix)
473
- assert_equal(%{1325775487.123456000}, json)
474
- end
475
- def test_unix_time_compat_precision
476
- t = Time.xmlschema("2012-01-05T23:58:07.123456789+09:00")
477
- #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
478
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
479
- assert_equal(%{1325775487.12346}, json)
480
- t = Time.xmlschema("2012-01-05T23:58:07.999600+09:00")
481
- json = Oj.dump(t, :mode => :compat, :second_precision => 3, :time_format => :unix)
482
- assert_equal(%{1325775488.000}, json)
483
- end
484
- def test_unix_time_compat_early
485
- t = Time.xmlschema("1954-01-05T00:00:00.123456789+00:00")
486
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
487
- assert_equal(%{-504575999.87654}, json)
488
- end
489
- def test_unix_time_compat_1970
490
- t = Time.xmlschema("1970-01-01T00:00:00.123456789+00:00")
491
- json = Oj.dump(t, :mode => :compat, :second_precision => 5, :time_format => :unix)
492
- assert_equal(%{0.12346}, json)
493
- end
494
- def test_ruby_time_compat
495
- t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
496
- json = Oj.dump(t, :mode => :compat, :time_format => :ruby)
497
- #assert_equal(%{"2012-01-05 23:58:07 +0900"}, json)
498
- assert_equal(%{"#{t.to_s}"}, json)
499
- end
500
- def test_xml_time_compat
501
- begin
502
- t = Time.new(2012, 1, 5, 23, 58, 7.123456000, 34200)
503
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
504
- assert_equal(%{"2012-01-05T23:58:07.123456000+09:30"}, json)
505
- rescue Exception
506
- # some Rubies (1.8.7) do not allow the timezome to be set
507
- t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
508
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
509
- tz = t.utc_offset
510
- # Ruby does not handle a %+02d properly so...
511
- sign = '+'
512
- if 0 > tz
513
- sign = '-'
514
- tz = -tz
515
- end
516
- assert_equal(%{"2012-01-05T23:58:07.123456000%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
517
- end
518
- end
519
- def test_xml_time_compat_no_secs
520
- begin
521
- t = Time.new(2012, 1, 5, 23, 58, 7.0, 34200)
522
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
523
- assert_equal(%{"2012-01-05T23:58:07+09:30"}, json)
524
- rescue Exception
525
- # some Rubies (1.8.7) do not allow the timezome to be set
526
- t = Time.local(2012, 1, 5, 23, 58, 7, 0)
527
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
528
- tz = t.utc_offset
529
- # Ruby does not handle a %+02d properly so...
530
- sign = '+'
531
- if 0 > tz
532
- sign = '-'
533
- tz = -tz
534
- end
535
- assert_equal(%{"2012-01-05T23:58:07%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
536
- end
537
- end
538
- def test_xml_time_compat_precision
539
- begin
540
- t = Time.new(2012, 1, 5, 23, 58, 7.123456789, 32400)
541
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 5)
542
- assert_equal(%{"2012-01-05T23:58:07.12346+09:00"}, json)
543
- rescue Exception
544
- # some Rubies (1.8.7) do not allow the timezome to be set
545
- t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
546
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 5)
547
- tz = t.utc_offset
548
- # Ruby does not handle a %+02d properly so...
549
- sign = '+'
550
- if 0 > tz
551
- sign = '-'
552
- tz = -tz
553
- end
554
- assert_equal(%{"2012-01-05T23:58:07.12346%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
555
- end
556
- end
557
- def test_xml_time_compat_precision_round
558
- begin
559
- t = Time.new(2012, 1, 5, 23, 58, 7.9996, 32400)
560
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 3)
561
- assert_equal(%{"2012-01-05T23:58:08+09:00"}, json)
562
- rescue Exception
563
- # some Rubies (1.8.7) do not allow the timezome to be set
564
- t = Time.local(2012, 1, 5, 23, 58, 7, 999600)
565
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 3)
566
- tz = t.utc_offset
567
- # Ruby does not handle a %+02d properly so...
568
- sign = '+'
569
- if 0 > tz
570
- sign = '-'
571
- tz = -tz
572
- end
573
- assert_equal(%{"2012-01-05T23:58:08%s%02d:%02d"} % [sign, tz / 3600, tz / 60 % 60], json)
574
- end
396
+
397
+ def test_time_neg
398
+ t = Time.parse("1900-01-01 00:18:59 UTC")
399
+ json = Oj.dump(t, :mode => :custom, :time_format => :unix)
400
+ assert_equal('-2208987661.000000000', json)
575
401
  end
576
- def test_xml_time_compat_zulu
577
- begin
578
- t = Time.new(2012, 1, 5, 23, 58, 7.0, 0)
579
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
580
- assert_equal(%{"2012-01-05T23:58:07Z"}, json)
581
- rescue Exception
582
- # some Rubies (1.8.7) do not allow the timezome to be set
583
- t = Time.utc(2012, 1, 5, 23, 58, 7, 0)
584
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
585
- #tz = t.utc_offset
586
- assert_equal(%{"2012-01-05T23:58:07Z"}, json)
587
- end
402
+
403
+ def test_time_years
404
+ (-2020..2020).each { |year|
405
+ s = "%04d-03-01T15:14:13Z" % [year]
406
+ json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: -1)
407
+ assert_equal(s, json[1..-2])
408
+
409
+ json = Oj.dump(Time.parse(s), mode: :custom, time_format: :xmlschema, second_precision: 3)
410
+ assert_equal(s[0..-2] + '.000Z', json[1..-2])
411
+ }
588
412
  end
589
413
 
590
414
  # Class
591
- def test_class_strict
592
- begin
593
- Oj.dump(Juice, :mode => :strict)
594
- rescue Exception
595
- assert(true)
596
- return
597
- end
598
- assert(false, "*** expected an exception")
599
- end
600
415
  def test_class_null
601
416
  json = Oj.dump(Juice, :mode => :null)
602
417
  assert_equal('null', json)
603
418
  end
604
- def test_class_compat
605
- json = Oj.dump(Juice, :mode => :compat)
606
- assert_equal(%{"Juice"}, json)
607
- end
608
- def test_class_object
609
- Oj.default_options = { :mode => :object }
610
- dump_and_load(Juice, false)
611
- end
612
419
 
613
420
  # Module
614
- def test_module_strict
615
- begin
616
- Oj.dump(TestModule, :mode => :strict)
617
- rescue Exception
618
- assert(true)
619
- return
620
- end
621
- assert(false, "*** expected an exception")
622
- end
623
421
  def test_module_null
624
422
  json = Oj.dump(TestModule, :mode => :null)
625
423
  assert_equal('null', json)
626
424
  end
627
- def test_module_compat
628
- json = Oj.dump(TestModule, :mode => :compat)
629
- assert_equal(%{"Juice::TestModule"}, json)
630
- end
631
- def test_module_object
632
- Oj.default_options = { :mode => :object }
633
- dump_and_load(TestModule, false)
634
- end
635
425
 
636
426
  # Hash
637
- def test_hash
638
- Oj.default_options = { :mode => :strict }
639
- dump_and_load({}, false)
640
- dump_and_load({ 'true' => true, 'false' => false}, false)
641
- dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
642
- end
643
- def test_non_str_hash_strict
644
- begin
645
- Oj.dump({ 1 => true, 0 => false }, :mode => :strict)
646
- rescue Exception
647
- assert(true)
648
- return
649
- end
650
- assert(false, "*** expected an exception")
651
- end
652
427
  def test_non_str_hash_null
653
428
  begin
654
429
  Oj.dump({ 1 => true, 0 => false }, :mode => :null)
@@ -658,27 +433,7 @@ class Juice < Minitest::Test
658
433
  end
659
434
  assert(false, "*** expected an exception")
660
435
  end
661
- def test_non_str_hash_compat
662
- json = Oj.dump({ 1 => true, 0 => false }, :mode => :compat)
663
- h = Oj.load(json, :mode => :strict)
664
- assert_equal({ "1" => true, "0" => false }, h)
665
- end
666
- def test_non_str_hash_object
667
- Oj.default_options = { :mode => :object }
668
- json = Oj.dump({ 1 => true, :sim => nil })
669
- h = Oj.load(json, :mode => :strict)
670
- assert_equal({"^#1" => [1, true], ":sim" => nil}, h)
671
- h = Oj.load(json)
672
- assert_equal({ 1 => true, :sim => nil }, h)
673
- end
674
- def test_mixed_hash_object
675
- Oj.default_options = { :mode => :object }
676
- json = Oj.dump({ 1 => true, 'nil' => nil, :sim => 4 })
677
- h = Oj.load(json, :mode => :strict)
678
- assert_equal({"^#1" => [1, true], "nil" => nil, ":sim" => 4}, h)
679
- h = Oj.load(json)
680
- assert_equal({ 1 => true, 'nil' => nil, :sim => 4 }, h)
681
- end
436
+
682
437
  def test_hash_not_closed
683
438
  begin
684
439
  Oj.load('{')
@@ -690,297 +445,44 @@ class Juice < Minitest::Test
690
445
  end
691
446
 
692
447
  # Object with to_json()
693
- def test_json_object_strict
694
- obj = Jeez.new(true, 58)
695
- begin
696
- Oj.dump(obj, :mode => :strict)
697
- rescue Exception
698
- assert(true)
699
- return
700
- end
701
- assert(false, "*** expected an exception")
702
- end
703
448
  def test_json_object_null
704
449
  obj = Jeez.new(true, 58)
705
450
  json = Oj.dump(obj, :mode => :null)
706
451
  assert_equal('null', json)
707
452
  end
708
- def test_json_object_compat
709
- Oj.default_options = { :mode => :compat, :use_to_json => true }
710
- obj = Jeez.new(true, 58)
711
- json = Oj.dump(obj, :indent => 2)
712
- assert(%{{"json_class":"Juice::Jeez","x":true,"y":58}
713
- } == json ||
714
- %{{"json_class":"Juice::Jeez","y":58,"x":true}
715
- } == json)
716
- dump_and_load(obj, false)
717
- Oj.default_options = { :mode => :compat, :use_to_json => false }
718
- end
719
- def test_json_object_create_id
720
- Oj.default_options = { :mode => :compat, :create_id => 'kson_class' }
721
- expected = Jeez.new(true, 58)
722
- json = %{{"kson_class":"Juice::Jeez","x":true,"y":58}}
723
- obj = Oj.load(json)
724
- assert_equal(expected, obj)
725
- Oj.default_options = { :create_id => 'json_class' }
726
- end
727
- def test_json_object_object
728
- obj = Jeez.new(true, 58)
729
- json = Oj.dump(obj, :mode => :object, :indent => 2)
730
- assert(%{{
731
- "^o":"Juice::Jeez",
732
- "x":true,
733
- "y":58
734
- }
735
- } == json ||
736
- %{{
737
- "^o":"Juice::Jeez",
738
- "y":58,
739
- "x":true
740
- }
741
- } == json)
742
- obj2 = Oj.load(json, :mode => :object)
743
- assert_equal(obj, obj2)
744
- end
745
453
 
746
454
  # Object with to_hash()
747
- def test_to_hash_object_strict
748
- obj = Jazz.new(true, 58)
749
- begin
750
- Oj.dump(obj, :mode => :strict)
751
- rescue Exception
752
- assert(true)
753
- return
754
- end
755
- assert(false, "*** expected an exception")
756
- end
757
455
  def test_to_hash_object_null
758
456
  obj = Jazz.new(true, 58)
759
457
  json = Oj.dump(obj, :mode => :null)
760
458
  assert_equal('null', json)
761
459
  end
762
- def test_to_hash_object_compat
763
- Oj.default_options = { :use_to_json => true }
764
- obj = Jazz.new(true, 58)
765
- json = Oj.dump(obj, :mode => :compat, :indent => 2)
766
- h = Oj.load(json, :mode => :strict)
767
- assert_equal(obj.to_hash, h)
768
- end
769
- def test_to_hash_object_object
770
- obj = Jazz.new(true, 58)
771
- json = Oj.dump(obj, :mode => :object, :indent => 2)
772
- assert(%{{
773
- "^o":"Juice::Jazz",
774
- "x":true,
775
- "y":58
776
- }
777
- } == json ||
778
- %{{
779
- "^o":"Juice::Jazz",
780
- "y":58,
781
- "x":true
782
- }
783
- } == json)
784
- obj2 = Oj.load(json, :mode => :object)
785
- assert_equal(obj, obj2)
786
- end
787
460
 
788
461
  # Object with as_json() # contributed by sauliusg
789
- def test_as_json_object_strict
790
- obj = Orange.new(true, 58)
791
- begin
792
- Oj.dump(obj, :mode => :strict)
793
- rescue Exception
794
- assert(true)
795
- return
796
- end
797
- assert(false, "*** expected an exception")
798
- end
799
-
800
462
  def test_as_json_object_null
801
463
  obj = Orange.new(true, 58)
802
464
  json = Oj.dump(obj, :mode => :null)
803
465
  assert_equal('null', json)
804
466
  end
805
467
 
806
- def test_as_json_object_compat_hash
807
- Oj.default_options = { :mode => :compat, :use_as_json => true }
808
- obj = Orange.new(true, 58)
809
- json = Oj.dump(obj, :indent => 2)
810
- assert(!json.nil?)
811
- dump_and_load(obj, false)
812
- end
813
-
814
- def test_as_json_object_compat_non_hash
815
- Oj.default_options = { :mode => :compat, :use_as_json => true }
816
- obj = Melon.new(true, 58)
817
- json = Oj.dump(obj, :indent => 2)
818
- assert_equal(%{"true 58"}, json)
819
- end
820
-
821
- def test_as_json_object_object
822
- obj = Orange.new(true, 58)
823
- json = Oj.dump(obj, :mode => :object, :indent => 2)
824
- assert(%{{
825
- "^o":"Juice::Orange",
826
- "x":true,
827
- "y":58
828
- }
829
- } == json ||
830
- %{{
831
- "^o":"Juice::Orange",
832
- "y":58,
833
- "x":true
834
- }
835
- } == json)
836
- obj2 = Oj.load(json, :mode => :object)
837
- assert_equal(obj, obj2)
838
- end
839
-
840
468
  # Object without to_json() or to_hash()
841
- def test_object_strict
842
- obj = Jam.new(true, 58)
843
- begin
844
- Oj.dump(obj, :mode => :strict)
845
- rescue Exception
846
- assert(true)
847
- return
848
- end
849
- assert(false, "*** expected an exception")
850
- end
851
469
  def test_object_null
852
470
  obj = Jam.new(true, 58)
853
471
  json = Oj.dump(obj, :mode => :null)
854
472
  assert_equal('null', json)
855
473
  end
856
- def test_object_compat
857
- obj = Jam.new(true, 58)
858
- json = Oj.dump(obj, :mode => :compat, :indent => 2)
859
- assert(%{{
860
- "x":true,
861
- "y":58
862
- }
863
- } == json ||
864
- %{{
865
- "y":58,
866
- "x":true
867
- }
868
- } == json)
869
- end
870
- def test_object_object
871
- obj = Jam.new(true, 58)
872
- json = Oj.dump(obj, :mode => :object, :indent => 2)
873
- assert(%{{
874
- "^o":"Juice::Jam",
875
- "x":true,
876
- "y":58
877
- }
878
- } == json ||
879
- %{{
880
- "^o":"Juice::Jam",
881
- "y":58,
882
- "x":true
883
- }
884
- } == json)
885
- obj2 = Oj.load(json, :mode => :object)
886
- assert_equal(obj, obj2)
887
- end
888
-
889
- def test_object_object_no_cache
890
- obj = Jam.new(true, 58)
891
- json = Oj.dump(obj, :mode => :object, :indent => 2)
892
- assert(%{{
893
- "^o":"Juice::Jam",
894
- "x":true,
895
- "y":58
896
- }
897
- } == json ||
898
- %{{
899
- "^o":"Juice::Jam",
900
- "y":58,
901
- "x":true
902
- }
903
- } == json)
904
- obj2 = Oj.load(json, :mode => :object, :class_cache => false)
905
- assert_equal(obj, obj2)
906
- end
907
-
908
- # Exception
909
- def test_exception
910
- err = nil
911
- begin
912
- raise StandardError.new('A Message')
913
- rescue Exception => e
914
- err = e
915
- end
916
- json = Oj.dump(err, :mode => :object, :indent => 2)
917
- #puts "*** #{json}"
918
- e2 = Oj.load(json, :mode => :strict)
919
- assert_equal(err.class.to_s, e2['^o'])
920
- assert_equal(err.message, e2['~mesg'])
921
- assert_equal(err.backtrace, e2['~bt'])
922
- e2 = Oj.load(json, :mode => :object)
923
- if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby
924
- assert_equal(e.class, e2.class);
925
- assert_equal(e.message, e2.message);
926
- assert_equal(e.backtrace, e2.backtrace);
927
- else
928
- assert_equal(e, e2);
929
- end
930
- end
931
474
 
932
475
  # Range
933
- def test_range_strict
934
- begin
935
- Oj.dump(1..7, :mode => :strict)
936
- rescue Exception
937
- assert(true)
938
- return
939
- end
940
- assert(false, "*** expected an exception")
941
- end
942
476
  def test_range_null
943
477
  json = Oj.dump(1..7, :mode => :null)
944
478
  assert_equal('null', json)
945
479
  end
946
- def test_range_compat
947
- Oj.default_options = { :use_to_json => true }
948
- json = Oj.dump(1..7, :mode => :compat)
949
- h = Oj.load(json, :mode => :strict)
950
- assert_equal({'begin' => 1, 'end' => 7, 'exclude_end' => false}, h)
951
- json = Oj.dump(1...7, :mode => :compat)
952
- h = Oj.load(json, :mode => :strict)
953
- assert_equal({'begin' => 1, 'end' => 7, 'exclude_end' => true}, h)
954
- end
955
- def test_range_object
956
- unless RUBY_VERSION.start_with?('1.8')
957
- Oj.default_options = { :mode => :object }
958
- json = Oj.dump(1..7, :mode => :object, :indent => 0)
959
- if 'rubinius' == $ruby
960
- assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
961
- else
962
- assert_equal(%{{"^u":["Range",1,7,false]}}, json)
963
- end
964
- dump_and_load(1..7, false)
965
- dump_and_load(1..1, false)
966
- dump_and_load(1...7, false)
967
- end
968
- end
969
480
 
970
481
  # BigNum
971
- def test_bignum_strict
972
- json = Oj.dump(7 ** 55, :mode => :strict)
973
- assert_equal('30226801971775055948247051683954096612865741943', json)
974
- end
975
482
  def test_bignum_null
976
483
  json = Oj.dump(7 ** 55, :mode => :null)
977
484
  assert_equal('30226801971775055948247051683954096612865741943', json)
978
485
  end
979
- def test_bignum_compat
980
- json = Oj.dump(7 ** 55, :mode => :compat)
981
- b = Oj.load(json, :mode => :strict)
982
- assert_equal(30226801971775055948247051683954096612865741943, b)
983
- end
984
486
 
985
487
  def test_bignum_object
986
488
  dump_and_load(7 ** 55, false)
@@ -988,136 +490,31 @@ class Juice < Minitest::Test
988
490
  end
989
491
 
990
492
  # BigDecimal
991
- def test_bigdecimal_strict
992
- mode = Oj.default_options[:mode]
993
- Oj.default_options = {:mode => :strict}
994
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
995
- Oj.default_options = {:mode => mode}
996
- end
997
493
  def test_bigdecimal_null
998
494
  mode = Oj.default_options[:mode]
999
495
  Oj.default_options = {:mode => :null}
1000
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
496
+ dump_and_load(BigDecimal('3.14159265358979323846'), false)
1001
497
  Oj.default_options = {:mode => mode}
1002
498
  end
1003
- def test_bigdecimal_compat
1004
- orig = BigDecimal.new('80.51')
1005
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1006
- bg = Oj.load(json, :mode => :compat)
1007
- assert_equal(orig.to_s, bg)
1008
- orig = BigDecimal.new('3.14159265358979323846')
1009
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1010
- bg = Oj.load(json, :mode => :compat)
1011
- assert_equal(orig.to_s, bg)
1012
- end
1013
- def test_bigdecimal_load
1014
- orig = BigDecimal.new('80.51')
1015
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => true)
1016
- bg = Oj.load(json, :mode => :compat, :bigdecimal_load => true)
1017
- assert_equal(BigDecimal, bg.class)
1018
- assert_equal(orig, bg)
1019
- end
1020
- def test_float_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 => :float)
1024
- assert_equal(Float, bg.class)
1025
- assert_equal(orig.to_f, bg)
1026
- end
1027
- def test_bigdecimal_compat_as_json
1028
- Oj.default_options = { :use_as_json => true }
1029
- orig = BigDecimal.new('80.51')
1030
- BigDecimal.send(:define_method, :as_json) do
1031
- %{this is big}
1032
- end
1033
- json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => false)
1034
- bg = Oj.load(json, :mode => :compat)
1035
- assert_equal("this is big", bg)
1036
- BigDecimal.send(:remove_method, :as_json) # cleanup
1037
- end
1038
- def test_bigdecimal_object
1039
- mode = Oj.default_options[:mode]
1040
- Oj.default_options = {:mode => :object}
1041
- dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
1042
- Oj.default_options = {:mode => mode}
1043
- # Infinity is the same for Float and BigDecimal
1044
- json = Oj.dump(BigDecimal.new('Infinity'), :mode => :object)
1045
- assert_equal('Infinity', json)
1046
- json = Oj.dump(BigDecimal.new('-Infinity'), :mode => :object)
1047
- assert_equal('-Infinity', json)
1048
- end
1049
499
 
1050
500
  def test_infinity
1051
501
  n = Oj.load('Infinity', :mode => :object)
1052
- assert_equal(BigDecimal.new('Infinity').to_f, n);
1053
- begin
1054
- Oj.load('Infinity', :mode => :strict)
1055
- fail()
1056
- rescue Oj::ParseError
1057
- assert(true)
1058
- end
502
+ assert_equal(BigDecimal('Infinity').to_f, n);
1059
503
  x = Oj.load('Infinity', :mode => :compat)
1060
504
  assert_equal('Infinity', x.to_s)
1061
-
1062
505
  end
1063
506
 
1064
507
  # Date
1065
- def test_date_strict
1066
- begin
1067
- Oj.dump(Date.new(2012, 6, 19), :mode => :strict)
1068
- rescue Exception
1069
- assert(true)
1070
- return
1071
- end
1072
- assert(false, "*** expected an exception")
1073
- end
1074
508
  def test_date_null
1075
509
  json = Oj.dump(Date.new(2012, 6, 19), :mode => :null)
1076
510
  assert_equal('null', json)
1077
511
  end
1078
- def test_date_compat
1079
- orig = Date.new(2012, 6, 19)
1080
- json = Oj.dump(orig, :mode => :compat)
1081
- x = Oj.load(json, :mode => :compat)
1082
- # Some Rubies implement Date as data and some as a real Object. Either are
1083
- # okay for the test.
1084
- if x.is_a?(String)
1085
- assert_equal(orig.to_s, x)
1086
- else # better be a Hash
1087
- assert_equal({"year" => orig.year, "month" => orig.month, "day" => orig.day, "start" => orig.start}, x)
1088
- end
1089
- end
1090
- def test_date_object
1091
- Oj.default_options = {:mode => :object}
1092
- dump_and_load(Date.new(2012, 6, 19), false)
1093
- end
1094
512
 
1095
513
  # DateTime
1096
- def test_datetime_strict
1097
- begin
1098
- Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :strict)
1099
- rescue Exception
1100
- assert(true)
1101
- return
1102
- end
1103
- assert(false, "*** expected an exception")
1104
- end
1105
514
  def test_datetime_null
1106
515
  json = Oj.dump(DateTime.new(2012, 6, 19, 20, 19, 27), :mode => :null)
1107
516
  assert_equal('null', json)
1108
517
  end
1109
- def test_datetime_compat
1110
- orig = DateTime.new(2012, 6, 19, 20, 19, 27)
1111
- json = Oj.dump(orig, :mode => :compat)
1112
- x = Oj.load(json, :mode => :compat)
1113
- # Some Rubies implement Date as data and some as a real Object. Either are
1114
- # okay for the test.
1115
- assert_equal(orig.to_s, x)
1116
- end
1117
- def test_datetime_object
1118
- Oj.default_options = {:mode => :object}
1119
- dump_and_load(DateTime.new(2012, 6, 19), false)
1120
- end
1121
518
 
1122
519
  # autodefine Oj::Bag
1123
520
  def test_bag
@@ -1131,75 +528,7 @@ class Juice < Minitest::Test
1131
528
  assert_equal(58, obj.y)
1132
529
  end
1133
530
 
1134
- # Circular
1135
- def test_circular_object
1136
- obj = Jam.new(nil, 58)
1137
- obj.x = obj
1138
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
1139
- assert(%{{
1140
- "^o":"Juice::Jam",
1141
- "^i":1,
1142
- "x":"^r1",
1143
- "y":58
1144
- }
1145
- } == json ||
1146
- %{{
1147
- "^o":"Juice::Jam",
1148
- "^i":1,
1149
- "y":58,
1150
- "x":"^r1"
1151
- }
1152
- } == json)
1153
- obj2 = Oj.load(json, :mode => :object, :circular => true)
1154
- assert_equal(obj2.x.__id__, obj2.__id__)
1155
- end
1156
-
1157
- def test_circular_hash
1158
- h = { 'a' => 7 }
1159
- h['b'] = h
1160
- json = Oj.dump(h, :mode => :object, :indent => 2, :circular => true)
1161
- ha = Oj.load(json, :mode => :strict)
1162
- assert_equal({'^i' => 1, 'a' => 7, 'b' => '^r1'}, ha)
1163
- Oj.load(json, :mode => :object, :circular => true)
1164
- assert_equal(h['b'].__id__, h.__id__)
1165
- end
1166
-
1167
- def test_circular_array
1168
- a = [7]
1169
- a << a
1170
- json = Oj.dump(a, :mode => :object, :indent => 2, :circular => true)
1171
- assert_equal(%{[
1172
- "^i1",
1173
- 7,
1174
- "^r1"
1175
- ]
1176
- }, json)
1177
- a2 = Oj.load(json, :mode => :object, :circular => true)
1178
- assert_equal(a2[1].__id__, a2.__id__)
1179
- end
1180
-
1181
- def test_circular
1182
- h = { 'a' => 7 }
1183
- obj = Jam.new(h, 58)
1184
- obj.x['b'] = obj
1185
- json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
1186
- ha = Oj.load(json, :mode => :strict)
1187
- assert_equal({'^o' => 'Juice::Jam', '^i' => 1, 'x' => { '^i' => 2, 'a' => 7, 'b' => '^r1' }, 'y' => 58 }, ha)
1188
- Oj.load(json, :mode => :object, :circular => true)
1189
- assert_equal(obj.x.__id__, h.__id__)
1190
- assert_equal(h['b'].__id__, obj.__id__)
1191
- end
1192
-
1193
- # Stream Deeply Nested
1194
- def test_deep_nest
1195
- begin
1196
- n = 10000
1197
- Oj.strict_load('[' * n + ']' * n)
1198
- rescue Exception => e
1199
- assert(false, e.message)
1200
- end
1201
- end
1202
-
531
+ # Stream Deeply Nested
1203
532
  def test_deep_nest_dump
1204
533
  begin
1205
534
  a = []
@@ -1212,7 +541,7 @@ class Juice < Minitest::Test
1212
541
  assert(false, "*** expected an exception")
1213
542
  end
1214
543
 
1215
- # Stream IO
544
+ # Stream IO
1216
545
  def test_io_string
1217
546
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
1218
547
  output = StringIO.open("", "w+")
@@ -1224,6 +553,9 @@ class Juice < Minitest::Test
1224
553
  end
1225
554
 
1226
555
  def test_io_file
556
+ # Windows does not support fork
557
+ return if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
558
+
1227
559
  src = { 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}
1228
560
  filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
1229
561
  File.open(filename, "w") { |f|
@@ -1235,16 +567,26 @@ class Juice < Minitest::Test
1235
567
  assert_equal(src, obj)
1236
568
  end
1237
569
 
1238
- # symbol_keys option
1239
- def test_symbol_keys
1240
- json = %{{
1241
- "x":true,
1242
- "y":58,
1243
- "z": [1,2,3]
1244
- }
1245
- }
1246
- obj = Oj.load(json, :mode => :strict, :symbol_keys => true)
1247
- assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
570
+ def test_io_stream
571
+ IO.pipe do |r, w|
572
+ if fork
573
+ r.close
574
+ #w.nonblock = false
575
+ a = []
576
+ 10_000.times do |i|
577
+ a << i
578
+ end
579
+ Oj.to_stream(w, a, indent: 2)
580
+ w.close
581
+ else
582
+ w.close
583
+ sleep(0.1) # to force a busy
584
+ cnt = 0
585
+ r.each_line { cnt += 1 }
586
+ r.close
587
+ Process.exit(0)
588
+ end
589
+ end
1248
590
  end
1249
591
 
1250
592
  # comments
@@ -1286,7 +628,7 @@ class Juice < Minitest::Test
1286
628
 
1287
629
  def test_nilnil_false
1288
630
  begin
1289
- Oj.load(nil)
631
+ Oj.load(nil, :nilnil => false)
1290
632
  rescue Exception
1291
633
  assert(true)
1292
634
  return
@@ -1296,12 +638,30 @@ class Juice < Minitest::Test
1296
638
 
1297
639
  def test_nilnil_true
1298
640
  obj = Oj.load(nil, :nilnil => true)
1299
- assert_equal(nil, obj)
641
+ assert_nil(obj)
642
+ end
643
+
644
+ def test_empty_string_true
645
+ result = Oj.load(gen_whitespaced_string, :empty_string => true, mode: :strict)
646
+ assert_nil(result)
647
+ end
648
+
649
+ def test_empty_string_false
650
+ # Could be either a Oj::ParseError or an EncodingError depending on
651
+ # whether mimic_JSON has been called. Since we don't know when the test
652
+ # will be called either is okay.
653
+ begin
654
+ Oj.load(gen_whitespaced_string, :empty_string => false)
655
+ rescue Exception => e
656
+ assert(Oj::ParseError == e.class || EncodingError == e.class)
657
+ return
658
+ end
659
+ assert(false, "*** expected an exception")
1300
660
  end
1301
661
 
1302
662
  def test_quirks_null_mode
1303
663
  assert_raises(Oj::ParseError) { Oj.load("null", :quirks_mode => false) }
1304
- assert_equal(nil, Oj.load("null", :quirks_mode => true))
664
+ assert_nil(Oj.load("null", :quirks_mode => true))
1305
665
  end
1306
666
 
1307
667
  def test_quirks_bool_mode
@@ -1324,6 +684,31 @@ class Juice < Minitest::Test
1324
684
  assert_equal('string', Oj.load('"string"', :quirks_mode => true))
1325
685
  end
1326
686
 
687
+ def test_error_path
688
+ msg = ''
689
+ assert_raises(Oj::ParseError) {
690
+ begin
691
+ Oj.load(%|{
692
+ "first": [
693
+ 1, 2, { "third": 123x }
694
+ ]
695
+ }|)
696
+ rescue Oj::ParseError => e
697
+ msg = e.message
698
+ raise e
699
+ end
700
+ }
701
+ assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
702
+ end
703
+
704
+ def test_bad_bignum
705
+ if '2.4.0' < RUBY_VERSION
706
+ assert_raises Oj::ParseError do
707
+ Oj.load(%|{ "big": -e123456789 }|, mode: :strict)
708
+ end
709
+ end
710
+ end
711
+
1327
712
  def test_quirks_array_mode
1328
713
  assert_equal([], Oj.load("[]", :quirks_mode => false))
1329
714
  assert_equal([], Oj.load("[]", :quirks_mode => true))
@@ -1340,9 +725,6 @@ class Juice < Minitest::Test
1340
725
  json = Oj.dump(jam, :omit_nil => true, :mode => :object)
1341
726
  assert_equal(%|{"^o":"Juice::Jam","x":{"a":1}}|, json)
1342
727
 
1343
- json = Oj.dump(jam, :omit_nil => true, :mode => :compat)
1344
- assert_equal(%|{"x":{"a":1}}|, json)
1345
-
1346
728
  json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true, :mode => :strict)
1347
729
  assert_equal(%|{"x":{"a":1}}|, json)
1348
730
 
@@ -1354,7 +736,11 @@ class Juice < Minitest::Test
1354
736
  json = Oj.dump(obj, :indent => 2)
1355
737
  puts json if trace
1356
738
  loaded = Oj.load(json)
1357
- assert_equal(obj, loaded)
739
+ if obj.nil?
740
+ assert_nil(loaded)
741
+ else
742
+ assert_equal(obj, loaded)
743
+ end
1358
744
  loaded
1359
745
  end
1360
746