msgpack 1.4.5 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
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