/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_xml.py

  • Committer: John Arbash Meinel
  • Date: 2008-08-18 22:34:21 UTC
  • mto: (3606.5.6 1.6)
  • mto: This revision was merged to the branch mainline in revision 3641.
  • Revision ID: john@arbash-meinel.com-20080818223421-todjny24vj4faj4t
Add tests for the fetching behavior.

The proper parameter passed is 'unordered' add an assert for it, and
fix callers that were passing 'unsorted' instead.
Add tests that we make the right get_record_stream call based
on the value of _fetch_uses_deltas.
Fix the fetch request for signatures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 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
from cStringIO import StringIO
 
18
 
 
19
from bzrlib import (
 
20
    errors, 
 
21
    inventory, 
 
22
    xml7,
 
23
    xml8,
 
24
    xml_serializer,
 
25
    )
 
26
from bzrlib.tests import TestCase
 
27
from bzrlib.inventory import Inventory, InventoryEntry
 
28
from bzrlib.xml4 import serializer_v4
 
29
import bzrlib.xml5
 
30
 
 
31
_working_inventory_v4 = """<inventory file_id="TREE_ROOT">
 
32
<entry file_id="bar-20050901064931-73b4b1138abc9cd2" kind="file" name="bar" parent_id="TREE_ROOT" />
 
33
<entry file_id="foo-20050801201819-4139aa4a272f4250" kind="directory" name="foo" parent_id="TREE_ROOT" />
 
34
<entry file_id="bar-20050824000535-6bc48cfad47ed134" kind="file" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" />
 
35
</inventory>"""
 
36
 
 
37
 
 
38
_revision_v4 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
 
39
    inventory_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
 
40
    inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
 
41
    revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
 
42
    timestamp="1125907235.212"
 
43
    timezone="36000">
 
44
<message>- start splitting code for xml (de)serialization away from objects
 
45
  preparatory to supporting multiple formats by a single library
 
46
</message>
 
47
<parents>
 
48
<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92" revision_sha1="7bdf4cc8c5bdac739f8cf9b10b78cf4b68f915ff" />
 
49
</parents>
 
50
</revision>
 
51
"""
 
52
 
 
53
_revision_v5 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
 
54
    inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
 
55
    revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
 
56
    timestamp="1125907235.212"
 
57
    timezone="36000">
 
58
<message>- start splitting code for xml (de)serialization away from objects
 
59
  preparatory to supporting multiple formats by a single library
 
60
</message>
 
61
<parents>
 
62
<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92"/>
 
63
</parents>
 
64
</revision>
 
65
"""
 
66
 
 
67
_revision_v5_utc = """\
 
68
<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
 
69
    inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
 
70
    revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
 
71
    timestamp="1125907235.212"
 
72
    timezone="0">
 
73
<message>- start splitting code for xml (de)serialization away from objects
 
74
  preparatory to supporting multiple formats by a single library
 
75
</message>
 
76
<parents>
 
77
<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92"/>
 
78
</parents>
 
79
</revision>
 
80
"""
 
81
 
 
82
_committed_inv_v5 = """<inventory>
 
83
<file file_id="bar-20050901064931-73b4b1138abc9cd2" 
 
84
      name="bar" parent_id="TREE_ROOT" 
 
85
      revision="mbp@foo-123123"
 
86
      text_sha1="A" text_size="1"/>
 
87
<directory name="subdir"
 
88
           file_id="foo-20050801201819-4139aa4a272f4250"
 
89
           parent_id="TREE_ROOT" 
 
90
           revision="mbp@foo-00"/>
 
91
<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" 
 
92
      name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" 
 
93
      revision="mbp@foo-00"
 
94
      text_sha1="B" text_size="0"/>
 
95
</inventory>
 
96
"""
 
97
 
 
98
_basis_inv_v5 = """<inventory revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92">
 
99
<file file_id="bar-20050901064931-73b4b1138abc9cd2" 
 
100
      name="bar" parent_id="TREE_ROOT" 
 
101
      revision="mbp@foo-123123"/>
 
102
<directory name="subdir"
 
103
           file_id="foo-20050801201819-4139aa4a272f4250"
 
104
           parent_id="TREE_ROOT" 
 
105
           revision="mbp@foo-00"/>
 
106
<file file_id="bar-20050824000535-6bc48cfad47ed134" 
 
107
      name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" 
 
108
      revision="mbp@foo-00"/>
 
109
</inventory>
 
110
"""
 
111
 
 
112
 
 
113
# DO NOT REFLOW THIS. Its the exact revision we want.
 
114
_expected_rev_v5 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;" format="5" inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41" revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9" timestamp="1125907235.212" timezone="36000">
 
115
<message>- start splitting code for xml (de)serialization away from objects
 
116
  preparatory to supporting multiple formats by a single library
 
117
</message>
 
118
<parents>
 
119
<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92" />
 
120
</parents>
 
121
</revision>
 
122
"""
 
123
 
 
124
 
 
125
# DO NOT REFLOW THIS. Its the exact inventory we want.
 
126
_expected_inv_v5 = """<inventory format="5">
 
127
<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" revision="mbp@foo-123123" text_sha1="A" text_size="1" />
 
128
<directory file_id="foo-20050801201819-4139aa4a272f4250" name="subdir" revision="mbp@foo-00" />
 
129
<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp@foo-00" text_sha1="B" text_size="0" />
 
130
</inventory>
 
131
"""
 
132
 
 
133
 
 
134
_expected_inv_v5_root = """<inventory file_id="f&lt;" format="5" revision_id="mother!">
 
135
<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" parent_id="f&lt;" revision="mbp@foo-123123" text_sha1="A" text_size="1" />
 
136
<directory file_id="foo-20050801201819-4139aa4a272f4250" name="subdir" parent_id="f&lt;" revision="mbp@foo-00" />
 
137
<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp@foo-00" text_sha1="B" text_size="0" />
 
138
<symlink file_id="link-1" name="link" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp@foo-00" symlink_target="a" />
 
139
</inventory>
 
140
"""
 
141
 
 
142
_expected_inv_v7 = """<inventory format="7" revision_id="rev_outer">
 
143
<directory file_id="tree-root-321" name="" revision="rev_outer" />
 
144
<directory file_id="dir-id" name="dir" parent_id="tree-root-321" revision="rev_outer" />
 
145
<file file_id="file-id" name="file" parent_id="tree-root-321" revision="rev_outer" text_sha1="A" text_size="1" />
 
146
<symlink file_id="link-id" name="link" parent_id="tree-root-321" revision="rev_outer" symlink_target="a" />
 
147
<tree-reference file_id="nested-id" name="nested" parent_id="tree-root-321" revision="rev_outer" reference_revision="rev_inner" />
 
148
</inventory>
 
149
"""
 
150
 
 
151
_expected_rev_v8 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;" format="8" inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41" revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9" timestamp="1125907235.212" timezone="36000">
 
152
<message>- start splitting code for xml (de)serialization away from objects
 
153
  preparatory to supporting multiple formats by a single library
 
154
</message>
 
155
<parents>
 
156
<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92" />
 
157
</parents>
 
158
</revision>
 
159
"""
 
160
 
 
161
_expected_inv_v8 = """<inventory format="8" revision_id="rev_outer">
 
162
<directory file_id="tree-root-321" name="" revision="rev_outer" />
 
163
<directory file_id="dir-id" name="dir" parent_id="tree-root-321" revision="rev_outer" />
 
164
<file file_id="file-id" name="file" parent_id="tree-root-321" revision="rev_outer" text_sha1="A" text_size="1" />
 
165
<symlink file_id="link-id" name="link" parent_id="tree-root-321" revision="rev_outer" symlink_target="a" />
 
166
</inventory>
 
167
"""
 
168
 
 
169
_revision_utf8_v5 = """<revision committer="Erik B&#229;gfors &lt;erik@foo.net&gt;"
 
170
    inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
 
171
    revision_id="erik@b&#229;gfors-02"
 
172
    timestamp="1125907235.212"
 
173
    timezone="36000">
 
174
<message>Include &#181;nicode characters
 
175
</message>
 
176
<parents>
 
177
<revision_ref revision_id="erik@b&#229;gfors-01"/>
 
178
</parents>
 
179
</revision>
 
180
"""
 
181
 
 
182
_inventory_utf8_v5 = """<inventory file_id="TRE&#233;_ROOT" format="5"
 
183
                                   revision_id="erik@b&#229;gfors-02">
 
184
<file file_id="b&#229;r-01"
 
185
      name="b&#229;r" parent_id="TRE&#233;_ROOT"
 
186
      revision="erik@b&#229;gfors-01"/>
 
187
<directory name="s&#181;bdir"
 
188
           file_id="s&#181;bdir-01"
 
189
           parent_id="TRE&#233;_ROOT"
 
190
           revision="erik@b&#229;gfors-01"/>
 
191
<file executable="yes" file_id="b&#229;r-02"
 
192
      name="b&#229;r" parent_id="s&#181;bdir-01"
 
193
      revision="erik@b&#229;gfors-02"/>
 
194
</inventory>
 
195
"""
 
196
 
 
197
# Before revision_id was always stored as an attribute
 
198
_inventory_v5a = """<inventory format="5">
 
199
</inventory>
 
200
"""
 
201
 
 
202
# Before revision_id was always stored as an attribute
 
203
_inventory_v5b = """<inventory format="5" revision_id="a-rev-id">
 
204
</inventory>
 
205
"""
 
206
 
 
207
 
 
208
class TestSerializer(TestCase):
 
209
    """Test XML serialization"""
 
210
 
 
211
    def test_canned_inventory(self):
 
212
        """Test unpacked a canned inventory v4 file."""
 
213
        inp = StringIO(_working_inventory_v4)
 
214
        inv = serializer_v4.read_inventory(inp)
 
215
        self.assertEqual(len(inv), 4)
 
216
        self.assert_('bar-20050901064931-73b4b1138abc9cd2' in inv)
 
217
 
 
218
    def test_unpack_revision(self):
 
219
        """Test unpacking a canned revision v4"""
 
220
        inp = StringIO(_revision_v4)
 
221
        rev = serializer_v4.read_revision(inp)
 
222
        eq = self.assertEqual
 
223
        eq(rev.committer,
 
224
           "Martin Pool <mbp@sourcefrog.net>")
 
225
        eq(rev.inventory_id,
 
226
           "mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9")
 
227
        eq(len(rev.parent_ids), 1)
 
228
        eq(rev.parent_ids[0],
 
229
           "mbp@sourcefrog.net-20050905063503-43948f59fa127d92")
 
230
 
 
231
    def test_unpack_revision_5(self):
 
232
        """Test unpacking a canned revision v5"""
 
233
        inp = StringIO(_revision_v5)
 
234
        rev = bzrlib.xml5.serializer_v5.read_revision(inp)
 
235
        eq = self.assertEqual
 
236
        eq(rev.committer,
 
237
           "Martin Pool <mbp@sourcefrog.net>")
 
238
        eq(len(rev.parent_ids), 1)
 
239
        eq(rev.timezone, 36000)
 
240
        eq(rev.parent_ids[0],
 
241
           "mbp@sourcefrog.net-20050905063503-43948f59fa127d92")
 
242
 
 
243
    def test_unpack_revision_5_utc(self):
 
244
        inp = StringIO(_revision_v5_utc)
 
245
        rev = bzrlib.xml5.serializer_v5.read_revision(inp)
 
246
        eq = self.assertEqual
 
247
        eq(rev.committer,
 
248
           "Martin Pool <mbp@sourcefrog.net>")
 
249
        eq(len(rev.parent_ids), 1)
 
250
        eq(rev.timezone, 0)
 
251
        eq(rev.parent_ids[0],
 
252
           "mbp@sourcefrog.net-20050905063503-43948f59fa127d92")
 
253
 
 
254
    def test_unpack_inventory_5(self):
 
255
        """Unpack canned new-style inventory"""
 
256
        inp = StringIO(_committed_inv_v5)
 
257
        inv = bzrlib.xml5.serializer_v5.read_inventory(inp)
 
258
        eq = self.assertEqual
 
259
        eq(len(inv), 4)
 
260
        ie = inv['bar-20050824000535-6bc48cfad47ed134']
 
261
        eq(ie.kind, 'file')
 
262
        eq(ie.revision, 'mbp@foo-00')
 
263
        eq(ie.name, 'bar')
 
264
        eq(inv[ie.parent_id].kind, 'directory')
 
265
 
 
266
    def test_unpack_basis_inventory_5(self):
 
267
        """Unpack canned new-style inventory"""
 
268
        inp = StringIO(_basis_inv_v5)
 
269
        inv = bzrlib.xml5.serializer_v5.read_inventory(inp)
 
270
        eq = self.assertEqual
 
271
        eq(len(inv), 4)
 
272
        eq(inv.revision_id, 'mbp@sourcefrog.net-20050905063503-43948f59fa127d92')
 
273
        ie = inv['bar-20050824000535-6bc48cfad47ed134']
 
274
        eq(ie.kind, 'file')
 
275
        eq(ie.revision, 'mbp@foo-00')
 
276
        eq(ie.name, 'bar')
 
277
        eq(inv[ie.parent_id].kind, 'directory')
 
278
 
 
279
    def test_unpack_inventory_5a(self):
 
280
        inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(
 
281
                _inventory_v5a, revision_id='test-rev-id')
 
282
        self.assertEqual('test-rev-id', inv.root.revision)
 
283
 
 
284
    def test_unpack_inventory_5b(self):
 
285
        inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(
 
286
                _inventory_v5b, revision_id='test-rev-id')
 
287
        self.assertEqual('a-rev-id', inv.root.revision)
 
288
 
 
289
    def test_repack_inventory_5(self):
 
290
        inp = StringIO(_committed_inv_v5)
 
291
        inv = bzrlib.xml5.serializer_v5.read_inventory(inp)
 
292
        outp = StringIO()
 
293
        bzrlib.xml5.serializer_v5.write_inventory(inv, outp)
 
294
        self.assertEqualDiff(_expected_inv_v5, outp.getvalue())
 
295
        inv2 = bzrlib.xml5.serializer_v5.read_inventory(StringIO(outp.getvalue()))
 
296
        self.assertEqual(inv, inv2)
 
297
    
 
298
    def assertRoundTrips(self, xml_string):
 
299
        inp = StringIO(xml_string)
 
300
        inv = bzrlib.xml5.serializer_v5.read_inventory(inp)
 
301
        outp = StringIO()
 
302
        bzrlib.xml5.serializer_v5.write_inventory(inv, outp)
 
303
        self.assertEqualDiff(xml_string, outp.getvalue())
 
304
        lines = bzrlib.xml5.serializer_v5.write_inventory_to_lines(inv)
 
305
        outp.seek(0)
 
306
        self.assertEqual(outp.readlines(), lines)
 
307
        inv2 = bzrlib.xml5.serializer_v5.read_inventory(StringIO(outp.getvalue()))
 
308
        self.assertEqual(inv, inv2)
 
309
 
 
310
    def tests_serialize_inventory_v5_with_root(self):
 
311
        self.assertRoundTrips(_expected_inv_v5_root)
 
312
 
 
313
    def check_repack_revision(self, txt):
 
314
        """Check that repacking a revision yields the same information"""
 
315
        inp = StringIO(txt)
 
316
        rev = bzrlib.xml5.serializer_v5.read_revision(inp)
 
317
        outp = StringIO()
 
318
        bzrlib.xml5.serializer_v5.write_revision(rev, outp)
 
319
        outfile_contents = outp.getvalue()
 
320
        rev2 = bzrlib.xml5.serializer_v5.read_revision(StringIO(outfile_contents))
 
321
        self.assertEqual(rev, rev2)
 
322
 
 
323
    def test_repack_revision_5(self):
 
324
        """Round-trip revision to XML v5"""
 
325
        self.check_repack_revision(_revision_v5)
 
326
 
 
327
    def test_repack_revision_5_utc(self):
 
328
        self.check_repack_revision(_revision_v5_utc)
 
329
 
 
330
    def test_pack_revision_5(self):
 
331
        """Pack revision to XML v5"""
 
332
        # fixed 20051025, revisions should have final newline
 
333
        rev = bzrlib.xml5.serializer_v5.read_revision_from_string(_revision_v5)
 
334
        outp = StringIO()
 
335
        bzrlib.xml5.serializer_v5.write_revision(rev, outp)
 
336
        outfile_contents = outp.getvalue()
 
337
        self.assertEqual(outfile_contents[-1], '\n')
 
338
        self.assertEqualDiff(outfile_contents, bzrlib.xml5.serializer_v5.write_revision_to_string(rev))
 
339
        self.assertEqualDiff(outfile_contents, _expected_rev_v5)
 
340
 
 
341
    def test_empty_property_value(self):
 
342
        """Create an empty property value check that it serializes correctly"""
 
343
        s_v5 = bzrlib.xml5.serializer_v5
 
344
        rev = s_v5.read_revision_from_string(_revision_v5)
 
345
        outp = StringIO()
 
346
        props = {'empty':'', 'one':'one'}
 
347
        rev.properties = props
 
348
        txt = s_v5.write_revision_to_string(rev)
 
349
        new_rev = s_v5.read_revision_from_string(txt)
 
350
        self.assertEqual(props, new_rev.properties)
 
351
 
 
352
    def get_sample_inventory(self):
 
353
        inv = Inventory('tree-root-321', revision_id='rev_outer')
 
354
        inv.add(inventory.InventoryFile('file-id', 'file', 'tree-root-321'))
 
355
        inv.add(inventory.InventoryDirectory('dir-id', 'dir', 
 
356
                                             'tree-root-321'))
 
357
        inv.add(inventory.InventoryLink('link-id', 'link', 'tree-root-321'))
 
358
        inv['tree-root-321'].revision = 'rev_outer'
 
359
        inv['dir-id'].revision = 'rev_outer'
 
360
        inv['file-id'].revision = 'rev_outer'
 
361
        inv['file-id'].text_sha1 = 'A'
 
362
        inv['file-id'].text_size = 1
 
363
        inv['link-id'].revision = 'rev_outer'
 
364
        inv['link-id'].symlink_target = 'a'
 
365
        return inv
 
366
 
 
367
    def test_roundtrip_inventory_v7(self):
 
368
        inv = self.get_sample_inventory()
 
369
        inv.add(inventory.TreeReference('nested-id', 'nested', 'tree-root-321',
 
370
                                        'rev_outer', 'rev_inner'))
 
371
        txt = xml7.serializer_v7.write_inventory_to_string(inv)
 
372
        lines = xml7.serializer_v7.write_inventory_to_lines(inv)
 
373
        self.assertEqual(bzrlib.osutils.split_lines(txt), lines)
 
374
        self.assertEqualDiff(_expected_inv_v7, txt)
 
375
        inv2 = xml7.serializer_v7.read_inventory_from_string(txt)
 
376
        self.assertEqual(5, len(inv2))
 
377
        for path, ie in inv.iter_entries():
 
378
            self.assertEqual(ie, inv2[ie.file_id])
 
379
 
 
380
    def test_wrong_format_v7(self):
 
381
        """Can't accidentally open a file with wrong serializer"""
 
382
        s_v6 = bzrlib.xml6.serializer_v6
 
383
        s_v7 = xml7.serializer_v7
 
384
        self.assertRaises(errors.UnexpectedInventoryFormat, 
 
385
                          s_v7.read_inventory_from_string, _expected_inv_v5)
 
386
        self.assertRaises(errors.UnexpectedInventoryFormat, 
 
387
                          s_v6.read_inventory_from_string, _expected_inv_v7)
 
388
 
 
389
    def test_tree_reference(self):
 
390
        s_v5 = bzrlib.xml5.serializer_v5
 
391
        s_v6 = bzrlib.xml6.serializer_v6
 
392
        s_v7 = xml7.serializer_v7
 
393
        inv = Inventory('tree-root-321', revision_id='rev-outer')
 
394
        inv.root.revision = 'root-rev'
 
395
        inv.add(inventory.TreeReference('nested-id', 'nested', 'tree-root-321',
 
396
                                        'rev-outer', 'rev-inner'))
 
397
        self.assertRaises(errors.UnsupportedInventoryKind,
 
398
                          s_v5.write_inventory_to_string, inv)
 
399
        self.assertRaises(errors.UnsupportedInventoryKind,
 
400
                          s_v6.write_inventory_to_string, inv)
 
401
        txt = s_v7.write_inventory_to_string(inv)
 
402
        lines = s_v7.write_inventory_to_lines(inv)
 
403
        self.assertEqual(bzrlib.osutils.split_lines(txt), lines)
 
404
        inv2 = s_v7.read_inventory_from_string(txt)
 
405
        self.assertEqual('tree-root-321', inv2['nested-id'].parent_id)
 
406
        self.assertEqual('rev-outer', inv2['nested-id'].revision)
 
407
        self.assertEqual('rev-inner', inv2['nested-id'].reference_revision)
 
408
        self.assertRaises(errors.UnsupportedInventoryKind, 
 
409
                          s_v6.read_inventory_from_string,
 
410
                          txt.replace('format="7"', 'format="6"'))
 
411
        self.assertRaises(errors.UnsupportedInventoryKind, 
 
412
                          s_v5.read_inventory_from_string,
 
413
                          txt.replace('format="7"', 'format="5"'))
 
414
 
 
415
    def test_roundtrip_inventory_v8(self):
 
416
        inv = self.get_sample_inventory()
 
417
        txt = xml8.serializer_v8.write_inventory_to_string(inv)
 
418
        inv2 = xml8.serializer_v8.read_inventory_from_string(txt)
 
419
        self.assertEqual(4, len(inv2))
 
420
        for path, ie in inv.iter_entries():
 
421
            self.assertEqual(ie, inv2[ie.file_id])
 
422
 
 
423
    def test_inventory_text_v8(self):
 
424
        inv = self.get_sample_inventory()
 
425
        txt = xml8.serializer_v8.write_inventory_to_string(inv)
 
426
        lines = xml8.serializer_v8.write_inventory_to_lines(inv)
 
427
        self.assertEqual(bzrlib.osutils.split_lines(txt), lines)
 
428
        self.assertEqualDiff(_expected_inv_v8, txt)
 
429
 
 
430
    def test_revision_text_v6(self):
 
431
        """Pack revision to XML v6"""
 
432
        rev = bzrlib.xml6.serializer_v6.read_revision_from_string(
 
433
            _expected_rev_v5)
 
434
        serialized = bzrlib.xml6.serializer_v6.write_revision_to_string(rev)
 
435
        self.assertEqualDiff(serialized, _expected_rev_v5)
 
436
 
 
437
    def test_revision_text_v7(self):
 
438
        """Pack revision to XML v7"""
 
439
        rev = bzrlib.xml7.serializer_v7.read_revision_from_string(
 
440
            _expected_rev_v5)
 
441
        serialized = bzrlib.xml7.serializer_v7.write_revision_to_string(rev)
 
442
        self.assertEqualDiff(serialized, _expected_rev_v5)
 
443
 
 
444
    def test_revision_text_v8(self):
 
445
        """Pack revision to XML v8"""
 
446
        rev = bzrlib.xml8.serializer_v8.read_revision_from_string(
 
447
            _expected_rev_v8)
 
448
        serialized = bzrlib.xml8.serializer_v8.write_revision_to_string(rev)
 
449
        self.assertEqualDiff(serialized, _expected_rev_v8)
 
450
 
 
451
    def test_revision_ids_are_utf8(self):
 
452
        """Parsed revision_ids should all be utf-8 strings, not unicode."""
 
453
        s_v5 = bzrlib.xml5.serializer_v5
 
454
        rev = s_v5.read_revision_from_string(_revision_utf8_v5)
 
455
        self.assertEqual('erik@b\xc3\xa5gfors-02', rev.revision_id)
 
456
        self.assertIsInstance(rev.revision_id, str)
 
457
        self.assertEqual(['erik@b\xc3\xa5gfors-01'], rev.parent_ids)
 
458
        for parent_id in rev.parent_ids:
 
459
            self.assertIsInstance(parent_id, str)
 
460
        self.assertEqual(u'Include \xb5nicode characters\n', rev.message)
 
461
        self.assertIsInstance(rev.message, unicode)
 
462
 
 
463
        # ie.revision should either be None or a utf-8 revision id
 
464
        inv = s_v5.read_inventory_from_string(_inventory_utf8_v5)
 
465
        rev_id_1 = u'erik@b\xe5gfors-01'.encode('utf8')
 
466
        rev_id_2 = u'erik@b\xe5gfors-02'.encode('utf8')
 
467
        fid_root = u'TRE\xe9_ROOT'.encode('utf8')
 
468
        fid_bar1 = u'b\xe5r-01'.encode('utf8')
 
469
        fid_sub = u's\xb5bdir-01'.encode('utf8')
 
470
        fid_bar2 = u'b\xe5r-02'.encode('utf8')
 
471
        expected = [(u'', fid_root, None, rev_id_2),
 
472
                    (u'b\xe5r', fid_bar1, fid_root, rev_id_1),
 
473
                    (u's\xb5bdir', fid_sub, fid_root, rev_id_1),
 
474
                    (u's\xb5bdir/b\xe5r', fid_bar2, fid_sub, rev_id_2),
 
475
                   ]
 
476
        self.assertEqual(rev_id_2, inv.revision_id)
 
477
        self.assertIsInstance(inv.revision_id, str)
 
478
 
 
479
        actual = list(inv.iter_entries_by_dir())
 
480
        for ((exp_path, exp_file_id, exp_parent_id, exp_rev_id),
 
481
             (act_path, act_ie)) in zip(expected, actual):
 
482
            self.assertEqual(exp_path, act_path)
 
483
            self.assertIsInstance(act_path, unicode)
 
484
            self.assertEqual(exp_file_id, act_ie.file_id)
 
485
            self.assertIsInstance(act_ie.file_id, str)
 
486
            self.assertEqual(exp_parent_id, act_ie.parent_id)
 
487
            if exp_parent_id is not None:
 
488
                self.assertIsInstance(act_ie.parent_id, str)
 
489
            self.assertEqual(exp_rev_id, act_ie.revision)
 
490
            if exp_rev_id is not None:
 
491
                self.assertIsInstance(act_ie.revision, str)
 
492
 
 
493
        self.assertEqual(len(expected), len(actual))
 
494
 
 
495
    def test_registry(self):
 
496
        self.assertIs(serializer_v4,
 
497
                      xml_serializer.format_registry.get('4'))
 
498
        self.assertIs(bzrlib.xml5.serializer_v5,
 
499
                      xml_serializer.format_registry.get('5'))
 
500
        self.assertIs(bzrlib.xml6.serializer_v6,
 
501
                      xml_serializer.format_registry.get('6'))
 
502
        self.assertIs(bzrlib.xml7.serializer_v7,
 
503
                      xml_serializer.format_registry.get('7'))
 
504
        self.assertIs(bzrlib.xml8.serializer_v8,
 
505
                      xml_serializer.format_registry.get('8'))
 
506
 
 
507
 
 
508
class TestEncodeAndEscape(TestCase):
 
509
    """Whitebox testing of the _encode_and_escape function."""
 
510
 
 
511
    def setUp(self):
 
512
        # Keep the cache clear before and after the test
 
513
        bzrlib.xml8._ensure_utf8_re()
 
514
        bzrlib.xml8._clear_cache()
 
515
        self.addCleanup(bzrlib.xml8._clear_cache)
 
516
 
 
517
    def test_simple_ascii(self):
 
518
        # _encode_and_escape always appends a final ", because these parameters
 
519
        # are being used in xml attributes, and by returning it now, we have to
 
520
        # do fewer string operations later.
 
521
        val = bzrlib.xml8._encode_and_escape('foo bar')
 
522
        self.assertEqual('foo bar"', val)
 
523
        # The second time should be cached
 
524
        val2 = bzrlib.xml8._encode_and_escape('foo bar')
 
525
        self.assertIs(val2, val)
 
526
 
 
527
    def test_ascii_with_xml(self):
 
528
        self.assertEqual('&amp;&apos;&quot;&lt;&gt;"',
 
529
                         bzrlib.xml8._encode_and_escape('&\'"<>'))
 
530
 
 
531
    def test_utf8_with_xml(self):
 
532
        # u'\xb5\xe5&\u062c'
 
533
        utf8_str = '\xc2\xb5\xc3\xa5&\xd8\xac'
 
534
        self.assertEqual('&#181;&#229;&amp;&#1580;"',
 
535
                         bzrlib.xml8._encode_and_escape(utf8_str))
 
536
 
 
537
    def test_unicode(self):
 
538
        uni_str = u'\xb5\xe5&\u062c'
 
539
        self.assertEqual('&#181;&#229;&amp;&#1580;"',
 
540
                         bzrlib.xml8._encode_and_escape(uni_str))