msgpack 1.4.4.pre1-java → 1.4.5-java

Sign up to get free protection for your applications and to get access to all the features.
data/spec/packer_spec.rb DELETED
@@ -1,575 +0,0 @@
1
- # encoding: ascii-8bit
2
- require 'spec_helper'
3
-
4
- require 'stringio'
5
- require 'tempfile'
6
- require 'zlib'
7
-
8
- if defined?(Encoding)
9
- Encoding.default_external = 'ASCII-8BIT'
10
- end
11
-
12
- describe MessagePack::Packer do
13
- let :packer do
14
- MessagePack::Packer.new
15
- end
16
-
17
- it 'initialize' do
18
- MessagePack::Packer.new
19
- MessagePack::Packer.new(nil)
20
- MessagePack::Packer.new(StringIO.new)
21
- MessagePack::Packer.new({})
22
- MessagePack::Packer.new(StringIO.new, {})
23
- end
24
-
25
- it 'gets IO or object which has #write to write/append data to it' do
26
- sample_data = {"message" => "morning!", "num" => 1}
27
- sample_packed = MessagePack.pack(sample_data)
28
-
29
- Tempfile.open("for_io") do |file|
30
- file.sync = true
31
- p1 = MessagePack::Packer.new(file)
32
- p1.write sample_data
33
- p1.flush
34
-
35
- file.rewind
36
- expect(file.read).to eql(sample_packed)
37
- file.unlink
38
- end
39
-
40
- dio = StringIO.new
41
- p2 = MessagePack::Packer.new(dio)
42
- p2.write sample_data
43
- p2.flush
44
- dio.rewind
45
- expect(dio.string).to eql(sample_packed)
46
-
47
- dio = StringIO.new
48
- writer = Zlib::GzipWriter.new(dio)
49
- writer.sync = true
50
- p3 = MessagePack::Packer.new(writer)
51
- p3.write sample_data
52
- p3.flush
53
- writer.flush(Zlib::FINISH)
54
- writer.close
55
- dio.rewind
56
- compressed = dio.string
57
- str = Zlib::GzipReader.wrap(StringIO.new(compressed)){|gz| gz.read }
58
- expect(str).to eql(sample_packed)
59
-
60
- class DummyIO
61
- def initialize
62
- @buf = "".force_encoding('ASCII-8BIT')
63
- @pos = 0
64
- end
65
- def write(val)
66
- @buf << val.to_s
67
- end
68
- def read(length=nil,outbuf="")
69
- if @pos == @buf.size
70
- nil
71
- elsif length.nil?
72
- val = @buf[@pos..(@buf.size)]
73
- @pos = @buf.size
74
- outbuf << val
75
- outbuf
76
- else
77
- val = @buf[@pos..(@pos + length)]
78
- @pos += val.size
79
- @pos = @buf.size if @pos > @buf.size
80
- outbuf << val
81
- outbuf
82
- end
83
- end
84
- def flush
85
- # nop
86
- end
87
- def close
88
- # nop
89
- end
90
- end
91
-
92
- dio = DummyIO.new
93
- p4 = MessagePack::Packer.new(dio)
94
- p4.write sample_data
95
- p4.flush
96
- expect(dio.read).to eql(sample_packed)
97
- end
98
-
99
- it 'gets options to specify how to pack values' do
100
- u1 = MessagePack::Packer.new
101
- u1.compatibility_mode?.should == false
102
-
103
- u2 = MessagePack::Packer.new(compatibility_mode: true)
104
- u2.compatibility_mode?.should == true
105
- end
106
-
107
- it 'write' do
108
- packer.write([])
109
- packer.to_s.should == "\x90"
110
- end
111
-
112
- it 'write_nil' do
113
- packer.write_nil
114
- packer.to_s.should == "\xc0"
115
- end
116
-
117
- it 'write_array_header 0' do
118
- packer.write_array_header(0)
119
- packer.to_s.should == "\x90"
120
- end
121
-
122
- it 'write_array_header 1' do
123
- packer.write_array_header(1)
124
- packer.to_s.should == "\x91"
125
- end
126
-
127
- it 'write_map_header 0' do
128
- packer.write_map_header(0)
129
- packer.to_s.should == "\x80"
130
- end
131
-
132
- it 'write_map_header 1' do
133
- packer.write_map_header(1)
134
- packer.to_s.should == "\x81"
135
- end
136
-
137
- it 'write_bin_header 0' do
138
- packer.write_bin_header(0)
139
- packer.to_s.should == "\xC4\x00"
140
- end
141
-
142
- it 'write_bin_header 255' do
143
- packer.write_bin_header(255)
144
- packer.to_s.should == "\xC4\xFF"
145
- end
146
-
147
- it 'write_bin_header 256' do
148
- packer.write_bin_header(256)
149
- packer.to_s.should == "\xC5\x01\x00"
150
- end
151
-
152
- it 'write_bin_header 65535' do
153
- packer.write_bin_header(65535)
154
- packer.to_s.should == "\xC5\xFF\xFF"
155
- end
156
-
157
- it 'write_bin_header 65536' do
158
- packer.write_bin_header(65536)
159
- packer.to_s.should == "\xC6\x00\x01\x00\x00"
160
- end
161
-
162
- it 'write_bin_header 999999' do
163
- packer.write_bin_header(999999)
164
- packer.to_s.should == "\xC6\x00\x0F\x42\x3F"
165
- end
166
-
167
- it 'write_bin' do
168
- packer.write_bin("hello")
169
- packer.to_s.should == "\xC4\x05hello"
170
- end
171
-
172
- describe '#write_float32' do
173
- tests = [
174
- ['small floats', 3.14, "\xCA\x40\x48\xF5\xC3"],
175
- ['big floats', Math::PI * 1_000_000_000_000_000_000, "\xCA\x5E\x2E\x64\xB7"],
176
- ['negative floats', -2.1, "\xCA\xC0\x06\x66\x66"],
177
- ['integer', 123, "\xCA\x42\xF6\x00\x00"],
178
- ]
179
-
180
- tests.each do |ctx, numeric, packed|
181
- context("with #{ctx}") do
182
- it("encodes #{numeric} as float32") do
183
- packer.write_float32(numeric)
184
- packer.to_s.should == packed
185
- end
186
- end
187
- end
188
-
189
- context 'with non numeric' do
190
- it 'raises argument error' do
191
- expect { packer.write_float32('abc') }.to raise_error(ArgumentError)
192
- end
193
- end
194
- end
195
-
196
- it 'flush' do
197
- io = StringIO.new
198
- pk = MessagePack::Packer.new(io)
199
- pk.write_nil
200
- pk.flush
201
- pk.to_s.should == ''
202
- io.string.should == "\xc0"
203
- end
204
-
205
- it 'to_msgpack returns String' do
206
- nil.to_msgpack.class.should == String
207
- true.to_msgpack.class.should == String
208
- false.to_msgpack.class.should == String
209
- 1.to_msgpack.class.should == String
210
- 1.0.to_msgpack.class.should == String
211
- "".to_msgpack.class.should == String
212
- Hash.new.to_msgpack.class.should == String
213
- Array.new.to_msgpack.class.should == String
214
- end
215
-
216
- it 'to_msgpack with packer equals to_msgpack' do
217
- nil.to_msgpack(MessagePack::Packer.new).to_str.should == nil.to_msgpack
218
- true.to_msgpack(MessagePack::Packer.new).to_str.should == true.to_msgpack
219
- false.to_msgpack(MessagePack::Packer.new).to_str.should == false.to_msgpack
220
- 1.to_msgpack(MessagePack::Packer.new).to_str.should == 1.to_msgpack
221
- 1.0.to_msgpack(MessagePack::Packer.new).to_str.should == 1.0.to_msgpack
222
- "".to_msgpack(MessagePack::Packer.new).to_str.should == "".to_msgpack
223
- Hash.new.to_msgpack(MessagePack::Packer.new).to_str.should == Hash.new.to_msgpack
224
- Array.new.to_msgpack(MessagePack::Packer.new).to_str.should == Array.new.to_msgpack
225
- end
226
-
227
- it 'raises type error on wrong type' do
228
- packer = MessagePack::Packer.new
229
- expect { packer.write_float "hello" }.to raise_error(TypeError)
230
- expect { packer.write_string 1 }.to raise_error(TypeError)
231
- expect { packer.write_bin 1 }.to raise_error(TypeError)
232
- expect { packer.write_array "hello" }.to raise_error(TypeError)
233
- expect { packer.write_hash "hello" }.to raise_error(TypeError)
234
- expect { packer.write_symbol "hello" }.to raise_error(TypeError)
235
- expect { packer.write_int "hello" }.to raise_error(TypeError)
236
- expect { packer.write_extension "hello" }.to raise_error(TypeError)
237
- end
238
-
239
- class CustomPack01
240
- def to_msgpack(pk=nil)
241
- return MessagePack.pack(self, pk) unless pk.class == MessagePack::Packer
242
- pk.write_array_header(2)
243
- pk.write(1)
244
- pk.write(2)
245
- return pk
246
- end
247
- end
248
-
249
- class CustomPack02
250
- def to_msgpack(pk=nil)
251
- [1,2].to_msgpack(pk)
252
- end
253
- end
254
-
255
- it 'calls custom to_msgpack method' do
256
- MessagePack.pack(CustomPack01.new).should == [1,2].to_msgpack
257
- MessagePack.pack(CustomPack02.new).should == [1,2].to_msgpack
258
- CustomPack01.new.to_msgpack.should == [1,2].to_msgpack
259
- CustomPack02.new.to_msgpack.should == [1,2].to_msgpack
260
- end
261
-
262
- it 'calls custom to_msgpack method with io' do
263
- s01 = StringIO.new
264
- MessagePack.pack(CustomPack01.new, s01)
265
- s01.string.should == [1,2].to_msgpack
266
-
267
- s02 = StringIO.new
268
- MessagePack.pack(CustomPack02.new, s02)
269
- s02.string.should == [1,2].to_msgpack
270
-
271
- s03 = StringIO.new
272
- CustomPack01.new.to_msgpack(s03)
273
- s03.string.should == [1,2].to_msgpack
274
-
275
- s04 = StringIO.new
276
- CustomPack02.new.to_msgpack(s04)
277
- s04.string.should == [1,2].to_msgpack
278
- end
279
-
280
- context 'in compatibility mode' do
281
- it 'does not use the bin types' do
282
- packed = MessagePack.pack('hello'.force_encoding(Encoding::BINARY), compatibility_mode: true)
283
- packed.should eq("\xA5hello")
284
- packed = MessagePack.pack(('hello' * 100).force_encoding(Encoding::BINARY), compatibility_mode: true)
285
- packed.should start_with("\xDA\x01\xF4")
286
-
287
- packer = MessagePack::Packer.new(compatibility_mode: 1)
288
- packed = packer.pack(('hello' * 100).force_encoding(Encoding::BINARY))
289
- packed.to_str.should start_with("\xDA\x01\xF4")
290
- end
291
-
292
- it 'does not use the str8 type' do
293
- packed = MessagePack.pack('x' * 32, compatibility_mode: true)
294
- packed.should start_with("\xDA\x00\x20")
295
- end
296
- end
297
-
298
- class ValueOne
299
- def initialize(num)
300
- @num = num
301
- end
302
- def num
303
- @num
304
- end
305
- def to_msgpack_ext
306
- @num.to_msgpack
307
- end
308
- def self.from_msgpack_ext(data)
309
- self.new(MessagePack.unpack(data))
310
- end
311
- end
312
-
313
- class ValueTwo
314
- def initialize(num)
315
- @num_s = num.to_s
316
- end
317
- def num
318
- @num_s.to_i
319
- end
320
- def to_msgpack_ext
321
- @num_s.to_msgpack
322
- end
323
- def self.from_msgpack_ext(data)
324
- self.new(MessagePack.unpack(data))
325
- end
326
- end
327
-
328
- describe '#type_registered?' do
329
- it 'receive Class or Integer, and return bool' do
330
- expect(subject.type_registered?(0x00)).to be_falsy
331
- expect(subject.type_registered?(0x01)).to be_falsy
332
- expect(subject.type_registered?(::ValueOne)).to be_falsy
333
- end
334
-
335
- it 'returns true if specified type or class is already registered' do
336
- subject.register_type(0x30, ::ValueOne, :to_msgpack_ext)
337
- subject.register_type(0x31, ::ValueTwo, :to_msgpack_ext)
338
-
339
- expect(subject.type_registered?(0x00)).to be_falsy
340
- expect(subject.type_registered?(0x01)).to be_falsy
341
-
342
- expect(subject.type_registered?(0x30)).to be_truthy
343
- expect(subject.type_registered?(0x31)).to be_truthy
344
- expect(subject.type_registered?(::ValueOne)).to be_truthy
345
- expect(subject.type_registered?(::ValueTwo)).to be_truthy
346
- end
347
- end
348
-
349
- describe '#register_type' do
350
- it 'get type and class mapping for packing' do
351
- packer = MessagePack::Packer.new
352
- packer.register_type(0x01, ValueOne){|obj| obj.to_msgpack_ext }
353
- packer.register_type(0x02, ValueTwo){|obj| obj.to_msgpack_ext }
354
-
355
- packer = MessagePack::Packer.new
356
- packer.register_type(0x01, ValueOne, :to_msgpack_ext)
357
- packer.register_type(0x02, ValueTwo, :to_msgpack_ext)
358
-
359
- packer = MessagePack::Packer.new
360
- packer.register_type(0x01, ValueOne, &:to_msgpack_ext)
361
- packer.register_type(0x02, ValueTwo, &:to_msgpack_ext)
362
- end
363
-
364
- it 'returns a Hash which contains map of Class and type' do
365
- packer = MessagePack::Packer.new
366
- packer.register_type(0x01, ValueOne, :to_msgpack_ext)
367
- packer.register_type(0x02, ValueTwo, :to_msgpack_ext)
368
-
369
- expect(packer.registered_types).to be_a(Array)
370
- expect(packer.registered_types.size).to eq(2)
371
-
372
- one = packer.registered_types[0]
373
- expect(one.keys.sort).to eq([:type, :class, :packer].sort)
374
- expect(one[:type]).to eq(0x01)
375
- expect(one[:class]).to eq(ValueOne)
376
- expect(one[:packer]).to eq(:to_msgpack_ext)
377
-
378
- two = packer.registered_types[1]
379
- expect(two.keys.sort).to eq([:type, :class, :packer].sort)
380
- expect(two[:type]).to eq(0x02)
381
- expect(two[:class]).to eq(ValueTwo)
382
- expect(two[:packer]).to eq(:to_msgpack_ext)
383
- end
384
-
385
- context 'when it has no ext type but a super class has' do
386
- before { stub_const('Value', Class.new) }
387
- before do
388
- Value.class_eval do
389
- def to_msgpack_ext
390
- 'value_msgpacked'
391
- end
392
- end
393
- end
394
- before { packer.register_type(0x01, Value, :to_msgpack_ext) }
395
-
396
- context "when it is a child class" do
397
- before { stub_const('InheritedValue', Class.new(Value)) }
398
- subject { packer.pack(InheritedValue.new).to_s }
399
-
400
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
401
-
402
- context "when it is a grandchild class" do
403
- before { stub_const('InheritedTwiceValue', Class.new(InheritedValue)) }
404
- subject { packer.pack(InheritedTwiceValue.new).to_s }
405
-
406
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
407
- end
408
- end
409
- end
410
-
411
- context 'when it and its super class has an ext type' do
412
- before { stub_const('Value', Class.new) }
413
- before do
414
- Value.class_eval do
415
- def to_msgpack_ext
416
- 'value_msgpacked'
417
- end
418
- end
419
- end
420
- before { packer.register_type(0x01, Value, :to_msgpack_ext) }
421
-
422
- context "when it is a child class" do
423
- before { stub_const('InheritedValue', Class.new(Value)) }
424
- before do
425
- InheritedValue.class_eval do
426
- def to_msgpack_ext
427
- 'inherited_value_msgpacked'
428
- end
429
- end
430
- end
431
-
432
- before { packer.register_type(0x02, InheritedValue, :to_msgpack_ext) }
433
- subject { packer.pack(InheritedValue.new).to_s }
434
-
435
- it { is_expected.to eq "\xC7\x19\x02inherited_value_msgpacked" }
436
- end
437
-
438
- context "even when it is a child class" do
439
- before { stub_const('InheritedValue', Class.new(Value)) }
440
- before do
441
- InheritedValue.class_eval do
442
- def to_msgpack_ext
443
- 'inherited_value_msgpacked'
444
- end
445
- end
446
- end
447
-
448
- before { packer.register_type(0x02, InheritedValue, :to_msgpack_ext) }
449
- subject { packer.pack(Value.new).to_s }
450
-
451
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
452
- end
453
- end
454
-
455
- context 'when it has no ext type but an included module has' do
456
- subject { packer.pack(Value.new).to_s }
457
-
458
- before do
459
- mod = Module.new do
460
- def to_msgpack_ext
461
- 'value_msgpacked'
462
- end
463
- end
464
- stub_const('Mod', mod)
465
- end
466
- before { packer.register_type(0x01, Mod, :to_msgpack_ext) }
467
-
468
- before { stub_const('Value', Class.new{ include Mod }) }
469
-
470
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
471
- end
472
-
473
- context 'when it has no ext type but it was extended by a module which has one' do
474
- subject { packer.pack(object).to_s }
475
- let(:object) { Object.new.extend Mod }
476
-
477
- before do
478
- mod = Module.new do
479
- def to_msgpack_ext
480
- 'value_msgpacked'
481
- end
482
- end
483
- stub_const('Mod', mod)
484
- end
485
- before { packer.register_type(0x01, Mod, :to_msgpack_ext) }
486
-
487
-
488
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
489
- end
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
-
509
- context 'when registering a type for symbols' do
510
- before { packer.register_type(0x00, ::Symbol, :to_msgpack_ext) }
511
-
512
- it 'packs symbols in an ext type' do
513
- expect(packer.pack(:symbol).to_s).to eq "\xc7\x06\x00symbol"
514
- end
515
- end
516
- end
517
-
518
- describe "fixnum and bignum" do
519
- it "fixnum.to_msgpack" do
520
- 23.to_msgpack.should == "\x17"
521
- end
522
-
523
- it "fixnum.to_msgpack(packer)" do
524
- 23.to_msgpack(packer)
525
- packer.to_s.should == "\x17"
526
- end
527
-
528
- it "bignum.to_msgpack" do
529
- -4294967296.to_msgpack.should == "\xD3\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
530
- end
531
-
532
- it "bignum.to_msgpack(packer)" do
533
- -4294967296.to_msgpack(packer)
534
- packer.to_s.should == "\xD3\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
535
- end
536
-
537
- it "unpack(fixnum)" do
538
- MessagePack.unpack("\x17").should == 23
539
- end
540
-
541
- it "unpack(bignum)" do
542
- MessagePack.unpack("\xD3\xFF\xFF\xFF\xFF\x00\x00\x00\x00").should == -4294967296
543
- end
544
- end
545
-
546
- describe "ext formats" do
547
- [1, 2, 4, 8, 16].zip([0xd4, 0xd5, 0xd6, 0xd7, 0xd8]).each do |n,b|
548
- it "msgpack fixext #{n} format" do
549
- MessagePack::ExtensionValue.new(1, "a"*n).to_msgpack.should ==
550
- [b, 1].pack('CC') + "a"*n
551
- end
552
- end
553
-
554
- it "msgpack ext 8 format" do
555
- MessagePack::ExtensionValue.new(1, "").to_msgpack.should ==
556
- [0xc7, 0, 1].pack('CCC') + ""
557
- MessagePack::ExtensionValue.new(-1, "a"*255).to_msgpack.should ==
558
- [0xc7, 255, -1].pack('CCC') + "a"*255
559
- end
560
-
561
- it "msgpack ext 16 format" do
562
- MessagePack::ExtensionValue.new(1, "a"*256).to_msgpack.should ==
563
- [0xc8, 256, 1].pack('CnC') + "a"*256
564
- MessagePack::ExtensionValue.new(-1, "a"*65535).to_msgpack.should ==
565
- [0xc8, 65535, -1].pack('CnC') + "a"*65535
566
- end
567
-
568
- it "msgpack ext 32 format" do
569
- MessagePack::ExtensionValue.new(1, "a"*65536).to_msgpack.should ==
570
- [0xc9, 65536, 1].pack('CNC') + "a"*65536
571
- MessagePack::ExtensionValue.new(-1, "a"*65538).to_msgpack.should ==
572
- [0xc9, 65538, -1].pack('CNC') + "a"*65538
573
- end
574
- end
575
- end
@@ -1,24 +0,0 @@
1
-
2
- unless defined? Random
3
- class Random
4
- def initialize(seed=Time.now.to_i)
5
- Kernel.srand(seed)
6
- @seed = seed
7
- end
8
-
9
- attr_reader :seed
10
-
11
- def rand(arg)
12
- Kernel.rand(arg)
13
- end
14
-
15
- def bytes(n)
16
- array = []
17
- n.times do
18
- array << rand(256)
19
- end
20
- array.pack('C*')
21
- end
22
- end
23
- end
24
-
data/spec/spec_helper.rb DELETED
@@ -1,65 +0,0 @@
1
-
2
- if ENV['SIMPLE_COV']
3
- require 'simplecov'
4
- SimpleCov.start do
5
- add_filter 'spec/'
6
- add_filter 'pkg/'
7
- add_filter 'vendor/'
8
- end
9
- end
10
-
11
- if ENV['GC_STRESS']
12
- puts "enable GC.stress"
13
- GC.stress = true
14
- end
15
-
16
- require 'msgpack'
17
-
18
- if GC.respond_to?(:verify_compaction_references)
19
- # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
20
- # move objects around, helping to find object movement bugs.
21
- GC.verify_compaction_references(double_heap: true, toward: :empty)
22
- end
23
-
24
- if GC.respond_to?(:auto_compact=)
25
- GC.auto_compact = true
26
- end
27
-
28
- def java?
29
- /java/ =~ RUBY_PLATFORM
30
- end
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 java?
50
- RSpec.configure do |c|
51
- c.treat_symbols_as_metadata_keys_with_true_values = true
52
- c.filter_run_excluding :encodings => !(defined? Encoding)
53
- end
54
- else
55
- RSpec.configure do |config|
56
- config.expect_with :rspec do |c|
57
- c.syntax = [:should, :expect]
58
- end
59
- end
60
- Packer = MessagePack::Packer
61
- Unpacker = MessagePack::Unpacker
62
- Buffer = MessagePack::Buffer
63
- Factory = MessagePack::Factory
64
- ExtensionValue = MessagePack::ExtensionValue
65
- end