msgpack 1.2.10 → 1.5.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +57 -0
  3. data/.gitignore +3 -1
  4. data/.rubocop.yml +4 -1
  5. data/ChangeLog +60 -0
  6. data/Gemfile +3 -0
  7. data/README.md +264 -0
  8. data/Rakefile +1 -9
  9. data/doclib/msgpack/factory.rb +47 -3
  10. data/doclib/msgpack/packer.rb +5 -4
  11. data/doclib/msgpack/time.rb +22 -0
  12. data/doclib/msgpack/timestamp.rb +44 -0
  13. data/doclib/msgpack/unpacker.rb +2 -2
  14. data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
  15. data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
  16. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  17. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +37 -49
  18. data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
  19. data/ext/java/org/msgpack/jruby/Factory.java +47 -7
  20. data/ext/java/org/msgpack/jruby/Packer.java +29 -17
  21. data/ext/java/org/msgpack/jruby/Unpacker.java +72 -37
  22. data/ext/msgpack/buffer.c +4 -16
  23. data/ext/msgpack/buffer.h +46 -5
  24. data/ext/msgpack/buffer_class.c +23 -15
  25. data/ext/msgpack/compat.h +1 -12
  26. data/ext/msgpack/extconf.rb +39 -7
  27. data/ext/msgpack/factory_class.c +87 -20
  28. data/ext/msgpack/packer.c +58 -8
  29. data/ext/msgpack/packer.h +24 -16
  30. data/ext/msgpack/packer_class.c +29 -31
  31. data/ext/msgpack/packer_ext_registry.c +22 -30
  32. data/ext/msgpack/packer_ext_registry.h +38 -31
  33. data/ext/msgpack/unpacker.c +102 -70
  34. data/ext/msgpack/unpacker.h +10 -2
  35. data/ext/msgpack/unpacker_class.c +35 -52
  36. data/ext/msgpack/unpacker_ext_registry.c +40 -16
  37. data/ext/msgpack/unpacker_ext_registry.h +21 -14
  38. data/lib/msgpack/bigint.rb +69 -0
  39. data/lib/msgpack/factory.rb +103 -0
  40. data/lib/msgpack/symbol.rb +21 -4
  41. data/lib/msgpack/time.rb +29 -0
  42. data/lib/msgpack/timestamp.rb +76 -0
  43. data/lib/msgpack/version.rb +4 -7
  44. data/lib/msgpack.rb +8 -12
  45. data/msgpack.gemspec +3 -7
  46. data/spec/bigint_spec.rb +26 -0
  47. data/spec/factory_spec.rb +299 -12
  48. data/spec/msgpack_spec.rb +1 -1
  49. data/spec/packer_spec.rb +18 -0
  50. data/spec/spec_helper.rb +30 -3
  51. data/spec/timestamp_spec.rb +159 -0
  52. data/spec/unpacker_spec.rb +135 -4
  53. metadata +21 -51
  54. data/.travis.yml +0 -43
  55. data/README.rdoc +0 -209
data/lib/msgpack.rb CHANGED
@@ -1,15 +1,10 @@
1
1
  require "msgpack/version"
2
2
 
3
3
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby" # This is same with `/java/ =~ RUBY_VERSION`
4
- require "java"
5
4
  require "msgpack/msgpack.jar"
6
- org.msgpack.jruby.MessagePackLibrary.new.load(JRuby.runtime, false)
5
+ JRuby::Util.load_ext("org.msgpack.jruby.MessagePackLibrary")
7
6
  else
8
- begin
9
- require "msgpack/#{RUBY_VERSION[/\d+.\d+/]}/msgpack"
10
- rescue LoadError
11
- require "msgpack/msgpack"
12
- end
7
+ require "msgpack/msgpack"
13
8
  end
14
9
 
15
10
  require "msgpack/packer"
@@ -17,19 +12,20 @@ require "msgpack/unpacker"
17
12
  require "msgpack/factory"
18
13
  require "msgpack/symbol"
19
14
  require "msgpack/core_ext"
15
+ require "msgpack/timestamp"
16
+ require "msgpack/time"
20
17
 
21
18
  module MessagePack
22
19
  DefaultFactory = MessagePack::Factory.new
23
- DEFAULT_EMPTY_PARAMS = {}.freeze
24
20
 
25
21
  def load(src, param = nil)
26
22
  unpacker = nil
27
23
 
28
24
  if src.is_a? String
29
- unpacker = DefaultFactory.unpacker param || DEFAULT_EMPTY_PARAMS
25
+ unpacker = DefaultFactory.unpacker param
30
26
  unpacker.feed_reference src
31
27
  else
32
- unpacker = DefaultFactory.unpacker src, param || DEFAULT_EMPTY_PARAMS
28
+ unpacker = DefaultFactory.unpacker src, param
33
29
  end
34
30
 
35
31
  unpacker.full_unpack
@@ -39,8 +35,8 @@ module MessagePack
39
35
  module_function :load
40
36
  module_function :unpack
41
37
 
42
- def pack(v, *rest)
43
- packer = DefaultFactory.packer(*rest)
38
+ def pack(v, io = nil, options = nil)
39
+ packer = DefaultFactory.packer(io, options)
44
40
  packer.write v
45
41
  packer.full_pack
46
42
  end
data/msgpack.gemspec CHANGED
@@ -10,7 +10,6 @@ Gem::Specification.new do |s|
10
10
  s.email = ["frsyuki@gmail.com", "theo@iconara.net", "tagomoris@gmail.com"]
11
11
  s.license = "Apache 2.0"
12
12
  s.homepage = "http://msgpack.org/"
13
- s.rubyforge_project = "msgpack"
14
13
  s.require_paths = ["lib"]
15
14
  if /java/ =~ RUBY_PLATFORM
16
15
  s.files = Dir['lib/**/*.rb', 'lib/**/*.jar']
@@ -19,15 +18,12 @@ Gem::Specification.new do |s|
19
18
  s.files = `git ls-files`.split("\n")
20
19
  s.extensions = ["ext/msgpack/extconf.rb"]
21
20
  end
22
- s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
21
+
22
+ s.required_ruby_version = ">= 2.4"
23
23
 
24
24
  s.add_development_dependency 'bundler'
25
25
  s.add_development_dependency 'rake'
26
- s.add_development_dependency 'rake-compiler', ['~> 1.0']
27
- if /java/ !~ RUBY_PLATFORM
28
- # NOTE: rake-compiler-dock SHOULD be updated for new Ruby versions
29
- s.add_development_dependency 'rake-compiler-dock', ['~> 0.7.0']
30
- end
26
+ s.add_development_dependency 'rake-compiler', ['>= 1.1.9']
31
27
  s.add_development_dependency 'rspec', ['~> 3.3']
32
28
  s.add_development_dependency 'yard'
33
29
  s.add_development_dependency 'json'
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe MessagePack::Bigint do
4
+ it 'serialize and deserialize arbitrary sized integer' do
5
+ [
6
+ 1,
7
+ -1,
8
+ 120938120391283122132313,
9
+ -21903120391203912391023920332103,
10
+ 210290021321301203912933021323,
11
+ ].each do |int|
12
+ expect(MessagePack::Bigint.from_msgpack_ext(MessagePack::Bigint.to_msgpack_ext(int))).to be == int
13
+ end
14
+ end
15
+
16
+ it 'has a stable format' do
17
+ {
18
+ 120938120391283122132313 => "\x00\x9F\xF4UY\x11\x92\x9A?\x00\x00\x19\x9C".b,
19
+ -21903120391203912391023920332103 => "\x01/\xB2\xBDG\xBD\xDE\xAA\xEBt\xCC\x8A\xC1\x00\x00\x01\x14".b,
20
+ 210290021321301203912933021323 => "\x00\xC4\xD8\x96\x8Bm\xCB\xC7\x03\xA7{\xD4\"\x00\x00\x00\x02".b,
21
+ }.each do |int, payload|
22
+ expect(MessagePack::Bigint.to_msgpack_ext(int)).to be == payload
23
+ expect(MessagePack::Bigint.from_msgpack_ext(payload)).to be == int
24
+ end
25
+ end
26
+ end
data/spec/factory_spec.rb CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: ascii-8bit
2
1
  require 'spec_helper'
3
2
 
4
3
  describe MessagePack::Factory do
@@ -42,6 +41,21 @@ describe MessagePack::Factory do
42
41
  unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
43
42
  expect{ unpacker.read }.to raise_error(MessagePack::UnknownExtTypeError)
44
43
  end
44
+
45
+ it 'does not share the extension registry with unpackers' do
46
+ subject.register_type(0x00, Symbol)
47
+ expect do
48
+ unpacker = subject.unpacker
49
+ expect do
50
+ unpacker.register_type(0x01) {}
51
+ end.to change { unpacker.registered_types }
52
+
53
+ second_unpacker = subject.unpacker
54
+ expect do
55
+ second_unpacker.register_type(0x01) {}
56
+ end.to_not change { unpacker.registered_types }
57
+ end.to_not change { subject.registered_types }
58
+ end
45
59
  end
46
60
 
47
61
  describe '#dump and #load' do
@@ -255,34 +269,221 @@ describe MessagePack::Factory do
255
269
  subject { factory.packer.pack(value).to_s }
256
270
  before { stub_const('Value', Class.new{ include Mod }) }
257
271
  let(:value) { Value.new }
258
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
272
+ it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
259
273
  end
260
274
 
261
275
  describe "packing an object which has been extended by the module" do
262
276
  subject { factory.packer.pack(object).to_s }
263
277
  let(:object) { Object.new.extend Mod }
264
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
278
+ it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
265
279
  end
266
280
 
267
281
  describe "unpacking with the module" do
268
- subject { factory.unpacker.feed("\xC7\x06\x01module").unpack }
282
+ subject { factory.unpacker.feed("\xC7\x06\x01module".force_encoding(Encoding::BINARY)).unpack }
269
283
  it { is_expected.to eq "unpacked module" }
270
284
  end
271
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
+ end
426
+
427
+ it 'can be nested' do
428
+ factory = MessagePack::Factory.new
429
+ factory.register_type(
430
+ 0x02,
431
+ Set,
432
+ packer: ->(set, packer) do
433
+ packer.write(set.to_a)
434
+ nil
435
+ end,
436
+ unpacker: ->(unpacker) do
437
+ unpacker.read.to_set
438
+ end,
439
+ recursive: true,
440
+ )
441
+
442
+ expected = Set[1, Set[2, Set[3]]]
443
+ payload = factory.dump(expected)
444
+ expect(payload).to be == "\xC7\v\x02\x92\x01\xC7\x06\x02\x92\x02\xD5\x02\x91\x03".b
445
+ expect(factory.load(factory.dump(expected))).to be == expected
446
+ end
447
+ end
272
448
  end
273
449
 
274
450
  describe 'the special treatment of symbols with ext type' do
275
- let(:packer) { subject.packer }
276
- let(:unpacker) { subject.unpacker }
451
+ def roundtrip(object, options = nil)
452
+ subject.load(subject.dump(object), options)
453
+ end
277
454
 
278
- def symbol_after_roundtrip
279
- packed_symbol = packer.pack(:symbol).to_s
280
- unpacker.feed(packed_symbol).unpack
455
+ context 'using the optimized symbol unpacker' do
456
+ before do
457
+ skip if IS_JRUBY # JRuby implementation doesn't support the optimized symbols unpacker for now
458
+ subject.register_type(
459
+ 0x00,
460
+ ::Symbol,
461
+ packer: :to_msgpack_ext,
462
+ unpacker: :from_msgpack_ext,
463
+ optimized_symbols_parsing: true,
464
+ )
465
+ end
466
+
467
+ it 'lets symbols survive a roundtrip' do
468
+ expect(roundtrip(:symbol)).to be :symbol
469
+ end
470
+
471
+ it 'preserves encoding for ASCII symbols' do
472
+ expect(:symbol.encoding).to be Encoding::US_ASCII
473
+ expect(roundtrip(:symbol)).to be :symbol
474
+ expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
475
+ end
476
+
477
+ it 'preserves encoding for UTF-8 symbols' do
478
+ expect(:"fée".encoding).to be Encoding::UTF_8
479
+ expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
480
+ expect(roundtrip(:"fée")).to be :"fée"
481
+ end
281
482
  end
282
483
 
283
484
  context 'if no ext type is registered for symbols' do
284
485
  it 'converts symbols to string' do
285
- expect(symbol_after_roundtrip).to eq 'symbol'
486
+ expect(roundtrip(:symbol)).to eq 'symbol'
286
487
  end
287
488
  end
288
489
 
@@ -291,7 +492,41 @@ describe MessagePack::Factory do
291
492
  before { subject.register_type(0x00, ::Symbol) }
292
493
 
293
494
  it 'lets symbols survive a roundtrip' do
294
- expect(symbol_after_roundtrip).to be :symbol
495
+ expect(roundtrip(:symbol)).to be :symbol
496
+ end
497
+
498
+ it 'works with hash keys' do
499
+ expect(roundtrip(symbol: 1)).to be == { symbol: 1 }
500
+ end
501
+
502
+ it 'works with frozen: true option' do
503
+ expect(roundtrip(:symbol, freeze: true)).to be :symbol
504
+ end
505
+
506
+ it 'preserves encoding for ASCII symbols' do
507
+ expect(:symbol.encoding).to be Encoding::US_ASCII
508
+ expect(roundtrip(:symbol)).to be :symbol
509
+ expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
510
+ end
511
+
512
+ it 'preserves encoding for UTF-8 symbols' do
513
+ expect(:"fée".encoding).to be Encoding::UTF_8
514
+ expect(roundtrip(:"fée")).to be :"fée"
515
+ expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
516
+ end
517
+
518
+ it 'does not handle symbols in other encodings' do
519
+ symbol = "fàe".encode(Encoding::ISO_8859_1).to_sym
520
+ expect(symbol.encoding).to be Encoding::ISO_8859_1
521
+
522
+ if IS_JRUBY
523
+ # JRuby doesn't quite behave like MRI here.
524
+ # "fàe".force_encoding(Encoding::BINARY).to_sym is able to lookup the existing ISO-8859-1 symbol
525
+ # It likely is a JRuby bug.
526
+ expect(roundtrip(symbol).encoding).to be Encoding::ISO_8859_1
527
+ else
528
+ expect(roundtrip(symbol).encoding).to be Encoding::BINARY
529
+ end
295
530
  end
296
531
  end
297
532
 
@@ -315,7 +550,7 @@ describe MessagePack::Factory do
315
550
  before { subject.register_type(0x00, ::Symbol) }
316
551
 
317
552
  it 'lets symbols survive a roundtrip' do
318
- expect(symbol_after_roundtrip).to be :symbol
553
+ expect(roundtrip(:symbol)).to be :symbol
319
554
  end
320
555
 
321
556
  after do
@@ -364,4 +599,56 @@ describe MessagePack::Factory do
364
599
  expect(MessagePack.unpack(MessagePack.pack(dm2))).to eq(dm2)
365
600
  end
366
601
  end
602
+
603
+ describe '#pool' do
604
+ let(:factory) { described_class.new }
605
+
606
+ it 'responds to serializers interface' do
607
+ pool = factory.pool(1)
608
+ expect(pool.load(pool.dump(42))).to be == 42
609
+ end
610
+
611
+ it 'types can be registered before the pool is created' do
612
+ factory.register_type(0x00, Symbol)
613
+ pool = factory.pool(1)
614
+ expect(pool.load(pool.dump(:foo))).to be == :foo
615
+ end
616
+
617
+ it 'types cannot be registered after the pool is created' do
618
+ pool = factory.pool(1)
619
+ factory.register_type(0x20, ::MyType)
620
+
621
+ expect do
622
+ pool.dump(MyType.new(1, 2))
623
+ end.to raise_error NoMethodError
624
+
625
+ payload = factory.dump(MyType.new(1, 2))
626
+ expect do
627
+ pool.load(payload)
628
+ end.to raise_error MessagePack::UnknownExtTypeError
629
+ end
630
+
631
+ it 'support symbolize_keys: true' do
632
+ pool = factory.pool(1, symbolize_keys: true)
633
+ expect(pool.load(pool.dump('foo' => 1))).to be == { foo: 1 }
634
+ end
635
+
636
+ it 'support freeze: true' do
637
+ pool = factory.pool(1, freeze: true)
638
+ expect(pool.load(pool.dump('foo'))).to be_frozen
639
+ end
640
+
641
+ it 'is thread safe' do
642
+ pool = factory.pool(1)
643
+
644
+ threads = 10.times.map do
645
+ Thread.new do
646
+ 1_000.times do |i|
647
+ expect(pool.load(pool.dump(i))).to be == i
648
+ end
649
+ end
650
+ end
651
+ threads.each(&:join)
652
+ end
653
+ end
367
654
  end
data/spec/msgpack_spec.rb CHANGED
@@ -115,7 +115,7 @@ describe MessagePack do
115
115
  expect { MessagePack.pack(self) }.to raise_error(NoMethodError, /^undefined method `to_msgpack'/)
116
116
  end
117
117
 
118
- it 'rasies an error on #unpack with garbage' do
118
+ it 'raises an error on #unpack with garbage' do
119
119
  skip "but nothing was raised. why?"
120
120
  expect { MessagePack.unpack('asdka;sd') }.to raise_error(MessagePack::UnpackError)
121
121
  end
data/spec/packer_spec.rb CHANGED
@@ -488,6 +488,24 @@ describe MessagePack::Packer do
488
488
  it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
489
489
  end
490
490
 
491
+ shared_examples_for 'extension subclasses core type' do |klass|
492
+ before { stub_const('Value', Class.new(klass)) }
493
+ let(:object) { Value.new }
494
+ subject { packer.pack(object).to_s }
495
+
496
+ it "defaults to #{klass.name} packer if no extension is present" do
497
+ expect(subject).to eq(MessagePack.dump(klass.new))
498
+ end
499
+
500
+ it "uses core type extension for #{klass.name}" do
501
+ packer.register_type(0x01, Value, ->(_) { 'value_msgpacked' })
502
+ expect(subject).to eq("\xC7\x0F\x01value_msgpacked")
503
+ end
504
+ end
505
+ it_behaves_like 'extension subclasses core type', Hash
506
+ it_behaves_like 'extension subclasses core type', Array
507
+ it_behaves_like 'extension subclasses core type', String
508
+
491
509
  context 'when registering a type for symbols' do
492
510
  before { packer.register_type(0x00, ::Symbol, :to_msgpack_ext) }
493
511
 
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,12 +15,38 @@ if ENV['GC_STRESS']
14
15
  end
15
16
 
16
17
  require 'msgpack'
18
+ require "msgpack/bigint"
17
19
 
18
- def java?
19
- /java/ =~ RUBY_PLATFORM
20
+ if GC.respond_to?(:verify_compaction_references)
21
+ # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
22
+ # move objects around, helping to find object movement bugs.
23
+ GC.verify_compaction_references(double_heap: true, toward: :empty)
20
24
  end
21
25
 
22
- if java?
26
+ if GC.respond_to?(:auto_compact=)
27
+ GC.auto_compact = true
28
+ end
29
+
30
+ IS_JRUBY = RUBY_ENGINE == 'jruby'
31
+
32
+ # checking if Hash#[]= (rb_hash_aset) dedupes string keys
33
+ def automatic_string_keys_deduplication?
34
+ h = {}
35
+ x = {}
36
+ r = rand.to_s
37
+ h[%W(#{r}).join('')] = :foo
38
+ x[%W(#{r}).join('')] = :foo
39
+
40
+ x.keys[0].equal?(h.keys[0])
41
+ end
42
+
43
+ def string_deduplication?
44
+ r1 = rand.to_s
45
+ r2 = r1.dup
46
+ (-r1).equal?(-r2)
47
+ end
48
+
49
+ if IS_JRUBY
23
50
  RSpec.configure do |c|
24
51
  c.treat_symbols_as_metadata_keys_with_true_values = true
25
52
  c.filter_run_excluding :encodings => !(defined? Encoding)