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