stomper 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,313 +2,332 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  module Stomper
5
- if RUBY_VERSION >= '1.9'
6
- describe FrameSerializer do
7
- before(:each) do
8
- @messages = {
9
- :content_type_and_charset => "MESSAGE\ncontent-type:text/plain; charset=ISO-8859-1\ncontent-length:6\na-header: padded \n\nh\xEBllo!\000",
10
- :escaped_headers => "MESSAGE\ncontent-type:text/plain;charset=UTF-8\ncontent-length:7\na\\nspecial\\chead\\\\cer: padded\\c and using\\nspecial\\\\\\\\\\\\ncharacters \n\nh\xC3\xABllo!\000",
11
- :no_content_length => "MESSAGE\ncontent-type:text/plain\n\nh\xC3\xABllo!\000",
12
- :repeated_headers => "MESSAGE\ncontent-type:text/plain\nrepeated header:a value\nrepeated header:alternate value\n\nh\xC3\xABllo!\000",
13
- :non_text_content_type => "MESSAGE\ncontent-type:not-text/other\n\nh\xC3\xABllo!\000",
14
- :no_content_type => "MESSAGE\n\nh\xC3\xABllo!\000",
15
- :invalid_content_length => "MESSAGE\ncontent-length:4\n\n12345\000",
16
- :invalid_header_character => "MESSAGE\ngrandpa:he was:anti\n\n12345\000",
17
- :invalid_header_sequence => "MESSAGE\ngrandpa:he was\\ranti\n\n12345\000",
18
- :malformed_header => "MESSAGE\nearth_below_us\nfloating:weightless\n\n12345\000",
19
- :dangling_header_sequence => "MESSAGE\ngrandpa:he was anti\\\n\n12345\000",
20
- }
5
+ describe FrameSerializer do
6
+ before(:each) do
7
+ @messages = {
8
+ :content_type_and_charset => "MESSAGE\ncontent-type:text/plain; charset=ISO-8859-1\ncontent-length:6\na-header: padded \n\nh\xEBllo!\000",
9
+ :escaped_headers => "MESSAGE\ncontent-type:text/plain;charset=UTF-8\ncontent-length:7\na\\nspecial\\chead\\\\cer: padded\\c and using\\nspecial\\\\\\\\\\\\ncharacters \n\nh\xC3\xABllo!\000",
10
+ :no_content_length => "MESSAGE\ncontent-type:text/plain\n\nh\xC3\xABllo!\000",
11
+ :repeated_headers => "MESSAGE\ncontent-type:text/plain\nrepeated header:a value\nrepeated header:alternate value\n\nh\xC3\xABllo!\000",
12
+ :non_text_content_type => "MESSAGE\ncontent-type:not-text/other\n\nh\xC3\xABllo!\000",
13
+ :no_content_type => "MESSAGE\n\nh\xC3\xABllo!\000",
14
+ :invalid_content_length => "MESSAGE\ncontent-length:4\n\n12345\000",
15
+ :invalid_header_character => "MESSAGE\ngrandpa:he was:anti\n\n12345\000",
16
+ :invalid_header_sequence => "MESSAGE\ngrandpa:he was\\ranti\n\n12345\000",
17
+ :malformed_header => "MESSAGE\nearth_below_us\nfloating:weightless\n\n12345\000",
18
+ :dangling_header_sequence => "MESSAGE\ngrandpa:he was anti\\\n\n12345\000",
19
+ }
20
+
21
+ @frames = {
22
+ :common => ::Stomper::Frame.new('FRAME', {}, 'body of message'),
23
+ :no_headers => ::Stomper::Frame.new('FRAME', {}, 'body of message'),
24
+ :no_body => ::Stomper::Frame.new('FRAME', {}),
25
+ :no_command => ::Stomper::Frame.new,
26
+ :header_name_with_linefeed => ::Stomper::Frame.new('FRAME', { "a\ntest\nheader" => "va\\lue : is\n\nme"}),
27
+ :header_name_with_colon => ::Stomper::Frame.new('FRAME', { "a:test:header" => "va\\lue : is\n\nme"}),
28
+ :header_name_with_backslash => ::Stomper::Frame.new('FRAME', { "a\\test\\header" => "va\\lue : is\n\nme"}),
29
+ :binary_body_no_content_type => ::Stomper::Frame.new('FRAME', {}, 'body of message'),
30
+ :charset_header_text_body => ::Stomper::Frame.new('FRAME', {:'content-type' => 'text/plain; param="value";charset=ISO-8859-1'}, 'body of message'),
31
+ :charset_header_binary_body => ::Stomper::Frame.new('FRAME', {:'content-type' => 'application/pdf; param="value";charset=ISO-8859-1'}, 'body of message')
32
+ }
33
+ # Curse Ruby 1.8.7 and it's unordered hashes!
34
+ @frames[:common][:header_1] = 'value 1'
35
+ @frames[:common][:header_2] = '3'
36
+ @frames[:common][:header_3] = ''
37
+ @frames[:common][:'content-type'] = 'text/plain'
38
+ @frames[:no_body][:header_1] = 'val'
39
+ @frames[:no_body][:musical] = ''
40
+ @frames[:no_body][:offering] = '4'
41
+ if RUBY_VERSION >= "1.9"
21
42
  @messages.each { |k, v| v.force_encoding('ASCII-8BIT') }
43
+ @frames[:no_headers].body = @frames[:no_headers].body.encode('ISO-8859-1')
44
+ @frames[:binary_body_no_content_type].body = @frames[:binary_body_no_content_type].body.encode('ASCII-8BIT')
45
+ @frames[:charset_header_binary_body].body = @frames[:charset_header_binary_body].body.encode('ASCII-8BIT')
46
+ @frames[:charset_header_text_body].body = @frames[:charset_header_text_body].body.encode('UTF-8')
47
+ end
48
+ @frame_io = StringIO.new
49
+ @frame_serializer = FrameSerializer.new(@frame_io)
50
+ end
51
+
52
+ describe "thread safety" do
53
+ before(:each) do
54
+ @frame_serializer = FrameSerializer.new(mock('frame io'))
55
+ end
56
+ it "should synchronize writing to the underlying IO" do
57
+ first_called = false
58
+ call_next = false
59
+ ordered = []
60
+ @frame_serializer.stub!(:__write_frame__).and_return do |f|
61
+ first_called = true
62
+ ordered << 1
63
+ Thread.stop
64
+ ordered << 2
65
+ f
66
+ end
67
+
68
+ thread_1 = Thread.new do
69
+ @frame_serializer.write_frame(mock('frame'))
70
+ end
71
+ thread_2 = Thread.new do
72
+ Thread.pass until call_next
73
+ Thread.pass
74
+ thread_1.run
75
+ end
76
+ Thread.pass until first_called
77
+ call_next = true
22
78
 
23
- @frames = {
24
- :common => ::Stomper::Frame.new('FRAME', { :header_1 => 'value 1', :header_2 => '3', :header_3 => '', :'content-type' => 'text/plain'}, 'body of message'),
25
- :no_headers => ::Stomper::Frame.new('FRAME', {}, 'body of message'.encode('ISO-8859-1')),
26
- :no_body => ::Stomper::Frame.new('FRAME', { :header_1 => 'val', :musical => '', :offering => '4'}),
27
- :no_command => ::Stomper::Frame.new,
28
- :header_name_with_linefeed => ::Stomper::Frame.new('FRAME', { "a\ntest\nheader" => "va\\lue : is\n\nme"}),
29
- :header_name_with_colon => ::Stomper::Frame.new('FRAME', { "a:test:header" => "va\\lue : is\n\nme"}),
30
- :header_name_with_backslash => ::Stomper::Frame.new('FRAME', { "a\\test\\header" => "va\\lue : is\n\nme"}),
31
- :binary_body_no_content_type => ::Stomper::Frame.new('FRAME', {}, 'body of message'.encode('ASCII-8BIT')),
32
- :charset_header_text_body => ::Stomper::Frame.new('FRAME', {:'content-type' => 'text/plain; param="value";charset=ISO-8859-1'}, 'body of message'.encode('UTF-8')),
33
- :charset_header_binary_body => ::Stomper::Frame.new('FRAME', {:'content-type' => 'application/pdf; param="value";charset=ISO-8859-1'}, 'body of message'.encode('ASCII-8BIT'))
34
- }
35
- @frame_io = StringIO.new
36
- @frame_serializer = FrameSerializer.new(@frame_io)
79
+ @frame_serializer.stub!(:__write_frame__).and_return do |f|
80
+ ordered << 3
81
+ f
82
+ end
83
+ @frame_serializer.write_frame(mock('frame'))
84
+ thread_1.join
85
+ thread_2.join
86
+ ordered.should == [1, 2, 3]
37
87
  end
38
88
 
39
- describe "thread safety" do
40
- before(:each) do
41
- @frame_serializer = FrameSerializer.new(mock('frame io'))
42
- end
43
- it "should synchronize writing to the underlying IO" do
44
- first_called = false
45
- call_next = false
46
- ordered = []
47
- @frame_serializer.stub!(:__write_frame__).and_return do |f|
48
- first_called = true
49
- ordered << 1
50
- Thread.stop
51
- ordered << 2
52
- f
53
- end
54
-
55
- thread_1 = Thread.new do
56
- @frame_serializer.write_frame(mock('frame'))
57
- end
58
- thread_2 = Thread.new do
59
- Thread.pass until call_next
60
- Thread.pass
61
- thread_1.run
62
- end
63
- Thread.pass until first_called
64
- call_next = true
65
-
66
- @frame_serializer.stub!(:__write_frame__).and_return do |f|
67
- ordered << 3
68
- f
69
- end
70
- @frame_serializer.write_frame(mock('frame'))
71
- thread_1.join
72
- thread_2.join
73
- ordered.should == [1, 2, 3]
89
+ it "should synchronize reading from the underlying IO" do
90
+ first_called = false
91
+ call_next = false
92
+ ordered = []
93
+ @frame_serializer.stub!(:__read_frame__).and_return do
94
+ first_called = true
95
+ ordered << 1
96
+ Thread.stop
97
+ ordered << 2
98
+ mock('frame 1')
74
99
  end
75
100
 
76
- it "should synchronize reading from the underlying IO" do
77
- first_called = false
78
- call_next = false
79
- ordered = []
80
- @frame_serializer.stub!(:__read_frame__).and_return do
81
- first_called = true
82
- ordered << 1
83
- Thread.stop
84
- ordered << 2
85
- mock('frame 1')
86
- end
87
-
88
- thread_1 = Thread.new do
89
- @frame_serializer.read_frame
90
- end
91
- thread_2 = Thread.new do
92
- Thread.pass until call_next
93
- Thread.pass
94
- thread_1.run
95
- end
96
- Thread.pass until first_called
97
- call_next = true
98
-
99
- @frame_serializer.stub!(:__read_frame__).and_return do
100
- ordered << 3
101
- mock('frame 2')
102
- end
101
+ thread_1 = Thread.new do
103
102
  @frame_serializer.read_frame
104
- thread_1.join
105
- thread_2.join
106
- ordered.should == [1, 2, 3]
107
103
  end
104
+ thread_2 = Thread.new do
105
+ Thread.pass until call_next
106
+ Thread.pass
107
+ thread_1.run
108
+ end
109
+ Thread.pass until first_called
110
+ call_next = true
108
111
 
109
- it "should not make reading and writing mutually exclusive" do
110
- first_called = false
111
- call_next = false
112
- ordered = []
113
- @frame_serializer.stub!(:__write_frame__).and_return do |f|
114
- first_called = true
115
- ordered << 1
116
- Thread.stop
117
- ordered << 2
118
- f
119
- end
120
- @frame_serializer.stub!(:__read_frame__).and_return do
121
- ordered << 3
122
- mock('frame 2')
123
- end
124
-
125
- thread_1 = Thread.new do
126
- @frame_serializer.write_frame(mock('frame'))
127
- end
128
- thread_2 = Thread.new do
129
- Thread.pass until call_next
130
- Thread.pass
131
- thread_1.run
132
- end
133
- Thread.pass until first_called
134
- call_next = true
135
- @frame_serializer.read_frame
136
- thread_1.join
137
- thread_2.join
138
- ordered.should == [1, 3, 2]
112
+ @frame_serializer.stub!(:__read_frame__).and_return do
113
+ ordered << 3
114
+ mock('frame 2')
139
115
  end
116
+ @frame_serializer.read_frame
117
+ thread_1.join
118
+ thread_2.join
119
+ ordered.should == [1, 2, 3]
140
120
  end
141
121
 
142
- describe "Protocol 1.0" do
143
- it "should not have extended the V1_1 mixin" do
144
- ::Stomper::FrameSerializer::EXTEND_BY_VERSION['1.1'].each do |mod|
145
- @frame_serializer.should_not be_a_kind_of(mod)
146
- end
122
+ it "should not make reading and writing mutually exclusive" do
123
+ first_called = false
124
+ call_next = false
125
+ ordered = []
126
+ @frame_serializer.stub!(:__write_frame__).and_return do |f|
127
+ first_called = true
128
+ ordered << 1
129
+ Thread.stop
130
+ ordered << 2
131
+ f
132
+ end
133
+ @frame_serializer.stub!(:__read_frame__).and_return do
134
+ ordered << 3
135
+ mock('frame 2')
147
136
  end
148
137
 
149
- describe "writing frames" do
150
- it "should properly serialize a common frame" do
151
- @frame_serializer.write_frame(@frames[:common])
152
- @frame_io.string.should == "FRAME\nheader_1:value 1\nheader_2:3\nheader_3:\ncontent-type:text/plain;charset=UTF-8\ncontent-length:15\n\nbody of message\000"
153
- end
138
+ thread_1 = Thread.new do
139
+ @frame_serializer.write_frame(mock('frame'))
140
+ end
141
+ thread_2 = Thread.new do
142
+ Thread.pass until call_next
143
+ Thread.pass
144
+ thread_1.run
145
+ end
146
+ Thread.pass until first_called
147
+ call_next = true
148
+ @frame_serializer.read_frame
149
+ thread_1.join
150
+ thread_2.join
151
+ ordered.should == [1, 3, 2]
152
+ end
153
+ end
154
+
155
+ describe "Protocol 1.0" do
156
+ it "should not have extended the V1_1 mixin" do
157
+ ::Stomper::FrameSerializer::EXTEND_BY_VERSION['1.1'].each do |mod|
158
+ @frame_serializer.should_not be_a_kind_of(mod)
159
+ end
160
+ end
161
+
162
+ describe "writing frames" do
163
+ it "should properly serialize a common frame" do
164
+ @frame_serializer.write_frame(@frames[:common])
165
+ @frame_io.string.should == "FRAME\nheader_1:value 1\nheader_2:3\nheader_3:\ncontent-type:text/plain;charset=UTF-8\ncontent-length:15\n\nbody of message\000"
166
+ end
167
+
168
+ it "should properly serialize a frame without headers" do
169
+ @frame_serializer.write_frame(@frames[:no_headers])
170
+ expected = RUBY_VERSION >= '1.9' ? "FRAME\ncontent-type:text/plain;charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000" :
171
+ "FRAME\ncontent-length:15\n\nbody of message\000"
172
+ @frame_io.string.should == expected
173
+ end
174
+
175
+ it "should properly serialize a frame without a body" do
176
+ @frame_serializer.write_frame(@frames[:no_body])
177
+ @frame_io.string.should == "FRAME\nheader_1:val\nmusical:\noffering:4\n\n\000"
178
+ end
179
+
180
+ it "should properly serialize a frame without a command as a new line" do
181
+ @frame_serializer.write_frame(@frames[:no_command])
182
+ @frame_io.string.should == "\n"
183
+ end
184
+
185
+ it "should properly drop LF from header names and values" do
186
+ @frame_serializer.write_frame(@frames[:header_name_with_linefeed])
187
+ @frame_io.string.should == "FRAME\natestheader:va\\lue : isme\n\n\000"
188
+ end
154
189
 
155
- it "should properly serialize a frame without headers" do
156
- @frame_serializer.write_frame(@frames[:no_headers])
157
- @frame_io.string.should == "FRAME\ncontent-type:text/plain;charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000"
158
- end
190
+ it "should not escape backslash characters in header names or values" do
191
+ @frame_serializer.write_frame(@frames[:header_name_with_backslash])
192
+ @frame_io.string.should == "FRAME\na\\test\\header:va\\lue : isme\n\n\000"
193
+ end
159
194
 
160
- it "should properly serialize a frame without a body" do
161
- @frame_serializer.write_frame(@frames[:no_body])
162
- @frame_io.string.should == "FRAME\nheader_1:val\nmusical:\noffering:4\n\n\000"
163
- end
195
+ it "should drop colons in header names, but leave them alone in values" do
196
+ @frame_serializer.write_frame(@frames[:header_name_with_colon])
197
+ @frame_io.string.should == "FRAME\natestheader:va\\lue : isme\n\n\000"
198
+ end
164
199
 
165
- it "should properly serialize a frame without a command as a new line" do
166
- @frame_serializer.write_frame(@frames[:no_command])
167
- @frame_io.string.should == "\n"
168
- end
200
+ it "should not generate a content-type header if the encoding is binary" do
201
+ @frame_serializer.write_frame(@frames[:binary_body_no_content_type])
202
+ @frame_io.string.should == "FRAME\ncontent-length:15\n\nbody of message\000"
203
+ end
204
+
205
+ it "should overwrite the charset parameter with the encoding when the body is text" do
206
+ @frame_serializer.write_frame(@frames[:charset_header_text_body])
207
+ expected = RUBY_VERSION >= '1.9' ? "FRAME\ncontent-type:text/plain; param=\"value\";charset=UTF-8\ncontent-length:15\n\nbody of message\000" :
208
+ "FRAME\ncontent-type:text/plain; param=\"value\";charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000"
209
+ @frame_io.string.should == expected
210
+ end
169
211
 
170
- it "should properly drop LF from header names and values" do
171
- @frame_serializer.write_frame(@frames[:header_name_with_linefeed])
172
- @frame_io.string.should == "FRAME\natestheader:va\\lue : isme\n\n\000"
173
- end
174
-
175
- it "should not escape backslash characters in header names or values" do
176
- @frame_serializer.write_frame(@frames[:header_name_with_backslash])
177
- @frame_io.string.should == "FRAME\na\\test\\header:va\\lue : isme\n\n\000"
178
- end
179
-
180
- it "should drop colons in header names, but leave them alone in values" do
181
- @frame_serializer.write_frame(@frames[:header_name_with_colon])
182
- @frame_io.string.should == "FRAME\natestheader:va\\lue : isme\n\n\000"
183
- end
184
-
185
- it "should not generate a content-type header if the encoding is binary" do
186
- @frame_serializer.write_frame(@frames[:binary_body_no_content_type])
187
- @frame_io.string.should == "FRAME\ncontent-length:15\n\nbody of message\000"
188
- end
189
-
190
- it "should overwrite the charset parameter with the encoding when the body is text" do
191
- @frame_serializer.write_frame(@frames[:charset_header_text_body])
192
- @frame_io.string.should == "FRAME\ncontent-type:text/plain; param=\"value\";charset=UTF-8\ncontent-length:15\n\nbody of message\000"
193
- end
194
-
195
- it "should omit the charset parameter when the content-type is not text/* and the encoding is binary" do
196
- @frame_serializer.write_frame(@frames[:charset_header_binary_body])
197
- @frame_io.string.should == "FRAME\ncontent-type:application/pdf; param=\"value\"\ncontent-length:15\n\nbody of message\000"
198
- end
212
+ it "should omit the charset parameter when the content-type is not text/* and the encoding is binary" do
213
+ @frame_serializer.write_frame(@frames[:charset_header_binary_body])
214
+ expected = RUBY_VERSION >= '1.9' ? "FRAME\ncontent-type:application/pdf; param=\"value\"\ncontent-length:15\n\nbody of message\000" :
215
+ "FRAME\ncontent-type:application/pdf; param=\"value\";charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000"
216
+ @frame_io.string.should == expected
199
217
  end
200
218
  end
219
+ end
220
+
221
+ describe "Protocol 1.1" do
222
+ before(:each) do
223
+ @frame_serializer.extend_for_protocol '1.1'
224
+ end
201
225
 
202
- describe "Protocol 1.1" do
203
- before(:each) do
204
- @frame_serializer.extend_for_protocol '1.1'
226
+ it "should have extended the V1_1 mixin" do
227
+ ::Stomper::FrameSerializer::EXTEND_BY_VERSION['1.1'].each do |mod|
228
+ @frame_serializer.should be_a_kind_of(mod)
205
229
  end
206
-
207
- it "should have extended the V1_1 mixin" do
208
- ::Stomper::FrameSerializer::EXTEND_BY_VERSION['1.1'].each do |mod|
209
- @frame_serializer.should be_a_kind_of(mod)
210
- end
230
+ end
231
+
232
+ describe "writing frames" do
233
+ it "should properly serialize a common frame" do
234
+ @frame_serializer.write_frame(@frames[:common])
235
+ @frame_io.string.should == "FRAME\nheader_1:value 1\nheader_2:3\nheader_3:\ncontent-type:text/plain;charset=UTF-8\ncontent-length:15\n\nbody of message\000"
236
+ end
237
+
238
+ it "should properly serialize a frame without headers" do
239
+ @frame_serializer.write_frame(@frames[:no_headers])
240
+ expected = RUBY_VERSION >= '1.9' ? "FRAME\ncontent-type:text/plain;charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000" :
241
+ "FRAME\ncontent-length:15\n\nbody of message\000"
242
+ @frame_io.string.should == expected
243
+ end
244
+
245
+ it "should properly serialize a frame without a body" do
246
+ @frame_serializer.write_frame(@frames[:no_body])
247
+ @frame_io.string.should == "FRAME\nheader_1:val\nmusical:\noffering:4\n\n\000"
248
+ end
249
+
250
+ it "should properly serialize a frame without a command as a new line" do
251
+ @frame_serializer.write_frame(@frames[:no_command])
252
+ @frame_io.string.should == "\n"
211
253
  end
212
-
213
- describe "writing frames" do
214
- it "should properly serialize a common frame" do
215
- @frame_serializer.write_frame(@frames[:common])
216
- @frame_io.string.should == "FRAME\nheader_1:value 1\nheader_2:3\nheader_3:\ncontent-type:text/plain;charset=UTF-8\ncontent-length:15\n\nbody of message\000"
217
- end
218
254
 
219
- it "should properly serialize a frame without headers" do
220
- @frame_serializer.write_frame(@frames[:no_headers])
221
- @frame_io.string.should == "FRAME\ncontent-type:text/plain;charset=ISO-8859-1\ncontent-length:15\n\nbody of message\000"
222
- end
255
+ it "should escape LF in header names and values" do
256
+ @frame_serializer.write_frame(@frames[:header_name_with_linefeed])
257
+ @frame_io.string.should == "FRAME\na\\ntest\\nheader:va\\\\lue \\c is\\n\\nme\n\n\000"
258
+ end
223
259
 
224
- it "should properly serialize a frame without a body" do
225
- @frame_serializer.write_frame(@frames[:no_body])
226
- @frame_io.string.should == "FRAME\nheader_1:val\nmusical:\noffering:4\n\n\000"
227
- end
260
+ it "should escape backslashes in header names and values" do
261
+ @frame_serializer.write_frame(@frames[:header_name_with_backslash])
262
+ @frame_io.string.should == "FRAME\na\\\\test\\\\header:va\\\\lue \\c is\\n\\nme\n\n\000"
263
+ end
228
264
 
229
- it "should properly serialize a frame without a command as a new line" do
230
- @frame_serializer.write_frame(@frames[:no_command])
231
- @frame_io.string.should == "\n"
232
- end
233
-
234
- it "should escape LF in header names and values" do
235
- @frame_serializer.write_frame(@frames[:header_name_with_linefeed])
236
- @frame_io.string.should == "FRAME\na\\ntest\\nheader:va\\\\lue \\c is\\n\\nme\n\n\000"
237
- end
238
-
239
- it "should escape backslashes in header names and values" do
240
- @frame_serializer.write_frame(@frames[:header_name_with_backslash])
241
- @frame_io.string.should == "FRAME\na\\\\test\\\\header:va\\\\lue \\c is\\n\\nme\n\n\000"
242
- end
243
-
244
- it "should escape colons in header names and values" do
245
- @frame_serializer.write_frame(@frames[:header_name_with_colon])
246
- @frame_io.string.should == "FRAME\na\\ctest\\cheader:va\\\\lue \\c is\\n\\nme\n\n\000"
247
- end
265
+ it "should escape colons in header names and values" do
266
+ @frame_serializer.write_frame(@frames[:header_name_with_colon])
267
+ @frame_io.string.should == "FRAME\na\\ctest\\cheader:va\\\\lue \\c is\\n\\nme\n\n\000"
248
268
  end
249
-
250
- describe "reading frames" do
251
- it "should properly de-serialize a simple frame" do
252
- @frame_io.string = @messages[:content_type_and_charset]
253
- frame = @frame_serializer.read_frame
254
- frame.command.should == "MESSAGE"
255
- frame.headers.sort { |a, b| a.first <=> b.first }.should == [
256
- ['a-header', ' padded '], ['content-length', '6'],
257
- ['content-type', 'text/plain; charset=ISO-8859-1']
258
- ]
259
- frame.body.should == "hëllo!".encode("ISO-8859-1")
260
- frame.body.encoding.name.should == 'ISO-8859-1'
261
- end
262
- it "should properly read a frame with special characters in its header" do
263
- @frame_io.string = @messages[:escaped_headers]
264
- frame = @frame_serializer.read_frame
265
- frame["a\nspecial:head\\cer"].should == " padded: and using\nspecial\\\\\\ncharacters "
266
- frame.body.encoding.name.should == 'UTF-8'
267
- end
268
- it "should properly read a frame with a body and no content-length" do
269
- @frame_io.string = @messages[:no_content_length]
270
- frame = @frame_serializer.read_frame
271
- frame.body.should == "hëllo!"
272
- frame.body.encoding.name.should == 'UTF-8'
273
- end
274
- it "should assume a binary charset if none is set and the content-type does not match text/*" do
275
- @frame_io.string = @messages[:non_text_content_type]
276
- frame = @frame_serializer.read_frame
277
- frame.body.encoding.name.should == 'ASCII-8BIT'
278
- end
279
- it "should assume a binary charset if the content-type header is not specified" do
280
- @frame_io.string = @messages[:no_content_type]
281
- frame = @frame_serializer.read_frame
282
- frame.body.encoding.name.should == 'ASCII-8BIT'
283
- end
284
- it "should set the value of a header to the first occurrence" do
285
- @frame_io.string = @messages[:repeated_headers]
286
- frame = @frame_serializer.read_frame
287
- frame['repeated header'].should == 'a value'
288
- end
289
- it "should raise a malformed frame error if the frame is not properly terminated" do
290
- @frame_io.string = @messages[:invalid_content_length]
291
- lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::MalformedFrameError)
292
- end
293
- # While the spec suggests that all ":" chars be replaced with "\c", ActiveMQ 5.3.2 sends
294
- # a "session" header with a value that contains ":" chars. So, we are NOT going to
295
- # freak out if we receive more than one ":" on a header line.
296
- it "should not raise an error if the frame contains a header value with a raw ':'" do
297
- @frame_io.string = @messages[:invalid_header_character]
298
- lambda { @frame_serializer.read_frame }.should_not raise_error
299
- end
300
- it "should raise an invalid header esacape sequence error if the frame contains a header with an invalid escape sequence" do
301
- @frame_io.string = @messages[:invalid_header_sequence]
302
- lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::InvalidHeaderEscapeSequenceError)
303
- end
304
- it "should raise an malfored header error if the frame contains an incomplete header" do
305
- @frame_io.string = @messages[:malformed_header]
306
- lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::MalformedHeaderError)
307
- end
308
- it "should raise an invalid header esacape sequence error if the frame contains a header with a dangling escape sequence" do
309
- @frame_io.string = @messages[:dangling_header_sequence]
310
- lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::InvalidHeaderEscapeSequenceError)
311
- end
269
+ end
270
+
271
+ describe "reading frames" do
272
+ it "should properly de-serialize a simple frame" do
273
+ @frame_io.string = @messages[:content_type_and_charset]
274
+ frame = @frame_serializer.read_frame
275
+ frame.should have_command('MESSAGE')
276
+ frame.should have_header(:'a-header', ' padded ')
277
+ frame.should have_header(:'content-length', '6')
278
+ frame.should have_header(:'content-type', 'text/plain; charset=ISO-8859-1')
279
+ frame.should have_body("hëllo!", "h\xEBllo!", 'ISO-8859-1')
280
+ frame.should have_body_encoding('ISO-8859-1')
281
+ end
282
+ it "should properly read a frame with special characters in its header" do
283
+ @frame_io.string = @messages[:escaped_headers]
284
+ frame = @frame_serializer.read_frame
285
+ frame.should have_header("a\nspecial:head\\cer", " padded: and using\nspecial\\\\\\ncharacters ")
286
+ frame.should have_body_encoding('UTF-8')
287
+ end
288
+ it "should properly read a frame with a body and no content-length" do
289
+ @frame_io.string = @messages[:no_content_length]
290
+ frame = @frame_serializer.read_frame
291
+ frame.should have_body("hëllo!", "h\xC3\xABllo!", 'UTF-8')
292
+ frame.should have_body_encoding('UTF-8')
293
+ end
294
+ it "should assume a binary charset if none is set and the content-type does not match text/*" do
295
+ @frame_io.string = @messages[:non_text_content_type]
296
+ frame = @frame_serializer.read_frame
297
+ frame.should have_body_encoding('ASCII-8BIT')
298
+ end
299
+ it "should assume a binary charset if the content-type header is not specified" do
300
+ @frame_io.string = @messages[:no_content_type]
301
+ frame = @frame_serializer.read_frame
302
+ frame.should have_body_encoding('ASCII-8BIT')
303
+ end
304
+ it "should set the value of a header to the first occurrence" do
305
+ @frame_io.string = @messages[:repeated_headers]
306
+ frame = @frame_serializer.read_frame
307
+ frame.should have_header(:'repeated header', 'a value')
308
+ end
309
+ it "should raise a malformed frame error if the frame is not properly terminated" do
310
+ @frame_io.string = @messages[:invalid_content_length]
311
+ lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::MalformedFrameError)
312
+ end
313
+ # While the spec suggests that all ":" chars be replaced with "\c", ActiveMQ 5.3.2 sends
314
+ # a "session" header with a value that contains ":" chars. So, we are NOT going to
315
+ # freak out if we receive more than one ":" on a header line.
316
+ it "should not raise an error if the frame contains a header value with a raw ':'" do
317
+ @frame_io.string = @messages[:invalid_header_character]
318
+ lambda { @frame_serializer.read_frame }.should_not raise_error
319
+ end
320
+ it "should raise an invalid header esacape sequence error if the frame contains a header with an invalid escape sequence" do
321
+ @frame_io.string = @messages[:invalid_header_sequence]
322
+ lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::InvalidHeaderEscapeSequenceError)
323
+ end
324
+ it "should raise an malfored header error if the frame contains an incomplete header" do
325
+ @frame_io.string = @messages[:malformed_header]
326
+ lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::MalformedHeaderError)
327
+ end
328
+ it "should raise an invalid header esacape sequence error if the frame contains a header with a dangling escape sequence" do
329
+ @frame_io.string = @messages[:dangling_header_sequence]
330
+ lambda { @frame_serializer.read_frame }.should raise_error(::Stomper::Errors::InvalidHeaderEscapeSequenceError)
312
331
  end
313
332
  end
314
333
  end
@@ -11,7 +11,6 @@ module Stomper
11
11
  receipt = mock('receipt')
12
12
  @connection.should_receive(:on_message)
13
13
  @connection.should_receive(:on_unsubscribe)
14
- @connection.should_receive(:on_connection_closed)
15
14
  @subscription_manager = SubscriptionManager.new(@connection)
16
15
  end
17
16
 
@@ -49,13 +48,13 @@ module Stomper
49
48
  @subscription_manager.subscriptions.should be_empty
50
49
  end
51
50
 
52
- it "should clear out all remaining subscriptions when the connection is closed" do
51
+ it "should clear out all remaining subscriptions when cleared" do
53
52
  alt_subscribe_frame = ::Stomper::Frame.new('SUBSCRIBE', {:id => '4567', :destination => '/queue/test_further'})
54
53
  @subscription_manager.add(@subscribe_frame, lambda { |m| true })
55
54
  @subscription_manager.add(alt_subscribe_frame, lambda { |m| true })
56
55
  @subscription_manager.remove('4567')
57
56
  @subscription_manager.subscriptions.map { |s| s.id }.should == ['1234']
58
- @connection.__send__(:trigger_event, :on_connection_closed, @connection)
57
+ @subscription_manager.clear
59
58
  @subscription_manager.subscriptions.should be_empty
60
59
  end
61
60