msgpack 0.7.0dev1-x86-mingw32 → 0.7.0-x86-mingw32

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.
@@ -116,7 +116,7 @@ describe MessagePack do
116
116
  end
117
117
 
118
118
  it 'rasies an error on #unpack with garbage' do
119
- skip "???"
119
+ skip "but nothing was raised. why?"
120
120
  expect { MessagePack.unpack('asdka;sd') }.to raise_error(MessagePack::UnpackError)
121
121
  end
122
122
  end
@@ -1,6 +1,141 @@
1
+ # encoding: ascii-8bit
1
2
  require 'spec_helper'
2
3
 
4
+ require 'stringio'
5
+ if defined?(Encoding)
6
+ Encoding.default_external = 'ASCII-8BIT'
7
+ end
8
+
3
9
  describe MessagePack::Packer do
10
+ let :packer do
11
+ MessagePack::Packer.new
12
+ end
13
+
14
+ it 'initialize' do
15
+ MessagePack::Packer.new
16
+ MessagePack::Packer.new(nil)
17
+ MessagePack::Packer.new(StringIO.new)
18
+ MessagePack::Packer.new({})
19
+ MessagePack::Packer.new(StringIO.new, {})
20
+ end
21
+
22
+ it 'gets options to specify how to pack values' do
23
+ u1 = MessagePack::Packer.new
24
+ u1.compatibility_mode?.should == false
25
+
26
+ u2 = MessagePack::Packer.new(compatibility_mode: true)
27
+ u2.compatibility_mode?.should == true
28
+ end
29
+
30
+ it 'write' do
31
+ packer.write([])
32
+ packer.to_s.should == "\x90"
33
+ end
34
+
35
+ it 'write_nil' do
36
+ packer.write_nil
37
+ packer.to_s.should == "\xc0"
38
+ end
39
+
40
+ it 'write_array_header 0' do
41
+ packer.write_array_header(0)
42
+ packer.to_s.should == "\x90"
43
+ end
44
+
45
+ it 'write_array_header 1' do
46
+ packer.write_array_header(1)
47
+ packer.to_s.should == "\x91"
48
+ end
49
+
50
+ it 'write_map_header 0' do
51
+ packer.write_map_header(0)
52
+ packer.to_s.should == "\x80"
53
+ end
54
+
55
+ it 'write_map_header 1' do
56
+ packer.write_map_header(1)
57
+ packer.to_s.should == "\x81"
58
+ end
59
+
60
+ it 'flush' do
61
+ io = StringIO.new
62
+ pk = MessagePack::Packer.new(io)
63
+ pk.write_nil
64
+ pk.flush
65
+ pk.to_s.should == ''
66
+ io.string.should == "\xc0"
67
+ end
68
+
69
+ it 'to_msgpack returns String' do
70
+ nil.to_msgpack.class.should == String
71
+ true.to_msgpack.class.should == String
72
+ false.to_msgpack.class.should == String
73
+ 1.to_msgpack.class.should == String
74
+ 1.0.to_msgpack.class.should == String
75
+ "".to_msgpack.class.should == String
76
+ Hash.new.to_msgpack.class.should == String
77
+ Array.new.to_msgpack.class.should == String
78
+ end
79
+
80
+ class CustomPack01
81
+ def to_msgpack(pk=nil)
82
+ return MessagePack.pack(self, pk) unless pk.class == MessagePack::Packer
83
+ pk.write_array_header(2)
84
+ pk.write(1)
85
+ pk.write(2)
86
+ return pk
87
+ end
88
+ end
89
+
90
+ class CustomPack02
91
+ def to_msgpack(pk=nil)
92
+ [1,2].to_msgpack(pk)
93
+ end
94
+ end
95
+
96
+ it 'calls custom to_msgpack method' do
97
+ MessagePack.pack(CustomPack01.new).should == [1,2].to_msgpack
98
+ MessagePack.pack(CustomPack02.new).should == [1,2].to_msgpack
99
+ CustomPack01.new.to_msgpack.should == [1,2].to_msgpack
100
+ CustomPack02.new.to_msgpack.should == [1,2].to_msgpack
101
+ end
102
+
103
+ it 'calls custom to_msgpack method with io' do
104
+ s01 = StringIO.new
105
+ MessagePack.pack(CustomPack01.new, s01)
106
+ s01.string.should == [1,2].to_msgpack
107
+
108
+ s02 = StringIO.new
109
+ MessagePack.pack(CustomPack02.new, s02)
110
+ s02.string.should == [1,2].to_msgpack
111
+
112
+ s03 = StringIO.new
113
+ CustomPack01.new.to_msgpack(s03)
114
+ s03.string.should == [1,2].to_msgpack
115
+
116
+ s04 = StringIO.new
117
+ CustomPack02.new.to_msgpack(s04)
118
+ s04.string.should == [1,2].to_msgpack
119
+ end
120
+
121
+ context 'in compatibility mode' do
122
+ it 'does not use the bin types' do
123
+ packed = MessagePack.pack('hello'.force_encoding(Encoding::BINARY), compatibility_mode: true)
124
+ packed.should eq("\xA5hello")
125
+ packed = MessagePack.pack(('hello' * 100).force_encoding(Encoding::BINARY), compatibility_mode: true)
126
+ packed.should start_with("\xDA\x01\xF4")
127
+
128
+ packer = MessagePack::Packer.new(compatibility_mode: 1)
129
+ packed = packer.pack(('hello' * 100).force_encoding(Encoding::BINARY))
130
+ packed.to_str.should start_with("\xDA\x01\xF4")
131
+ end
132
+
133
+ it 'does not use the str8 type' do
134
+ packed = MessagePack.pack('x' * 32, compatibility_mode: true)
135
+ packed.should start_with("\xDA\x00\x20")
136
+ end
137
+ end
138
+
4
139
  class ValueOne
5
140
  def initialize(num)
6
141
  @num = num
@@ -33,14 +168,12 @@ describe MessagePack::Packer do
33
168
 
34
169
  describe '#type_registered?' do
35
170
  it 'receive Class or Integer, and return bool' do
36
- skip("not supported yet in JRuby implementation") if java?
37
171
  expect(subject.type_registered?(0x00)).to be_falsy
38
172
  expect(subject.type_registered?(0x01)).to be_falsy
39
173
  expect(subject.type_registered?(::ValueOne)).to be_falsy
40
174
  end
41
175
 
42
176
  it 'returns true if specified type or class is already registered' do
43
- skip("not supported yet in JRuby implementation") if java?
44
177
  subject.register_type(0x30, ::ValueOne, :to_msgpack_ext)
45
178
  subject.register_type(0x31, ::ValueTwo, :to_msgpack_ext)
46
179
 
@@ -56,7 +189,6 @@ describe MessagePack::Packer do
56
189
 
57
190
  describe '#register_type' do
58
191
  it 'get type and class mapping for packing' do
59
- skip("not supported yet in JRuby implementation") if java?
60
192
  packer = MessagePack::Packer.new
61
193
  packer.register_type(0x01, ValueOne){|obj| obj.to_msgpack_ext }
62
194
  packer.register_type(0x02, ValueTwo){|obj| obj.to_msgpack_ext }
@@ -71,7 +203,6 @@ describe MessagePack::Packer do
71
203
  end
72
204
 
73
205
  it 'returns a Hash which contains map of Class and type' do
74
- skip("not supported yet in JRuby implementation") if java?
75
206
  packer = MessagePack::Packer.new
76
207
  packer.register_type(0x01, ValueOne, :to_msgpack_ext)
77
208
  packer.register_type(0x02, ValueTwo, :to_msgpack_ext)
@@ -1,6 +1,265 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'stringio'
4
+ require 'tempfile'
5
+
1
6
  require 'spec_helper'
2
7
 
3
8
  describe MessagePack::Unpacker do
9
+ let :unpacker do
10
+ MessagePack::Unpacker.new
11
+ end
12
+
13
+ let :packer do
14
+ MessagePack::Packer.new
15
+ end
16
+
17
+ it 'gets options to specify how to unpack values' do
18
+ u1 = MessagePack::Unpacker.new
19
+ u1.symbolize_keys?.should == false
20
+ u1.allow_unknown_ext?.should == false
21
+
22
+ u2 = MessagePack::Unpacker.new(symbolize_keys: true, allow_unknown_ext: true)
23
+ u2.symbolize_keys?.should == true
24
+ u2.allow_unknown_ext?.should == true
25
+ end
26
+
27
+ it 'read_array_header succeeds' do
28
+ unpacker.feed("\x91")
29
+ unpacker.read_array_header.should == 1
30
+ end
31
+
32
+ it 'read_array_header fails' do
33
+ unpacker.feed("\x81")
34
+ lambda {
35
+ unpacker.read_array_header
36
+ }.should raise_error(MessagePack::TypeError) # TypeError is included in UnexpectedTypeError
37
+ lambda {
38
+ unpacker.read_array_header
39
+ }.should raise_error(MessagePack::UnexpectedTypeError)
40
+ end
41
+
42
+ it 'read_map_header converts an map to key-value sequence' do
43
+ packer.write_array_header(2)
44
+ packer.write("e")
45
+ packer.write(1)
46
+ unpacker = MessagePack::Unpacker.new
47
+ unpacker.feed(packer.to_s)
48
+ unpacker.read_array_header.should == 2
49
+ unpacker.read.should == "e"
50
+ unpacker.read.should == 1
51
+ end
52
+
53
+ it 'read_map_header succeeds' do
54
+ unpacker.feed("\x81")
55
+ unpacker.read_map_header.should == 1
56
+ end
57
+
58
+ it 'read_map_header converts an map to key-value sequence' do
59
+ packer.write_map_header(1)
60
+ packer.write("k")
61
+ packer.write("v")
62
+ unpacker = MessagePack::Unpacker.new
63
+ unpacker.feed(packer.to_s)
64
+ unpacker.read_map_header.should == 1
65
+ unpacker.read.should == "k"
66
+ unpacker.read.should == "v"
67
+ end
68
+
69
+ it 'read_map_header fails' do
70
+ unpacker.feed("\x91")
71
+ lambda {
72
+ unpacker.read_map_header
73
+ }.should raise_error(MessagePack::TypeError) # TypeError is included in UnexpectedTypeError
74
+ lambda {
75
+ unpacker.read_map_header
76
+ }.should raise_error(MessagePack::UnexpectedTypeError)
77
+ end
78
+
79
+ it 'read raises EOFError before feeding' do
80
+ lambda {
81
+ unpacker.read
82
+ }.should raise_error(EOFError)
83
+ end
84
+
85
+ let :sample_object do
86
+ [1024, {["a","b"]=>["c","d"]}, ["e","f"], "d", 70000, 4.12, 1.5, 1.5, 1.5]
87
+ end
88
+
89
+ it 'feed and each continue internal state' do
90
+ raw = sample_object.to_msgpack.to_s * 4
91
+ objects = []
92
+
93
+ raw.split(//).each do |b|
94
+ unpacker.feed(b)
95
+ unpacker.each {|c|
96
+ objects << c
97
+ }
98
+ end
99
+
100
+ objects.should == [sample_object] * 4
101
+ end
102
+
103
+ it 'feed_each continues internal state' do
104
+ raw = sample_object.to_msgpack.to_s * 4
105
+ objects = []
106
+
107
+ raw.split(//).each do |b|
108
+ unpacker.feed_each(b) {|c|
109
+ objects << c
110
+ }
111
+ end
112
+
113
+ objects.should == [sample_object] * 4
114
+ end
115
+
116
+ it 'feed_each enumerator' do
117
+ raw = sample_object.to_msgpack.to_s * 4
118
+
119
+ enum = unpacker.feed_each(raw)
120
+ enum.should be_instance_of(Enumerator)
121
+ enum.to_a.should == [sample_object] * 4
122
+ end
123
+
124
+ it 'reset clears internal buffer' do
125
+ # 1-element array
126
+ unpacker.feed("\x91")
127
+ unpacker.reset
128
+ unpacker.feed("\x01")
129
+
130
+ unpacker.each.map {|x| x }.should == [1]
131
+ end
132
+
133
+ it 'reset clears internal state' do
134
+ # 1-element array
135
+ unpacker.feed("\x91")
136
+ unpacker.each.map {|x| x }.should == []
137
+
138
+ unpacker.reset
139
+
140
+ unpacker.feed("\x01")
141
+ unpacker.each.map {|x| x }.should == [1]
142
+ end
143
+
144
+ it 'frozen short strings' do
145
+ raw = sample_object.to_msgpack.to_s.force_encoding('UTF-8')
146
+ lambda {
147
+ unpacker.feed_each(raw.freeze) { }
148
+ }.should_not raise_error
149
+ end
150
+
151
+ it 'frozen long strings' do
152
+ raw = (sample_object.to_msgpack.to_s * 10240).force_encoding('UTF-8')
153
+ lambda {
154
+ unpacker.feed_each(raw.freeze) { }
155
+ }.should_not raise_error
156
+ end
157
+
158
+ it 'read raises invalid byte error' do
159
+ unpacker.feed("\xc1")
160
+ lambda {
161
+ unpacker.read
162
+ }.should raise_error(MessagePack::MalformedFormatError)
163
+ end
164
+
165
+ it "gc mark" do
166
+ raw = sample_object.to_msgpack.to_s * 4
167
+
168
+ n = 0
169
+ raw.split(//).each do |b|
170
+ GC.start
171
+ unpacker.feed_each(b) {|o|
172
+ GC.start
173
+ o.should == sample_object
174
+ n += 1
175
+ }
176
+ GC.start
177
+ end
178
+
179
+ n.should == 4
180
+ end
181
+
182
+ it "buffer" do
183
+ orig = "a"*32*1024*4
184
+ raw = orig.to_msgpack.to_s
185
+
186
+ n = 655
187
+ times = raw.size / n
188
+ times += 1 unless raw.size % n == 0
189
+
190
+ off = 0
191
+ parsed = false
192
+
193
+ times.times do
194
+ parsed.should == false
195
+
196
+ seg = raw[off, n]
197
+ off += seg.length
198
+
199
+ unpacker.feed_each(seg) {|obj|
200
+ parsed.should == false
201
+ obj.should == orig
202
+ parsed = true
203
+ }
204
+ end
205
+
206
+ parsed.should == true
207
+ end
208
+
209
+ it 'MessagePack.unpack symbolize_keys' do
210
+ symbolized_hash = {:a => 'b', :c => 'd'}
211
+ MessagePack.load(MessagePack.pack(symbolized_hash), :symbolize_keys => true).should == symbolized_hash
212
+ MessagePack.unpack(MessagePack.pack(symbolized_hash), :symbolize_keys => true).should == symbolized_hash
213
+ end
214
+
215
+ it 'Unpacker#unpack symbolize_keys' do
216
+ unpacker = MessagePack::Unpacker.new(:symbolize_keys => true)
217
+ symbolized_hash = {:a => 'b', :c => 'd'}
218
+ unpacker.feed(MessagePack.pack(symbolized_hash)).read.should == symbolized_hash
219
+ end
220
+
221
+ it "msgpack str 8 type" do
222
+ MessagePack.unpack([0xd9, 0x00].pack('C*')).should == ""
223
+ MessagePack.unpack([0xd9, 0x00].pack('C*')).encoding.should == Encoding::UTF_8
224
+ MessagePack.unpack([0xd9, 0x01].pack('C*') + 'a').should == "a"
225
+ MessagePack.unpack([0xd9, 0x02].pack('C*') + 'aa').should == "aa"
226
+ end
227
+
228
+ it "msgpack str 16 type" do
229
+ MessagePack.unpack([0xda, 0x00, 0x00].pack('C*')).should == ""
230
+ MessagePack.unpack([0xda, 0x00, 0x00].pack('C*')).encoding.should == Encoding::UTF_8
231
+ MessagePack.unpack([0xda, 0x00, 0x01].pack('C*') + 'a').should == "a"
232
+ MessagePack.unpack([0xda, 0x00, 0x02].pack('C*') + 'aa').should == "aa"
233
+ end
234
+
235
+ it "msgpack str 32 type" do
236
+ MessagePack.unpack([0xdb, 0x00, 0x00, 0x00, 0x00].pack('C*')).should == ""
237
+ MessagePack.unpack([0xdb, 0x00, 0x00, 0x00, 0x00].pack('C*')).encoding.should == Encoding::UTF_8
238
+ MessagePack.unpack([0xdb, 0x00, 0x00, 0x00, 0x01].pack('C*') + 'a').should == "a"
239
+ MessagePack.unpack([0xdb, 0x00, 0x00, 0x00, 0x02].pack('C*') + 'aa').should == "aa"
240
+ end
241
+
242
+ it "msgpack bin 8 type" do
243
+ MessagePack.unpack([0xc4, 0x00].pack('C*')).should == ""
244
+ MessagePack.unpack([0xc4, 0x00].pack('C*')).encoding.should == Encoding::ASCII_8BIT
245
+ MessagePack.unpack([0xc4, 0x01].pack('C*') + 'a').should == "a"
246
+ MessagePack.unpack([0xc4, 0x02].pack('C*') + 'aa').should == "aa"
247
+ end
248
+
249
+ it "msgpack bin 16 type" do
250
+ MessagePack.unpack([0xc5, 0x00, 0x00].pack('C*')).should == ""
251
+ MessagePack.unpack([0xc5, 0x00, 0x00].pack('C*')).encoding.should == Encoding::ASCII_8BIT
252
+ MessagePack.unpack([0xc5, 0x00, 0x01].pack('C*') + 'a').should == "a"
253
+ MessagePack.unpack([0xc5, 0x00, 0x02].pack('C*') + 'aa').should == "aa"
254
+ end
255
+
256
+ it "msgpack bin 32 type" do
257
+ MessagePack.unpack([0xc6, 0x00, 0x00, 0x00, 0x00].pack('C*')).should == ""
258
+ MessagePack.unpack([0xc6, 0x0, 0x00, 0x00, 0x000].pack('C*')).encoding.should == Encoding::ASCII_8BIT
259
+ MessagePack.unpack([0xc6, 0x00, 0x00, 0x00, 0x01].pack('C*') + 'a').should == "a"
260
+ MessagePack.unpack([0xc6, 0x00, 0x00, 0x00, 0x02].pack('C*') + 'aa').should == "aa"
261
+ end
262
+
4
263
  class ValueOne
5
264
  attr_reader :num
6
265
  def initialize(num)
@@ -41,14 +300,12 @@ describe MessagePack::Unpacker do
41
300
 
42
301
  describe '#type_registered?' do
43
302
  it 'receive Class or Integer, and return bool' do
44
- skip("not supported yet in JRuby implementation") if java?
45
303
  expect(subject.type_registered?(0x00)).to be_falsy
46
304
  expect(subject.type_registered?(0x01)).to be_falsy
47
305
  expect(subject.type_registered?(::ValueOne)).to be_falsy
48
306
  end
49
307
 
50
308
  it 'returns true if specified type or class is already registered' do
51
- skip("not supported yet in JRuby implementation") if java?
52
309
  subject.register_type(0x30, ::ValueOne, :from_msgpack_ext)
53
310
  subject.register_type(0x31, ::ValueTwo, :from_msgpack_ext)
54
311
 
@@ -62,7 +319,6 @@ describe MessagePack::Unpacker do
62
319
  end
63
320
 
64
321
  it 'cannot detect unpack rule with block, not method' do
65
- skip("not supported yet in JRuby implementation") if java?
66
322
  subject.register_type(0x40){|data| ValueOne.from_msgpack_ext(data) }
67
323
 
68
324
  expect(subject.type_registered?(0x40)).to be_truthy
@@ -72,7 +328,6 @@ describe MessagePack::Unpacker do
72
328
 
73
329
  context 'with ext definitions' do
74
330
  it 'get type and class mapping for packing' do
75
- skip("not supported yet in JRuby implementation") if java?
76
331
  unpacker = MessagePack::Unpacker.new
77
332
  unpacker.register_type(0x01){|data| ValueOne.from_msgpack_ext }
78
333
  unpacker.register_type(0x02){|data| ValueTwo.from_msgpack_ext(data) }
@@ -83,7 +338,6 @@ describe MessagePack::Unpacker do
83
338
  end
84
339
 
85
340
  it 'returns a Array of Hash which contains :type, :class and :unpacker' do
86
- skip("not supported yet in JRuby implementation") if java?
87
341
  unpacker = MessagePack::Unpacker.new
88
342
  unpacker.register_type(0x02, ValueTwo, :from_msgpack_ext)
89
343
  unpacker.register_type(0x01, ValueOne, :from_msgpack_ext)
@@ -107,7 +361,6 @@ describe MessagePack::Unpacker do
107
361
  end
108
362
 
109
363
  it 'returns a Array of Hash, which contains nil for class if block unpacker specified' do
110
- skip("not supported yet in JRuby implementation") if java?
111
364
  unpacker = MessagePack::Unpacker.new
112
365
  unpacker.register_type(0x01){|data| ValueOne.from_msgpack_ext }
113
366
  unpacker.register_type(0x02, &ValueTwo.method(:from_msgpack_ext))
@@ -130,4 +383,210 @@ describe MessagePack::Unpacker do
130
383
  expect(two[:unpacker]).to be_instance_of(Proc)
131
384
  end
132
385
  end
386
+
387
+ def flatten(struct, results = [])
388
+ case struct
389
+ when Array
390
+ struct.each { |v| flatten(v, results) }
391
+ when Hash
392
+ struct.each { |k, v| flatten(v, flatten(k, results)) }
393
+ else
394
+ results << struct
395
+ end
396
+ results
397
+ end
398
+
399
+ subject do
400
+ described_class.new
401
+ end
402
+
403
+ let :buffer1 do
404
+ MessagePack.pack(:foo => 'bar')
405
+ end
406
+
407
+ let :buffer2 do
408
+ MessagePack.pack(:hello => {:world => [1, 2, 3]})
409
+ end
410
+
411
+ let :buffer3 do
412
+ MessagePack.pack(:x => 'y')
413
+ end
414
+
415
+ describe '#read' do
416
+ context 'with a buffer' do
417
+ it 'reads objects' do
418
+ objects = []
419
+ subject.feed(buffer1)
420
+ subject.feed(buffer2)
421
+ subject.feed(buffer3)
422
+ objects << subject.read
423
+ objects << subject.read
424
+ objects << subject.read
425
+ objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
426
+ end
427
+
428
+ it 'reads map header' do
429
+ subject.feed({}.to_msgpack)
430
+ subject.read_map_header.should == 0
431
+ end
432
+
433
+ it 'reads array header' do
434
+ subject.feed([].to_msgpack)
435
+ subject.read_array_header.should == 0
436
+ end
437
+ end
438
+ end
439
+
440
+ describe '#each' do
441
+ context 'with a buffer' do
442
+ it 'yields each object in the buffer' do
443
+ objects = []
444
+ subject.feed(buffer1)
445
+ subject.feed(buffer2)
446
+ subject.feed(buffer3)
447
+ subject.each do |obj|
448
+ objects << obj
449
+ end
450
+ objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
451
+ end
452
+
453
+ it 'returns an enumerator when no block is given' do
454
+ subject.feed(buffer1)
455
+ subject.feed(buffer2)
456
+ subject.feed(buffer3)
457
+ enum = subject.each
458
+ enum.map { |obj| obj.keys.first }.should == %w[foo hello x]
459
+ end
460
+ end
461
+
462
+ context 'with a stream passed to the constructor' do
463
+ it 'yields each object in the stream' do
464
+ objects = []
465
+ unpacker = described_class.new(StringIO.new(buffer1 + buffer2 + buffer3))
466
+ unpacker.each do |obj|
467
+ objects << obj
468
+ end
469
+ objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
470
+ end
471
+ end
472
+ end
473
+
474
+ describe '#feed_each' do
475
+ it 'feeds the buffer then runs #each' do
476
+ objects = []
477
+ subject.feed_each(buffer1 + buffer2 + buffer3) do |obj|
478
+ objects << obj
479
+ end
480
+ objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
481
+ end
482
+
483
+ it 'handles chunked data' do
484
+ objects = []
485
+ buffer = buffer1 + buffer2 + buffer3
486
+ buffer.chars.each do |ch|
487
+ subject.feed_each(ch) do |obj|
488
+ objects << obj
489
+ end
490
+ end
491
+ objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
492
+ end
493
+ end
494
+
495
+ context 'regressions' do
496
+ it 'handles massive arrays (issue #2)' do
497
+ array = ['foo'] * 10_000
498
+ MessagePack.unpack(MessagePack.pack(array)).size.should == 10_000
499
+ end
500
+ end
501
+
502
+ context 'extensions' do
503
+ context 'symbolized keys' do
504
+ let :buffer do
505
+ MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
506
+ end
507
+
508
+ let :unpacker do
509
+ described_class.new(:symbolize_keys => true)
510
+ end
511
+
512
+ it 'can symbolize keys when using #each' do
513
+ objs = []
514
+ unpacker.feed(buffer)
515
+ unpacker.each do |obj|
516
+ objs << obj
517
+ end
518
+ objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
519
+ end
520
+
521
+ it 'can symbolize keys when using #feed_each' do
522
+ objs = []
523
+ unpacker.feed_each(buffer) do |obj|
524
+ objs << obj
525
+ end
526
+ objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
527
+ end
528
+ end
529
+
530
+ context 'binary encoding', :encodings do
531
+ let :buffer do
532
+ MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
533
+ end
534
+
535
+ let :unpacker do
536
+ described_class.new()
537
+ end
538
+
539
+ it 'decodes binary as ascii-8bit when using #feed' do
540
+ objs = []
541
+ unpacker.feed(buffer)
542
+ unpacker.each do |obj|
543
+ objs << obj
544
+ end
545
+ strings = flatten(objs).grep(String)
546
+ strings.should == %w[hello world nested object structure]
547
+ strings.map(&:encoding).uniq.should == [Encoding::ASCII_8BIT]
548
+ end
549
+
550
+ it 'decodes binary as ascii-8bit when using #feed_each' do
551
+ objs = []
552
+ unpacker.feed_each(buffer) do |obj|
553
+ objs << obj
554
+ end
555
+ strings = flatten(objs).grep(String)
556
+ strings.should == %w[hello world nested object structure]
557
+ strings.map(&:encoding).uniq.should == [Encoding::ASCII_8BIT]
558
+ end
559
+ end
560
+
561
+ context 'string encoding', :encodings do
562
+ let :buffer do
563
+ MessagePack.pack({'hello'.force_encoding(Encoding::UTF_8) => 'world'.force_encoding(Encoding::UTF_8), 'nested'.force_encoding(Encoding::UTF_8) => ['object'.force_encoding(Encoding::UTF_8), {'structure'.force_encoding(Encoding::UTF_8) => true}]})
564
+ end
565
+
566
+ let :unpacker do
567
+ described_class.new()
568
+ end
569
+
570
+ it 'decodes string as utf-8 when using #feed' do
571
+ objs = []
572
+ unpacker.feed(buffer)
573
+ unpacker.each do |obj|
574
+ objs << obj
575
+ end
576
+ strings = flatten(objs).grep(String)
577
+ strings.should == %w[hello world nested object structure]
578
+ strings.map(&:encoding).uniq.should == [Encoding::UTF_8]
579
+ end
580
+
581
+ it 'decodes binary as ascii-8bit when using #feed_each' do
582
+ objs = []
583
+ unpacker.feed_each(buffer) do |obj|
584
+ objs << obj
585
+ end
586
+ strings = flatten(objs).grep(String)
587
+ strings.should == %w[hello world nested object structure]
588
+ strings.map(&:encoding).uniq.should == [Encoding::UTF_8]
589
+ end
590
+ end
591
+ end
133
592
  end