/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_rio.py

  • Committer: Jelmer Vernooij
  • Date: 2020-08-22 22:46:24 UTC
  • mfrom: (7490.40.105 work)
  • mto: This revision was merged to the branch mainline in revision 7521.
  • Revision ID: jelmer@jelmer.uk-20200822224624-om4a4idsr7cn8jew
merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2016 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
22
22
but this depends on the transport.
23
23
"""
24
24
 
25
 
import cStringIO
26
 
import os
27
25
import re
28
 
import sys
29
26
from tempfile import TemporaryFile
30
27
 
31
 
from bzrlib import (
 
28
from breezy import (
32
29
    rio,
33
30
    )
34
 
from bzrlib.tests import TestCaseInTempDir, TestCase
35
 
from bzrlib.rio import (RioWriter, Stanza, read_stanza, read_stanzas, rio_file,
36
 
                        RioReader)
 
31
from breezy.tests import TestCase
 
32
from breezy.rio import (
 
33
    RioReader,
 
34
    Stanza,
 
35
    read_stanza,
 
36
    read_stanzas,
 
37
    rio_file,
 
38
    )
37
39
 
38
40
 
39
41
class TestRio(TestCase):
44
46
        self.assertTrue('number' in s)
45
47
        self.assertFalse('color' in s)
46
48
        self.assertFalse('42' in s)
47
 
        self.assertEquals(list(s.iter_pairs()),
48
 
                [('name', 'fred'), ('number', '42')])
49
 
        self.assertEquals(s.get('number'), '42')
50
 
        self.assertEquals(s.get('name'), 'fred')
51
 
 
52
 
    def test_value_checks(self):
53
 
        """rio checks types on construction"""
54
 
        # these aren't enforced at construction time
55
 
        ## self.assertRaises(ValueError,
56
 
        ##        Stanza, complex=42 + 3j)
57
 
        ## self.assertRaises(ValueError,
58
 
        ##        Stanza, several=range(10))
 
49
        self.assertEqual(list(s.iter_pairs()),
 
50
                         [('name', 'fred'), ('number', '42')])
 
51
        self.assertEqual(s.get('number'), '42')
 
52
        self.assertEqual(s.get('name'), 'fred')
59
53
 
60
54
    def test_empty_value(self):
61
55
        """Serialize stanza with empty field"""
62
56
        s = Stanza(empty='')
63
 
        self.assertEqualDiff(s.to_string(),
64
 
                "empty: \n")
 
57
        self.assertEquals(s.to_string(),
 
58
                          b"empty: \n")
65
59
 
66
60
    def test_to_lines(self):
67
61
        """Write simple rio stanza to string"""
68
62
        s = Stanza(number='42', name='fred')
69
 
        self.assertEquals(list(s.to_lines()),
70
 
                ['name: fred\n',
71
 
                 'number: 42\n'])
 
63
        self.assertEqual(list(s.to_lines()),
 
64
                         [b'name: fred\n',
 
65
                          b'number: 42\n'])
72
66
 
73
67
    def test_as_dict(self):
74
68
        """Convert rio Stanza to dictionary"""
75
69
        s = Stanza(number='42', name='fred')
76
70
        sd = s.as_dict()
77
 
        self.assertEquals(sd, dict(number='42', name='fred'))
 
71
        self.assertEqual(sd, dict(number='42', name='fred'))
78
72
 
79
73
    def test_to_file(self):
80
74
        """Write rio to file"""
81
75
        tmpf = TemporaryFile()
82
 
        s = Stanza(a_thing='something with "quotes like \\"this\\""', number='42', name='fred')
 
76
        s = Stanza(a_thing='something with "quotes like \\"this\\""',
 
77
                   number='42', name='fred')
83
78
        s.write(tmpf)
84
79
        tmpf.seek(0)
85
 
        self.assertEqualDiff(tmpf.read(), r'''
86
 
a_thing: something with "quotes like \"this\""
 
80
        self.assertEqual(tmpf.read(), b'''\
 
81
a_thing: something with "quotes like \\"this\\""
87
82
name: fred
88
83
number: 42
89
 
'''[1:])
 
84
''')
90
85
 
91
86
    def test_multiline_string(self):
92
87
        tmpf = TemporaryFile()
93
 
        s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
 
88
        s = Stanza(
 
89
            motto="war is peace\nfreedom is slavery\nignorance is strength")
94
90
        s.write(tmpf)
95
91
        tmpf.seek(0)
96
 
        self.assertEqualDiff(tmpf.read(), '''\
 
92
        self.assertEqual(tmpf.read(), b'''\
97
93
motto: war is peace
98
94
\tfreedom is slavery
99
95
\tignorance is strength
100
96
''')
101
97
        tmpf.seek(0)
102
98
        s2 = read_stanza(tmpf)
103
 
        self.assertEquals(s, s2)
 
99
        self.assertEqual(s, s2)
104
100
 
105
101
    def test_read_stanza(self):
106
102
        """Load stanza from string"""
107
 
        lines = """\
 
103
        lines = b"""\
108
104
revision: mbp@sourcefrog.net-123-abc
109
105
timestamp: 1130653962
110
106
timezone: 36000
112
108
""".splitlines(True)
113
109
        s = read_stanza(lines)
114
110
        self.assertTrue('revision' in s)
115
 
        self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
116
 
        self.assertEquals(list(s.iter_pairs()),
117
 
                [('revision', 'mbp@sourcefrog.net-123-abc'),
118
 
                 ('timestamp', '1130653962'),
119
 
                 ('timezone', '36000'),
120
 
                 ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
121
 
        self.assertEquals(len(s), 4)
 
111
        self.assertEqual(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
 
112
        self.assertEqual(list(s.iter_pairs()),
 
113
                         [('revision', 'mbp@sourcefrog.net-123-abc'),
 
114
                          ('timestamp', '1130653962'),
 
115
                          ('timezone', '36000'),
 
116
                          ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
 
117
        self.assertEqual(len(s), 4)
122
118
 
123
119
    def test_repeated_field(self):
124
120
        """Repeated field in rio"""
127
123
                     ('a', '1000'), ('b', '2000')]:
128
124
            s.add(k, v)
129
125
        s2 = read_stanza(s.to_lines())
130
 
        self.assertEquals(s, s2)
131
 
        self.assertEquals(s.get_all('a'), map(str, [10, 100, 1000]))
132
 
        self.assertEquals(s.get_all('b'), map(str, [20, 200, 2000]))
 
126
        self.assertEqual(s, s2)
 
127
        self.assertEqual(s.get_all('a'), ['10', '100', '1000'])
 
128
        self.assertEqual(s.get_all('b'), ['20', '200', '2000'])
133
129
 
134
130
    def test_backslash(self):
135
131
        s = Stanza(q='\\')
136
132
        t = s.to_string()
137
 
        self.assertEqualDiff(t, 'q: \\\n')
 
133
        self.assertEqual(t, b'q: \\\n')
138
134
        s2 = read_stanza(s.to_lines())
139
 
        self.assertEquals(s, s2)
 
135
        self.assertEqual(s, s2)
140
136
 
141
137
    def test_blank_line(self):
142
138
        s = Stanza(none='', one='\n', two='\n\n')
143
 
        self.assertEqualDiff(s.to_string(), """\
 
139
        self.assertEqual(s.to_string(), b"""\
144
140
none:\x20
145
141
one:\x20
146
142
\t
149
145
\t
150
146
""")
151
147
        s2 = read_stanza(s.to_lines())
152
 
        self.assertEquals(s, s2)
 
148
        self.assertEqual(s, s2)
153
149
 
154
150
    def test_whitespace_value(self):
155
151
        s = Stanza(space=' ', tabs='\t\t\t', combo='\n\t\t\n')
156
 
        self.assertEqualDiff(s.to_string(), """\
 
152
        self.assertEqual(s.to_string(), b"""\
157
153
combo:\x20
158
154
\t\t\t
159
155
\t
161
157
tabs: \t\t\t
162
158
""")
163
159
        s2 = read_stanza(s.to_lines())
164
 
        self.assertEquals(s, s2)
 
160
        self.assertEqual(s, s2)
165
161
        self.rio_file_stanzas([s])
166
162
 
167
163
    def test_quoted(self):
177
173
                   q9='\\"\\"',
178
174
                   )
179
175
        s2 = read_stanza(s.to_lines())
180
 
        self.assertEquals(s, s2)
 
176
        self.assertEqual(s, s2)
181
177
        # apparent bug in read_stanza
182
178
        # s3 = read_stanza(self.stanzas_to_str([s]))
183
 
        # self.assertEquals(s, s3)
 
179
        # self.assertEqual(s, s3)
184
180
 
185
181
    def test_read_empty(self):
186
182
        """Detect end of rio file"""
188
184
        self.assertEqual(s, None)
189
185
        self.assertTrue(s is None)
190
186
 
 
187
    def test_read_nul_byte(self):
 
188
        """File consisting of a nul byte causes an error."""
 
189
        self.assertRaises(ValueError, read_stanza, [b'\0'])
 
190
 
 
191
    def test_read_nul_bytes(self):
 
192
        """File consisting of many nul bytes causes an error."""
 
193
        self.assertRaises(ValueError, read_stanza, [b'\0' * 100])
 
194
 
191
195
    def test_read_iter(self):
192
196
        """Read several stanzas from file"""
193
197
        tmpf = TemporaryFile()
194
 
        tmpf.write("""\
 
198
        tmpf.write(b"""\
195
199
version_header: 1
196
200
 
197
201
name: foo
205
209
        read_iter = iter(reader)
206
210
        stuff = list(reader)
207
211
        self.assertEqual(stuff,
208
 
                [ Stanza(version_header='1'),
209
 
                  Stanza(name="foo", val='123'),
210
 
                  Stanza(name="bar", val='129319'), ])
 
212
                         [Stanza(version_header='1'),
 
213
                          Stanza(name="foo", val='123'),
 
214
                             Stanza(name="bar", val='129319'), ])
211
215
 
212
216
    def test_read_several(self):
213
217
        """Read several stanzas from file"""
214
218
        tmpf = TemporaryFile()
215
 
        tmpf.write("""\
 
219
        tmpf.write(b"""\
216
220
version_header: 1
217
221
 
218
222
name: foo
228
232
""")
229
233
        tmpf.seek(0)
230
234
        s = read_stanza(tmpf)
231
 
        self.assertEquals(s, Stanza(version_header='1'))
232
 
        s = read_stanza(tmpf)
233
 
        self.assertEquals(s, Stanza(name="foo", val='123'))
234
 
        s = read_stanza(tmpf)
235
 
        self.assertEqualDiff(s.get('name'), 'quoted')
236
 
        self.assertEqualDiff(s.get('address'), '  "Willowglen"\n  42 Wallaby Way\n  Sydney')
237
 
        s = read_stanza(tmpf)
238
 
        self.assertEquals(s, Stanza(name="bar", val='129319'))
239
 
        s = read_stanza(tmpf)
240
 
        self.assertEquals(s, None)
 
235
        self.assertEqual(s, Stanza(version_header='1'))
 
236
        s = read_stanza(tmpf)
 
237
        self.assertEqual(s, Stanza(name="foo", val='123'))
 
238
        s = read_stanza(tmpf)
 
239
        self.assertEqual(s.get('name'), 'quoted')
 
240
        self.assertEqual(
 
241
            s.get('address'), '  "Willowglen"\n  42 Wallaby Way\n  Sydney')
 
242
        s = read_stanza(tmpf)
 
243
        self.assertEqual(s, Stanza(name="bar", val='129319'))
 
244
        s = read_stanza(tmpf)
 
245
        self.assertEqual(s, None)
241
246
        self.check_rio_file(tmpf)
242
247
 
243
248
    def check_rio_file(self, real_file):
244
249
        real_file.seek(0)
245
250
        read_write = rio_file(RioReader(real_file)).read()
246
251
        real_file.seek(0)
247
 
        self.assertEquals(read_write, real_file.read())
 
252
        self.assertEqual(read_write, real_file.read())
248
253
 
249
254
    @staticmethod
250
255
    def stanzas_to_str(stanzas):
256
261
 
257
262
    def test_tricky_quoted(self):
258
263
        tmpf = TemporaryFile()
259
 
        tmpf.write('''\
 
264
        tmpf.write(b'''\
260
265
s: "one"
261
266
 
262
267
s:\x20
290
295
''')
291
296
        tmpf.seek(0)
292
297
        expected_vals = ['"one"',
293
 
            '\n"one"\n',
294
 
            '"',
295
 
            '""',
296
 
            '"""',
297
 
            '\n',
298
 
            '\\',
299
 
            '\n\\\n\\\\\n',
300
 
            'word\\',
301
 
            'quote\"',
302
 
            'backslashes\\\\\\',
303
 
            'both\\\"',
304
 
            ]
 
298
                         '\n"one"\n',
 
299
                         '"',
 
300
                         '""',
 
301
                         '"""',
 
302
                         '\n',
 
303
                         '\\',
 
304
                         '\n\\\n\\\\\n',
 
305
                         'word\\',
 
306
                         'quote\"',
 
307
                         'backslashes\\\\\\',
 
308
                         'both\\\"',
 
309
                         ]
305
310
        for expected in expected_vals:
306
311
            stanza = read_stanza(tmpf)
307
312
            self.rio_file_stanzas([stanza])
308
 
            self.assertEquals(len(stanza), 1)
309
 
            self.assertEqualDiff(stanza.get('s'), expected)
 
313
            self.assertEqual(len(stanza), 1)
 
314
            self.assertEqual(stanza.get('s'), expected)
310
315
 
311
316
    def test_write_empty_stanza(self):
312
317
        """Write empty stanza"""
313
318
        l = list(Stanza().to_lines())
314
 
        self.assertEquals(l, [])
 
319
        self.assertEqual(l, [])
315
320
 
316
321
    def test_rio_raises_type_error(self):
317
322
        """TypeError on adding invalid type to Stanza"""
323
328
        s = Stanza()
324
329
        self.assertRaises(TypeError, s.add, 10, {})
325
330
 
 
331
    def test_rio_surrogateescape(self):
 
332
        raw_bytes = b'\xcb'
 
333
        self.assertRaises(UnicodeDecodeError, raw_bytes.decode, 'utf-8')
 
334
        try:
 
335
            uni_data = raw_bytes.decode('utf-8', 'surrogateescape')
 
336
        except LookupError:
 
337
            self.skipTest('surrogateescape is not available on Python < 3')
 
338
        s = Stanza(foo=uni_data)
 
339
        self.assertEqual(s.get('foo'), uni_data)
 
340
        raw_lines = s.to_lines()
 
341
        self.assertEqual(raw_lines,
 
342
                         [b'foo: ' + uni_data.encode('utf-8', 'surrogateescape') + b'\n'])
 
343
        new_s = read_stanza(raw_lines)
 
344
        self.assertEqual(new_s.get('foo'), uni_data)
 
345
 
326
346
    def test_rio_unicode(self):
327
347
        uni_data = u'\N{KATAKANA LETTER O}'
328
348
        s = Stanza(foo=uni_data)
329
 
        self.assertEquals(s.get('foo'), uni_data)
 
349
        self.assertEqual(s.get('foo'), uni_data)
330
350
        raw_lines = s.to_lines()
331
 
        self.assertEquals(raw_lines,
332
 
                ['foo: ' + uni_data.encode('utf-8') + '\n'])
 
351
        self.assertEqual(raw_lines,
 
352
                         [b'foo: ' + uni_data.encode('utf-8') + b'\n'])
333
353
        new_s = read_stanza(raw_lines)
334
 
        self.assertEquals(new_s.get('foo'), uni_data)
 
354
        self.assertEqual(new_s.get('foo'), uni_data)
335
355
 
336
356
    def test_rio_to_unicode(self):
337
357
        uni_data = u'\N{KATAKANA LETTER O}'
346
366
        s = Stanza(foo=uni_data)
347
367
        parent_stanza = Stanza(child=s.to_unicode())
348
368
        raw_lines = parent_stanza.to_lines()
349
 
        self.assertEqual(['child: foo: ' + uni_data.encode('utf-8') + '\n',
350
 
                          '\t\n',
351
 
                         ], raw_lines)
 
369
        self.assertEqual([b'child: foo: ' + uni_data.encode('utf-8') + b'\n',
 
370
                          b'\t\n',
 
371
                          ], raw_lines)
352
372
        new_parent = read_stanza(raw_lines)
353
373
        child_text = new_parent.get('child')
354
374
        self.assertEqual(u'foo: %s\n' % uni_data, child_text)
358
378
    def mail_munge(self, lines, dos_nl=True):
359
379
        new_lines = []
360
380
        for line in lines:
361
 
            line = re.sub(' *\n', '\n', line)
 
381
            line = re.sub(b' *\n', b'\n', line)
362
382
            if dos_nl:
363
 
                line = re.sub('([^\r])\n', '\\1\r\n', line)
 
383
                line = re.sub(b'([^\r])\n', b'\\1\r\n', line)
364
384
            new_lines.append(line)
365
385
        return new_lines
366
386
 
368
388
        stanza = Stanza(data='#\n\r\\r ', space=' ' * 255, hash='#' * 255)
369
389
        lines = rio.to_patch_lines(stanza)
370
390
        for line in lines:
371
 
            self.assertContainsRe(line, '^# ')
 
391
            self.assertContainsRe(line, b'^# ')
372
392
            self.assertTrue(72 >= len(line))
373
393
        for line in rio.to_patch_lines(stanza, max_width=12):
374
394
            self.assertTrue(12 >= len(line))
377
397
        lines = self.mail_munge(lines)
378
398
        new_stanza = rio.read_patch_stanza(lines)
379
399
        self.assertEqual('#\n\r\\r ', new_stanza.get('data'))
380
 
        self.assertEqual(' '* 255, new_stanza.get('space'))
381
 
        self.assertEqual('#'* 255, new_stanza.get('hash'))
 
400
        self.assertEqual(' ' * 255, new_stanza.get('space'))
 
401
        self.assertEqual('#' * 255, new_stanza.get('hash'))
382
402
 
383
403
    def test_patch_rio_linebreaks(self):
384
 
        stanza = Stanza(breaktest='linebreak -/'*30)
 
404
        stanza = Stanza(breaktest='linebreak -/' * 30)
385
405
        self.assertContainsRe(rio.to_patch_lines(stanza, 71)[0],
386
 
                              'linebreak\\\\\n')
387
 
        stanza = Stanza(breaktest='linebreak-/'*30)
388
 
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
389
 
                              'linebreak-\\\\\n')
390
 
        stanza = Stanza(breaktest='linebreak/'*30)
391
 
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
392
 
                              'linebreak\\\\\n')
 
406
                              b'linebreak\\\\\n')
 
407
        stanza = Stanza(breaktest='linebreak-/' * 30)
 
408
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
 
409
                              b'linebreak-\\\\\n')
 
410
        stanza = Stanza(breaktest='linebreak/' * 30)
 
411
        self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
 
412
                              b'linebreak\\\\\n')