~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_basicio.py

Merge from mbp.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
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
16
 
 
17
 
"""Tests for basic_io serialization
18
 
 
19
 
A simple, reproducible structured IO format.
20
 
 
21
 
basic_io itself works in Unicode strings.  It is typically encoded to UTF-8,
22
 
but this depends on the transport.
23
 
"""
24
 
 
25
 
import os
26
 
import sys
27
 
from tempfile import TemporaryFile
28
 
 
29
 
from bzrlib.tests import TestCaseInTempDir, TestCase
30
 
from bzrlib.basicio import BasicWriter, Stanza, read_stanza, read_stanzas
31
 
 
32
 
 
33
 
class TestBasicIO(TestCase):
34
 
 
35
 
    def test_stanza(self):
36
 
        """Construct basic_io stanza in memory"""
37
 
        s = Stanza(number=42, name="fred")
38
 
        self.assertTrue('number' in s)
39
 
        self.assertFalse('color' in s)
40
 
        self.assertFalse(42 in s)
41
 
        self.assertEquals(list(s.iter_pairs()),
42
 
                [('name', 'fred'), ('number', 42)])
43
 
        self.assertEquals(s.get('number'), 42)
44
 
        self.assertEquals(s.get('name'), 'fred')
45
 
 
46
 
    def test_value_checks(self):
47
 
        """basic_io checks types on construction"""
48
 
        # these aren't enforced at construction time
49
 
        ## self.assertRaises(ValueError,
50
 
        ##        Stanza, complex=42 + 3j)
51
 
        ## self.assertRaises(ValueError, 
52
 
        ##        Stanza, several=range(10))
53
 
 
54
 
    def test_to_lines(self):
55
 
        """Write simple basic_io stanza to string"""
56
 
        s = Stanza(number=42, name='fred')
57
 
        self.assertEquals(list(s.to_lines()),
58
 
                ['  name "fred"\n',
59
 
                 'number 42\n'])
60
 
 
61
 
    def test_to_file(self):
62
 
        """Write basic_io to file"""
63
 
        tmpf = TemporaryFile()
64
 
        s = Stanza(a_thing='something with "quotes like \\"this\\""', number=42, name='fred')
65
 
        s.write(tmpf)
66
 
        tmpf.seek(0)
67
 
        self.assertEqualDiff(tmpf.read(), r'''
68
 
a_thing "something with \"quotes like \\\"this\\\"\""
69
 
   name "fred"
70
 
 number 42
71
 
'''[1:])
72
 
 
73
 
    def test_multiline_string(self):
74
 
        """Write basic_io with multiline string"""
75
 
        tmpf = TemporaryFile()
76
 
        s = Stanza(a=123, motto="war is peace\nfreedom is slavery\nignorance is strength\n",
77
 
                   charlie_horse=456)
78
 
        s.write(tmpf)
79
 
        tmp.seek(0)
80
 
        self.assertEqualDiff(tmpf.read(), r'''\
81
 
            a 123
82
 
        motto "war is peace
83
 
freedom is slavery
84
 
ignorance is strength
85
 
"
86
 
charlie_horse 456
87
 
''')
88
 
 
89
 
    def test_multiline_string(self):
90
 
        tmpf = TemporaryFile()
91
 
        s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
92
 
        s.write(tmpf)
93
 
        tmpf.seek(0)
94
 
        self.assertEqualDiff(tmpf.read(), '''\
95
 
motto "war is peace
96
 
freedom is slavery
97
 
ignorance is strength"
98
 
''')
99
 
        tmpf.seek(0)
100
 
        s2 = read_stanza(tmpf)
101
 
        self.assertEquals(s, s2)
102
 
 
103
 
    def test_read_stanza(self):
104
 
        """Load stanza from string"""
105
 
        lines = """\
106
 
 revision "mbp@sourcefrog.net-123-abc"
107
 
timestamp 1130653962
108
 
 timezone 36000
109
 
committer "Martin Pool <mbp@test.sourcefrog.net>"
110
 
""".splitlines(True)
111
 
        s = read_stanza(lines)
112
 
        self.assertTrue('revision' in s)
113
 
        self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
114
 
        self.assertEquals(list(s.iter_pairs()),
115
 
                [('revision', 'mbp@sourcefrog.net-123-abc'),
116
 
                 ('timestamp', 1130653962),
117
 
                 ('timezone', 36000),
118
 
                 ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
119
 
        self.assertEquals(len(s), 4)
120
 
 
121
 
    def test_repeated_field(self):
122
 
        """Repeated field in basic_io"""
123
 
        s = Stanza()
124
 
        for k, v in [('a', 10), ('b', 20), ('a', 100), ('b', 200), ('a', 1000), ('b', 2000)]:
125
 
            s.add(k, v)
126
 
        s2 = read_stanza(s.to_lines())
127
 
        self.assertEquals(s, s2)
128
 
        self.assertEquals(s.get_all('a'), [10, 100, 1000])
129
 
        self.assertEquals(s.get_all('b'), [20, 200, 2000])
130
 
 
131
 
    def test_longint(self):
132
 
        """basic_io packing long integers"""
133
 
        s = Stanza(x=-12345678901234567890,
134
 
                   y=1<<100)
135
 
        lines = s.to_lines()
136
 
        s2 = read_stanza(lines)
137
 
        self.assertEquals(s, s2)
138
 
 
139
 
    def test_quoted_0(self):
140
 
        """Backslash quoted cases"""
141
 
        s = Stanza(q='\\')
142
 
        t = s.to_string()
143
 
        self.assertEqualDiff(t, 'q "\\\\"\n')
144
 
        s2 = read_stanza(s.to_lines())
145
 
        self.assertEquals(s, s2)
146
 
 
147
 
    def test_quoted_1(self):
148
 
        """Backslash quoted cases"""
149
 
        s = Stanza(q=r'\"\"')
150
 
        self.assertEqualDiff(s.to_string(), r'q "\\\"\\\""' + '\n')
151
 
 
152
 
    def test_quoted_4(self):
153
 
        s = Stanza(q=r'""""')
154
 
        t = s.to_string()
155
 
        self.assertEqualDiff(t, r'q "\"\"\"\""' + '\n')
156
 
        s2 = read_stanza(s.to_lines())
157
 
        self.assertEquals(s, s2)
158
 
 
159
 
    def test_quoted_5(self):
160
 
        s = Stanza(q=r'\\\\\"')
161
 
        t = s.to_string()
162
 
        s2 = read_stanza(s.to_lines())
163
 
        self.assertEquals(s, s2)
164
 
 
165
 
    def test_quoted_6(self):
166
 
        qval = r'''
167
 
                "
168
 
                \"
169
 
'''
170
 
        s = Stanza(q=qval)
171
 
        t = s.to_string()
172
 
        self.log(t)
173
 
        s2 = read_stanza(s.to_lines())
174
 
        self.assertEquals(s2['q'], qval)
175
 
        
176
 
    def test_quoted_7(self):
177
 
        qval = r'''
178
 
                "
179
 
                \"
180
 
                \\"
181
 
trailing stuff'''
182
 
        s = Stanza(q=qval)
183
 
        t = s.to_string()
184
 
        self.log(t)
185
 
        s2 = read_stanza(s.to_lines())
186
 
        self.assertEquals(s2['q'], qval)
187
 
        
188
 
    def test_quoted_8(self):
189
 
        qval = r'''trailing
190
 
        quote"'''
191
 
        s = Stanza(q=qval)
192
 
        t = s.to_string()
193
 
        self.log(t)
194
 
        s2 = read_stanza(s.to_lines())
195
 
        self.assertEquals(s2['q'], qval)
196
 
        
197
 
    def test_quoted(self):
198
 
        """basic_io quoted string cases"""
199
 
        s = Stanza(q1='"hello"', 
200
 
                   q2=' "for', 
201
 
                   q3='\n\n"for"\n',
202
 
                   q4='for\n"\nfor',
203
 
                   q5='\n',
204
 
                   q6='"', 
205
 
                   q7='""',
206
 
                   q8='\\',
207
 
                   q9='\\"\\"',
208
 
                   )
209
 
        s2 = read_stanza(s.to_lines())
210
 
        self.assertEquals(s, s2)
211
 
 
212
 
    def test_read_empty(self):
213
 
        """Detect end of basic_io file"""
214
 
        s = read_stanza([])
215
 
        self.assertEqual(s, None)
216
 
        self.assertTrue(s is None)
217
 
        
218
 
    def test_read_iter(self):
219
 
        """Read several stanzas from file"""
220
 
        tmpf = TemporaryFile()
221
 
        tmpf.write("""\
222
 
version_header 1
223
 
 
224
 
name "foo"
225
 
val 123
226
 
 
227
 
name "bar"
228
 
val 129319
229
 
""")
230
 
        tmpf.seek(0)
231
 
        reader = read_stanzas(tmpf)
232
 
        read_iter = iter(reader)
233
 
        stuff = list(reader)
234
 
        self.assertEqual(stuff, 
235
 
                [ Stanza(version_header=1),
236
 
                  Stanza(name="foo", val=123),
237
 
                  Stanza(name="bar", val=129319), ])
238
 
 
239
 
    def test_read_several(self):
240
 
        """Read several stanzas from file"""
241
 
        tmpf = TemporaryFile()
242
 
        tmpf.write("""\
243
 
version_header 1
244
 
 
245
 
name "foo"
246
 
val 123
247
 
 
248
 
name "quoted"
249
 
address "  \\"Willowglen\\"
250
 
  42 Wallaby Way
251
 
  Sydney"
252
 
 
253
 
name "bar"
254
 
val 129319
255
 
""")
256
 
        tmpf.seek(0)
257
 
        s = read_stanza(tmpf)
258
 
        self.assertEquals(s, Stanza(version_header=1))
259
 
        s = read_stanza(tmpf)
260
 
        self.assertEquals(s, Stanza(name="foo", val=123))
261
 
        s = read_stanza(tmpf)
262
 
        self.assertEqualDiff(s.get('name'), 'quoted')
263
 
        self.assertEqualDiff(s.get('address'), '  "Willowglen"\n  42 Wallaby Way\n  Sydney')
264
 
        s = read_stanza(tmpf)
265
 
        self.assertEquals(s, Stanza(name="bar", val=129319))
266
 
        s = read_stanza(tmpf)
267
 
        self.assertEquals(s, None)
268
 
 
269
 
    def test_tricky_quoted(self):
270
 
        tmpf = TemporaryFile()
271
 
        tmpf.write(r"""
272
 
s "\"one\""
273
 
 
274
 
s "
275
 
\"one\"
276
 
"
277
 
 
278
 
s "\""
279
 
 
280
 
s "\"\""
281
 
 
282
 
s "\"\"\""
283
 
 
284
 
s "
285
 
"
286
 
 
287
 
s "\\"
288
 
 
289
 
s "
290
 
\\
291
 
\\\\
292
 
"
293
 
 
294
 
s "word\\"
295
 
 
296
 
s "quote\""
297
 
 
298
 
s "backslashes\\\\\\"
299
 
 
300
 
s "both\\\""
301
 
 
302
 
"""[1:]) # remove initial newline
303
 
        tmpf.seek(0)
304
 
        expected_vals = ['"one"',
305
 
            '\n"one"\n',
306
 
            '"',
307
 
            '""',
308
 
            '"""',
309
 
            '\n',
310
 
            '\\',
311
 
            '\n\\\n\\\\\n',
312
 
            'word\\',
313
 
            'quote\"',
314
 
            'backslashes\\\\\\',
315
 
            'both\\\"',
316
 
            ]
317
 
        for expected in expected_vals:
318
 
            stanza = read_stanza(tmpf)
319
 
            self.assertEquals(len(stanza), 1)
320
 
            self.assertEqualDiff(stanza.get('s'), expected)
321
 
 
322
 
    def test_write_bool(self):
323
 
        """Write bool to basic_io"""
324
 
        l = list(Stanza(my_bool=True).to_lines())
325
 
        self.assertEquals(l, ['my_bool 1\n'])
326
 
 
327
 
    def test_write_empty_stanza(self):
328
 
        """Write empty stanza"""
329
 
        l = list(Stanza().to_lines())
330
 
        self.assertEquals(l, [])