~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-07-11 03:42:53 UTC
  • Revision ID: mbp@sourcefrog.net-20050711034253-412281abeb9f56ad
doc

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
 
        tmpf = TemporaryFile()
81
 
        s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
82
 
        s.write(tmpf)
83
 
        tmpf.seek(0)
84
 
        self.assertEqualDiff(tmpf.read(), '''\
85
 
motto: war is peace
86
 
\tfreedom is slavery
87
 
\tignorance is strength
88
 
''')
89
 
        tmpf.seek(0)
90
 
        s2 = read_stanza(tmpf)
91
 
        self.assertEquals(s, s2)
92
 
 
93
 
    def test_read_stanza(self):
94
 
        """Load stanza from string"""
95
 
        lines = """\
96
 
revision: mbp@sourcefrog.net-123-abc
97
 
timestamp: 1130653962
98
 
timezone: 36000
99
 
committer: Martin Pool <mbp@test.sourcefrog.net>
100
 
""".splitlines(True)
101
 
        s = read_stanza(lines)
102
 
        self.assertTrue('revision' in s)
103
 
        self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
104
 
        self.assertEquals(list(s.iter_pairs()),
105
 
                [('revision', 'mbp@sourcefrog.net-123-abc'),
106
 
                 ('timestamp', '1130653962'),
107
 
                 ('timezone', '36000'),
108
 
                 ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
109
 
        self.assertEquals(len(s), 4)
110
 
 
111
 
    def test_repeated_field(self):
112
 
        """Repeated field in rio"""
113
 
        s = Stanza()
114
 
        for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'), 
115
 
                     ('a', '1000'), ('b', '2000')]:
116
 
            s.add(k, v)
117
 
        s2 = read_stanza(s.to_lines())
118
 
        self.assertEquals(s, s2)
119
 
        self.assertEquals(s.get_all('a'), map(str, [10, 100, 1000]))
120
 
        self.assertEquals(s.get_all('b'), map(str, [20, 200, 2000]))
121
 
 
122
 
    def test_backslash(self):
123
 
        s = Stanza(q='\\')
124
 
        t = s.to_string()
125
 
        self.assertEqualDiff(t, 'q: \\\n')
126
 
        s2 = read_stanza(s.to_lines())
127
 
        self.assertEquals(s, s2)
128
 
 
129
 
    def test_blank_line(self):
130
 
        s = Stanza(none='', one='\n', two='\n\n')
131
 
        self.assertEqualDiff(s.to_string(), """\
132
 
none: 
133
 
one: 
134
 
\t
135
 
two: 
136
 
\t
137
 
\t
138
 
""")
139
 
        s2 = read_stanza(s.to_lines())
140
 
        self.assertEquals(s, s2)
141
 
 
142
 
    def test_whitespace_value(self):
143
 
        s = Stanza(space=' ', tabs='\t\t\t', combo='\n\t\t\n')
144
 
        self.assertEqualDiff(s.to_string(), """\
145
 
combo: 
146
 
\t\t\t
147
 
\t
148
 
space:  
149
 
tabs: \t\t\t
150
 
""")
151
 
        s2 = read_stanza(s.to_lines())
152
 
        self.assertEquals(s, s2)
153
 
 
154
 
    def test_quoted(self):
155
 
        """rio quoted string cases"""
156
 
        s = Stanza(q1='"hello"', 
157
 
                   q2=' "for', 
158
 
                   q3='\n\n"for"\n',
159
 
                   q4='for\n"\nfor',
160
 
                   q5='\n',
161
 
                   q6='"', 
162
 
                   q7='""',
163
 
                   q8='\\',
164
 
                   q9='\\"\\"',
165
 
                   )
166
 
        s2 = read_stanza(s.to_lines())
167
 
        self.assertEquals(s, s2)
168
 
 
169
 
    def test_read_empty(self):
170
 
        """Detect end of rio file"""
171
 
        s = read_stanza([])
172
 
        self.assertEqual(s, None)
173
 
        self.assertTrue(s is None)
174
 
        
175
 
    def test_read_iter(self):
176
 
        """Read several stanzas from file"""
177
 
        tmpf = TemporaryFile()
178
 
        tmpf.write("""\
179
 
version_header: 1
180
 
 
181
 
name: foo
182
 
val: 123
183
 
 
184
 
name: bar
185
 
val: 129319
186
 
""")
187
 
        tmpf.seek(0)
188
 
        reader = read_stanzas(tmpf)
189
 
        read_iter = iter(reader)
190
 
        stuff = list(reader)
191
 
        self.assertEqual(stuff, 
192
 
                [ Stanza(version_header='1'),
193
 
                  Stanza(name="foo", val='123'),
194
 
                  Stanza(name="bar", val='129319'), ])
195
 
 
196
 
    def test_read_several(self):
197
 
        """Read several stanzas from file"""
198
 
        tmpf = TemporaryFile()
199
 
        tmpf.write("""\
200
 
version_header: 1
201
 
 
202
 
name: foo
203
 
val: 123
204
 
 
205
 
name: quoted
206
 
address:   "Willowglen"
207
 
\t  42 Wallaby Way
208
 
\t  Sydney
209
 
 
210
 
name: bar
211
 
val: 129319
212
 
""")
213
 
        tmpf.seek(0)
214
 
        s = read_stanza(tmpf)
215
 
        self.assertEquals(s, Stanza(version_header='1'))
216
 
        s = read_stanza(tmpf)
217
 
        self.assertEquals(s, Stanza(name="foo", val='123'))
218
 
        s = read_stanza(tmpf)
219
 
        self.assertEqualDiff(s.get('name'), 'quoted')
220
 
        self.assertEqualDiff(s.get('address'), '  "Willowglen"\n  42 Wallaby Way\n  Sydney')
221
 
        s = read_stanza(tmpf)
222
 
        self.assertEquals(s, Stanza(name="bar", val='129319'))
223
 
        s = read_stanza(tmpf)
224
 
        self.assertEquals(s, None)
225
 
 
226
 
    def test_tricky_quoted(self):
227
 
        tmpf = TemporaryFile()
228
 
        tmpf.write('''\
229
 
s: "one"
230
 
 
231
 
s: 
232
 
\t"one"
233
 
\t
234
 
 
235
 
s: "
236
 
 
237
 
s: ""
238
 
 
239
 
s: """
240
 
 
241
 
s: 
242
 
\t
243
 
 
244
 
s: \\
245
 
 
246
 
s: 
247
 
\t\\
248
 
\t\\\\
249
 
\t
250
 
 
251
 
s: word\\
252
 
 
253
 
s: quote"
254
 
 
255
 
s: backslashes\\\\\\
256
 
 
257
 
s: both\\\"
258
 
 
259
 
''')
260
 
        tmpf.seek(0)
261
 
        expected_vals = ['"one"',
262
 
            '\n"one"\n',
263
 
            '"',
264
 
            '""',
265
 
            '"""',
266
 
            '\n',
267
 
            '\\',
268
 
            '\n\\\n\\\\\n',
269
 
            'word\\',
270
 
            'quote\"',
271
 
            'backslashes\\\\\\',
272
 
            'both\\\"',
273
 
            ]
274
 
        for expected in expected_vals:
275
 
            stanza = read_stanza(tmpf)
276
 
            self.assertEquals(len(stanza), 1)
277
 
            self.assertEqualDiff(stanza.get('s'), expected)
278
 
 
279
 
    def test_write_empty_stanza(self):
280
 
        """Write empty stanza"""
281
 
        l = list(Stanza().to_lines())
282
 
        self.assertEquals(l, [])