~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_rio.py

  • Committer: Martin Pool
  • Date: 2005-11-28 08:03:42 UTC
  • mto: (1185.33.61 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 1518.
  • Revision ID: mbp@sourcefrog.net-20051128080342-b7db3190dca90484
[broken] start converting basic_io to more rfc822-like format

Suggestions from mailing list:
 
  no double quotes
  no cute right-alignment
  no escaping
  just indent continuation lines

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 rio serialization
 
18
 
 
19
A simple, reproducible structured IO format.
 
20
 
 
21
rio 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.rio import RioWriter, Stanza, read_stanza, read_stanzas
 
31
 
 
32
 
 
33
class TestRio(TestCase):
 
34
 
 
35
    def test_stanza(self):
 
36
        """Construct rio 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
        """rio 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_empty_value(self):
 
55
        """Serialize stanza with empty field"""
 
56
        s = Stanza(empty='')
 
57
        self.assertEqualDiff(s.to_string(),
 
58
                "empty: \n")
 
59
 
 
60
    def test_to_lines(self):
 
61
        """Write simple rio stanza to string"""
 
62
        s = Stanza(number=42, name='fred')
 
63
        self.assertEquals(list(s.to_lines()),
 
64
                ['name: fred\n',
 
65
                 'number: 42\n'])
 
66
 
 
67
    def test_to_file(self):
 
68
        """Write rio to file"""
 
69
        tmpf = TemporaryFile()
 
70
        s = Stanza(a_thing='something with "quotes like \\"this\\""', number=42, name='fred')
 
71
        s.write(tmpf)
 
72
        tmpf.seek(0)
 
73
        self.assertEqualDiff(tmpf.read(), r'''
 
74
a_thing: something with "quotes like \"this\""
 
75
name: fred
 
76
number: 42
 
77
'''[1:])
 
78
 
 
79
    def test_multiline_string(self):
 
80
        """Write rio with multiline string"""
 
81
        tmpf = TemporaryFile()
 
82
        s = Stanza(a=123, motto="war is peace\nfreedom is slavery\nignorance is strength\n",
 
83
                   charlie_horse=456)
 
84
        s.write(tmpf)
 
85
        tmp.seek(0)
 
86
        self.assertEqualDiff(tmpf.read(), r'''\
 
87
            a 123
 
88
        motto "war is peace
 
89
freedom is slavery
 
90
ignorance is strength
 
91
"
 
92
charlie_horse 456
 
93
''')
 
94
 
 
95
    def test_multiline_string(self):
 
96
        tmpf = TemporaryFile()
 
97
        s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
 
98
        s.write(tmpf)
 
99
        tmpf.seek(0)
 
100
        self.assertEqualDiff(tmpf.read(), '''\
 
101
motto: war is peace
 
102
\tfreedom is slavery
 
103
\tignorance is strength
 
104
''')
 
105
        tmpf.seek(0)
 
106
        s2 = read_stanza(tmpf)
 
107
        self.assertEquals(s, s2)
 
108
 
 
109
    def test_read_stanza(self):
 
110
        """Load stanza from string"""
 
111
        lines = """\
 
112
revision: mbp@sourcefrog.net-123-abc
 
113
timestamp: 1130653962
 
114
timezone: 36000
 
115
committer: Martin Pool <mbp@test.sourcefrog.net>
 
116
""".splitlines(True)
 
117
        s = read_stanza(lines)
 
118
        self.assertTrue('revision' in s)
 
119
        self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
 
120
        self.assertEquals(list(s.iter_pairs()),
 
121
                [('revision', 'mbp@sourcefrog.net-123-abc'),
 
122
                 ('timestamp', '1130653962'),
 
123
                 ('timezone', '36000'),
 
124
                 ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
 
125
        self.assertEquals(len(s), 4)
 
126
 
 
127
    def test_repeated_field(self):
 
128
        """Repeated field in rio"""
 
129
        s = Stanza()
 
130
        for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'), 
 
131
                     ('a', '1000'), ('b', '2000')]:
 
132
            s.add(k, v)
 
133
        s2 = read_stanza(s.to_lines())
 
134
        self.assertEquals(s, s2)
 
135
        self.assertEquals(s.get_all('a'), map(str, [10, 100, 1000]))
 
136
        self.assertEquals(s.get_all('b'), map(str, [20, 200, 2000]))
 
137
 
 
138
    def test_longint(self):
 
139
        """rio packing long integers"""
 
140
        s = Stanza(x=-12345678901234567890,
 
141
                   y=1<<100)
 
142
        lines = s.to_lines()
 
143
        s2 = read_stanza(lines)
 
144
        self.assertEquals(s, s2)
 
145
 
 
146
    def test_quoted_0(self):
 
147
        """Backslash quoted cases"""
 
148
        s = Stanza(q='\\')
 
149
        t = s.to_string()
 
150
        self.assertEqualDiff(t, 'q "\\\\"\n')
 
151
        s2 = read_stanza(s.to_lines())
 
152
        self.assertEquals(s, s2)
 
153
 
 
154
    def test_quoted_1(self):
 
155
        """Backslash quoted cases"""
 
156
        s = Stanza(q=r'\"\"')
 
157
        self.assertEqualDiff(s.to_string(), r'q "\\\"\\\""' + '\n')
 
158
 
 
159
    def test_quoted_4(self):
 
160
        s = Stanza(q=r'""""')
 
161
        t = s.to_string()
 
162
        self.assertEqualDiff(t, r'q "\"\"\"\""' + '\n')
 
163
        s2 = read_stanza(s.to_lines())
 
164
        self.assertEquals(s, s2)
 
165
 
 
166
    def test_quoted_5(self):
 
167
        s = Stanza(q=r'\\\\\"')
 
168
        t = s.to_string()
 
169
        s2 = read_stanza(s.to_lines())
 
170
        self.assertEquals(s, s2)
 
171
 
 
172
    def test_quoted_6(self):
 
173
        qval = r'''
 
174
                "
 
175
                \"
 
176
'''
 
177
        s = Stanza(q=qval)
 
178
        t = s.to_string()
 
179
        self.log(t)
 
180
        s2 = read_stanza(s.to_lines())
 
181
        self.assertEquals(s2['q'], qval)
 
182
        
 
183
    def test_quoted_7(self):
 
184
        qval = r'''
 
185
                "
 
186
                \"
 
187
                \\"
 
188
trailing stuff'''
 
189
        s = Stanza(q=qval)
 
190
        t = s.to_string()
 
191
        self.log(t)
 
192
        s2 = read_stanza(s.to_lines())
 
193
        self.assertEquals(s2['q'], qval)
 
194
        
 
195
    def test_quoted_8(self):
 
196
        qval = r'''trailing
 
197
        quote"'''
 
198
        s = Stanza(q=qval)
 
199
        t = s.to_string()
 
200
        self.log(t)
 
201
        s2 = read_stanza(s.to_lines())
 
202
        self.assertEquals(s2['q'], qval)
 
203
        
 
204
    def test_quoted(self):
 
205
        """rio quoted string cases"""
 
206
        s = Stanza(q1='"hello"', 
 
207
                   q2=' "for', 
 
208
                   q3='\n\n"for"\n',
 
209
                   q4='for\n"\nfor',
 
210
                   q5='\n',
 
211
                   q6='"', 
 
212
                   q7='""',
 
213
                   q8='\\',
 
214
                   q9='\\"\\"',
 
215
                   )
 
216
        s2 = read_stanza(s.to_lines())
 
217
        self.assertEquals(s, s2)
 
218
 
 
219
    def test_read_empty(self):
 
220
        """Detect end of rio file"""
 
221
        s = read_stanza([])
 
222
        self.assertEqual(s, None)
 
223
        self.assertTrue(s is None)
 
224
        
 
225
    def test_read_iter(self):
 
226
        """Read several stanzas from file"""
 
227
        tmpf = TemporaryFile()
 
228
        tmpf.write("""\
 
229
version_header 1
 
230
 
 
231
name "foo"
 
232
val 123
 
233
 
 
234
name "bar"
 
235
val 129319
 
236
""")
 
237
        tmpf.seek(0)
 
238
        reader = read_stanzas(tmpf)
 
239
        read_iter = iter(reader)
 
240
        stuff = list(reader)
 
241
        self.assertEqual(stuff, 
 
242
                [ Stanza(version_header=1),
 
243
                  Stanza(name="foo", val=123),
 
244
                  Stanza(name="bar", val=129319), ])
 
245
 
 
246
    def test_read_several(self):
 
247
        """Read several stanzas from file"""
 
248
        tmpf = TemporaryFile()
 
249
        tmpf.write("""\
 
250
version_header 1
 
251
 
 
252
name "foo"
 
253
val 123
 
254
 
 
255
name "quoted"
 
256
address "  \\"Willowglen\\"
 
257
  42 Wallaby Way
 
258
  Sydney"
 
259
 
 
260
name "bar"
 
261
val 129319
 
262
""")
 
263
        tmpf.seek(0)
 
264
        s = read_stanza(tmpf)
 
265
        self.assertEquals(s, Stanza(version_header=1))
 
266
        s = read_stanza(tmpf)
 
267
        self.assertEquals(s, Stanza(name="foo", val=123))
 
268
        s = read_stanza(tmpf)
 
269
        self.assertEqualDiff(s.get('name'), 'quoted')
 
270
        self.assertEqualDiff(s.get('address'), '  "Willowglen"\n  42 Wallaby Way\n  Sydney')
 
271
        s = read_stanza(tmpf)
 
272
        self.assertEquals(s, Stanza(name="bar", val=129319))
 
273
        s = read_stanza(tmpf)
 
274
        self.assertEquals(s, None)
 
275
 
 
276
    def test_tricky_quoted(self):
 
277
        tmpf = TemporaryFile()
 
278
        tmpf.write(r"""
 
279
s "\"one\""
 
280
 
 
281
s "
 
282
\"one\"
 
283
"
 
284
 
 
285
s "\""
 
286
 
 
287
s "\"\""
 
288
 
 
289
s "\"\"\""
 
290
 
 
291
s "
 
292
"
 
293
 
 
294
s "\\"
 
295
 
 
296
s "
 
297
\\
 
298
\\\\
 
299
"
 
300
 
 
301
s "word\\"
 
302
 
 
303
s "quote\""
 
304
 
 
305
s "backslashes\\\\\\"
 
306
 
 
307
s "both\\\""
 
308
 
 
309
"""[1:]) # remove initial newline
 
310
        tmpf.seek(0)
 
311
        expected_vals = ['"one"',
 
312
            '\n"one"\n',
 
313
            '"',
 
314
            '""',
 
315
            '"""',
 
316
            '\n',
 
317
            '\\',
 
318
            '\n\\\n\\\\\n',
 
319
            'word\\',
 
320
            'quote\"',
 
321
            'backslashes\\\\\\',
 
322
            'both\\\"',
 
323
            ]
 
324
        for expected in expected_vals:
 
325
            stanza = read_stanza(tmpf)
 
326
            self.assertEquals(len(stanza), 1)
 
327
            self.assertEqualDiff(stanza.get('s'), expected)
 
328
 
 
329
    def test_write_bool(self):
 
330
        """Write bool to rio"""
 
331
        l = list(Stanza(my_bool=True).to_lines())
 
332
        self.assertEquals(l, ['my_bool 1\n'])
 
333
 
 
334
    def test_write_empty_stanza(self):
 
335
        """Write empty stanza"""
 
336
        l = list(Stanza().to_lines())
 
337
        self.assertEquals(l, [])