root/trunk/tests/test_ltp2.rb

Revision 725, 7.5 kB (checked in by francis, 1 year ago)

Fixed bug in set_text_mode which made it break when called inside receive_binary_data.

  • Property svn:keywords set to Id
Line 
1 # $Id$
2 #
3 # Author:: Francis Cianfrocca (gmail: blackhedd)
4 # Homepage::  http://rubyeventmachine.com
5 # Date:: 8 April 2006
6 #
7 # See EventMachine and EventMachine::Connection for documentation and
8 # usage examples.
9 #
10 #----------------------------------------------------------------------------
11 #
12 # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13 # Gmail: blackhedd
14 #
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of either: 1) the GNU General Public License
17 # as published by the Free Software Foundation; either version 2 of the
18 # License, or (at your option) any later version; or 2) Ruby's License.
19 #
20 # See the file COPYING for complete licensing information.
21 #
22 #---------------------------------------------------------------------------
23 #
24 #
25 #
26 #
27
28 $:.unshift "../lib"
29 require 'eventmachine'
30 require 'test/unit'
31
32 # TODO!!! Need tests for overlength headers and text bodies.
33
34 class TestLineText2 < Test::Unit::TestCase
35
36         # Run each of these tests two ways: passing in the whole test-dataset in one chunk,
37         # and passing it in one character at a time.
38
39         class Basic
40                 include EM::Protocols::LineText2
41                 attr_reader :lines
42                 def receive_line line
43                         (@lines ||= []) << line
44                 end
45         end
46         def test_basic
47                 testdata = "Line 1\nLine 2\r\nLine 3\n"
48
49                 a = Basic.new
50                 a.receive_data testdata
51                 assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
52
53                 a = Basic.new
54                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
55                 assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
56         end
57
58
59         class ChangeDelimiter
60                 include EM::Protocols::LineText2
61                 attr_reader :lines
62                 def initialize *args
63                         super
64                         @delim = "A"
65                         set_delimiter @delim
66                 end
67                 def receive_line line
68                         (@lines ||= []) << line
69                         set_delimiter( @delim.succ! )
70                 end
71         end
72
73         def test_change_delimiter
74                 testdata = %Q(LineaALinebBLinecCLinedD)
75
76                 a = ChangeDelimiter.new
77                 a.receive_data testdata
78                 assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
79
80                 a = ChangeDelimiter.new
81                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
82                 assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines )
83         end
84
85
86         #--
87         # Test two lines followed by an empty line, ten bytes of binary data, then
88         # two more lines.
89
90         class Binary
91                 include EM::Protocols::LineText2
92                 attr_reader :lines, :body
93                 def initialize *args
94                         super
95                         @lines = []
96                         @body = nil
97                 end
98                 def receive_line ln
99                         if ln == ""
100                                 set_text_mode 10
101                         else
102                                 @lines << ln
103                         end
104                 end
105                 def receive_binary_data data
106                         @body = data
107                 end
108         end
109
110         def test_binary
111                 testdata = %Q(Line 1
112 Line 2
113
114 0000000000Line 3
115 Line 4
116 )
117
118                 a = Binary.new
119                 a.receive_data testdata
120                 assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
121                 assert_equal( "0000000000", a.body )
122
123                 a = Binary.new
124                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
125                 assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines)
126                 assert_equal( "0000000000", a.body )
127         end
128
129
130         # Test unsized binary data. The expectation is that each chunk of it
131         # will be passed to us as it it received.
132         class UnsizedBinary
133                 include EM::Protocols::LineText2
134                 attr_reader :n_calls, :body
135                 def initialize *args
136                         super
137                         set_text_mode
138                 end
139                 def receive_binary_data data
140                         @n_calls ||= 0
141                         @n_calls += 1
142                         (@body ||= "") << data
143                 end
144         end
145
146         def test_unsized_binary
147                 testdata = "X\0" * 1000
148
149                 a = UnsizedBinary.new
150                 a.receive_data testdata
151                 assert_equal( 1, a.n_calls )
152                 assert_equal( testdata, a.body )
153
154                 a = UnsizedBinary.new
155                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
156                 assert_equal( 2000, a.n_calls )
157                 assert_equal( testdata, a.body )
158         end
159
160
161         # Test binary data with a "throw back" into line-mode.
162         class ThrowBack
163                 include EM::Protocols::LineText2
164                 attr_reader :headers
165                 def initialize *args
166                         super
167                         @headers = []
168                         @n_bytes = 0
169                         set_text_mode
170                 end
171                 def receive_binary_data data
172                         wanted = 25 - @n_bytes
173                         will_take = if data.length > wanted
174                                 data.length - wanted
175                         else
176                                 data.length
177                         end
178                         @n_bytes += will_take
179
180                         if @n_bytes == 25
181                                 set_line_mode( data[will_take..-1] )
182                         end
183                 end
184                 def receive_line ln
185                         @headers << ln
186                 end
187         end
188         def test_throw_back
189                 testdata = "Line\n" * 10
190
191                 a = ThrowBack.new
192                 a.receive_data testdata
193                 assert_equal( ["Line"] * 5, a.headers )
194
195                 a = ThrowBack.new
196                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
197                 assert_equal( ["Line"] * 5, a.headers )
198         end
199
200         # Test multi-character line delimiters.
201         # Also note that the test data has a "tail" with no delimiter, that will be
202         # discarded, but cf. the BinaryTail test.
203         # TODO!!! This test doesn't work in the byte-by-byte case.
204         class Multichar
205                 include EM::Protocols::LineText2
206                 attr_reader :lines
207                 def initialize *args
208                         super
209                         @lines = []
210                         set_delimiter "012"
211                 end
212                 def receive_line ln
213                         @lines << ln
214                 end
215         end
216         def test_multichar
217                 testdata = "Line012Line012Line012Line"
218
219                 a = Multichar.new
220                 a.receive_data testdata
221                 assert_equal( ["Line"]*3, a.lines )
222
223                 a = Multichar.new
224                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
225                 # DOESN'T WORK in this case. Multi-character delimiters are broken.
226                 #assert_equal( ["Line"]*3, a.lines )
227         end
228
229         # Test a binary "tail," when a sized binary transfer doesn't complete because
230         # of an unbind. We get a partial result.
231         class BinaryTail
232                 include EM::Protocols::LineText2
233                 attr_reader :data
234                 def initialize *args
235                         super
236                         @data = ""
237                         set_text_mode 1000
238                 end
239                 def receive_binary_data data
240                         # we expect to get all the data in one chunk, even in the byte-by-byte case,
241                         # because sized transfers by definition give us exactly one call to
242                         # #receive_binary_data.
243                         @data = data
244                 end
245         end
246         def test_binary_tail
247                 testdata = "0" * 500
248
249                 a = BinaryTail.new
250                 a.receive_data testdata
251                 a.unbind
252                 assert_equal( "0" * 500, a.data )
253
254                 a = BinaryTail.new
255                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
256                 a.unbind
257                 assert_equal( "0" * 500, a.data )
258         end
259
260
261
262         # Test an end-of-binary call. Arrange to receive binary data but don't bother counting it
263         # as it comes. Rely on getting receive_end_of_binary_data to signal the transition back to
264         # line mode.
265         # At the present time, this isn't strictly necessary with sized binary chunks because by
266         # definition we accumulate them and make exactly one call to receive_binary_data, but
267         # we may want to support a mode in the future that would break up large chunks into multiple
268         # calls.
269         class LazyBinary
270                 include EM::Protocols::LineText2
271                 attr_reader :data, :end
272                 def initialize *args
273                         super
274                         @data = ""
275                         set_text_mode 1000
276                 end
277                 def receive_binary_data data
278                         # we expect to get all the data in one chunk, even in the byte-by-byte case,
279                         # because sized transfers by definition give us exactly one call to
280                         # #receive_binary_data.
281                         @data = data
282                 end
283                 def receive_end_of_binary_data
284                         @end = true
285                 end
286         end
287         def test_receive_end_of_binary_data
288                 testdata = "_" * 1000
289                 a = LazyBinary.new
290                 testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) }
291                 assert_equal( "_" * 1000, a.data )
292                 assert( a.end )
293         end
294
295
296         # This tests a bug fix in which calling set_text_mode failed when called
297         # inside receive_binary_data.
298         #
299         class BinaryPair
300                 include EM::Protocols::LineText2
301                 attr_reader :sizes
302                 def initialize *args
303                         super
304                         set_text_mode 1
305                         @sizes = []
306                 end
307                 def receive_binary_data dt
308                         @sizes <<  dt.length
309                         set_text_mode( (dt.length == 1) ? 2 : 1 )
310                 end
311         end
312         def test_binary_pairs
313                 test_data = "123" * 5
314                 a = BinaryPair.new
315                 a.receive_data test_data
316                 assert_equal( [1,2,1,2,1,2,1,2,1,2], a.sizes )
317         end
318
319 end
320
Note: See TracBrowser for help on using the browser.