oj 3.16.0 → 3.17.3

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +107 -0
  3. data/README.md +0 -16
  4. data/ext/oj/cache.c +4 -2
  5. data/ext/oj/cache.h +3 -2
  6. data/ext/oj/compat.c +3 -3
  7. data/ext/oj/custom.c +17 -11
  8. data/ext/oj/dump.c +624 -90
  9. data/ext/oj/dump.h +9 -2
  10. data/ext/oj/dump_compat.c +15 -9
  11. data/ext/oj/dump_leaf.c +1 -1
  12. data/ext/oj/dump_object.c +32 -17
  13. data/ext/oj/dump_strict.c +20 -14
  14. data/ext/oj/extconf.rb +11 -9
  15. data/ext/oj/fast.c +50 -32
  16. data/ext/oj/intern.c +24 -7
  17. data/ext/oj/mimic_json.c +17 -11
  18. data/ext/oj/object.c +21 -13
  19. data/ext/oj/oj.c +387 -140
  20. data/ext/oj/oj.h +59 -55
  21. data/ext/oj/parse.c +248 -47
  22. data/ext/oj/parser.c +179 -89
  23. data/ext/oj/parser.h +4 -2
  24. data/ext/oj/rails.c +64 -42
  25. data/ext/oj/reader.c +1 -1
  26. data/ext/oj/rxclass.c +1 -1
  27. data/ext/oj/rxclass.h +1 -1
  28. data/ext/oj/safe.c +230 -0
  29. data/ext/oj/safe.h +79 -0
  30. data/ext/oj/saj.c +15 -10
  31. data/ext/oj/scp.c +3 -6
  32. data/ext/oj/simd.h +219 -0
  33. data/ext/oj/sparse.c +6 -3
  34. data/ext/oj/stream_writer.c +38 -28
  35. data/ext/oj/strict.c +2 -4
  36. data/ext/oj/string_writer.c +54 -22
  37. data/ext/oj/usual.c +57 -35
  38. data/ext/oj/usual.h +1 -0
  39. data/ext/oj/val_stack.c +13 -2
  40. data/ext/oj/wab.c +5 -4
  41. data/lib/oj/mimic.rb +1 -5
  42. data/lib/oj/schandler.rb +5 -4
  43. data/lib/oj/version.rb +1 -1
  44. data/pages/Encoding.md +1 -1
  45. metadata +36 -100
  46. data/test/_test_active.rb +0 -75
  47. data/test/_test_active_mimic.rb +0 -95
  48. data/test/_test_mimic_rails.rb +0 -123
  49. data/test/activerecord/result_test.rb +0 -31
  50. data/test/activesupport6/abstract_unit.rb +0 -44
  51. data/test/activesupport6/decoding_test.rb +0 -133
  52. data/test/activesupport6/encoding_test.rb +0 -507
  53. data/test/activesupport6/encoding_test_cases.rb +0 -98
  54. data/test/activesupport6/test_common.rb +0 -17
  55. data/test/activesupport6/test_helper.rb +0 -163
  56. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  57. data/test/activesupport7/abstract_unit.rb +0 -49
  58. data/test/activesupport7/decoding_test.rb +0 -125
  59. data/test/activesupport7/encoding_test.rb +0 -486
  60. data/test/activesupport7/encoding_test_cases.rb +0 -104
  61. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  62. data/test/files.rb +0 -29
  63. data/test/foo.rb +0 -14
  64. data/test/helper.rb +0 -39
  65. data/test/isolated/shared.rb +0 -309
  66. data/test/isolated/test_mimic_after.rb +0 -13
  67. data/test/isolated/test_mimic_alone.rb +0 -12
  68. data/test/isolated/test_mimic_as_json.rb +0 -45
  69. data/test/isolated/test_mimic_before.rb +0 -13
  70. data/test/isolated/test_mimic_define.rb +0 -28
  71. data/test/isolated/test_mimic_rails_after.rb +0 -22
  72. data/test/isolated/test_mimic_rails_before.rb +0 -21
  73. data/test/isolated/test_mimic_redefine.rb +0 -15
  74. data/test/json_gem/json_addition_test.rb +0 -216
  75. data/test/json_gem/json_common_interface_test.rb +0 -155
  76. data/test/json_gem/json_encoding_test.rb +0 -107
  77. data/test/json_gem/json_ext_parser_test.rb +0 -21
  78. data/test/json_gem/json_fixtures_test.rb +0 -36
  79. data/test/json_gem/json_generator_test.rb +0 -407
  80. data/test/json_gem/json_generic_object_test.rb +0 -90
  81. data/test/json_gem/json_parser_test.rb +0 -477
  82. data/test/json_gem/json_string_matching_test.rb +0 -42
  83. data/test/json_gem/test_helper.rb +0 -30
  84. data/test/mem.rb +0 -34
  85. data/test/perf.rb +0 -102
  86. data/test/perf_compat.rb +0 -128
  87. data/test/perf_dump.rb +0 -50
  88. data/test/perf_fast.rb +0 -162
  89. data/test/perf_file.rb +0 -62
  90. data/test/perf_object.rb +0 -134
  91. data/test/perf_once.rb +0 -59
  92. data/test/perf_parser.rb +0 -183
  93. data/test/perf_saj.rb +0 -101
  94. data/test/perf_scp.rb +0 -140
  95. data/test/perf_simple.rb +0 -289
  96. data/test/perf_strict.rb +0 -137
  97. data/test/perf_wab.rb +0 -129
  98. data/test/prec.rb +0 -23
  99. data/test/sample/change.rb +0 -13
  100. data/test/sample/dir.rb +0 -18
  101. data/test/sample/doc.rb +0 -35
  102. data/test/sample/file.rb +0 -47
  103. data/test/sample/group.rb +0 -15
  104. data/test/sample/hasprops.rb +0 -15
  105. data/test/sample/layer.rb +0 -11
  106. data/test/sample/line.rb +0 -20
  107. data/test/sample/oval.rb +0 -10
  108. data/test/sample/rect.rb +0 -9
  109. data/test/sample/shape.rb +0 -34
  110. data/test/sample/text.rb +0 -19
  111. data/test/sample.rb +0 -54
  112. data/test/sample_json.rb +0 -37
  113. data/test/test_compat.rb +0 -567
  114. data/test/test_custom.rb +0 -554
  115. data/test/test_debian.rb +0 -50
  116. data/test/test_fast.rb +0 -526
  117. data/test/test_file.rb +0 -250
  118. data/test/test_gc.rb +0 -60
  119. data/test/test_generate.rb +0 -21
  120. data/test/test_hash.rb +0 -39
  121. data/test/test_integer_range.rb +0 -72
  122. data/test/test_null.rb +0 -376
  123. data/test/test_object.rb +0 -1016
  124. data/test/test_parser.rb +0 -11
  125. data/test/test_parser_debug.rb +0 -27
  126. data/test/test_parser_saj.rb +0 -337
  127. data/test/test_parser_usual.rb +0 -217
  128. data/test/test_rails.rb +0 -35
  129. data/test/test_saj.rb +0 -188
  130. data/test/test_scp.rb +0 -431
  131. data/test/test_strict.rb +0 -431
  132. data/test/test_various.rb +0 -801
  133. data/test/test_wab.rb +0 -311
  134. data/test/test_writer.rb +0 -380
  135. data/test/tests.rb +0 -33
  136. data/test/tests_mimic.rb +0 -23
  137. data/test/tests_mimic_addition.rb +0 -16
data/test/test_strict.rb DELETED
@@ -1,431 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << __dir__
5
- @oj_dir = File.dirname(File.expand_path(__dir__))
6
- %w(lib ext).each do |dir|
7
- $LOAD_PATH << 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 StrictJuice < Minitest::Test
18
-
19
- module TestModule
20
- end
21
-
22
- class Jeez
23
- attr_accessor :x, :y
24
-
25
- def initialize(x, y)
26
- @x = x
27
- @y = y
28
- end
29
- end
30
-
31
- def setup
32
- @default_options = Oj.default_options
33
- # in strict mode other options other than the number formats are not used.
34
- Oj.default_options = { :mode => :strict }
35
- end
36
-
37
- def teardown
38
- Oj.default_options = @default_options
39
- end
40
-
41
- def test_nil
42
- dump_and_load(nil, false)
43
- end
44
-
45
- def test_true
46
- dump_and_load(true, false)
47
- end
48
-
49
- def test_false
50
- dump_and_load(false, false)
51
- end
52
-
53
- def test_fixnum
54
- dump_and_load(0, false)
55
- dump_and_load(12_345, false)
56
- dump_and_load(-54_321, false)
57
- dump_and_load(1, false)
58
- end
59
-
60
- def test_float
61
- dump_and_load(0.0, false)
62
- dump_and_load(12_345.6789, false)
63
- dump_and_load(70.35, false)
64
- dump_and_load(-54_321.012, false)
65
- dump_and_load(1.7775, false)
66
- dump_and_load(2.5024, false)
67
- dump_and_load(2.48e16, false)
68
- dump_and_load(2.48e100 * 1.0e10, false)
69
- dump_and_load(-2.48e100 * 1.0e10, false)
70
- end
71
-
72
- def test_nan_dump
73
- assert_equal('null', Oj.dump(0/0.0, :nan => :null))
74
- assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :nan => :huge))
75
- begin
76
- Oj.dump(0/0.0, :nan => :word)
77
- rescue Exception
78
- assert(true)
79
- return
80
- end
81
- assert(false, '*** expected an exception')
82
- end
83
-
84
- def test_infinity_dump
85
- assert_equal('null', Oj.dump(1/0.0, :nan => :null))
86
- assert_equal('3.0e14159265358979323846', Oj.dump(1/0.0, :nan => :huge))
87
- begin
88
- Oj.dump(1/0.0, :nan => :word)
89
- rescue Exception
90
- assert(true)
91
- return
92
- end
93
- assert(false, '*** expected an exception')
94
- end
95
-
96
- def test_neg_infinity_dump
97
- assert_equal('null', Oj.dump(-1/0.0, :nan => :null))
98
- assert_equal('-3.0e14159265358979323846', Oj.dump(-1/0.0, :nan => :huge))
99
- begin
100
- Oj.dump(-1/0.0, :nan => :word)
101
- rescue Exception
102
- assert(true)
103
- return
104
- end
105
- assert(false, '*** expected an exception')
106
- end
107
-
108
- def test_string
109
- dump_and_load('', false)
110
- dump_and_load('abc', false)
111
- dump_and_load("abc\ndef", false)
112
- dump_and_load("a\u0041", false)
113
- end
114
-
115
- def test_encode
116
- opts = Oj.default_options
117
- Oj.default_options = { :ascii_only => false }
118
- dump_and_load('ぴーたー', false)
119
- Oj.default_options = { :ascii_only => true }
120
- json = Oj.dump('ぴーたー')
121
- assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
122
- dump_and_load('ぴーたー', false)
123
- Oj.default_options = opts
124
- end
125
-
126
- def test_unicode
127
- # hits the 3 normal ranges and one extended surrogate pair
128
- json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
129
- obj = Oj.load(json)
130
- json2 = Oj.dump(obj, :ascii_only => true)
131
- assert_equal(json, json2)
132
- end
133
-
134
- def test_unicode_long
135
- # tests buffer overflow
136
- json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e #{'x' * 2000}"}
137
- obj = Oj.load(json)
138
- json2 = Oj.dump(obj, :ascii_only => true)
139
- assert_equal(json, json2)
140
- end
141
-
142
- def test_array
143
- dump_and_load([], false)
144
- dump_and_load([true, false], false)
145
- dump_and_load(['a', 1, nil], false)
146
- dump_and_load([[nil]], false)
147
- dump_and_load([[nil], 58], false)
148
- end
149
-
150
- def test_array_deep
151
- dump_and_load([1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20]]]]]]]]]]]]]]]]]]]], false)
152
- end
153
-
154
- def test_deep_nest
155
- skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
156
-
157
- begin
158
- n = 10_000
159
- Oj.strict_load(('[' * n) + (']' * n))
160
- rescue Exception => e
161
- refute(e.message)
162
- end
163
- end
164
-
165
- # Hash
166
- def test_hash
167
- dump_and_load({}, false)
168
- dump_and_load({ 'true' => true, 'false' => false}, false)
169
- dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
170
- end
171
-
172
- def test_hash_deep
173
- dump_and_load({'1' => {
174
- '2' => {
175
- '3' => {
176
- '4' => {
177
- '5' => {
178
- '6' => {
179
- '7' => {
180
- '8' => {
181
- '9' => {
182
- '10' => {
183
- '11' => {
184
- '12' => {
185
- '13' => {
186
- '14' => {
187
- '15' => {
188
- '16' => {
189
- '17' => {
190
- '18' => {
191
- '19' => {
192
- '20' => {}}}}}}}}}}}}}}}}}}}}}, false)
193
- end
194
-
195
- def test_hash_escaped_key
196
- json = %{{"a\nb":true,"c\td":false}}
197
- obj = Oj.strict_load(json)
198
- assert_equal({"a\nb" => true, "c\td" => false}, obj)
199
- end
200
-
201
- def test_non_str_hash
202
- begin
203
- Oj.dump({ 1 => true, 0 => false })
204
- rescue Exception
205
- assert(true)
206
- return
207
- end
208
- assert(false, '*** expected an exception')
209
- end
210
-
211
- def test_bignum_object
212
- dump_and_load(7 ** 55, false)
213
- end
214
-
215
- # BigDecimal
216
- def test_bigdecimal_strict
217
- Oj.default_options = { :bigdecimal_load => true}
218
- dump_and_load(BigDecimal('3.14159265358979323846'), false)
219
- end
220
-
221
- def test_bigdecimal_load
222
- orig = BigDecimal('80.51')
223
- json = Oj.dump(orig, :mode => :strict, :bigdecimal_as_decimal => true)
224
- bg = Oj.load(json, :mode => :strict, :bigdecimal_load => true)
225
- assert_equal(BigDecimal, bg.class)
226
- assert_equal(orig, bg)
227
- end
228
-
229
- def test_json_object
230
- obj = Jeez.new(true, 58)
231
- begin
232
- Oj.dump(obj)
233
- rescue Exception
234
- assert(true)
235
- return
236
- end
237
- assert(false, '*** expected an exception')
238
- end
239
-
240
- def test_range
241
- begin
242
- Oj.dump(1..7)
243
- rescue Exception
244
- assert(true)
245
- return
246
- end
247
- assert(false, '*** expected an exception')
248
- end
249
-
250
- # Stream IO
251
- def test_io_string
252
- json = %{{
253
- "x":true,
254
- "y":58,
255
- "z": [1,2,3]
256
- }
257
- }
258
- input = StringIO.new(json)
259
- obj = Oj.strict_load(input)
260
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
261
- end
262
-
263
- def test_io_file
264
- filename = File.join(__dir__, 'open_file_test.json')
265
- File.write(filename, %{{
266
- "x":true,
267
- "y":58,
268
- "z": [1,2,3]
269
- }
270
- })
271
- f = File.new(filename)
272
- obj = Oj.strict_load(f)
273
- f.close()
274
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
275
- end
276
-
277
- def test_symbol
278
- json = Oj.dump(:abc)
279
- assert_equal('"abc"', json)
280
- end
281
-
282
- def test_time
283
- t = Time.local(2012, 1, 5, 23, 58, 7)
284
- begin
285
- Oj.dump(t)
286
- rescue Exception
287
- assert(true)
288
- return
289
- end
290
- assert(false, '*** expected an exception')
291
- end
292
-
293
- def test_class
294
- begin
295
- Oj.dump(StrictJuice)
296
- rescue Exception
297
- assert(true)
298
- return
299
- end
300
- assert(false, '*** expected an exception')
301
- end
302
-
303
- def test_module
304
- begin
305
- Oj.dump(TestModule)
306
- rescue Exception
307
- assert(true)
308
- return
309
- end
310
- assert(false, '*** expected an exception')
311
- end
312
-
313
- # symbol_keys option
314
- def test_symbol_keys
315
- json = %{{
316
- "x":true,
317
- "y":58,
318
- "z": [1,2,3]
319
- }
320
- }
321
- obj = Oj.strict_load(json, :symbol_keys => true)
322
- assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
323
- end
324
-
325
- def test_symbol_keys_safe
326
- json = %{{
327
- "x":true,
328
- "y":58,
329
- "z": [1,2,3]
330
- }
331
- }
332
- obj = Oj.safe_load(json)
333
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
334
- end
335
-
336
- # comments
337
- def test_comment_slash
338
- json = %{{
339
- "x":true,//three
340
- "y":58,
341
- "z": [1,2,
342
- 3 // six
343
- ]}
344
- }
345
- obj = Oj.strict_load(json)
346
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
347
- end
348
-
349
- def test_comment_c
350
- json = %{{
351
- "x"/*one*/:/*two*/true,
352
- "y":58,
353
- "z": [1,2,3]}
354
- }
355
- obj = Oj.strict_load(json)
356
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
357
- end
358
-
359
- def test_comment
360
- json = %{{
361
- "x"/*one*/:/*two*/true,//three
362
- "y":58/*four*/,
363
- "z": [1,2/*five*/,
364
- 3 // six
365
- ]
366
- }
367
- }
368
- obj = Oj.strict_load(json)
369
- assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
370
- end
371
-
372
- def test_double
373
- json = %{{ "x": 1}{ "y": 2}}
374
- results = []
375
- Oj.load(json, :mode => :strict) { |x| results << x }
376
-
377
- assert_equal([{ 'x' => 1 }, { 'y' => 2 }], results)
378
- end
379
-
380
- def test_invalid_decimal_dot_start
381
- assert_raises(Oj::ParseError) {
382
- Oj.load('.123', mode: :strict)
383
- }
384
- assert_raises(Oj::ParseError) {
385
- Oj.load('-.123', mode: :strict)
386
- }
387
- end
388
-
389
- def test_invalid_decimal_dot_end
390
- json = '123.'
391
- assert_raises(Oj::ParseError) {
392
- Oj.load(json, mode: :strict)
393
- }
394
- end
395
-
396
- def test_invalid_decimal_plus
397
- json = '+12'
398
- assert_raises(Oj::ParseError) {
399
- Oj.load(json, mode: :strict)
400
- }
401
- end
402
-
403
- def test_circular_hash
404
- h = { 'a' => 7 }
405
- h['b'] = h
406
- json = Oj.dump(h, :indent => 2, :circular => true)
407
- assert_equal(%|{
408
- "a":7,
409
- "b":null
410
- }
411
- |, json)
412
- end
413
-
414
- def test_omit_nil
415
- json = Oj.dump({'x' => {'a' => 1, 'b' => nil }, 'y' => nil}, :omit_nil => true)
416
- assert_equal(%|{"x":{"a":1}}|, json)
417
- end
418
-
419
- def dump_and_load(obj, trace=false)
420
- json = Oj.dump(obj, :indent => 2)
421
- puts json if trace
422
- loaded = Oj.strict_load(json)
423
- if obj.nil?
424
- assert_nil(loaded)
425
- else
426
- assert_equal(obj, loaded)
427
- end
428
- loaded
429
- end
430
-
431
- end