msgpack 1.4.5 → 1.5.2

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/spec/factory_spec.rb CHANGED
@@ -283,6 +283,174 @@ describe MessagePack::Factory do
283
283
  it { is_expected.to eq "unpacked module" }
284
284
  end
285
285
  end
286
+
287
+ describe "registering an ext type for Integer" do
288
+ let(:factory) { described_class.new }
289
+ let(:bigint) { 10**150 }
290
+
291
+ it 'does not work by default without passing `oversized_integer_extension: true`' do
292
+ factory.register_type(0x01, Integer, packer: :to_s, unpacker: method(:Integer))
293
+
294
+ expect do
295
+ factory.dump(bigint)
296
+ end.to raise_error RangeError
297
+ end
298
+
299
+ it 'raises ArgumentError if the type is not Integer' do
300
+ expect do
301
+ factory.register_type(0x01, MyType, packer: :to_s, unpacker: method(:Integer), oversized_integer_extension: true)
302
+ end.to raise_error(ArgumentError)
303
+ end
304
+
305
+ it 'invokes the packer if registered with `oversized_integer_extension: true`' do
306
+ factory.register_type(0x01, Integer, packer: :to_s, unpacker: method(:Integer), oversized_integer_extension: true)
307
+
308
+ expect(factory.load(factory.dump(bigint))).to be == bigint
309
+ end
310
+
311
+ it 'does not use the oversized_integer_extension packer for integers fitting in native types' do
312
+ factory.register_type(
313
+ 0x01,
314
+ Integer,
315
+ packer: ->(int) { raise NotImplementedError },
316
+ unpacker: ->(payload) { raise NotImplementedError },
317
+ oversized_integer_extension: true
318
+ )
319
+
320
+ expect(factory.dump(42)).to eq(MessagePack.dump(42))
321
+ end
322
+ end
323
+
324
+ describe "registering ext type with recursive serialization" do
325
+ before do
326
+ stub_const("Point", Struct.new(:x, :y, :z))
327
+ end
328
+
329
+ it 'can receive the packer as argument (proc)' do
330
+ factory = MessagePack::Factory.new
331
+ factory.register_type(0x00, Symbol)
332
+ factory.register_type(
333
+ 0x01,
334
+ Point,
335
+ packer: ->(point, packer) do
336
+ packer.write(point.to_h)
337
+ nil
338
+ end,
339
+ unpacker: ->(unpacker) do
340
+ attrs = unpacker.read
341
+ Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
342
+ end,
343
+ recursive: true,
344
+ )
345
+
346
+ point = Point.new(1, 2, 3)
347
+ payload = factory.dump(point)
348
+ expect(factory.load(payload)).to be == point
349
+ end
350
+
351
+ it 'can receive the packer as argument (Method)' do
352
+ mod = Module.new
353
+ mod.define_singleton_method(:packer) do |point, packer|
354
+ packer.write(point.to_h)
355
+ nil
356
+ end
357
+
358
+ mod.define_singleton_method(:unpacker) do |unpacker|
359
+ attrs = unpacker.read
360
+ Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
361
+ end
362
+
363
+ factory = MessagePack::Factory.new
364
+ factory.register_type(0x00, Symbol)
365
+ factory.register_type(
366
+ 0x01,
367
+ Point,
368
+ packer: mod.method(:packer),
369
+ unpacker: mod.method(:unpacker),
370
+ recursive: true,
371
+ )
372
+
373
+ point = Point.new(1, 2, 3)
374
+ payload = factory.dump(point)
375
+ expect(factory.load(payload)).to be == point
376
+ end
377
+
378
+ it 'respect message pack format' do
379
+ factory = MessagePack::Factory.new
380
+ factory.register_type(0x00, Symbol)
381
+ factory.register_type(
382
+ 0x01,
383
+ Point,
384
+ packer: ->(point, packer) do
385
+ packer.write(point.to_a)
386
+ nil
387
+ end,
388
+ unpacker: ->(unpacker) do
389
+ attrs = unpacker.read
390
+ Point.new(*attrs)
391
+ end,
392
+ recursive: true,
393
+ )
394
+
395
+ point = Point.new(1, 2, 3)
396
+ expect(factory.dump(point)).to be == "\xD6\x01".b + MessagePack.dump([1, 2, 3])
397
+ end
398
+
399
+ it 'sets the correct length' do
400
+ factory = MessagePack::Factory.new
401
+ factory.register_type(0x00, Symbol)
402
+ factory.register_type(
403
+ 0x01,
404
+ Point,
405
+ packer: ->(point, packer) do
406
+ packer.write(point.to_h)
407
+ nil
408
+ end,
409
+ unpacker: ->(unpacker) do
410
+ attrs = unpacker.read
411
+ Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
412
+ end,
413
+ recursive: true,
414
+ )
415
+
416
+ point = Point.new(1, 2, 3)
417
+ payload = factory.dump([1, point, 3])
418
+
419
+ obj = MessagePack::Factory.new.load(payload, allow_unknown_ext: true)
420
+ expect(obj).to be == [
421
+ 1,
422
+ MessagePack::ExtensionValue.new(1, factory.dump(x: 1, y: 2, z: 3)),
423
+ 3,
424
+ ]
425
+
426
+ expect(factory.load(payload)).to be == [
427
+ 1,
428
+ Point.new(1, 2, 3),
429
+ 3,
430
+ ]
431
+ end
432
+
433
+ it 'can be nested' do
434
+ factory = MessagePack::Factory.new
435
+ factory.register_type(
436
+ 0x02,
437
+ Set,
438
+ packer: ->(set, packer) do
439
+ packer.write(set.to_a)
440
+ nil
441
+ end,
442
+ unpacker: ->(unpacker) do
443
+ unpacker.read.to_set
444
+ end,
445
+ recursive: true,
446
+ )
447
+
448
+ expected = Set[1, Set[2, Set[3]]]
449
+ payload = factory.dump(expected)
450
+ expect(payload).to be == "\xC7\v\x02\x92\x01\xC7\x06\x02\x92\x02\xD5\x02\x91\x03".b
451
+ expect(factory.load(factory.dump(expected))).to be == expected
452
+ end
453
+ end
286
454
  end
287
455
 
288
456
  describe 'the special treatment of symbols with ext type' do
@@ -437,4 +605,56 @@ describe MessagePack::Factory do
437
605
  expect(MessagePack.unpack(MessagePack.pack(dm2))).to eq(dm2)
438
606
  end
439
607
  end
608
+
609
+ describe '#pool' do
610
+ let(:factory) { described_class.new }
611
+
612
+ it 'responds to serializers interface' do
613
+ pool = factory.pool(1)
614
+ expect(pool.load(pool.dump(42))).to be == 42
615
+ end
616
+
617
+ it 'types can be registered before the pool is created' do
618
+ factory.register_type(0x00, Symbol)
619
+ pool = factory.pool(1)
620
+ expect(pool.load(pool.dump(:foo))).to be == :foo
621
+ end
622
+
623
+ it 'types cannot be registered after the pool is created' do
624
+ pool = factory.pool(1)
625
+ factory.register_type(0x20, ::MyType)
626
+
627
+ expect do
628
+ pool.dump(MyType.new(1, 2))
629
+ end.to raise_error NoMethodError
630
+
631
+ payload = factory.dump(MyType.new(1, 2))
632
+ expect do
633
+ pool.load(payload)
634
+ end.to raise_error MessagePack::UnknownExtTypeError
635
+ end
636
+
637
+ it 'support symbolize_keys: true' do
638
+ pool = factory.pool(1, symbolize_keys: true)
639
+ expect(pool.load(pool.dump('foo' => 1))).to be == { foo: 1 }
640
+ end
641
+
642
+ it 'support freeze: true' do
643
+ pool = factory.pool(1, freeze: true)
644
+ expect(pool.load(pool.dump('foo'))).to be_frozen
645
+ end
646
+
647
+ it 'is thread safe' do
648
+ pool = factory.pool(1)
649
+
650
+ threads = 10.times.map do
651
+ Thread.new do
652
+ 1_000.times do |i|
653
+ expect(pool.load(pool.dump(i))).to be == i
654
+ end
655
+ end
656
+ end
657
+ threads.each(&:join)
658
+ end
659
+ end
440
660
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "set"
1
2
 
2
3
  if ENV['SIMPLE_COV']
3
4
  require 'simplecov'
@@ -14,6 +15,7 @@ if ENV['GC_STRESS']
14
15
  end
15
16
 
16
17
  require 'msgpack'
18
+ require "msgpack/bigint"
17
19
 
18
20
  if GC.respond_to?(:verify_compaction_references)
19
21
  # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
@@ -27,6 +29,8 @@ end
27
29
 
28
30
  IS_JRUBY = RUBY_ENGINE == 'jruby'
29
31
 
32
+ IS_TRUFFLERUBY = RUBY_ENGINE == 'truffleruby'
33
+
30
34
  # checking if Hash#[]= (rb_hash_aset) dedupes string keys
31
35
  def automatic_string_keys_deduplication?
32
36
  h = {}
@@ -87,14 +87,14 @@ describe MessagePack::Timestamp do
87
87
 
88
88
  let(:time96_min) { Time.at(-2**63).utc }
89
89
  it 'is serialized into timestamp96' do
90
- skip if IS_JRUBY # JRuby cannot handle numerics larger than long
90
+ skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
91
91
  expect(factory.pack(time96_min).size).to be 15
92
92
  expect(factory.unpack(factory.pack(time96_min)).utc).to eq(time96_min)
93
93
  end
94
94
 
95
95
  let(:time96_max) { Time.at(2**63 - 1).utc }
96
96
  it 'is serialized into timestamp96' do
97
- skip if IS_JRUBY # JRuby cannot handle numerics larger than long
97
+ skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
98
98
  expect(factory.pack(time96_max).size).to be 15
99
99
  expect(factory.unpack(factory.pack(time96_max)).utc).to eq(time96_max)
100
100
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msgpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-02-15 00:00:00.000000000 Z
13
+ date: 2022-05-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -176,6 +176,7 @@ files:
176
176
  - ext/msgpack/unpacker_ext_registry.c
177
177
  - ext/msgpack/unpacker_ext_registry.h
178
178
  - lib/msgpack.rb
179
+ - lib/msgpack/bigint.rb
179
180
  - lib/msgpack/core_ext.rb
180
181
  - lib/msgpack/factory.rb
181
182
  - lib/msgpack/packer.rb
@@ -186,6 +187,7 @@ files:
186
187
  - lib/msgpack/version.rb
187
188
  - msgpack.gemspec
188
189
  - msgpack.org.md
190
+ - spec/bigint_spec.rb
189
191
  - spec/cases.json
190
192
  - spec/cases.msg
191
193
  - spec/cases_compact.msg