46
40
self.assertTrue('number' in s)
47
41
self.assertFalse('color' in s)
48
42
self.assertFalse('42' in s)
49
self.assertEqual(list(s.iter_pairs()),
50
[('name', 'fred'), ('number', '42')])
51
self.assertEqual(s.get('number'), '42')
52
self.assertEqual(s.get('name'), 'fred')
43
self.assertEquals(list(s.iter_pairs()),
44
[('name', 'fred'), ('number', '42')])
45
self.assertEquals(s.get('number'), '42')
46
self.assertEquals(s.get('name'), 'fred')
48
def test_value_checks(self):
49
"""rio checks types on construction"""
50
# these aren't enforced at construction time
51
## self.assertRaises(ValueError,
52
## Stanza, complex=42 + 3j)
53
## self.assertRaises(ValueError,
54
## Stanza, several=range(10))
54
56
def test_empty_value(self):
55
57
"""Serialize stanza with empty field"""
56
58
s = Stanza(empty='')
57
self.assertEquals(s.to_string(),
59
self.assertEqualDiff(s.to_string(),
60
62
def test_to_lines(self):
61
63
"""Write simple rio stanza to string"""
62
64
s = Stanza(number='42', name='fred')
63
self.assertEqual(list(s.to_lines()),
65
self.assertEquals(list(s.to_lines()),
67
69
def test_as_dict(self):
68
70
"""Convert rio Stanza to dictionary"""
69
71
s = Stanza(number='42', name='fred')
71
self.assertEqual(sd, dict(number='42', name='fred'))
73
self.assertEquals(sd, dict(number='42', name='fred'))
73
75
def test_to_file(self):
74
76
"""Write rio to file"""
75
77
tmpf = TemporaryFile()
76
s = Stanza(a_thing='something with "quotes like \\"this\\""',
77
number='42', name='fred')
78
s = Stanza(a_thing='something with "quotes like \\"this\\""', number='42', name='fred')
80
self.assertEqual(tmpf.read(), b'''\
81
a_thing: something with "quotes like \\"this\\""
81
self.assertEqualDiff(tmpf.read(), r'''
82
a_thing: something with "quotes like \"this\""
86
87
def test_multiline_string(self):
87
88
tmpf = TemporaryFile()
89
motto="war is peace\nfreedom is slavery\nignorance is strength")
89
s = Stanza(motto="war is peace\nfreedom is slavery\nignorance is strength")
92
self.assertEqual(tmpf.read(), b'''\
92
self.assertEqualDiff(tmpf.read(), '''\
93
93
motto: war is peace
94
94
\tfreedom is slavery
95
95
\tignorance is strength
98
98
s2 = read_stanza(tmpf)
99
self.assertEqual(s, s2)
99
self.assertEquals(s, s2)
101
101
def test_read_stanza(self):
102
102
"""Load stanza from string"""
104
104
revision: mbp@sourcefrog.net-123-abc
105
105
timestamp: 1130653962
108
108
""".splitlines(True)
109
109
s = read_stanza(lines)
110
110
self.assertTrue('revision' in s)
111
self.assertEqual(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
112
self.assertEqual(list(s.iter_pairs()),
113
[('revision', 'mbp@sourcefrog.net-123-abc'),
114
('timestamp', '1130653962'),
115
('timezone', '36000'),
116
('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
117
self.assertEqual(len(s), 4)
111
self.assertEqualDiff(s.get('revision'), 'mbp@sourcefrog.net-123-abc')
112
self.assertEquals(list(s.iter_pairs()),
113
[('revision', 'mbp@sourcefrog.net-123-abc'),
114
('timestamp', '1130653962'),
115
('timezone', '36000'),
116
('committer', "Martin Pool <mbp@test.sourcefrog.net>")])
117
self.assertEquals(len(s), 4)
119
119
def test_repeated_field(self):
120
120
"""Repeated field in rio"""
122
for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'),
122
for k, v in [('a', '10'), ('b', '20'), ('a', '100'), ('b', '200'),
123
123
('a', '1000'), ('b', '2000')]:
125
125
s2 = read_stanza(s.to_lines())
126
self.assertEqual(s, s2)
127
self.assertEqual(s.get_all('a'), ['10', '100', '1000'])
128
self.assertEqual(s.get_all('b'), ['20', '200', '2000'])
126
self.assertEquals(s, s2)
127
self.assertEquals(s.get_all('a'), map(str, [10, 100, 1000]))
128
self.assertEquals(s.get_all('b'), map(str, [20, 200, 2000]))
130
130
def test_backslash(self):
131
131
s = Stanza(q='\\')
132
132
t = s.to_string()
133
self.assertEqual(t, b'q: \\\n')
133
self.assertEqualDiff(t, 'q: \\\n')
134
134
s2 = read_stanza(s.to_lines())
135
self.assertEqual(s, s2)
135
self.assertEquals(s, s2)
137
137
def test_blank_line(self):
138
138
s = Stanza(none='', one='\n', two='\n\n')
139
self.assertEqual(s.to_string(), b"""\
139
self.assertEqualDiff(s.to_string(), """\
147
147
s2 = read_stanza(s.to_lines())
148
self.assertEqual(s, s2)
148
self.assertEquals(s, s2)
150
150
def test_whitespace_value(self):
151
151
s = Stanza(space=' ', tabs='\t\t\t', combo='\n\t\t\n')
152
self.assertEqual(s.to_string(), b"""\
152
self.assertEqualDiff(s.to_string(), """\
159
159
s2 = read_stanza(s.to_lines())
160
self.assertEqual(s, s2)
160
self.assertEquals(s, s2)
161
161
self.rio_file_stanzas([s])
163
163
def test_quoted(self):
164
164
"""rio quoted string cases"""
165
s = Stanza(q1='"hello"',
165
s = Stanza(q1='"hello"',
167
167
q3='\n\n"for"\n',
168
168
q4='for\n"\nfor',
175
175
s2 = read_stanza(s.to_lines())
176
self.assertEqual(s, s2)
176
self.assertEquals(s, s2)
177
177
# apparent bug in read_stanza
178
178
# s3 = read_stanza(self.stanzas_to_str([s]))
179
# self.assertEqual(s, s3)
179
# self.assertEquals(s, s3)
181
181
def test_read_empty(self):
182
182
"""Detect end of rio file"""
183
183
s = read_stanza([])
184
184
self.assertEqual(s, None)
185
185
self.assertTrue(s is None)
187
def test_read_nul_byte(self):
188
"""File consisting of a nul byte causes an error."""
189
self.assertRaises(ValueError, read_stanza, [b'\0'])
191
def test_read_nul_bytes(self):
192
"""File consisting of many nul bytes causes an error."""
193
self.assertRaises(ValueError, read_stanza, [b'\0' * 100])
195
187
def test_read_iter(self):
196
188
"""Read several stanzas from file"""
197
189
tmpf = TemporaryFile()
199
191
version_header: 1
234
226
s = read_stanza(tmpf)
235
self.assertEqual(s, Stanza(version_header='1'))
236
s = read_stanza(tmpf)
237
self.assertEqual(s, Stanza(name="foo", val='123'))
238
s = read_stanza(tmpf)
239
self.assertEqual(s.get('name'), 'quoted')
241
s.get('address'), ' "Willowglen"\n 42 Wallaby Way\n Sydney')
242
s = read_stanza(tmpf)
243
self.assertEqual(s, Stanza(name="bar", val='129319'))
244
s = read_stanza(tmpf)
245
self.assertEqual(s, None)
227
self.assertEquals(s, Stanza(version_header='1'))
228
s = read_stanza(tmpf)
229
self.assertEquals(s, Stanza(name="foo", val='123'))
230
s = read_stanza(tmpf)
231
self.assertEqualDiff(s.get('name'), 'quoted')
232
self.assertEqualDiff(s.get('address'), ' "Willowglen"\n 42 Wallaby Way\n Sydney')
233
s = read_stanza(tmpf)
234
self.assertEquals(s, Stanza(name="bar", val='129319'))
235
s = read_stanza(tmpf)
236
self.assertEquals(s, None)
246
237
self.check_rio_file(tmpf)
248
239
def check_rio_file(self, real_file):
249
240
real_file.seek(0)
250
241
read_write = rio_file(RioReader(real_file)).read()
251
242
real_file.seek(0)
252
self.assertEqual(read_write, real_file.read())
243
self.assertEquals(read_write, real_file.read())
255
246
def stanzas_to_str(stanzas):
297
288
expected_vals = ['"one"',
310
301
for expected in expected_vals:
311
302
stanza = read_stanza(tmpf)
312
303
self.rio_file_stanzas([stanza])
313
self.assertEqual(len(stanza), 1)
314
self.assertEqual(stanza.get('s'), expected)
304
self.assertEquals(len(stanza), 1)
305
self.assertEqualDiff(stanza.get('s'), expected)
316
307
def test_write_empty_stanza(self):
317
308
"""Write empty stanza"""
318
309
l = list(Stanza().to_lines())
319
self.assertEqual(l, [])
310
self.assertEquals(l, [])
321
312
def test_rio_raises_type_error(self):
322
313
"""TypeError on adding invalid type to Stanza"""
329
320
self.assertRaises(TypeError, s.add, 10, {})
331
322
def test_rio_unicode(self):
323
# intentionally use cStringIO which doesn't accomodate unencoded unicode objects
324
sio = cStringIO.StringIO()
332
325
uni_data = u'\N{KATAKANA LETTER O}'
333
326
s = Stanza(foo=uni_data)
334
self.assertEqual(s.get('foo'), uni_data)
327
self.assertEquals(s.get('foo'), uni_data)
335
328
raw_lines = s.to_lines()
336
self.assertEqual(raw_lines,
337
[b'foo: ' + uni_data.encode('utf-8') + b'\n'])
329
self.assertEquals(raw_lines,
330
['foo: ' + uni_data.encode('utf-8') + '\n'])
338
331
new_s = read_stanza(raw_lines)
339
self.assertEqual(new_s.get('foo'), uni_data)
341
def test_rio_to_unicode(self):
342
uni_data = u'\N{KATAKANA LETTER O}'
343
s = Stanza(foo=uni_data)
344
unicode_str = s.to_unicode()
345
self.assertEqual(u'foo: %s\n' % (uni_data,), unicode_str)
346
new_s = rio.read_stanza_unicode(unicode_str.splitlines(True))
347
self.assertEqual(uni_data, new_s.get('foo'))
349
def test_nested_rio_unicode(self):
350
uni_data = u'\N{KATAKANA LETTER O}'
351
s = Stanza(foo=uni_data)
352
parent_stanza = Stanza(child=s.to_unicode())
353
raw_lines = parent_stanza.to_lines()
354
self.assertEqual([b'child: foo: ' + uni_data.encode('utf-8') + b'\n',
357
new_parent = read_stanza(raw_lines)
358
child_text = new_parent.get('child')
359
self.assertEqual(u'foo: %s\n' % uni_data, child_text)
360
new_child = rio.read_stanza_unicode(child_text.splitlines(True))
361
self.assertEqual(uni_data, new_child.get('foo'))
363
def mail_munge(self, lines, dos_nl=True):
366
line = re.sub(b' *\n', b'\n', line)
368
line = re.sub(b'([^\r])\n', b'\\1\r\n', line)
369
new_lines.append(line)
372
def test_patch_rio(self):
373
stanza = Stanza(data='#\n\r\\r ', space=' ' * 255, hash='#' * 255)
374
lines = rio.to_patch_lines(stanza)
376
self.assertContainsRe(line, b'^# ')
377
self.assertTrue(72 >= len(line))
378
for line in rio.to_patch_lines(stanza, max_width=12):
379
self.assertTrue(12 >= len(line))
380
new_stanza = rio.read_patch_stanza(self.mail_munge(lines,
382
lines = self.mail_munge(lines)
383
new_stanza = rio.read_patch_stanza(lines)
384
self.assertEqual('#\n\r\\r ', new_stanza.get('data'))
385
self.assertEqual(' ' * 255, new_stanza.get('space'))
386
self.assertEqual('#' * 255, new_stanza.get('hash'))
388
def test_patch_rio_linebreaks(self):
389
stanza = Stanza(breaktest='linebreak -/' * 30)
390
self.assertContainsRe(rio.to_patch_lines(stanza, 71)[0],
392
stanza = Stanza(breaktest='linebreak-/' * 30)
393
self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
395
stanza = Stanza(breaktest='linebreak/' * 30)
396
self.assertContainsRe(rio.to_patch_lines(stanza, 70)[0],
332
self.assertEquals(new_s.get('foo'), uni_data)