msgpack 1.2.10 → 1.5.1

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