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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +57 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +4 -1
- data/ChangeLog +60 -0
- data/Gemfile +3 -0
- data/README.md +264 -0
- data/Rakefile +1 -9
- data/doclib/msgpack/factory.rb +47 -3
- data/doclib/msgpack/packer.rb +5 -4
- data/doclib/msgpack/time.rb +22 -0
- data/doclib/msgpack/timestamp.rb +44 -0
- data/doclib/msgpack/unpacker.rb +2 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
- data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
- data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +37 -49
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
- data/ext/java/org/msgpack/jruby/Factory.java +47 -7
- data/ext/java/org/msgpack/jruby/Packer.java +29 -17
- data/ext/java/org/msgpack/jruby/Unpacker.java +72 -37
- data/ext/msgpack/buffer.c +4 -16
- data/ext/msgpack/buffer.h +46 -5
- data/ext/msgpack/buffer_class.c +23 -15
- data/ext/msgpack/compat.h +1 -12
- data/ext/msgpack/extconf.rb +39 -7
- data/ext/msgpack/factory_class.c +87 -20
- data/ext/msgpack/packer.c +58 -8
- data/ext/msgpack/packer.h +24 -16
- data/ext/msgpack/packer_class.c +29 -31
- data/ext/msgpack/packer_ext_registry.c +22 -30
- data/ext/msgpack/packer_ext_registry.h +38 -31
- data/ext/msgpack/unpacker.c +102 -70
- data/ext/msgpack/unpacker.h +10 -2
- data/ext/msgpack/unpacker_class.c +35 -52
- data/ext/msgpack/unpacker_ext_registry.c +40 -16
- data/ext/msgpack/unpacker_ext_registry.h +21 -14
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/version.rb +4 -7
- data/lib/msgpack.rb +8 -12
- data/msgpack.gemspec +3 -7
- data/spec/bigint_spec.rb +26 -0
- data/spec/factory_spec.rb +299 -12
- data/spec/msgpack_spec.rb +1 -1
- data/spec/packer_spec.rb +18 -0
- data/spec/spec_helper.rb +30 -3
- data/spec/timestamp_spec.rb +159 -0
- data/spec/unpacker_spec.rb +135 -4
- metadata +21 -51
- data/.travis.yml +0 -43
- 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
|
5
|
+
JRuby::Util.load_ext("org.msgpack.jruby.MessagePackLibrary")
|
7
6
|
else
|
8
|
-
|
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
|
25
|
+
unpacker = DefaultFactory.unpacker param
|
30
26
|
unpacker.feed_reference src
|
31
27
|
else
|
32
|
-
unpacker = DefaultFactory.unpacker src, param
|
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,
|
43
|
-
packer = DefaultFactory.packer(
|
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
|
-
|
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', ['
|
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'
|
data/spec/bigint_spec.rb
ADDED
@@ -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
|
-
|
276
|
-
|
451
|
+
def roundtrip(object, options = nil)
|
452
|
+
subject.load(subject.dump(object), options)
|
453
|
+
end
|
277
454
|
|
278
|
-
|
279
|
-
|
280
|
-
|
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(
|
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(
|
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(
|
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 '
|
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
|
-
|
19
|
-
|
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
|
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)
|