1
# Copyright (C) 2005 by Canonical Ltd
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.
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.
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
17
"""Tests for basic_io serialization
19
A simple, reproducible structured IO format.
21
basic_io itself works in Unicode strings. It is typically encoded to UTF-8,
22
but this depends on the transport.
27
from tempfile import TemporaryFile
29
from bzrlib.selftest import TestCaseInTempDir, TestCase
30
from bzrlib.basicio import BasicWriter, Stanza, read_stanza, read_stanzas
33
class TestBasicIO(TestCase):
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')
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))
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()),
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')
67
self.assertEqualDiff(tmpf.read(), r'''
68
a_thing "something with \"quotes like \\\"this\\\"\""
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",
80
self.assertEqualDiff(tmpf.read(), r'''\
89
def test_multiline_string(self):
90
tmpf = TemporaryFile()
91
s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
94
self.assertEqualDiff(tmpf.read(), '''\
97
ignorance is strength"
100
s2 = read_stanza(tmpf)
101
self.assertEquals(s, s2)
103
def test_read_stanza(self):
104
"""Load stanza from string"""
106
revision "mbp@sourcefrog.net-123-abc"
109
committer "Martin Pool <mbp@test.sourcefrog.net>"
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),
118
('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
119
self.assertEquals(len(s), 4)
121
def test_repeated_field(self):
122
"""Repeated field in basic_io"""
124
for k, v in [('a', 10), ('b', 20), ('a', 100), ('b', 200), ('a', 1000), ('b', 2000)]:
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])
131
def test_longint(self):
132
"""basic_io packing long integers"""
133
s = Stanza(x=-12345678901234567890,
136
s2 = read_stanza(lines)
137
self.assertEquals(s, s2)
139
def test_quoted_0(self):
140
"""Backslash quoted cases"""
143
self.assertEqualDiff(t, 'q "\\\\"\n')
144
s2 = read_stanza(s.to_lines())
145
self.assertEquals(s, s2)
147
def test_quoted_1(self):
148
"""Backslash quoted cases"""
149
s = Stanza(q=r'\"\"')
150
self.assertEqualDiff(s.to_string(), r'q "\\\"\\\""' + '\n')
152
def test_quoted_4(self):
153
s = Stanza(q=r'""""')
155
self.assertEqualDiff(t, r'q "\"\"\"\""' + '\n')
156
s2 = read_stanza(s.to_lines())
157
self.assertEquals(s, s2)
159
def test_quoted_5(self):
160
s = Stanza(q=r'\\\\\"')
162
s2 = read_stanza(s.to_lines())
163
self.assertEquals(s, s2)
165
def test_quoted_6(self):
173
s2 = read_stanza(s.to_lines())
174
self.assertEquals(s2['q'], qval)
176
def test_quoted_7(self):
185
s2 = read_stanza(s.to_lines())
186
self.assertEquals(s2['q'], qval)
188
def test_quoted_8(self):
194
s2 = read_stanza(s.to_lines())
195
self.assertEquals(s2['q'], qval)
197
def test_quoted(self):
198
"""basic_io quoted string cases"""
199
s = Stanza(q1='"hello"',
209
s2 = read_stanza(s.to_lines())
210
self.assertEquals(s, s2)
212
def test_read_empty(self):
213
"""Detect end of basic_io file"""
215
self.assertEqual(s, None)
216
self.assertTrue(s is None)
218
def test_read_iter(self):
219
"""Read several stanzas from file"""
220
tmpf = TemporaryFile()
231
reader = read_stanzas(tmpf)
232
read_iter = iter(reader)
234
self.assertEqual(stuff,
235
[ Stanza(version_header=1),
236
Stanza(name="foo", val=123),
237
Stanza(name="bar", val=129319), ])
239
def test_read_several(self):
240
"""Read several stanzas from file"""
241
tmpf = TemporaryFile()
249
address " \\"Willowglen\\"
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)
269
def test_tricky_quoted(self):
270
tmpf = TemporaryFile()
298
s "backslashes\\\\\\"
302
"""[1:]) # remove initial newline
304
expected_vals = ['"one"',
317
for expected in expected_vals:
318
stanza = read_stanza(tmpf)
319
self.assertEquals(len(stanza), 1)
320
self.assertEqualDiff(stanza.get('s'), expected)
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'])
327
def test_write_empty_stanza(self):
328
"""Write empty stanza"""
329
l = list(Stanza().to_lines())
330
self.assertEquals(l, [])