msgpack 1.5.1 → 1.7.2

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