msgpack 1.5.1 → 1.7.2

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +55 -0
  3. data/README.md +30 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
  5. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
  6. data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
  7. data/ext/java/org/msgpack/jruby/Factory.java +11 -50
  8. data/ext/java/org/msgpack/jruby/Packer.java +9 -24
  9. data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
  10. data/ext/msgpack/buffer.c +54 -69
  11. data/ext/msgpack/buffer.h +16 -18
  12. data/ext/msgpack/buffer_class.c +138 -37
  13. data/ext/msgpack/buffer_class.h +1 -0
  14. data/ext/msgpack/compat.h +0 -99
  15. data/ext/msgpack/extconf.rb +25 -39
  16. data/ext/msgpack/factory_class.c +75 -86
  17. data/ext/msgpack/packer.c +12 -39
  18. data/ext/msgpack/packer.h +1 -11
  19. data/ext/msgpack/packer_class.c +73 -99
  20. data/ext/msgpack/packer_class.h +11 -0
  21. data/ext/msgpack/packer_ext_registry.c +31 -28
  22. data/ext/msgpack/packer_ext_registry.h +10 -14
  23. data/ext/msgpack/rbinit.c +1 -1
  24. data/ext/msgpack/rmem.c +3 -4
  25. data/ext/msgpack/sysdep.h +5 -2
  26. data/ext/msgpack/unpacker.c +66 -94
  27. data/ext/msgpack/unpacker.h +13 -12
  28. data/ext/msgpack/unpacker_class.c +64 -80
  29. data/ext/msgpack/unpacker_class.h +11 -0
  30. data/ext/msgpack/unpacker_ext_registry.c +4 -16
  31. data/ext/msgpack/unpacker_ext_registry.h +3 -7
  32. data/lib/msgpack/buffer.rb +9 -0
  33. data/lib/msgpack/factory.rb +90 -63
  34. data/lib/msgpack/packer.rb +10 -1
  35. data/lib/msgpack/unpacker.rb +14 -1
  36. data/lib/msgpack/version.rb +1 -1
  37. data/lib/msgpack.rb +1 -0
  38. data/msgpack.gemspec +7 -3
  39. metadata +33 -56
  40. data/.github/workflows/ci.yaml +0 -57
  41. data/.gitignore +0 -23
  42. data/.rubocop.yml +0 -36
  43. data/Gemfile +0 -9
  44. data/Rakefile +0 -70
  45. data/appveyor.yml +0 -18
  46. data/bench/pack.rb +0 -23
  47. data/bench/pack_log.rb +0 -33
  48. data/bench/pack_log_long.rb +0 -65
  49. data/bench/pack_symbols.rb +0 -28
  50. data/bench/run.sh +0 -14
  51. data/bench/run_long.sh +0 -35
  52. data/bench/run_symbols.sh +0 -26
  53. data/bench/unpack.rb +0 -21
  54. data/bench/unpack_log.rb +0 -34
  55. data/bench/unpack_log_long.rb +0 -67
  56. data/doclib/msgpack/buffer.rb +0 -193
  57. data/doclib/msgpack/core_ext.rb +0 -101
  58. data/doclib/msgpack/error.rb +0 -19
  59. data/doclib/msgpack/extension_value.rb +0 -9
  60. data/doclib/msgpack/factory.rb +0 -145
  61. data/doclib/msgpack/packer.rb +0 -209
  62. data/doclib/msgpack/time.rb +0 -22
  63. data/doclib/msgpack/timestamp.rb +0 -44
  64. data/doclib/msgpack/unpacker.rb +0 -183
  65. data/doclib/msgpack.rb +0 -87
  66. data/msgpack.org.md +0 -46
  67. data/spec/bigint_spec.rb +0 -26
  68. data/spec/cases.json +0 -1
  69. data/spec/cases.msg +0 -0
  70. data/spec/cases_compact.msg +0 -0
  71. data/spec/cases_spec.rb +0 -39
  72. data/spec/cruby/buffer_io_spec.rb +0 -255
  73. data/spec/cruby/buffer_packer.rb +0 -29
  74. data/spec/cruby/buffer_spec.rb +0 -575
  75. data/spec/cruby/buffer_unpacker.rb +0 -19
  76. data/spec/cruby/unpacker_spec.rb +0 -70
  77. data/spec/ext_value_spec.rb +0 -99
  78. data/spec/exttypes.rb +0 -51
  79. data/spec/factory_spec.rb +0 -654
  80. data/spec/format_spec.rb +0 -301
  81. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  82. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  83. data/spec/jruby/unpacker_spec.rb +0 -186
  84. data/spec/msgpack_spec.rb +0 -214
  85. data/spec/pack_spec.rb +0 -61
  86. data/spec/packer_spec.rb +0 -575
  87. data/spec/random_compat.rb +0 -24
  88. data/spec/spec_helper.rb +0 -65
  89. data/spec/timestamp_spec.rb +0 -159
  90. data/spec/unpack_spec.rb +0 -57
  91. data/spec/unpacker_spec.rb +0 -847
data/spec/factory_spec.rb DELETED
@@ -1,654 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe MessagePack::Factory do
4
- subject do
5
- described_class.new
6
- end
7
-
8
- describe '#packer' do
9
- it 'creates a Packer instance' do
10
- subject.packer.should be_kind_of(MessagePack::Packer)
11
- end
12
-
13
- it 'creates new instance' do
14
- subject.packer.object_id.should_not == subject.packer.object_id
15
- end
16
- end
17
-
18
- describe '#unpacker' do
19
- it 'creates a Unpacker instance' do
20
- subject.unpacker.should be_kind_of(MessagePack::Unpacker)
21
- end
22
-
23
- it 'creates new instance' do
24
- subject.unpacker.object_id.should_not == subject.unpacker.object_id
25
- end
26
-
27
- it 'creates unpacker with symbolize_keys option' do
28
- unpacker = subject.unpacker(symbolize_keys: true)
29
- unpacker.feed(MessagePack.pack({'k'=>'v'}))
30
- unpacker.read.should == {:k => 'v'}
31
- end
32
-
33
- it 'creates unpacker with allow_unknown_ext option' do
34
- unpacker = subject.unpacker(allow_unknown_ext: true)
35
- unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
36
- unpacker.read.should == MessagePack::ExtensionValue.new(1, 'a')
37
- end
38
-
39
- it 'creates unpacker without allow_unknown_ext option' do
40
- unpacker = subject.unpacker
41
- unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
42
- expect{ unpacker.read }.to raise_error(MessagePack::UnknownExtTypeError)
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
59
- end
60
-
61
- describe '#dump and #load' do
62
- it 'can be used like a standard coder' do
63
- subject.register_type(0x00, Symbol)
64
- expect(subject.load(subject.dump(:symbol))).to be == :symbol
65
- end
66
-
67
- it 'is alias as pack and unpack' do
68
- subject.register_type(0x00, Symbol)
69
- expect(subject.unpack(subject.pack(:symbol))).to be == :symbol
70
- end
71
-
72
- it 'accept options' do
73
- hash = subject.unpack(MessagePack.pack('k' => 'v'), symbolize_keys: true)
74
- expect(hash).to be == { k: 'v' }
75
- end
76
- end
77
-
78
- describe '#freeze' do
79
- it 'can freeze factory instance to deny new registrations anymore' do
80
- subject.register_type(0x00, Symbol)
81
- subject.freeze
82
- expect(subject.frozen?).to be_truthy
83
- expect{ subject.register_type(0x01, Array) }.to raise_error(RuntimeError, "can't modify frozen Factory")
84
- end
85
- end
86
-
87
- class MyType
88
- def initialize(a, b)
89
- @a = a
90
- @b = b
91
- end
92
-
93
- attr_reader :a, :b
94
-
95
- def to_msgpack_ext
96
- [a, b].pack('CC')
97
- end
98
-
99
- def self.from_msgpack_ext(data)
100
- new(*data.unpack('CC'))
101
- end
102
-
103
- def to_msgpack_ext_only_a
104
- [a, 0].pack('CC')
105
- end
106
-
107
- def self.from_msgpack_ext_only_b(data)
108
- a, b = *data.unpack('CC')
109
- new(0, b)
110
- end
111
- end
112
-
113
- class MyType2 < MyType
114
- end
115
-
116
- describe '#registered_types' do
117
- it 'returns Array' do
118
- expect(subject.registered_types).to be_instance_of(Array)
119
- end
120
-
121
- it 'returns Array of Hash contains :type, :class, :packer, :unpacker' do
122
- subject.register_type(0x20, ::MyType)
123
- subject.register_type(0x21, ::MyType2)
124
-
125
- list = subject.registered_types
126
-
127
- expect(list.size).to eq(2)
128
- expect(list[0]).to be_instance_of(Hash)
129
- expect(list[1]).to be_instance_of(Hash)
130
- expect(list[0].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
131
- expect(list[1].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
132
-
133
- expect(list[0][:type]).to eq(0x20)
134
- expect(list[0][:class]).to eq(::MyType)
135
- expect(list[0][:packer]).to eq(:to_msgpack_ext)
136
- expect(list[0][:unpacker]).to eq(:from_msgpack_ext)
137
-
138
- expect(list[1][:type]).to eq(0x21)
139
- expect(list[1][:class]).to eq(::MyType2)
140
- expect(list[1][:packer]).to eq(:to_msgpack_ext)
141
- expect(list[1][:unpacker]).to eq(:from_msgpack_ext)
142
- end
143
-
144
- it 'returns Array of Hash which has nil for unregistered feature' do
145
- subject.register_type(0x21, ::MyType2, unpacker: :from_msgpack_ext)
146
- subject.register_type(0x20, ::MyType, packer: :to_msgpack_ext)
147
-
148
- list = subject.registered_types
149
-
150
- expect(list.size).to eq(2)
151
- expect(list[0]).to be_instance_of(Hash)
152
- expect(list[1]).to be_instance_of(Hash)
153
- expect(list[0].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
154
- expect(list[1].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
155
-
156
- expect(list[0][:type]).to eq(0x20)
157
- expect(list[0][:class]).to eq(::MyType)
158
- expect(list[0][:packer]).to eq(:to_msgpack_ext)
159
- expect(list[0][:unpacker]).to be_nil
160
-
161
- expect(list[1][:type]).to eq(0x21)
162
- expect(list[1][:class]).to eq(::MyType2)
163
- expect(list[1][:packer]).to be_nil
164
- expect(list[1][:unpacker]).to eq(:from_msgpack_ext)
165
- end
166
- end
167
-
168
- describe '#type_registered?' do
169
- it 'receive Class or Integer, and return bool' do
170
- expect(subject.type_registered?(0x00)).to be_falsy
171
- expect(subject.type_registered?(0x01)).to be_falsy
172
- expect(subject.type_registered?(::MyType)).to be_falsy
173
- end
174
-
175
- it 'has option to specify what types are registered for' do
176
- expect(subject.type_registered?(0x00, :both)).to be_falsy
177
- expect(subject.type_registered?(0x00, :packer)).to be_falsy
178
- expect(subject.type_registered?(0x00, :unpacker)).to be_falsy
179
- expect{ subject.type_registered?(0x00, :something) }.to raise_error(ArgumentError)
180
- end
181
-
182
- it 'returns true if specified type or class is already registered' do
183
- subject.register_type(0x20, ::MyType)
184
- subject.register_type(0x21, ::MyType2)
185
-
186
- expect(subject.type_registered?(0x00)).to be_falsy
187
- expect(subject.type_registered?(0x01)).to be_falsy
188
-
189
- expect(subject.type_registered?(0x20)).to be_truthy
190
- expect(subject.type_registered?(0x21)).to be_truthy
191
- expect(subject.type_registered?(::MyType)).to be_truthy
192
- expect(subject.type_registered?(::MyType2)).to be_truthy
193
- end
194
- end
195
-
196
- describe '#register_type' do
197
- let :src do
198
- ::MyType.new(1, 2)
199
- end
200
-
201
- it 'registers #to_msgpack_ext and .from_msgpack_ext by default' do
202
- subject.register_type(0x7f, ::MyType)
203
-
204
- data = subject.packer.write(src).to_s
205
- my = subject.unpacker.feed(data).read
206
- my.a.should == 1
207
- my.b.should == 2
208
- end
209
-
210
- it 'registers custom packer method name' do
211
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext_only_a, unpacker: :from_msgpack_ext)
212
-
213
- data = subject.packer.write(src).to_s
214
- my = subject.unpacker.feed(data).read
215
- my.a.should == 1
216
- my.b.should == 0
217
- end
218
-
219
- it 'registers custom unpacker method name' do
220
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext, unpacker: 'from_msgpack_ext_only_b')
221
-
222
- data = subject.packer.write(src).to_s
223
- my = subject.unpacker.feed(data).read
224
- my.a.should == 0
225
- my.b.should == 2
226
- end
227
-
228
- it 'registers custom proc objects' do
229
- pk = lambda {|obj| [obj.a + obj.b].pack('C') }
230
- uk = lambda {|data| ::MyType.new(data.unpack('C').first, -1) }
231
- subject.register_type(0x7f, ::MyType, packer: pk, unpacker: uk)
232
-
233
- data = subject.packer.write(src).to_s
234
- my = subject.unpacker.feed(data).read
235
- my.a.should == 3
236
- my.b.should == -1
237
- end
238
-
239
- it 'does not affect existent packer and unpackers' do
240
- subject.register_type(0x7f, ::MyType)
241
- packer = subject.packer
242
- unpacker = subject.unpacker
243
-
244
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext_only_a, unpacker: :from_msgpack_ext_only_b)
245
-
246
- data = packer.write(src).to_s
247
- my = unpacker.feed(data).read
248
- my.a.should == 1
249
- my.b.should == 2
250
- end
251
-
252
- describe "registering an ext type for a module" do
253
- before do
254
- mod = Module.new do
255
- def self.from_msgpack_ext(data)
256
- "unpacked #{data}"
257
- end
258
-
259
- def to_msgpack_ext
260
- 'value_msgpacked'
261
- end
262
- end
263
- stub_const('Mod', mod)
264
- end
265
- let(:factory) { described_class.new }
266
- before { factory.register_type(0x01, Mod) }
267
-
268
- describe "packing an object whose class included the module" do
269
- subject { factory.packer.pack(value).to_s }
270
- before { stub_const('Value', Class.new{ include Mod }) }
271
- let(:value) { Value.new }
272
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
273
- end
274
-
275
- describe "packing an object which has been extended by the module" do
276
- subject { factory.packer.pack(object).to_s }
277
- let(:object) { Object.new.extend Mod }
278
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
279
- end
280
-
281
- describe "unpacking with the module" do
282
- subject { factory.unpacker.feed("\xC7\x06\x01module".force_encoding(Encoding::BINARY)).unpack }
283
- it { is_expected.to eq "unpacked module" }
284
- end
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
448
- end
449
-
450
- describe 'the special treatment of symbols with ext type' do
451
- def roundtrip(object, options = nil)
452
- subject.load(subject.dump(object), options)
453
- end
454
-
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
482
- end
483
-
484
- context 'if no ext type is registered for symbols' do
485
- it 'converts symbols to string' do
486
- expect(roundtrip(:symbol)).to eq 'symbol'
487
- end
488
- end
489
-
490
- context 'if an ext type is registered for symbols' do
491
- context 'if using the default serializer' do
492
- before { subject.register_type(0x00, ::Symbol) }
493
-
494
- it 'lets symbols survive a roundtrip' do
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
530
- end
531
- end
532
-
533
- context 'if using a custom serializer' do
534
- before do
535
- class Symbol
536
- alias_method :to_msgpack_ext_orig, :to_msgpack_ext
537
- def to_msgpack_ext
538
- self.to_s.codepoints.to_a.pack('n*')
539
- end
540
- end
541
-
542
- class << Symbol
543
- alias_method :from_msgpack_ext_orig, :from_msgpack_ext
544
- def from_msgpack_ext(data)
545
- data.unpack('n*').map(&:chr).join.to_sym
546
- end
547
- end
548
- end
549
-
550
- before { subject.register_type(0x00, ::Symbol) }
551
-
552
- it 'lets symbols survive a roundtrip' do
553
- expect(roundtrip(:symbol)).to be :symbol
554
- end
555
-
556
- after do
557
- class Symbol
558
- alias_method :to_msgpack_ext, :to_msgpack_ext_orig
559
- end
560
-
561
- class << Symbol
562
- alias_method :from_msgpack_ext, :from_msgpack_ext_orig
563
- end
564
- end
565
- end
566
- end
567
- end
568
-
569
- describe 'under stressful GC' do
570
- it 'works well' do
571
- begin
572
- GC.stress = true
573
-
574
- f = MessagePack::Factory.new
575
- f.register_type(0x0a, Symbol)
576
- ensure
577
- GC.stress = false
578
- end
579
- end
580
- end
581
-
582
- describe 'DefaultFactory' do
583
- it 'is a factory' do
584
- MessagePack::DefaultFactory.should be_kind_of(MessagePack::Factory)
585
- end
586
-
587
- require_relative 'exttypes'
588
-
589
- it 'should be referred by MessagePack.pack and MessagePack.unpack' do
590
- MessagePack::DefaultFactory.register_type(DummyTimeStamp1::TYPE, DummyTimeStamp1)
591
- MessagePack::DefaultFactory.register_type(DummyTimeStamp2::TYPE, DummyTimeStamp2, packer: :serialize, unpacker: :deserialize)
592
-
593
- t = Time.now
594
-
595
- dm1 = DummyTimeStamp1.new(t.to_i, t.usec)
596
- expect(MessagePack.unpack(MessagePack.pack(dm1))).to eq(dm1)
597
-
598
- dm2 = DummyTimeStamp1.new(t.to_i, t.usec)
599
- expect(MessagePack.unpack(MessagePack.pack(dm2))).to eq(dm2)
600
- end
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
654
- end