~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_rio.py

(vila) Calling super() instead of mentioning the base class in setUp avoid
 mistakes. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for rio serialization
18
18
 
22
22
but this depends on the transport.
23
23
"""
24
24
 
25
 
import cStringIO
26
 
import os
27
 
import sys
 
25
import re
28
26
from tempfile import TemporaryFile
29
27
 
30
 
from bzrlib.tests import TestCaseInTempDir, TestCase
31
 
from bzrlib.rio import RioWriter, Stanza, read_stanza, read_stanzas
 
28
from bzrlib import (
 
29
    rio,
 
30
    )
 
31
from bzrlib.tests import TestCase
 
32
from bzrlib.rio import (
 
33
    RioReader,
 
34
    Stanza,
 
35
    read_stanza,
 
36
    read_stanzas,
 
37
    rio_file,
 
38
    )
32
39
 
33
40
 
34
41
class TestRio(TestCase):
49
56
        # these aren't enforced at construction time
50
57
        ## self.assertRaises(ValueError,
51
58
        ##        Stanza, complex=42 + 3j)
52
 
        ## self.assertRaises(ValueError, 
 
59
        ## self.assertRaises(ValueError,
53
60
        ##        Stanza, several=range(10))
54
61
 
55
62
    def test_empty_value(self):
118
125
    def test_repeated_field(self):
119
126
        """Repeated field in rio"""
120
127
        s = Stanza()
121
 
        for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'), 
 
128
        for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'),
122
129
                     ('a', '1000'), ('b', '2000')]:
123
130
            s.add(k, v)
124
131
        s2 = read_stanza(s.to_lines())
136
143
    def test_blank_line(self):
137
144
        s = Stanza(none='', one='\n', two='\n\n')
138
145
        self.assertEqualDiff(s.to_string(), """\
139
 
none: 
140
 
one: 
 
146
none:\x20
 
147
one:\x20
141
148
\t
142
 
two: 
 
149
two:\x20
143
150
\t
144
151
\t
145
152
""")
149
156
    def test_whitespace_value(self):
150
157
        s = Stanza(space=' ', tabs='\t\t\t', combo='\n\t\t\n')
151
158
        self.assertEqualDiff(s.to_string(), """\
152
 
combo: 
 
159
combo:\x20
153
160
\t\t\t
154
161
\t
155
 
space:  
 
162
space:\x20\x20
156
163
tabs: \t\t\t
157
164
""")
158
165
        s2 = read_stanza(s.to_lines())
159
166
        self.assertEquals(s, s2)
 
167
        self.rio_file_stanzas([s])
160
168
 
161
169
    def test_quoted(self):
162
170
        """rio quoted string cases"""
163
 
        s = Stanza(q1='"hello"', 
164
 
                   q2=' "for', 
 
171
        s = Stanza(q1='"hello"',
 
172
                   q2=' "for',
165
173
                   q3='\n\n"for"\n',
166
174
                   q4='for\n"\nfor',
167
175
                   q5='\n',
168
 
                   q6='"', 
 
176
                   q6='"',
169
177
                   q7='""',
170
178
                   q8='\\',
171
179
                   q9='\\"\\"',
172
180
                   )
173
181
        s2 = read_stanza(s.to_lines())
174
182
        self.assertEquals(s, s2)
 
183
        # apparent bug in read_stanza
 
184
        # s3 = read_stanza(self.stanzas_to_str([s]))
 
185
        # self.assertEquals(s, s3)
175
186
 
176
187
    def test_read_empty(self):
177
188
        """Detect end of rio file"""
178
189
        s = read_stanza([])
179
190
        self.assertEqual(s, None)
180
191
        self.assertTrue(s is None)
181
 
        
 
192
 
 
193
    def test_read_nul_byte(self):
 
194
        """File consisting of a nul byte causes an error."""
 
195
        self.assertRaises(ValueError, read_stanza, ['\0'])
 
196
 
 
197
    def test_read_nul_bytes(self):
 
198
        """File consisting of many nul bytes causes an error."""
 
199
        self.assertRaises(ValueError, read_stanza, ['\0' * 100])
 
200
 
182
201
    def test_read_iter(self):
183
202
        """Read several stanzas from file"""
184
203
        tmpf = TemporaryFile()
195
214
        reader = read_stanzas(tmpf)
196
215
        read_iter = iter(reader)
197
216
        stuff = list(reader)
198
 
        self.assertEqual(stuff, 
 
217
        self.assertEqual(stuff,
199
218
                [ Stanza(version_header='1'),
200
219
                  Stanza(name="foo", val='123'),
201
220
                  Stanza(name="bar", val='129319'), ])
229
248
        self.assertEquals(s, Stanza(name="bar", val='129319'))
230
249
        s = read_stanza(tmpf)
231
250
        self.assertEquals(s, None)
 
251
        self.check_rio_file(tmpf)
 
252
 
 
253
    def check_rio_file(self, real_file):
 
254
        real_file.seek(0)
 
255
        read_write = rio_file(RioReader(real_file)).read()
 
256
        real_file.seek(0)
 
257
        self.assertEquals(read_write, real_file.read())
 
258
 
 
259
    @staticmethod
 
260
    def stanzas_to_str(stanzas):
 
261
        return rio_file(stanzas).read()
 
262
 
 
263
    def rio_file_stanzas(self, stanzas):
 
264
        new_stanzas = list(RioReader(rio_file(stanzas)))
 
265
        self.assertEqual(new_stanzas, stanzas)
232
266
 
233
267
    def test_tricky_quoted(self):
234
268
        tmpf = TemporaryFile()
235
269
        tmpf.write('''\
236
270
s: "one"
237
271
 
238
 
s: 
 
272
s:\x20
239
273
\t"one"
240
274
\t
241
275
 
245
279
 
246
280
s: """
247
281
 
248
 
s: 
 
282
s:\x20
249
283
\t
250
284
 
251
285
s: \\
252
286
 
253
 
s: 
 
287
s:\x20
254
288
\t\\
255
289
\t\\\\
256
290
\t
280
314
            ]
281
315
        for expected in expected_vals:
282
316
            stanza = read_stanza(tmpf)
 
317
            self.rio_file_stanzas([stanza])
283
318
            self.assertEquals(len(stanza), 1)
284
319
            self.assertEqualDiff(stanza.get('s'), expected)
285
320
 
299
334
        self.assertRaises(TypeError, s.add, 10, {})
300
335
 
301
336
    def test_rio_unicode(self):
302
 
        # intentionally use cStringIO which doesn't accomodate unencoded unicode objects
303
 
        sio = cStringIO.StringIO()
304
337
        uni_data = u'\N{KATAKANA LETTER O}'
305
338
        s = Stanza(foo=uni_data)
306
339
        self.assertEquals(s.get('foo'), uni_data)
310
343
        new_s = read_stanza(raw_lines)
311
344
        self.assertEquals(new_s.get('foo'), uni_data)
312
345
 
 
346
    def test_rio_to_unicode(self):
 
347
        uni_data = u'\N{KATAKANA LETTER O}'
 
348
        s = Stanza(foo=uni_data)
 
349
        unicode_str = s.to_unicode()
 
350
        self.assertEqual(u'foo: %s\n' % (uni_data,), unicode_str)
 
351
        new_s = rio.read_stanza_unicode(unicode_str.splitlines(True))
 
352
        self.assertEqual(uni_data, new_s.get('foo'))
 
353
 
 
354
    def test_nested_rio_unicode(self):
 
355
        uni_data = u'\N{KATAKANA LETTER O}'
 
356
        s = Stanza(foo=uni_data)
 
357
        parent_stanza = Stanza(child=s.to_unicode())
 
358
        raw_lines = parent_stanza.to_lines()
 
359
        self.assertEqual(['child: foo: ' + uni_data.encode('utf-8') + '\n',
 
360
                          '\t\n',
 
361
                         ], raw_lines)
 
362
        new_parent = read_stanza(raw_lines)
 
363
        child_text = new_parent.get('child')
 
364
        self.assertEqual(u'foo: %s\n' % uni_data, child_text)
 
365
        new_child = rio.read_stanza_unicode(child_text.splitlines(True))
 
366
        self.assertEqual(uni_data, new_child.get('foo'))
 
367
 
 
368
    def mail_munge(self, lines, dos_nl=True):
 
369
        new_lines = []
 
370
        for line in lines:
 
371
            line = re.sub(' *\n', '\n', line)
 
372
            if dos_nl:
 
373
                line = re.sub('([^\r])\n', '\\1\r\n', line)
 
374
            new_lines.append(line)
 
375
        return new_lines
 
376
 
 
377
    def test_patch_rio(self):
 
378
        stanza = Stanza(data='#\n\r\\r ', space=' ' * 255, hash='#' * 255)
 
379
        lines = rio.to_patch_lines(stanza)
 
380
        for line in lines:
 
381
            self.assertContainsRe(line, '^# ')
 
382
            self.assertTrue(72 >= len(line))
 
383
        for line in rio.to_patch_lines(stanza, max_width=12):
 
384
            self.assertTrue(12 >= len(line))
 
385
        new_stanza = rio.read_patch_stanza(self.mail_munge(lines,
 
386
                                                           dos_nl=False))
 
387
        lines = self.mail_munge(lines)
 
388
        new_stanza = rio.read_patch_stanza(lines)
 
389
        self.assertEqual('#\n\r\\r ', new_stanza.get('data'))
 
390
        self.assertEqual(' '* 255, new_stanza.get('space'))
 
391
        self.assertEqual('#'* 255, new_stanza.get('hash'))
 
392
 
 
393
    def test_patch_rio_linebreaks(self):
 
394
        stanza = Stanza(breaktest='linebreak -/'*30)
 
395
        self.assertContainsRe(rio.to_patch_lines(stanza, 71)[0],
 
396
                              'linebreak\\\\\n')
 
397
        stanza = Stanza(breaktest='linebreak-/'*30)
 
398
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
 
399
                              'linebreak-\\\\\n')
 
400
        stanza = Stanza(breaktest='linebreak/'*30)
 
401
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
 
402
                              'linebreak\\\\\n')