oj 3.16.1 → 3.16.4

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.
data/ext/oj/usual.c CHANGED
@@ -281,7 +281,6 @@ static void close_object(ojParser p) {
281
281
  VALUE *head = d->vhead + c->vi + 1;
282
282
  volatile VALUE obj = rb_hash_new();
283
283
 
284
- #if HAVE_RB_HASH_BULK_INSERT
285
284
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
286
285
  *vp = d->get_key(p, kp);
287
286
  if (sizeof(kp->buf) <= (size_t)kp->len) {
@@ -289,14 +288,6 @@ static void close_object(ojParser p) {
289
288
  }
290
289
  }
291
290
  rb_hash_bulk_insert(d->vtail - head, head, obj);
292
- #else
293
- for (vp = head; kp < d->ktail; kp++, vp += 2) {
294
- rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
295
- if (sizeof(kp->buf) <= (size_t)kp->len) {
296
- OJ_R_FREE(kp->key);
297
- }
298
- }
299
- #endif
300
291
  d->ktail = d->khead + c->ki;
301
292
  d->vtail = head;
302
293
  head--;
@@ -341,7 +332,6 @@ static void close_object_create(ojParser p) {
341
332
  head++;
342
333
  if (Qnil == d->hash_class) {
343
334
  obj = rb_hash_new();
344
- #if HAVE_RB_HASH_BULK_INSERT
345
335
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
346
336
  *vp = d->get_key(p, kp);
347
337
  if (sizeof(kp->buf) <= (size_t)kp->len) {
@@ -349,14 +339,6 @@ static void close_object_create(ojParser p) {
349
339
  }
350
340
  }
351
341
  rb_hash_bulk_insert(d->vtail - head, head, obj);
352
- #else
353
- for (vp = head; kp < d->ktail; kp++, vp += 2) {
354
- rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
355
- if (sizeof(kp->buf) <= (size_t)kp->len) {
356
- OJ_R_FREE(kp->key);
357
- }
358
- }
359
- #endif
360
342
  } else {
361
343
  obj = rb_class_new_instance(0, NULL, d->hash_class);
362
344
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
@@ -373,7 +355,6 @@ static void close_object_create(ojParser p) {
373
355
  if (!d->ignore_json_create && rb_respond_to(clas, oj_json_create_id)) {
374
356
  volatile VALUE arg = rb_hash_new();
375
357
 
376
- #if HAVE_RB_HASH_BULK_INSERT
377
358
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
378
359
  *vp = d->get_key(p, kp);
379
360
  if (sizeof(kp->buf) <= (size_t)kp->len) {
@@ -381,14 +362,6 @@ static void close_object_create(ojParser p) {
381
362
  }
382
363
  }
383
364
  rb_hash_bulk_insert(d->vtail - head, head, arg);
384
- #else
385
- for (vp = head; kp < d->ktail; kp++, vp += 2) {
386
- rb_hash_aset(arg, d->get_key(p, kp), *(vp + 1));
387
- if (sizeof(kp->buf) <= (size_t)kp->len) {
388
- OJ_R_FREE(kp->key);
389
- }
390
- }
391
- #endif
392
365
  obj = rb_funcall(clas, oj_json_create_id, 1, arg);
393
366
  } else {
394
367
  obj = rb_class_new_instance(0, NULL, clas);
@@ -601,6 +574,9 @@ static VALUE result(ojParser p) {
601
574
  if (d->vhead < d->vtail) {
602
575
  return *d->vhead;
603
576
  }
577
+ if (d->raise_on_empty) {
578
+ rb_raise(oj_parse_error_class, "empty string");
579
+ }
604
580
  return Qnil;
605
581
  }
606
582
 
@@ -1066,6 +1042,20 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1066
1042
  return (NULL != d->sym_cache) ? Qtrue : Qfalse;
1067
1043
  }
1068
1044
 
1045
+ static VALUE opt_raise_on_empty(ojParser p, VALUE value) {
1046
+ Usual d = (Usual)p->ctx;
1047
+
1048
+ return d->raise_on_empty ? Qtrue : Qfalse;
1049
+ }
1050
+
1051
+ static VALUE opt_raise_on_empty_set(ojParser p, VALUE value) {
1052
+ Usual d = (Usual)p->ctx;
1053
+
1054
+ d->raise_on_empty = (Qtrue == value);
1055
+
1056
+ return d->raise_on_empty ? Qtrue : Qfalse;
1057
+ }
1058
+
1069
1059
  static VALUE option(ojParser p, const char *key, VALUE value) {
1070
1060
  struct opt *op;
1071
1061
  struct opt opts[] = {
@@ -1095,6 +1085,8 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
1095
1085
  {.name = "omit_null=", .func = opt_omit_null_set},
1096
1086
  {.name = "symbol_keys", .func = opt_symbol_keys},
1097
1087
  {.name = "symbol_keys=", .func = opt_symbol_keys_set},
1088
+ {.name = "raise_on_empty", .func = opt_raise_on_empty},
1089
+ {.name = "raise_on_empty=", .func = opt_raise_on_empty_set},
1098
1090
  {.name = NULL},
1099
1091
  };
1100
1092
 
@@ -1129,6 +1121,7 @@ void oj_init_usual(ojParser p, Usual d) {
1129
1121
  d->get_key = cache_key;
1130
1122
  d->cache_keys = true;
1131
1123
  d->ignore_json_create = false;
1124
+ d->raise_on_empty = false;
1132
1125
  d->cache_str = 6;
1133
1126
  d->array_class = Qnil;
1134
1127
  d->hash_class = Qnil;
data/ext/oj/usual.h CHANGED
@@ -60,6 +60,7 @@ typedef struct _usual {
60
60
  uint8_t miss_class;
61
61
  bool cache_keys;
62
62
  bool ignore_json_create;
63
+ bool raise_on_empty;
63
64
  } *Usual;
64
65
 
65
66
  // Initialize the parser with the usual delegate. If the usual delegate is
data/ext/oj/val_stack.c CHANGED
@@ -8,7 +8,7 @@
8
8
  #include "odd.h"
9
9
  #include "oj.h"
10
10
 
11
- static void mark(void *ptr) {
11
+ static void stack_mark(void *ptr) {
12
12
  ValStack stack = (ValStack)ptr;
13
13
  Val v;
14
14
 
@@ -46,6 +46,17 @@ static void mark(void *ptr) {
46
46
  #endif
47
47
  }
48
48
 
49
+ static const rb_data_type_t oj_stack_type = {
50
+ "Oj/stack",
51
+ {
52
+ stack_mark,
53
+ NULL,
54
+ NULL,
55
+ },
56
+ 0,
57
+ 0,
58
+ };
59
+
49
60
  VALUE
50
61
  oj_stack_init(ValStack stack) {
51
62
  #ifdef HAVE_PTHREAD_MUTEX_INIT
@@ -70,7 +81,7 @@ oj_stack_init(ValStack stack) {
70
81
  stack->head->clen = 0;
71
82
  stack->head->next = NEXT_NONE;
72
83
 
73
- return Data_Wrap_Struct(oj_cstack_class, mark, 0, stack);
84
+ return TypedData_Wrap_Struct(oj_cstack_class, &oj_stack_type, stack);
74
85
  }
75
86
 
76
87
  const char *oj_stack_next_string(ValNext n) {
data/lib/oj/schandler.rb CHANGED
@@ -64,13 +64,14 @@ module Oj
64
64
  #
65
65
  # hash_end
66
66
  #
67
- # When a hash key is encountered the hash_key method is called with the parsed
68
- # hash value key. The return value from the call is then used as the key in
69
- # the key-value pair that follows.
67
+ # At the end of a JSON object element the hash_end() callback is called if
68
+ # public.
70
69
  #
71
70
  # hash_key
72
71
  #
73
- # At the end of a JSON object element the hash_end() callback is called if public.
72
+ # When a hash key is encountered the hash_key() method is called with the
73
+ # parsed hash value key. The return value from the call is then used as the
74
+ # key in the key-value pair that follows.
74
75
  #
75
76
  # hash_set
76
77
  #
data/lib/oj/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Oj
2
2
  # Current version of the module.
3
- VERSION = '3.16.1'
3
+ VERSION = '3.16.4'
4
4
  end
@@ -74,42 +74,77 @@ class TestJSONEncoding < ActiveSupport::TestCase
74
74
  ActiveSupport.escape_html_entities_in_json = false
75
75
  end
76
76
 
77
- def test_utf8_string_encoded_properly
78
- # The original test seems to expect that
79
- # ActiveSupport.escape_html_entities_in_json reverts to true even after
80
- # being set to false. I haven't been able to figure that out so the value is
81
- # set to true, the default, before running the test. This might be wrong but
82
- # for now it will have to do.
83
- ActiveSupport.escape_html_entities_in_json = true
84
- result = ActiveSupport::JSON.encode("€2.99")
85
- assert_equal '"€2.99"', result
86
- assert_equal(Encoding::UTF_8, result.encoding)
87
-
88
- result = ActiveSupport::JSON.encode("✎☺")
89
- assert_equal '"✎☺"', result
90
- assert_equal(Encoding::UTF_8, result.encoding)
77
+ def test_hash_keys_encoding_without_escaping
78
+ assert_equal "{\"<>\":\"<>\"}", ActiveSupport::JSON.encode("<>" => "<>")
91
79
  end
92
80
 
93
- def test_non_utf8_string_transcodes
94
- s = "二".encode("Shift_JIS")
95
- result = ActiveSupport::JSON.encode(s)
96
- assert_equal '""', result
97
- assert_equal Encoding::UTF_8, result.encoding
81
+ module UnicodeTests
82
+ def test_utf8_string_encoded_properly
83
+ result = ActiveSupport::JSON.encode("€2.99")
84
+ assert_equal '"€2.99"', result
85
+ assert_equal(Encoding::UTF_8, result.encoding)
86
+
87
+ result = ActiveSupport::JSON.encode("✎☺")
88
+ assert_equal '"✎☺"', result
89
+ assert_equal(Encoding::UTF_8, result.encoding)
90
+ end
91
+
92
+ def test_non_utf8_string_transcodes
93
+ s = "二".encode("Shift_JIS")
94
+ result = ActiveSupport::JSON.encode(s)
95
+ assert_equal '"二"', result
96
+ assert_equal Encoding::UTF_8, result.encoding
97
+ end
98
+
99
+ def test_wide_utf8_chars
100
+ w = "𠜎"
101
+ result = ActiveSupport::JSON.encode(w)
102
+ assert_equal '"𠜎"', result
103
+ end
104
+
105
+ def test_wide_utf8_roundtrip
106
+ hash = { string: "𐒑" }
107
+ json = ActiveSupport::JSON.encode(hash)
108
+ decoded_hash = ActiveSupport::JSON.decode(json)
109
+ assert_equal "𐒑", decoded_hash["string"]
110
+ end
111
+
112
+ def test_invalid_encoding_raises
113
+ s = "\xAE\xFF\x9F"
114
+ refute s.valid_encoding?
115
+
116
+ # n.b. this raises EncodingError, because we didn't call Oj.mimic_JSON in the test setup; but,
117
+ # if you do that (even indirectly through Oj.optimize_rails), then this raises a
118
+ # JSON::GeneratorError instead of an EncodingError.
119
+ assert_raises(EncodingError) do
120
+ ActiveSupport::JSON.encode([s])
121
+ end
122
+ end
98
123
  end
99
124
 
100
- def test_wide_utf8_chars
101
- w = "𠜎"
102
- result = ActiveSupport::JSON.encode(w)
103
- assert_equal '"𠜎"', result
125
+ module UnicodeTestsWithEscapingOn
126
+ def setup
127
+ ActiveSupport.escape_html_entities_in_json = true
128
+ end
129
+
130
+ def teardown
131
+ ActiveSupport.escape_html_entities_in_json = false
132
+ end
133
+
134
+ include UnicodeTests
104
135
  end
105
136
 
106
- def test_wide_utf8_roundtrip
107
- hash = { string: "𐒑" }
108
- json = ActiveSupport::JSON.encode(hash)
109
- decoded_hash = ActiveSupport::JSON.decode(json)
110
- assert_equal "𐒑", decoded_hash["string"]
137
+ module UnicodeTestsWithEscapingOff
138
+ def setup
139
+ ActiveSupport.escape_html_entities_in_json = false
140
+ end
141
+
142
+ include UnicodeTests
111
143
  end
112
144
 
145
+ include UnicodeTestsWithEscapingOn
146
+ include UnicodeTestsWithEscapingOff
147
+
113
148
  def test_hash_key_identifiers_are_always_quoted
114
149
  values = { 0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B" }
115
150
  assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
@@ -8,9 +8,18 @@ require "active_support/time"
8
8
  require_relative "time_zone_test_helpers"
9
9
  require_relative "encoding_test_cases"
10
10
 
11
+ require 'oj'
12
+ # Sets the ActiveSupport encoder to be Oj and also wraps the setting of globals.
13
+ Oj::Rails.set_encoder()
14
+ Oj::Rails.optimize()
15
+
11
16
  class TestJSONEncoding < ActiveSupport::TestCase
12
17
  include TimeZoneTestHelpers
13
18
 
19
+ def test_is_actually_oj
20
+ assert_equal Oj::Rails::Encoder, ActiveSupport.json_encoder
21
+ end
22
+
14
23
  def sorted_json(json)
15
24
  if json.start_with?("{") && json.end_with?("}")
16
25
  "{" + json[1..-2].split(",").sort.join(",") + "}"
@@ -61,36 +70,77 @@ class TestJSONEncoding < ActiveSupport::TestCase
61
70
  ActiveSupport.escape_html_entities_in_json = false
62
71
  end
63
72
 
64
- def test_utf8_string_encoded_properly
65
- result = ActiveSupport::JSON.encode("€2.99")
66
- assert_equal '"€2.99"', result
67
- assert_equal(Encoding::UTF_8, result.encoding)
68
-
69
- result = ActiveSupport::JSON.encode("✎☺")
70
- assert_equal '"✎☺"', result
71
- assert_equal(Encoding::UTF_8, result.encoding)
73
+ def test_hash_keys_encoding_without_escaping
74
+ assert_equal "{\"<>\":\"<>\"}", ActiveSupport::JSON.encode("<>" => "<>")
72
75
  end
73
76
 
74
- def test_non_utf8_string_transcodes
75
- s = "二".encode("Shift_JIS")
76
- result = ActiveSupport::JSON.encode(s)
77
- assert_equal '""', result
78
- assert_equal Encoding::UTF_8, result.encoding
77
+ module UnicodeTests
78
+ def test_utf8_string_encoded_properly
79
+ result = ActiveSupport::JSON.encode("€2.99")
80
+ assert_equal '"€2.99"', result
81
+ assert_equal(Encoding::UTF_8, result.encoding)
82
+
83
+ result = ActiveSupport::JSON.encode("✎☺")
84
+ assert_equal '"✎☺"', result
85
+ assert_equal(Encoding::UTF_8, result.encoding)
86
+ end
87
+
88
+ def test_non_utf8_string_transcodes
89
+ s = "二".encode("Shift_JIS")
90
+ result = ActiveSupport::JSON.encode(s)
91
+ assert_equal '"二"', result
92
+ assert_equal Encoding::UTF_8, result.encoding
93
+ end
94
+
95
+ def test_wide_utf8_chars
96
+ w = "𠜎"
97
+ result = ActiveSupport::JSON.encode(w)
98
+ assert_equal '"𠜎"', result
99
+ end
100
+
101
+ def test_wide_utf8_roundtrip
102
+ hash = { string: "𐒑" }
103
+ json = ActiveSupport::JSON.encode(hash)
104
+ decoded_hash = ActiveSupport::JSON.decode(json)
105
+ assert_equal "𐒑", decoded_hash["string"]
106
+ end
107
+
108
+ def test_invalid_encoding_raises
109
+ s = "\xAE\xFF\x9F"
110
+ refute s.valid_encoding?
111
+
112
+ # n.b. this raises EncodingError, because we didn't call Oj.mimic_JSON in the test setup; but,
113
+ # if you do that (even indirectly through Oj.optimize_rails), then this raises a
114
+ # JSON::GeneratorError instead of an EncodingError.
115
+ assert_raises(EncodingError) do
116
+ ActiveSupport::JSON.encode([s])
117
+ end
118
+ end
79
119
  end
80
120
 
81
- def test_wide_utf8_chars
82
- w = "𠜎"
83
- result = ActiveSupport::JSON.encode(w)
84
- assert_equal '"𠜎"', result
121
+ module UnicodeTestsWithEscapingOn
122
+ def setup
123
+ ActiveSupport.escape_html_entities_in_json = true
124
+ end
125
+
126
+ def teardown
127
+ ActiveSupport.escape_html_entities_in_json = false
128
+ end
129
+
130
+ include UnicodeTests
85
131
  end
86
132
 
87
- def test_wide_utf8_roundtrip
88
- hash = { string: "𐒑" }
89
- json = ActiveSupport::JSON.encode(hash)
90
- decoded_hash = ActiveSupport::JSON.decode(json)
91
- assert_equal "𐒑", decoded_hash["string"]
133
+ module UnicodeTestsWithEscapingOff
134
+ def setup
135
+ ActiveSupport.escape_html_entities_in_json = false
136
+ end
137
+
138
+ include UnicodeTests
92
139
  end
93
140
 
141
+ include UnicodeTestsWithEscapingOn
142
+ include UnicodeTestsWithEscapingOff
143
+
94
144
  def test_hash_key_identifiers_are_always_quoted
95
145
  values = { 0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B" }
96
146
  assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
data/test/foo.rb CHANGED
@@ -5,16 +5,10 @@ $LOAD_PATH << '.'
5
5
  $LOAD_PATH << File.join(__dir__, '../lib')
6
6
  $LOAD_PATH << File.join(__dir__, '../ext')
7
7
 
8
- require 'active_support'
9
8
  require 'json'
10
9
  require 'oj'
10
+ require 'oj/json'
11
11
 
12
- Oj.mimic_JSON()
13
- # Oj::Rails.mimic_JSON()
12
+ Oj.mimic_JSON
14
13
 
15
- begin
16
- ::JSON.parse('{ "foo": 84e }')
17
- #::JSON.parse('{ "foo": 84eb234 }')
18
- rescue Exception => e
19
- puts "#{e.class}: #{e.message}"
20
- end
14
+ JSON.parse("[]")
@@ -142,6 +142,8 @@ class JSONGeneratorTest < Test::Unit::TestCase
142
142
  # seems to occur on travis but not locally.
143
143
  actual = state.to_h
144
144
  actual.delete(:escape_slash)
145
+ actual.delete(:strict)
146
+ actual.delete(:script_safe)
145
147
  assert_equal({
146
148
  :allow_nan => false,
147
149
  :array_nl => "\n",
@@ -162,6 +164,8 @@ class JSONGeneratorTest < Test::Unit::TestCase
162
164
  # seems to occur on travis but not locally.
163
165
  actual = state.to_h
164
166
  actual.delete(:escape_slash)
167
+ actual.delete(:strict)
168
+ actual.delete(:script_safe)
165
169
  assert_equal({
166
170
  :allow_nan => false,
167
171
  :array_nl => "",
@@ -182,6 +186,8 @@ class JSONGeneratorTest < Test::Unit::TestCase
182
186
  # seems to occur on travis but not locally.
183
187
  actual = state.to_h
184
188
  actual.delete(:escape_slash)
189
+ actual.delete(:strict)
190
+ actual.delete(:script_safe)
185
191
  assert_equal({
186
192
  :allow_nan => false,
187
193
  :array_nl => "",
data/test/perf_dump.rb CHANGED
@@ -28,7 +28,7 @@ opts.parse(ARGV)
28
28
  'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
29
29
  'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
30
30
  'f' => nil, # nil
31
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
31
+ 'h' => { 'a' => { 'b' => { 'c' => { 'd' => { 'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
32
32
  'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
33
33
  }
34
34
 
data/test/prec.rb CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'oj'
4
4
 
5
- extras = {'locationLng' => -97.14690769100295}
5
+ extras = { 'locationLng' => -97.14690769100295 }
6
6
 
7
- Oj.default_options = {float_precision: 17}
7
+ Oj.default_options = { float_precision: 17 }
8
8
 
9
9
  encoded = Oj.dump(extras)
10
10
  puts encoded
@@ -15,8 +15,8 @@ require 'active_record'
15
15
  Oj::Rails.set_encoder()
16
16
  Oj::Rails.set_decoder()
17
17
 
18
- Oj.default_options = {float_precision: 17}
19
- # Using Oj rails encoder, gets the correct value: {'locationLng':-97.14690769100295}
18
+ Oj.default_options = { float_precision: 17 }
19
+ # Using Oj rails encoder, gets the correct value: { 'locationLng':-97.14690769100295 }
20
20
  encoded = ActiveSupport::JSON.encode(extras)
21
21
  puts encoded
22
22
  puts ActiveSupport::JSON.decode(encoded)
data/test/test_custom.rb CHANGED
@@ -503,8 +503,9 @@ class CustomJuice < Minitest::Test
503
503
  # These two forms will lose precision while dumping as they don't
504
504
  # preserve full precision. We check that a dumped version is equal
505
505
  # to that version loaded and dumped a second time, but don't check
506
- # that the loaded Ruby objects is still the same as the original.
506
+ # that the loaded Ruby object is still the same as the original.
507
507
  dump_load_dump(obj, false, :time_format => :xmlschema, :create_id => '^o', :create_additions => true)
508
+ dump_load_dump(obj, false, :time_format => :xmlschema, :create_id => '^o', :create_additions => true, second_precision: 3)
508
509
  dump_load_dump(obj, false, :time_format => :ruby, :create_id => '^o', :create_additions => true)
509
510
  end
510
511
 
data/test/test_object.rb CHANGED
@@ -951,6 +951,20 @@ class ObjectJuice < Minitest::Test
951
951
  dump_and_load(DateTime.new(2012, 6, 19, 13, 5, Rational(7_123_456_789, 1_000_000_000)), false)
952
952
  end
953
953
 
954
+ def test_odd_xml_time
955
+ str = "2023-01-01T00:00:00Z"
956
+ assert_equal(Time.parse(str), Oj.load('{"^t":"' + str + '"}', mode: :object))
957
+
958
+ str = "2023-01-01T00:00:00.3Z"
959
+ assert_equal(Time.parse(str), Oj.load('{"^t":"' + str + '"}', mode: :object))
960
+
961
+ str = "2023-01-01T00:00:00.123456789123456789Z"
962
+ assert_equal(Time.parse(str), Oj.load('{"^t":"' + str + '"}', mode: :object))
963
+
964
+ str = "2023-01-01T00:00:00.123456789123456789123456789Z"
965
+ assert_equal(Time.parse(str), Oj.load('{"^t":"' + str + '"}', mode: :object))
966
+ end
967
+
954
968
  def test_bag
955
969
  json = %{{
956
970
  "^o":"ObjectJuice::Jem",
@@ -3,7 +3,7 @@
3
3
 
4
4
  $LOAD_PATH << __dir__
5
5
  @oj_dir = File.dirname(File.expand_path(__dir__))
6
- %w(lib ext).each do |dir|
6
+ %w[lib ext].each do |dir|
7
7
  $LOAD_PATH << File.join(@oj_dir, dir)
8
8
  end
9
9
 
@@ -147,6 +147,16 @@ class UsualTest < Minitest::Test
147
147
  assert_equal(MyHash, doc.class)
148
148
  end
149
149
 
150
+ def test_empty
151
+ p = Oj::Parser.new(:usual)
152
+ p.raise_on_empty = false
153
+ doc = p.parse(' ')
154
+ assert_nil(doc)
155
+
156
+ p.raise_on_empty = true
157
+ assert_raises(Oj::ParseError) { p.parse(' ') }
158
+ end
159
+
150
160
  class MyClass
151
161
  attr_accessor :a
152
162
  attr_accessor :b
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.1
4
+ version: 3.16.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-01 00:00:00.000000000 Z
11
+ date: 2024-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bigdecimal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: minitest
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -294,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
308
  - !ruby/object:Gem::Version
295
309
  version: '0'
296
310
  requirements: []
297
- rubygems_version: 3.4.1
311
+ rubygems_version: 3.4.10
298
312
  signing_key:
299
313
  specification_version: 4
300
314
  summary: A fast JSON parser and serializer.