/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1185.44.1 by Martin Pool
Start bringing in basicio code
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
1185.44.3 by Martin Pool
More basic_io development
27
from tempfile import TemporaryFile
1185.44.1 by Martin Pool
Start bringing in basicio code
28
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
29
from bzrlib.tests import TestCaseInTempDir, TestCase
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
30
from bzrlib.basicio import BasicWriter, Stanza, read_stanza, read_stanzas
1185.44.1 by Martin Pool
Start bringing in basicio code
31
32
1185.44.3 by Martin Pool
More basic_io development
33
class TestBasicIO(TestCase):
1185.44.1 by Martin Pool
Start bringing in basicio code
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)
1185.44.6 by Martin Pool
Simple basic_io from_lines and .get()
41
        self.assertEquals(list(s.iter_pairs()),
1185.44.2 by Martin Pool
Iteration of Stanzas()
42
                [('name', 'fred'), ('number', 42)])
1185.44.6 by Martin Pool
Simple basic_io from_lines and .get()
43
        self.assertEquals(s.get('number'), 42)
44
        self.assertEquals(s.get('name'), 'fred')
1185.44.3 by Martin Pool
More basic_io development
45
46
    def test_value_checks(self):
47
        """basic_io checks types on construction"""
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
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))
1185.44.3 by Martin Pool
More basic_io development
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()),
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
58
                ['  name "fred"\n',
1185.44.3 by Martin Pool
More basic_io development
59
                 'number 42\n'])
60
61
    def test_to_file(self):
62
        """Write basic_io to file"""
63
        tmpf = TemporaryFile()
1185.44.4 by Martin Pool
Larger test for writing basic_io
64
        s = Stanza(a_thing='something with "quotes like \\"this\\""', number=42, name='fred')
1185.44.3 by Martin Pool
More basic_io development
65
        s.write(tmpf)
66
        tmpf.seek(0)
1185.44.4 by Martin Pool
Larger test for writing basic_io
67
        self.assertEqualDiff(tmpf.read(), r'''
68
a_thing "something with \"quotes like \\\"this\\\"\""
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
69
   name "fred"
70
 number 42
1185.44.4 by Martin Pool
Larger test for writing basic_io
71
'''[1:])
1185.44.5 by Martin Pool
Test basic_io writing multiline strings.
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)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
80
        self.assertEqualDiff(tmpf.read(), r'''\
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
81
            a 123
82
        motto "war is peace
83
freedom is slavery
84
ignorance is strength
85
"
1185.44.5 by Martin Pool
Test basic_io writing multiline strings.
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(), '''\
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
95
motto "war is peace
96
freedom is slavery
97
ignorance is strength"
1185.44.5 by Martin Pool
Test basic_io writing multiline strings.
98
''')
1185.44.12 by Martin Pool
Fix up reading basic_io multiline strings
99
        tmpf.seek(0)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
100
        s2 = read_stanza(tmpf)
1185.44.12 by Martin Pool
Fix up reading basic_io multiline strings
101
        self.assertEquals(s, s2)
1185.44.5 by Martin Pool
Test basic_io writing multiline strings.
102
103
    def test_read_stanza(self):
104
        """Load stanza from string"""
105
        lines = """\
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
106
 revision "mbp@sourcefrog.net-123-abc"
1185.44.8 by Martin Pool
more basic_io read tests
107
timestamp 1130653962
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
108
 timezone 36000
1185.44.8 by Martin Pool
more basic_io read tests
109
committer "Martin Pool <mbp@test.sourcefrog.net>"
1185.44.6 by Martin Pool
Simple basic_io from_lines and .get()
110
""".splitlines(True)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
111
        s = read_stanza(lines)
1185.44.6 by Martin Pool
Simple basic_io from_lines and .get()
112
        self.assertTrue('revision' in s)
113
        self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
1185.44.7 by Martin Pool
Update Stanza iteration tests
114
        self.assertEquals(list(s.iter_pairs()),
1185.44.8 by Martin Pool
more basic_io read tests
115
                [('revision', 'mbp@sourcefrog.net-123-abc'),
116
                 ('timestamp', 1130653962),
117
                 ('timezone', 36000),
118
                 ('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
1185.44.9 by Martin Pool
Add len(Stanza)
119
        self.assertEquals(len(s), 4)
1185.44.10 by Martin Pool
Fix handling of negative integers and add test
120
1185.44.15 by Martin Pool
Add Stanza.get_all and test repeated fields
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)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
126
        s2 = read_stanza(s.to_lines())
1185.44.15 by Martin Pool
Add Stanza.get_all and test repeated fields
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
1185.44.10 by Martin Pool
Fix handling of negative integers and add test
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()
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
136
        s2 = read_stanza(lines)
1185.44.11 by Martin Pool
Add Stanza eq and ne methods and test.
137
        self.assertEquals(s, s2)
1185.44.13 by Martin Pool
More robust basic_io parsing of quoted/multiline strings
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')
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
144
        s2 = read_stanza(s.to_lines())
1185.44.13 by Martin Pool
More robust basic_io parsing of quoted/multiline strings
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
1185.44.14 by Martin Pool
More basic_io quoting tests
152
    def test_quoted_4(self):
153
        s = Stanza(q=r'""""')
154
        t = s.to_string()
155
        self.assertEqualDiff(t, r'q "\"\"\"\""' + '\n')
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
156
        s2 = read_stanza(s.to_lines())
1185.44.14 by Martin Pool
More basic_io quoting tests
157
        self.assertEquals(s, s2)
158
159
    def test_quoted_5(self):
160
        s = Stanza(q=r'\\\\\"')
161
        t = s.to_string()
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
162
        s2 = read_stanza(s.to_lines())
1185.44.14 by Martin Pool
More basic_io quoting tests
163
        self.assertEquals(s, s2)
164
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
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
                "
1185.44.28 by Martin Pool
More basic_io tests for quoting
179
                \"
1185.44.27 by Martin Pool
Go back to multiline quoted string values.
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
        
1185.44.30 by Martin Pool
more basic_io tests
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
        
1185.44.13 by Martin Pool
More robust basic_io parsing of quoted/multiline strings
197
    def test_quoted(self):
198
        """basic_io quoted string cases"""
199
        s = Stanza(q1='"hello"', 
1185.44.14 by Martin Pool
More basic_io quoting tests
200
                   q2=' "for', 
201
                   q3='\n\n"for"\n',
202
                   q4='for\n"\nfor',
203
                   q5='\n',
204
                   q6='"', 
205
                   q7='""',
1185.44.13 by Martin Pool
More robust basic_io parsing of quoted/multiline strings
206
                   q8='\\',
207
                   q9='\\"\\"',
208
                   )
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
209
        s2 = read_stanza(s.to_lines())
1185.44.13 by Martin Pool
More robust basic_io parsing of quoted/multiline strings
210
        self.assertEquals(s, s2)
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
211
212
    def test_read_empty(self):
213
        """Detect end of basic_io file"""
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
214
        s = read_stanza([])
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
215
        self.assertEqual(s, None)
216
        self.assertTrue(s is None)
217
        
1185.44.19 by Martin Pool
New BasicReader to pull a sequence of stanzas from a file, and test.
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"
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
225
val 123
1185.44.19 by Martin Pool
New BasicReader to pull a sequence of stanzas from a file, and test.
226
227
name "bar"
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
228
val 129319
1185.44.19 by Martin Pool
New BasicReader to pull a sequence of stanzas from a file, and test.
229
""")
230
        tmpf.seek(0)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
231
        reader = read_stanzas(tmpf)
1185.44.19 by Martin Pool
New BasicReader to pull a sequence of stanzas from a file, and test.
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
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
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"
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
246
val 123
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
247
1185.44.33 by Martin Pool
Fix up handling of escaped doublequotes at end of line.
248
name "quoted"
249
address "  \\"Willowglen\\"
250
  42 Wallaby Way
251
  Sydney"
252
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
253
name "bar"
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
254
val 129319
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
255
""")
256
        tmpf.seek(0)
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
257
        s = read_stanza(tmpf)
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
258
        self.assertEquals(s, Stanza(version_header=1))
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
259
        s = read_stanza(tmpf)
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
260
        self.assertEquals(s, Stanza(name="foo", val=123))
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
261
        s = read_stanza(tmpf)
1185.44.33 by Martin Pool
Fix up handling of escaped doublequotes at end of line.
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)
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
265
        self.assertEquals(s, Stanza(name="bar", val=129319))
1185.44.24 by Martin Pool
Get basic_io selftests running again for new format.
266
        s = read_stanza(tmpf)
1185.44.18 by Martin Pool
Fix up reading sequence of stanzas from a file, and test.
267
        self.assertEquals(s, None)
1185.44.20 by Martin Pool
Fix basic_io writing of bools, and test.
268
1185.44.34 by Martin Pool
Addition test and bugfix for basic_io escaped strings.
269
    def test_tricky_quoted(self):
270
        tmpf = TemporaryFile()
271
        tmpf.write(r"""
272
s "\"one\""
273
274
s "
275
\"one\"
276
"
277
1185.44.35 by Martin Pool
More basicio quoting tests.
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
1185.44.34 by Martin Pool
Addition test and bugfix for basic_io escaped strings.
302
"""[1:]) # remove initial newline
303
        tmpf.seek(0)
304
        expected_vals = ['"one"',
305
            '\n"one"\n',
1185.44.35 by Martin Pool
More basicio quoting tests.
306
            '"',
307
            '""',
308
            '"""',
309
            '\n',
310
            '\\',
311
            '\n\\\n\\\\\n',
312
            'word\\',
313
            'quote\"',
314
            'backslashes\\\\\\',
315
            'both\\\"',
1185.44.34 by Martin Pool
Addition test and bugfix for basic_io escaped strings.
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
1185.44.20 by Martin Pool
Fix basic_io writing of bools, and test.
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'])
1185.44.28 by Martin Pool
More basic_io tests for quoting
326
1185.44.30 by Martin Pool
more basic_io tests
327
    def test_write_empty_stanza(self):
328
        """Write empty stanza"""
1185.44.29 by Martin Pool
Packing of empty basic_io stanzas
329
        l = list(Stanza().to_lines())
330
        self.assertEquals(l, [])