Merge dev tree.
[jelmer/subvertpy.git] / tests / test_repos.py
1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
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 bzrlib.branch import Branch
18 from bzrlib.bzrdir import BzrDir
19 from bzrlib.errors import NoSuchRevision, BzrError, UninitializableFormat
20 from bzrlib.inventory import Inventory
21 import bzrlib.osutils as osutils
22 from bzrlib.repository import Repository
23 from bzrlib.revision import NULL_REVISION
24 from bzrlib.tests import TestCase
25 from bzrlib.trace import mutter
26 from bzrlib.transport.local import LocalTransport
27
28 import os
29
30 import svn.fs
31
32 from convert import load_dumpfile
33 import errors
34 import format
35 from scheme import TrunkBranchingScheme, NoBranchingScheme
36 from transport import SvnRaTransport
37 from tests import TestCaseWithSubversionRepository
38 import repository
39 from repository import (parse_svn_revision_id, generate_svn_revision_id, 
40                         svk_feature_to_revision_id, revision_id_to_svk_feature,
41                         MAPPING_VERSION, escape_svn_path, unescape_svn_path,
42                         SvnRepositoryFormat)
43
44
45 class TestSubversionRepositoryWorks(TestCaseWithSubversionRepository):
46     def test_format(self):
47         """ Test repository format is correct """
48         bzrdir = self.make_local_bzrdir('a', 'ac')
49         self.assertEqual(bzrdir._format.get_format_string(), \
50                 "Subversion Local Checkout")
51         
52         self.assertEqual(bzrdir._format.get_format_description(), \
53                 "Subversion Local Checkout")
54
55     def test_get_branch_log(self):
56         repos_url = self.make_client("a", "dc")
57         self.build_tree({'dc/foo': "data"})
58         self.client_add("dc/foo")
59         self.client_commit("dc", "My Message")
60
61         repos = Repository.open(repos_url)
62
63         self.assertEqual(1, len(list(repos.follow_branch_history("", 1))))
64
65     def test_make_working_trees(self):
66         repos_url = self.make_client("a", "dc")
67         repos = Repository.open(repos_url)
68         self.assertFalse(repos.make_working_trees())
69
70     def test_set_make_working_trees(self):
71         repos_url = self.make_client("a", "dc")
72         repos = Repository.open(repos_url)
73         repos.set_make_working_trees(True)
74         self.assertFalse(repos.make_working_trees())
75
76     def test_add_revision(self):
77         repos_url = self.make_client("a", "dc")
78         repos = Repository.open(repos_url)
79         self.assertRaises(NotImplementedError, repos.add_revision, "revid", 
80                 None)
81
82     def test_has_signature_for_revision_id(self):
83         repos_url = self.make_client("a", "dc")
84         repos = Repository.open(repos_url)
85         self.assertFalse(repos.has_signature_for_revision_id("foo"))
86
87     def test_repr(self):
88         repos_url = self.make_client("a", "dc")
89         self.build_tree({'dc/foo': "data"})
90         self.client_add("dc/foo")
91         self.client_commit("dc", "My Message")
92
93         repos = Repository.open(repos_url)
94
95         self.assertEqual("SvnRepository('file://%s/')" % os.path.join(self.test_dir, "a"), repos.__repr__())
96
97     def test_get_branch_invalid_revision(self):
98         repos_url = self.make_client("a", "dc")
99         repos = Repository.open(repos_url)
100         self.assertRaises(NoSuchRevision, list, 
101                           repos.follow_branch_history("/", 20))
102
103     def test_history_all(self):
104         repos_url = self.make_client("a", "dc")
105         self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
106         self.client_add("dc/trunk")
107         self.client_add("dc/foo")
108         self.client_commit("dc", "My Message")
109
110         repos = Repository.open(repos_url)
111
112         self.assertEqual(1, len(list(repos.follow_history(1))))
113
114     def test_all_revs_empty(self):
115         repos_url = self.make_client("a", "dc")
116         repos = Repository.open(repos_url)
117         repos.set_branching_scheme(TrunkBranchingScheme())
118         self.assertEqual([], list(repos.all_revision_ids()))
119
120     def test_all_revs(self):
121         repos_url = self.make_client("a", "dc")
122         self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
123         self.client_add("dc/trunk")
124         self.client_commit("dc", "add trunk")
125         self.build_tree({'dc/branches/somebranch/somefile': 'data'})
126         self.client_add("dc/branches")
127         self.client_commit("dc", "add a branch")
128         self.client_delete("dc/branches/somebranch")
129         self.client_commit("dc", "remove branch")
130
131         repos = Repository.open(repos_url)
132         repos.set_branching_scheme(TrunkBranchingScheme())
133         self.assertEqual([
134             repos.generate_revision_id(2, "branches/somebranch"),
135             repos.generate_revision_id(1, "trunk")], 
136             list(repos.all_revision_ids()))
137
138     def test_follow_history_follow(self):
139         repos_url = self.make_client("a", "dc")
140         self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
141         self.client_add("dc/trunk")
142         self.client_add("dc/branches")
143         self.client_commit("dc", "My Message")
144
145         self.client_copy("dc/trunk", "dc/branches/abranch")
146         self.client_commit("dc", "Create branch")
147
148         repos = Repository.open(repos_url)
149         repos.set_branching_scheme(TrunkBranchingScheme())
150
151         items = list(repos.follow_history(2))
152         self.assertEqual([('branches/abranch', 2), 
153                           ('trunk', 1)], items)
154
155     def test_branch_log_specific(self):
156         repos_url = self.make_client("a", "dc")
157         self.build_tree({
158             'dc/branches': None,
159             'dc/branches/brancha': None,
160             'dc/branches/branchab': None,
161             'dc/branches/brancha/data': "data", 
162             "dc/branches/branchab/data":"data"})
163         self.client_add("dc/branches")
164         self.client_commit("dc", "My Message")
165
166         repos = Repository.open(repos_url)
167         repos.set_branching_scheme(TrunkBranchingScheme())
168
169         self.assertEqual(1, len(list(repos.follow_branch_history("branches/brancha",
170             1))))
171
172     def test_branch_log_specific_ignore(self):
173         repos_url = self.make_client("a", "dc")
174         self.build_tree({'dc/branches': None})
175         self.client_add("dc/branches")
176         self.build_tree({
177             'dc/branches/brancha': None,
178             'dc/branches/branchab': None,
179             'dc/branches/brancha/data': "data", 
180             "dc/branches/branchab/data":"data"})
181         self.client_add("dc/branches/brancha")
182         self.client_commit("dc", "My Message")
183
184         self.client_add("dc/branches/branchab")
185         self.client_commit("dc", "My Message2")
186
187         repos = Repository.open(repos_url)
188         repos.set_branching_scheme(TrunkBranchingScheme())
189
190         self.assertEqual(1, len(list(repos.follow_branch_history("branches/brancha",
191             2))))
192
193     def test_find_branches_moved(self):
194         repos_url = self.make_client("a", "dc")
195         self.build_tree({
196             'dc/tmp/branches/brancha': None,
197             'dc/tmp/branches/branchab': None,
198             'dc/tmp/branches/brancha/data': "data", 
199             "dc/tmp/branches/branchab/data":"data"})
200         self.client_add("dc/tmp")
201         self.client_commit("dc", "My Message")
202         self.client_copy("dc/tmp/branches", "dc/tags")
203         self.client_commit("dc", "My Message 2")
204
205         repos = Repository.open(repos_url)
206         repos.set_branching_scheme(TrunkBranchingScheme())
207
208         self.assertEqual([("tags/branchab", 2, True), 
209                           ("tags/brancha", 2, True)], 
210                 list(repos.find_branches(2)))
211
212     def test_find_branches_moved_nobranch(self):
213         repos_url = self.make_client("a", "dc")
214         self.build_tree({
215             'dc/tmp/nested/foobar': None,
216             'dc/tmp/nested/branches/brancha': None,
217             'dc/tmp/nested/branches/branchab': None,
218             'dc/tmp/nested/branches/brancha/data': "data", 
219             "dc/tmp/nested/branches/branchab/data":"data"})
220         self.client_add("dc/tmp")
221         self.client_commit("dc", "My Message")
222         self.client_copy("dc/tmp/nested", "dc/t2")
223         self.client_commit("dc", "My Message 2")
224
225         repos = Repository.open(repos_url)
226         repos.set_branching_scheme(TrunkBranchingScheme(1))
227
228         self.assertEqual([("t2/branches/brancha", 2, True), 
229                           ("t2/branches/branchab", 2, True)], 
230                 list(repos.find_branches(2)))
231
232     def test_find_branches_no(self):
233         repos_url = self.make_client("a", "dc")
234
235         repos = Repository.open(repos_url)
236         repos.set_branching_scheme(NoBranchingScheme())
237
238         self.assertEqual([("", 0, True)], list(repos.find_branches(0)))
239
240     def test_find_branches_no_later(self):
241         repos_url = self.make_client("a", "dc")
242
243         repos = Repository.open(repos_url)
244         repos.set_branching_scheme(NoBranchingScheme())
245
246         self.assertEqual([("", 0, True)], list(repos.find_branches(0)))
247
248     def test_find_branches_trunk_empty(self):
249         repos_url = self.make_client("a", "dc")
250
251         repos = Repository.open(repos_url)
252         repos.set_branching_scheme(TrunkBranchingScheme())
253
254         self.assertEqual([], list(repos.find_branches(0)))
255
256     def test_find_branches_trunk_one(self):
257         repos_url = self.make_client("a", "dc")
258
259         repos = Repository.open(repos_url)
260         repos.set_branching_scheme(TrunkBranchingScheme())
261
262         self.build_tree({'dc/trunk/foo': "data"})
263         self.client_add("dc/trunk")
264         self.client_commit("dc", "My Message")
265
266         self.assertEqual([("trunk", 1, True)], list(repos.find_branches(1)))
267
268     def test_find_branches_removed(self):
269         repos_url = self.make_client("a", "dc")
270
271         repos = Repository.open(repos_url)
272         repos.set_branching_scheme(TrunkBranchingScheme())
273
274         self.build_tree({'dc/trunk/foo': "data"})
275         self.client_add("dc/trunk")
276         self.client_commit("dc", "My Message")
277
278         self.client_delete("dc/trunk")
279         self.client_commit("dc", "remove")
280
281         self.assertEqual([("trunk", 1, True)], list(repos.find_branches(1)))
282         self.assertEqual([("trunk", 2, False)], list(repos.find_branches(2)))
283
284     def test_url(self):
285         """ Test repository URL is kept """
286         bzrdir = self.make_local_bzrdir('b', 'bc')
287         self.assertTrue(isinstance(bzrdir, BzrDir))
288
289     def test_uuid(self):
290         """ Test UUID is retrieved correctly """
291         bzrdir = self.make_local_bzrdir('c', 'cc')
292         self.assertTrue(isinstance(bzrdir, BzrDir))
293         repository = bzrdir.find_repository()
294         fs = self.open_fs('c')
295         self.assertEqual(svn.fs.get_uuid(fs), repository.uuid)
296
297     def test_get_inventory_weave(self):
298         bzrdir = self.make_client_and_bzrdir('d', 'dc')
299         repository = bzrdir.find_repository()
300         self.assertRaises(NotImplementedError, repository.get_inventory_weave)
301
302     def test_has_revision(self):
303         bzrdir = self.make_client_and_bzrdir('d', 'dc')
304         repository = bzrdir.find_repository()
305         self.build_tree({'dc/foo': "data"})
306         self.client_add("dc/foo")
307         self.client_commit("dc", "My Message")
308         self.assertTrue(repository.has_revision(
309             repository.generate_revision_id(1, "")))
310         self.assertFalse(repository.has_revision("some-other-revision"))
311
312     def test_has_revision_none(self):
313         bzrdir = self.make_client_and_bzrdir('d', 'dc')
314         repository = bzrdir.find_repository()
315         self.assertTrue(repository.has_revision(None))
316
317     def test_revision_parents(self):
318         repos_url = self.make_client('d', 'dc')
319         self.build_tree({'dc/foo': "data"})
320         self.client_add("dc/foo")
321         self.client_commit("dc", "My Message")
322         self.build_tree({'dc/foo': "data2"})
323         self.client_commit("dc", "Second Message")
324         repository = Repository.open("svn+%s" % repos_url)
325         self.assertEqual([],
326                 repository.revision_parents(
327                     repository.generate_revision_id(1, "")))
328         self.assertEqual([
329             repository.generate_revision_id(1, "")],
330             repository.revision_parents(
331                 repository.generate_revision_id(2, "")))
332
333     def test_revision_fileidmap(self):
334         repos_url = self.make_client('d', 'dc')
335         self.build_tree({'dc/foo': "data"})
336         self.client_add("dc/foo")
337         self.client_set_prop("dc", "bzr:file-ids", "foo\tsomeid\n")
338         self.client_commit("dc", "My Message")
339         repository = Repository.open("svn+%s" % repos_url)
340         tree = repository.revision_tree(Branch.open(repos_url).last_revision())
341         self.assertEqual("someid", tree.inventory.path2id("foo"))
342         self.assertFalse("1@%s::foo" % repository.uuid in tree.inventory)
343
344     def test_revision_ghost_parents(self):
345         repos_url = self.make_client('d', 'dc')
346         self.build_tree({'dc/foo': "data"})
347         self.client_add("dc/foo")
348         self.client_commit("dc", "My Message")
349         self.build_tree({'dc/foo': "data2"})
350         self.client_set_prop("dc", "bzr:merge", "ghostparent\n")
351         self.client_commit("dc", "Second Message")
352         repository = Repository.open("svn+%s" % repos_url)
353         self.assertEqual([],
354                 repository.revision_parents(
355                     repository.generate_revision_id(1, "")))
356         self.assertEqual([repository.generate_revision_id(1, ""),
357             "ghostparent"], 
358                 repository.revision_parents(
359                     repository.generate_revision_id(2, "")))
360  
361     
362     def test_get_revision(self):
363         repos_url = self.make_client('d', 'dc')
364         repository = Repository.open("svn+%s" % repos_url)
365         self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
366         self.build_tree({'dc/foo': "data"})
367         self.client_add("dc/foo")
368         self.client_commit("dc", "My Message")
369         self.build_tree({'dc/foo': "data2"})
370         (num, date, author) = self.client_commit("dc", "Second Message")
371         repository = Repository.open("svn+%s" % repos_url)
372         rev = repository.get_revision(
373             repository.generate_revision_id(2, ""))
374         self.assertEqual([repository.generate_revision_id(1, "")],
375                 rev.parent_ids)
376         self.assertEqual(rev.revision_id, repository.generate_revision_id(2, ""))
377         self.assertEqual(author, rev.committer)
378         self.assertIsInstance(rev.properties, dict)
379
380     def test_get_ancestry(self):
381         repos_url = self.make_client('d', 'dc')
382         repository = Repository.open("svn+%s" % repos_url)
383         self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
384         self.build_tree({'dc/foo': "data"})
385         self.client_add("dc/foo")
386         self.client_commit("dc", "My Message")
387         self.build_tree({'dc/foo': "data2"})
388         self.client_commit("dc", "Second Message")
389         self.build_tree({'dc/foo': "data3"})
390         self.client_commit("dc", "Third Message")
391         repository = Repository.open("svn+%s" % repos_url)
392         self.assertEqual([None, 
393             repository.generate_revision_id(1, ""),
394             repository.generate_revision_id(2, "")],
395                 repository.get_ancestry(
396                     repository.generate_revision_id(3, "")))
397         self.assertEqual([None, 
398             repository.generate_revision_id(1, "")],
399                 repository.get_ancestry(
400                     repository.generate_revision_id(2, "")))
401         self.assertEqual([None],
402                 repository.get_ancestry(
403                     repository.generate_revision_id(1, "")))
404         self.assertEqual([None], repository.get_ancestry(None))
405
406     def test_get_revision_graph_empty(self):
407         repos_url = self.make_client('d', 'dc')
408         repository = Repository.open("svn+%s" % repos_url)
409         self.assertEqual({}, repository.get_revision_graph(NULL_REVISION))
410
411     def test_get_revision_graph_invalid(self):
412         repos_url = self.make_client('d', 'dc')
413         repository = Repository.open("svn+%s" % repos_url)
414         self.assertRaises(NoSuchRevision, repository.get_revision_graph, 
415                           "nonexisting")
416
417     def test_get_revision_graph_all_empty(self):
418         repos_url = self.make_client('d', 'dc')
419         repository = Repository.open(repos_url)
420         self.assertEqual({}, repository.get_revision_graph())
421
422     def test_get_revision_graph_all(self):
423         repos_url = self.make_client('d', 'dc')
424         self.build_tree({'dc/trunk/a': 'data', 'dc/branches/foo/b': 'alsodata'})
425         self.client_add("dc/trunk")
426         self.client_add("dc/branches")
427         self.client_commit("dc", "initial commit")
428         self.build_tree({'dc/trunk/a': "bloe"})
429         self.client_commit("dc", "second commit")
430         repository = Repository.open(repos_url)
431         repository.set_branching_scheme(TrunkBranchingScheme())
432         self.assertEqual({repository.generate_revision_id(1, "trunk"): [],
433                           repository.generate_revision_id(2, "trunk"): [repository.generate_revision_id(1, "trunk")],
434                           repository.generate_revision_id(1, "branches/foo"): []
435                           }, repository.get_revision_graph())
436
437     def test_get_revision_graph(self):
438         repos_url = self.make_client('d', 'dc')
439         repository = Repository.open("svn+%s" % repos_url)
440         self.build_tree({'dc/foo': "data"})
441         self.client_add("dc/foo")
442         self.client_commit("dc", "My Message")
443         self.build_tree({'dc/foo': "data2"})
444         self.client_commit("dc", "Second Message")
445         self.build_tree({'dc/foo': "data3"})
446         self.client_commit("dc", "Third Message")
447         repository = Repository.open("svn+%s" % repos_url)
448         self.assertEqual({
449            repository.generate_revision_id(3, ""): [
450                repository.generate_revision_id(2, "")],
451            repository.generate_revision_id(2, ""): [
452                repository.generate_revision_id(1, "")], 
453            repository.generate_revision_id(1, ""): []},
454                 repository.get_revision_graph(
455                     repository.generate_revision_id(3, "")))
456         self.assertEqual({
457            repository.generate_revision_id(2, ""): [
458                repository.generate_revision_id(1, "")],
459            repository.generate_revision_id(1, ""): []},
460                 repository.get_revision_graph(
461                     repository.generate_revision_id(2, "")))
462         self.assertEqual({
463             repository.generate_revision_id(1, ""): []},
464                 repository.get_revision_graph(
465                     repository.generate_revision_id(1, "")))
466
467     def test_get_ancestry2(self):
468         repos_url = self.make_client('d', 'dc')
469         self.build_tree({'dc/foo': "data"})
470         self.client_add("dc/foo")
471         self.client_commit("dc", "My Message")
472         self.build_tree({'dc/foo': "data2"})
473         self.client_commit("dc", "Second Message")
474         repository = Repository.open("svn+%s" % repos_url)
475         self.assertEqual([None],
476                 repository.get_ancestry(
477                     repository.generate_revision_id(1, "")))
478         self.assertEqual([None, 
479             repository.generate_revision_id(1, "")], 
480                 repository.get_ancestry(
481                     repository.generate_revision_id(2, "")))
482
483     def test_get_ancestry_merged(self):
484         repos_url = self.make_client('d', 'dc')
485         self.build_tree({'dc/foo': "data"})
486         self.client_add("dc/foo")
487         self.client_commit("dc", "My Message")
488         self.client_set_prop("dc", "bzr:merge", "a-parent\n")
489         self.build_tree({'dc/foo': "data2"})
490         self.client_commit("dc", "Second Message")
491         repository = Repository.open("svn+%s" % repos_url)
492         self.assertEqual([None],
493                 repository.get_ancestry(
494                     repository.generate_revision_id(1, "")))
495         self.assertEqual([None, 
496             repository.generate_revision_id(1, ""), 
497                           "a-parent"], 
498                 repository.get_ancestry(
499                     repository.generate_revision_id(2, "")))
500
501
502     def test_get_inventory(self):
503         repos_url = self.make_client('d', 'dc')
504         repository = Repository.open("svn+%s" % repos_url)
505         self.assertRaises(NoSuchRevision, repository.get_inventory, "nonexisting")
506         self.build_tree({'dc/foo': "data", 'dc/blah': "other data"})
507         self.client_add("dc/foo")
508         self.client_add("dc/blah")
509         self.client_commit("dc", "My Message")
510         self.build_tree({'dc/foo': "data2", "dc/bar/foo": "data3"})
511         self.client_add("dc/bar")
512         self.client_commit("dc", "Second Message")
513         self.build_tree({'dc/foo': "data3"})
514         self.client_commit("dc", "Third Message")
515         repository = Repository.open("svn+%s" % repos_url)
516         inv = repository.get_inventory(
517                 repository.generate_revision_id(1, ""))
518         self.assertIsInstance(inv, Inventory)
519         self.assertIsInstance(inv.path2id("foo"), basestring)
520         inv = repository.get_inventory(
521                 repository.generate_revision_id(2, ""))
522         self.assertEqual(repository.generate_revision_id(2, ""), 
523                          inv[inv.path2id("foo")].revision)
524         self.assertEqual(repository.generate_revision_id(1, ""), 
525                          inv[inv.path2id("blah")].revision)
526         self.assertIsInstance(inv, Inventory)
527         self.assertIsInstance(inv.path2id("foo"), basestring)
528         self.assertIsInstance(inv.path2id("bar"), basestring)
529         self.assertIsInstance(inv.path2id("bar/foo"), basestring)
530
531     def test_generate_revision_id(self):
532         repos_url = self.make_client('d', 'dc')
533         repository = Repository.open("svn+%s" % repos_url)
534         self.assertEqual(
535                u"svn-v%d-undefined:%s:bla%%2Fbloe:1" % (MAPPING_VERSION, repository.uuid), 
536             repository.generate_revision_id(1, "bla/bloe"))
537
538     def test_generate_revision_id_none(self):
539         repos_url = self.make_client('d', 'dc')
540         repository = Repository.open("svn+%s" % repos_url)
541         self.assertEqual(NULL_REVISION, 
542                 repository.generate_revision_id(0, "bla/bloe"))
543
544     def test_parse_revision_id(self):
545         repos_url = self.make_client('d', 'dc')
546         repository = Repository.open("svn+%s" % repos_url)
547         self.assertRaises(NoSuchRevision, repository.parse_revision_id, 
548             "nonexisting")
549         self.assertEqual(("bloe", 1), 
550             repository.parse_revision_id(
551                 repository.generate_revision_id(1, "bloe")))
552
553     def test_parse_revision_id_invalid_uuid(self):
554         repos_url = self.make_client('d', 'dc')
555         repository = Repository.open("svn+%s" % repos_url)
556         self.assertRaises(NoSuchRevision, 
557             repository.parse_revision_id, 
558                 generate_svn_revision_id("invaliduuid", 0, "bloe"))
559         
560     def test_check(self):
561         repos_url = self.make_client('d', 'dc')
562         self.build_tree({'dc/foo': "data"})
563         self.client_add("dc/foo")
564         self.client_commit("dc", "My Message")
565         repository = Repository.open("svn+%s" % repos_url)
566         repository.check([
567             repository.generate_revision_id(0, ""), 
568             repository.generate_revision_id(1, "")])
569
570     def test_copy_contents_into(self):
571         repos_url = self.make_client('d', 'dc')
572         self.build_tree({'dc/foo/bla': "data"})
573         self.client_add("dc/foo")
574         self.client_commit("dc", "My Message")
575         self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
576         self.client_add("dc/foo/blo")
577         self.client_add("dc/bar")
578         self.client_commit("dc", "Second Message")
579         repository = Repository.open("svn+%s" % repos_url)
580
581         to_repos = BzrDir.create_repository("e")
582
583         repository.copy_content_into(to_repos, 
584                 repository.generate_revision_id(2, ""))
585
586         self.assertTrue(repository.has_revision(
587             repository.generate_revision_id(2, "")))
588         self.assertTrue(repository.has_revision(
589             repository.generate_revision_id(1, "")))
590         self.assertFalse(repository.has_revision(
591             repository.generate_revision_id(4, "")))
592
593     def test_is_shared(self):
594         repos_url = self.make_client('d', 'dc')
595         self.build_tree({'dc/foo/bla': "data"})
596         self.client_add("dc/foo")
597         self.client_commit("dc", "My Message")
598         repository = Repository.open("svn+%s" % repos_url)
599         self.assertTrue(repository.is_shared())
600
601     def test_revision_fileid_renames(self):
602         repos_url = self.make_client('d', 'dc')
603         self.build_tree({'dc/test': "data"})
604         self.client_add("dc/test")
605         self.client_set_prop("dc", "bzr:file-ids", "test\tbla\n")
606         self.client_commit("dc", "Msg")
607
608         repos = Repository.open(repos_url)
609         renames = repos.revision_fileid_renames(repos.generate_revision_id(1, ""))
610         self.assertEqual({"test": "bla"}, renames)
611
612     def test_fetch_fileid_renames(self):
613         repos_url = self.make_client('d', 'dc')
614         self.build_tree({'dc/test': "data"})
615         self.client_add("dc/test")
616         self.client_set_prop("dc", "bzr:file-ids", "test\tbla\n")
617         self.client_commit("dc", "Msg")
618
619         oldrepos = Repository.open(repos_url)
620         dir = BzrDir.create("f")
621         newrepos = dir.create_repository()
622         oldrepos.copy_content_into(newrepos)
623         self.assertEqual("bla", newrepos.get_inventory(
624             oldrepos.generate_revision_id(1, "")).path2id("test"))
625
626     def test_fetch_trunk1(self):
627         repos_url = self.make_client('d', 'dc')
628         self.build_tree({'dc/proj1/trunk/file': "data"})
629         self.client_add("dc/proj1")
630         self.client_commit("dc", "My Message")
631         oldrepos = Repository.open(repos_url)
632         oldrepos.set_branching_scheme(TrunkBranchingScheme(1))
633         dir = BzrDir.create("f")
634         newrepos = dir.create_repository()
635         oldrepos.copy_content_into(newrepos)
636
637     def test_fetch_special_char(self):
638         repos_url = self.make_client('d', 'dc')
639         self.build_tree({u'dc/trunk/f\x2cle': "data"})
640         self.client_add("dc/trunk")
641         self.client_commit("dc", "My Message")
642         oldrepos = Repository.open(repos_url)
643         oldrepos.set_branching_scheme(TrunkBranchingScheme(1))
644         dir = BzrDir.create("f")
645         newrepos = dir.create_repository()
646         oldrepos.copy_content_into(newrepos)
647
648     def test_fetch_delete(self):
649         repos_url = self.make_client('d', 'dc')
650         self.build_tree({'dc/foo/bla': "data"})
651         self.client_add("dc/foo")
652         self.client_commit("dc", "My Message")
653         oldrepos = Repository.open(repos_url)
654         dir = BzrDir.create("f")
655         newrepos = dir.create_repository()
656         oldrepos.copy_content_into(newrepos)
657         self.client_delete("dc/foo/bla")
658         self.client_commit("dc", "Second Message")
659         newrepos = Repository.open("f")
660         oldrepos.copy_content_into(newrepos)
661         self.assertTrue(oldrepos.has_revision(oldrepos.generate_revision_id(2, "")))
662
663     def test_fetch_local(self):
664         repos_url = self.make_client('d', 'dc')
665         self.build_tree({'dc/foo/bla': "data"})
666         self.client_add("dc/foo")
667         self.client_commit("dc", "My Message")
668         self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
669         self.client_add("dc/foo/blo")
670         self.client_add("dc/bar")
671         self.client_commit("dc", "Second Message")
672         oldrepos = Repository.open(repos_url)
673         dir = BzrDir.create("f")
674         newrepos = dir.create_repository()
675         oldrepos.copy_content_into(newrepos)
676         self.assertTrue(newrepos.has_revision(
677             oldrepos.generate_revision_id(1, "")))
678         self.assertTrue(newrepos.has_revision(
679             oldrepos.generate_revision_id(2, "")))
680         tree = newrepos.revision_tree(
681                 oldrepos.generate_revision_id(2, ""))
682         self.assertTrue(tree.has_filename("foo/bla"))
683         self.assertTrue(tree.has_filename("foo"))
684         self.assertEqual("data", tree.get_file_by_path("foo/bla").read())
685
686     def test_control_code_msg(self):
687         repos_url = self.make_client('d', 'dc')
688
689         self.build_tree({'dc/trunk': None})
690         self.client_add("dc/trunk")
691         self.client_commit("dc", "\x24")
692
693         self.build_tree({'dc/trunk/hosts': 'hej2'})
694         self.client_add("dc/trunk/hosts")
695         self.client_commit("dc", "bla\xfcbla") #2
696
697         self.build_tree({'dc/trunk/hosts': 'hej3'})
698         self.client_commit("dc", "a\x0cb") #3
699
700         self.build_tree({'dc/branches/foobranch/file': 'foohosts'})
701         self.client_add("dc/branches")
702         self.client_commit("dc", "foohosts") #4
703
704         oldrepos = Repository.open("svn+"+repos_url)
705         oldrepos.set_branching_scheme(TrunkBranchingScheme())
706         dir = BzrDir.create("f")
707         newrepos = dir.create_repository()
708         oldrepos.copy_content_into(newrepos)
709
710         self.assertTrue(newrepos.has_revision(
711             oldrepos.generate_revision_id(1, "trunk")))
712         self.assertTrue(newrepos.has_revision(
713             oldrepos.generate_revision_id(2, "trunk")))
714         self.assertTrue(newrepos.has_revision(
715             oldrepos.generate_revision_id(3, "trunk")))
716         self.assertTrue(newrepos.has_revision(
717             oldrepos.generate_revision_id(4, "branches/foobranch")))
718         self.assertFalse(newrepos.has_revision(
719             oldrepos.generate_revision_id(4, "trunk")))
720         self.assertFalse(newrepos.has_revision(
721             oldrepos.generate_revision_id(2, "")))
722
723         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, "trunk"))
724         self.assertEqual("$", rev.message)
725
726         rev = newrepos.get_revision(
727             oldrepos.generate_revision_id(2, "trunk"))
728         self.assertEqual(u'bla\xfcbla', rev.message)
729
730         rev = newrepos.get_revision(oldrepos.generate_revision_id(3, "trunk"))
731         self.assertEqual(u"a\\x0cb", rev.message)
732
733     def test_fetch_replace(self):
734         repos_url = self.make_client('d', 'dc')
735         self.build_tree({'dc/bla': "data"})
736         self.client_add("dc/bla")
737         self.client_commit("dc", "My Message")
738         self.client_delete("dc/bla")
739         self.build_tree({'dc/bla': "data2"})
740         self.client_add("dc/bla")
741         self.client_commit("dc", "Second Message")
742         oldrepos = Repository.open("svn+"+repos_url)
743         dir = BzrDir.create("f")
744         newrepos = dir.create_repository()
745         oldrepos.copy_content_into(newrepos)
746         self.assertTrue(newrepos.has_revision(
747             oldrepos.generate_revision_id(1, "")))
748         self.assertTrue(newrepos.has_revision(
749             oldrepos.generate_revision_id(2, "")))
750         inv1 = newrepos.get_inventory(
751                 oldrepos.generate_revision_id(1, ""))
752         inv2 = newrepos.get_inventory(
753                 oldrepos.generate_revision_id(2, ""))
754         self.assertNotEqual(inv1.path2id("bla"), inv2.path2id("bla"))
755
756     def test_fetch_copy_subdir(self):
757         repos_url = self.make_client('d', 'dc')
758         self.build_tree({'dc/trunk/mydir/a': "data"})
759         self.client_add("dc/trunk")
760         self.client_commit("dc", "My Message")
761         self.build_tree({'dc/branches/tmp': None})
762         self.client_add("dc/branches")
763         self.client_commit("dc", "Second Message")
764         self.client_copy("dc/trunk/mydir", "dc/branches/tmp/abranch")
765         self.client_commit("dc", "Third Message")
766         oldrepos = Repository.open("svn+"+repos_url)
767         oldrepos.set_branching_scheme(TrunkBranchingScheme())
768         dir = BzrDir.create("f")
769         newrepos = dir.create_repository()
770         oldrepos.copy_content_into(newrepos)
771
772     def test_fetch_replace_nordic(self):
773         filename = os.path.join(self.test_dir, "dumpfile")
774         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
775
776 UUID: 606c7b1f-987c-4826-b37d-eb556ceb87e1
777
778 Revision-number: 0
779 Prop-content-length: 56
780 Content-length: 56
781
782 K 8
783 svn:date
784 V 27
785 2006-12-26T00:04:55.850520Z
786 PROPS-END
787
788 Revision-number: 1
789 Prop-content-length: 103
790 Content-length: 103
791
792 K 7
793 svn:log
794 V 3
795 add
796 K 10
797 svn:author
798 V 6
799 jelmer
800 K 8
801 svn:date
802 V 27
803 2006-12-26T00:05:15.504335Z
804 PROPS-END
805
806 Node-path: x\xc3\xa1
807 Node-kind: dir
808 Node-action: add
809 Prop-content-length: 10
810 Content-length: 10
811
812 PROPS-END
813
814 Node-path: u\xc3\xa1
815 Node-path: bla
816 Node-kind: file
817 Node-action: add
818 Prop-content-length: 10
819 Text-content-length: 5
820 Text-content-md5: 49803c8f7913948eb3e30bae749ae6bd
821 Content-length: 15
822
823 PROPS-END
824 bloe
825
826
827 Revision-number: 2
828 Prop-content-length: 105
829 Content-length: 105
830
831 K 7
832 svn:log
833 V 5
834 readd
835 K 10
836 svn:author
837 V 6
838 jelmer
839 K 8
840 svn:date
841 V 27
842 2006-12-26T00:05:43.584249Z
843 PROPS-END
844
845 Node-path: x\xc3\xa1
846 Node-action: delete
847
848 """)
849         os.mkdir("old")
850
851         load_dumpfile("dumpfile", "old")
852         oldrepos = Repository.open("old")
853         dir = BzrDir.create("f")
854         newrepos = dir.create_repository()
855         oldrepos.copy_content_into(newrepos)
856         self.assertTrue(newrepos.has_revision(
857             oldrepos.generate_revision_id(1, "")))
858         inv1 = newrepos.get_inventory(
859                 oldrepos.generate_revision_id(1, ""))
860         self.assertTrue(inv1.has_filename(u"x\xe1"))
861
862     def test_fetch_replace_with_subreplace(self):
863         filename = os.path.join(self.test_dir, "dumpfile")
864         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
865
866 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
867
868 Revision-number: 0
869 Prop-content-length: 56
870 Content-length: 56
871
872 K 8
873 svn:date
874 V 27
875 2006-12-26T00:04:55.850520Z
876 PROPS-END
877
878 Revision-number: 1
879 Prop-content-length: 103
880 Content-length: 103
881
882 K 7
883 svn:log
884 V 3
885 add
886 K 10
887 svn:author
888 V 6
889 jelmer
890 K 8
891 svn:date
892 V 27
893 2006-12-26T00:05:15.504335Z
894 PROPS-END
895
896 Node-path: x
897 Node-kind: dir
898 Node-action: add
899 Prop-content-length: 10
900 Content-length: 10
901
902 PROPS-END
903
904 Node-path: x/t
905 Node-kind: dir
906 Node-action: add
907 Prop-content-length: 10
908 Content-length: 10
909
910 PROPS-END
911
912 Node-path: u
913 Node-kind: dir
914 Node-action: add
915 Prop-content-length: 10
916 Content-length: 10
917
918 PROPS-END
919
920 Revision-number: 2
921 Prop-content-length: 105
922 Content-length: 105
923
924 K 7
925 svn:log
926 V 5
927 readd
928 K 10
929 svn:author
930 V 6
931 jelmer
932 K 8
933 svn:date
934 V 27
935 2006-12-26T00:05:43.584249Z
936 PROPS-END
937
938 Node-path: x
939 Node-action: delete
940
941 Node-path: x
942 Node-kind: dir
943 Node-action: add
944 Prop-content-length: 10
945 Content-length: 10
946
947 PROPS-END
948
949
950 Revision-number: 3
951 Prop-content-length: 108
952 Content-length: 108
953
954 K 7
955 svn:log
956 V 8
957 Replace
958
959 K 10
960 svn:author
961 V 6
962 jelmer
963 K 8
964 svn:date
965 V 27
966 2006-12-25T04:30:06.383777Z
967 PROPS-END
968
969 Node-path: x
970 Node-action: delete
971
972 Node-path: y
973 Node-kind: dir
974 Node-action: add
975 Node-copyfrom-rev: 1
976 Node-copyfrom-path: x
977
978 Node-path: y/t
979 Node-action: delete
980
981 Node-path: y/t
982 Node-kind: dir
983 Node-action: add
984 Node-copyfrom-rev: 1
985 Node-copyfrom-path: u
986
987
988 """)
989         os.mkdir("old")
990
991         load_dumpfile("dumpfile", "old")
992         oldrepos = Repository.open("old")
993         dir = BzrDir.create("f")
994         newrepos = dir.create_repository()
995         oldrepos.copy_content_into(newrepos)
996         self.assertTrue(newrepos.has_revision(
997             oldrepos.generate_revision_id(1, "")))
998         self.assertTrue(newrepos.has_revision(
999             oldrepos.generate_revision_id(3, "")))
1000         inv1 = newrepos.get_inventory(
1001                 oldrepos.generate_revision_id(1, ""))
1002         inv2 = newrepos.get_inventory(
1003                 oldrepos.generate_revision_id(3, ""))
1004
1005     def test_fetch_replace_self(self):
1006         filename = os.path.join(self.test_dir, "dumpfile")
1007         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1008
1009 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
1010
1011 Revision-number: 0
1012 Prop-content-length: 56
1013 Content-length: 56
1014
1015 K 8
1016 svn:date
1017 V 27
1018 2006-12-25T04:27:54.633666Z
1019 PROPS-END
1020
1021 Revision-number: 1
1022 Prop-content-length: 108
1023 Content-length: 108
1024
1025 K 7
1026 svn:log
1027 V 8
1028 Add dir
1029
1030 K 10
1031 svn:author
1032 V 6
1033 jelmer
1034 K 8
1035 svn:date
1036 V 27
1037 2006-12-25T04:28:17.503039Z
1038 PROPS-END
1039
1040 Node-path: bla
1041 Node-kind: dir
1042 Node-action: add
1043 Prop-content-length: 10
1044 Content-length: 10
1045
1046 PROPS-END
1047
1048
1049 Revision-number: 2
1050 Prop-content-length: 117
1051 Content-length: 117
1052
1053 K 7
1054 svn:log
1055 V 16
1056 Add another dir
1057
1058 K 10
1059 svn:author
1060 V 6
1061 jelmer
1062 K 8
1063 svn:date
1064 V 27
1065 2006-12-25T04:28:30.160663Z
1066 PROPS-END
1067
1068 Node-path: blie
1069 Node-kind: dir
1070 Node-action: add
1071 Prop-content-length: 10
1072 Content-length: 10
1073
1074 PROPS-END
1075
1076
1077 Revision-number: 3
1078 Prop-content-length: 105
1079 Content-length: 105
1080
1081 K 7
1082 svn:log
1083 V 5
1084 Copy
1085
1086 K 10
1087 svn:author
1088 V 6
1089 jelmer
1090 K 8
1091 svn:date
1092 V 27
1093 2006-12-25T04:28:44.996894Z
1094 PROPS-END
1095
1096 Node-path: bloe
1097 Node-kind: dir
1098 Node-action: add
1099 Node-copyfrom-rev: 1
1100 Node-copyfrom-path: bla
1101
1102
1103 Revision-number: 4
1104 Prop-content-length: 108
1105 Content-length: 108
1106
1107 K 7
1108 svn:log
1109 V 8
1110 Replace
1111
1112 K 10
1113 svn:author
1114 V 6
1115 jelmer
1116 K 8
1117 svn:date
1118 V 27
1119 2006-12-25T04:30:06.383777Z
1120 PROPS-END
1121
1122 Node-path: bla
1123 Node-action: delete
1124
1125
1126 Node-path: bla
1127 Node-kind: dir
1128 Node-action: add
1129 Node-copyfrom-rev: 2
1130 Node-copyfrom-path: bla
1131
1132
1133 """)
1134         os.mkdir("old")
1135
1136         load_dumpfile("dumpfile", "old")
1137         oldrepos = Repository.open("old")
1138         dir = BzrDir.create("f")
1139         newrepos = dir.create_repository()
1140         oldrepos.copy_content_into(newrepos)
1141         self.assertTrue(newrepos.has_revision(
1142             oldrepos.generate_revision_id(1, "")))
1143         self.assertTrue(newrepos.has_revision(
1144             oldrepos.generate_revision_id(3, "")))
1145         inv1 = newrepos.get_inventory(
1146                 oldrepos.generate_revision_id(1, ""))
1147         inv2 = newrepos.get_inventory(
1148                 oldrepos.generate_revision_id(3, ""))
1149         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
1150
1151     def test_fetch_replace_backup(self):
1152         filename = os.path.join(self.test_dir, "dumpfile")
1153         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1154
1155 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
1156
1157 Revision-number: 0
1158 Prop-content-length: 56
1159 Content-length: 56
1160
1161 K 8
1162 svn:date
1163 V 27
1164 2006-12-25T04:27:54.633666Z
1165 PROPS-END
1166
1167 Revision-number: 1
1168 Prop-content-length: 108
1169 Content-length: 108
1170
1171 K 7
1172 svn:log
1173 V 8
1174 Add dir
1175
1176 K 10
1177 svn:author
1178 V 6
1179 jelmer
1180 K 8
1181 svn:date
1182 V 27
1183 2006-12-25T04:28:17.503039Z
1184 PROPS-END
1185
1186 Node-path: bla
1187 Node-kind: dir
1188 Node-action: add
1189 Prop-content-length: 10
1190 Content-length: 10
1191
1192 PROPS-END
1193
1194
1195 Revision-number: 2
1196 Prop-content-length: 117
1197 Content-length: 117
1198
1199 K 7
1200 svn:log
1201 V 16
1202 Add another dir
1203
1204 K 10
1205 svn:author
1206 V 6
1207 jelmer
1208 K 8
1209 svn:date
1210 V 27
1211 2006-12-25T04:28:30.160663Z
1212 PROPS-END
1213
1214 Node-path: blie
1215 Node-kind: dir
1216 Node-action: add
1217 Prop-content-length: 10
1218 Content-length: 10
1219
1220 PROPS-END
1221
1222
1223 Revision-number: 3
1224 Prop-content-length: 105
1225 Content-length: 105
1226
1227 K 7
1228 svn:log
1229 V 5
1230 Copy
1231
1232 K 10
1233 svn:author
1234 V 6
1235 jelmer
1236 K 8
1237 svn:date
1238 V 27
1239 2006-12-25T04:28:44.996894Z
1240 PROPS-END
1241
1242 Node-path: bloe
1243 Node-kind: dir
1244 Node-action: add
1245 Node-copyfrom-rev: 1
1246 Node-copyfrom-path: bla
1247
1248
1249 Revision-number: 4
1250 Prop-content-length: 112
1251 Content-length: 112
1252
1253 K 7
1254 svn:log
1255 V 11
1256 Change bla
1257
1258 K 10
1259 svn:author
1260 V 6
1261 jelmer
1262 K 8
1263 svn:date
1264 V 27
1265 2006-12-25T23:51:09.678679Z
1266 PROPS-END
1267
1268 Node-path: bla
1269 Node-kind: dir
1270 Node-action: change
1271 Prop-content-length: 28
1272 Content-length: 28
1273
1274 K 3
1275 foo
1276 V 5
1277 bloe
1278
1279 PROPS-END
1280
1281
1282 Revision-number: 5
1283 Prop-content-length: 108
1284 Content-length: 108
1285
1286 K 7
1287 svn:log
1288 V 8
1289 Replace
1290
1291 K 10
1292 svn:author
1293 V 6
1294 jelmer
1295 K 8
1296 svn:date
1297 V 27
1298 2006-12-25T04:30:06.383777Z
1299 PROPS-END
1300
1301 Node-path: bla
1302 Node-action: delete
1303
1304
1305 Node-path: bla
1306 Node-kind: dir
1307 Node-action: add
1308 Node-copyfrom-rev: 1
1309 Node-copyfrom-path: bla
1310
1311
1312 """)
1313         os.mkdir("old")
1314
1315         load_dumpfile("dumpfile", "old")
1316         oldrepos = Repository.open("old")
1317         dir = BzrDir.create("f")
1318         newrepos = dir.create_repository()
1319         oldrepos.copy_content_into(newrepos)
1320         self.assertTrue(newrepos.has_revision(
1321             oldrepos.generate_revision_id(1, "")))
1322         self.assertTrue(newrepos.has_revision(
1323             oldrepos.generate_revision_id(3, "")))
1324         inv1 = newrepos.get_inventory(
1325                 oldrepos.generate_revision_id(1, ""))
1326         inv2 = newrepos.get_inventory(
1327                 oldrepos.generate_revision_id(3, ""))
1328         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
1329
1330     def test_fetch_replace_unrelated(self):
1331         filename = os.path.join(self.test_dir, "dumpfile")
1332         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1333
1334 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
1335
1336 Revision-number: 0
1337 Prop-content-length: 56
1338 Content-length: 56
1339
1340 K 8
1341 svn:date
1342 V 27
1343 2006-12-26T00:04:55.850520Z
1344 PROPS-END
1345
1346 Revision-number: 1
1347 Prop-content-length: 103
1348 Content-length: 103
1349
1350 K 7
1351 svn:log
1352 V 3
1353 add
1354 K 10
1355 svn:author
1356 V 6
1357 jelmer
1358 K 8
1359 svn:date
1360 V 27
1361 2006-12-26T00:05:15.504335Z
1362 PROPS-END
1363
1364 Node-path: x
1365 Node-kind: dir
1366 Node-action: add
1367 Prop-content-length: 10
1368 Content-length: 10
1369
1370 PROPS-END
1371
1372
1373 Revision-number: 2
1374 Prop-content-length: 102
1375 Content-length: 102
1376
1377 K 7
1378 svn:log
1379 V 2
1380 rm
1381 K 10
1382 svn:author
1383 V 6
1384 jelmer
1385 K 8
1386 svn:date
1387 V 27
1388 2006-12-26T00:05:30.775369Z
1389 PROPS-END
1390
1391 Node-path: x
1392 Node-action: delete
1393
1394
1395 Revision-number: 3
1396 Prop-content-length: 105
1397 Content-length: 105
1398
1399 K 7
1400 svn:log
1401 V 5
1402 readd
1403 K 10
1404 svn:author
1405 V 6
1406 jelmer
1407 K 8
1408 svn:date
1409 V 27
1410 2006-12-26T00:05:43.584249Z
1411 PROPS-END
1412
1413 Node-path: x
1414 Node-kind: dir
1415 Node-action: add
1416 Prop-content-length: 10
1417 Content-length: 10
1418
1419 PROPS-END
1420
1421
1422 Revision-number: 4
1423 Prop-content-length: 108
1424 Content-length: 108
1425
1426 K 7
1427 svn:log
1428 V 8
1429 Replace
1430
1431 K 10
1432 svn:author
1433 V 6
1434 jelmer
1435 K 8
1436 svn:date
1437 V 27
1438 2006-12-25T04:30:06.383777Z
1439 PROPS-END
1440
1441 Node-path: x
1442 Node-action: delete
1443
1444
1445 Node-path: x
1446 Node-kind: dir
1447 Node-action: add
1448 Node-copyfrom-rev: 1
1449 Node-copyfrom-path: x
1450
1451                 
1452 """)
1453         os.mkdir("old")
1454
1455         load_dumpfile("dumpfile", "old")
1456         oldrepos = Repository.open("old")
1457         dir = BzrDir.create("f")
1458         newrepos = dir.create_repository()
1459         oldrepos.copy_content_into(newrepos)
1460         self.assertTrue(newrepos.has_revision(
1461             oldrepos.generate_revision_id(1, "")))
1462         self.assertTrue(newrepos.has_revision(
1463             oldrepos.generate_revision_id(4, "")))
1464         inv1 = newrepos.get_inventory(
1465                 oldrepos.generate_revision_id(1, ""))
1466         inv2 = newrepos.get_inventory(
1467                 oldrepos.generate_revision_id(4, ""))
1468         self.assertNotEqual(inv1.path2id("x"), inv2.path2id("x"))
1469
1470     def test_fetch_replace_related(self):
1471         filename = os.path.join(self.test_dir, "dumpfile")
1472         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1473
1474 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
1475
1476 Revision-number: 0
1477 Prop-content-length: 56
1478 Content-length: 56
1479
1480 K 8
1481 svn:date
1482 V 27
1483 2006-12-26T00:04:55.850520Z
1484 PROPS-END
1485
1486 Revision-number: 1
1487 Prop-content-length: 103
1488 Content-length: 103
1489
1490 K 7
1491 svn:log
1492 V 3
1493 add
1494 K 10
1495 svn:author
1496 V 6
1497 jelmer
1498 K 8
1499 svn:date
1500 V 27
1501 2006-12-26T00:05:15.504335Z
1502 PROPS-END
1503
1504 Node-path: x
1505 Node-kind: dir
1506 Node-action: add
1507 Prop-content-length: 10
1508 Content-length: 10
1509
1510 PROPS-END
1511
1512
1513 Revision-number: 2
1514 Prop-content-length: 102
1515 Content-length: 102
1516
1517 K 7
1518 svn:log
1519 V 2
1520 rm
1521 K 10
1522 svn:author
1523 V 6
1524 jelmer
1525 K 8
1526 svn:date
1527 V 27
1528 2006-12-26T00:05:30.775369Z
1529 PROPS-END
1530
1531 Node-path: x
1532 Node-action: delete
1533
1534
1535 Revision-number: 3
1536 Prop-content-length: 105
1537 Content-length: 105
1538
1539 K 7
1540 svn:log
1541 V 5
1542 readd
1543 K 10
1544 svn:author
1545 V 6
1546 jelmer
1547 K 8
1548 svn:date
1549 V 27
1550 2006-12-26T00:05:43.584249Z
1551 PROPS-END
1552
1553 Node-path: y
1554 Node-kind: dir
1555 Node-action: add
1556 Node-copyfrom-rev: 1
1557 Node-copyfrom-path: x
1558 Prop-content-length: 10
1559 Content-length: 10
1560
1561 PROPS-END
1562
1563
1564 Revision-number: 4
1565 Prop-content-length: 108
1566 Content-length: 108
1567
1568 K 7
1569 svn:log
1570 V 8
1571 Replace
1572
1573 K 10
1574 svn:author
1575 V 6
1576 jelmer
1577 K 8
1578 svn:date
1579 V 27
1580 2006-12-25T04:30:06.383777Z
1581 PROPS-END
1582
1583 Node-path: y
1584 Node-action: delete
1585
1586
1587 Revision-number: 5
1588 Prop-content-length: 108
1589 Content-length: 108
1590
1591 K 7
1592 svn:log
1593 V 8
1594 Replace
1595
1596 K 10
1597 svn:author
1598 V 6
1599 jelmer
1600 K 8
1601 svn:date
1602 V 27
1603 2006-12-25T04:30:06.383777Z
1604 PROPS-END
1605
1606
1607 Node-path: y
1608 Node-kind: dir
1609 Node-action: add
1610 Node-copyfrom-rev: 1
1611 Node-copyfrom-path: x
1612
1613
1614 """)
1615         os.mkdir("old")
1616
1617         load_dumpfile("dumpfile", "old")
1618         oldrepos = Repository.open("old")
1619         dir = BzrDir.create("f")
1620         newrepos = dir.create_repository()
1621         oldrepos.copy_content_into(newrepos)
1622         self.assertTrue(newrepos.has_revision(
1623             oldrepos.generate_revision_id(1, "")))
1624         self.assertTrue(newrepos.has_revision(
1625             oldrepos.generate_revision_id(5, "")))
1626         inv1 = newrepos.get_inventory(
1627                 oldrepos.generate_revision_id(1, ""))
1628         inv2 = newrepos.get_inventory(
1629                 oldrepos.generate_revision_id(5, ""))
1630         self.assertNotEqual(inv1.path2id("y"), inv2.path2id("y"))
1631
1632     def test_fetch_dir_upgrade(self):
1633         repos_url = self.make_client('d', 'dc')
1634
1635         self.build_tree({'dc/trunk/lib/file': 'data'})
1636         self.client_add("dc/trunk")
1637         self.client_commit("dc", "trunk data")
1638
1639         self.build_tree({'dc/branches': None})
1640         self.client_add("dc/branches")
1641         self.client_copy("dc/trunk/lib", "dc/branches/mybranch")
1642         self.client_commit("dc", "split out lib")
1643
1644         oldrepos = Repository.open(repos_url)
1645         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1646         dir = BzrDir.create("f")
1647         newrepos = dir.create_repository()
1648         oldrepos.copy_content_into(newrepos)
1649
1650         branch = Branch.open("%s/branches/mybranch" % repos_url)
1651         self.assertEqual([oldrepos.generate_revision_id(2, "branches/mybranch")], 
1652                          branch.revision_history())
1653
1654     def test_fetch_file_from_non_branch(self):
1655         repos_url = self.make_client('d', 'dc')
1656
1657         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1658         self.client_add("dc/old-trunk")
1659         self.client_commit("dc", "trunk data")
1660
1661         self.build_tree({'dc/trunk/lib': None})
1662         self.client_add("dc/trunk")
1663         self.client_copy("dc/old-trunk/lib/file", "dc/trunk/lib/file")
1664         self.client_commit("dc", "revive old trunk")
1665
1666         oldrepos = Repository.open(repos_url)
1667         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1668         dir = BzrDir.create("f")
1669         newrepos = dir.create_repository()
1670         oldrepos.copy_content_into(newrepos)
1671
1672         branch = Branch.open("%s/trunk" % repos_url)
1673         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")], 
1674                          branch.revision_history())
1675
1676     def test_fetch_dir_from_non_branch(self):
1677         repos_url = self.make_client('d', 'dc')
1678
1679         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1680         self.client_add("dc/old-trunk")
1681         self.client_commit("dc", "trunk data")
1682
1683         self.build_tree({'dc/trunk': None})
1684         self.client_add("dc/trunk")
1685         self.client_copy("dc/old-trunk/lib", "dc/trunk")
1686         self.client_commit("dc", "revive old trunk")
1687
1688         oldrepos = Repository.open(repos_url)
1689         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1690         dir = BzrDir.create("f")
1691         newrepos = dir.create_repository()
1692         oldrepos.copy_content_into(newrepos)
1693
1694         branch = Branch.open("%s/trunk" % repos_url)
1695         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")],
1696                          branch.revision_history())
1697
1698     def test_fetch_from_non_branch(self):
1699         repos_url = self.make_client('d', 'dc')
1700
1701         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1702         self.client_add("dc/old-trunk")
1703         self.client_commit("dc", "trunk data")
1704
1705         self.client_copy("dc/old-trunk", "dc/trunk")
1706         self.client_commit("dc", "revive old trunk")
1707
1708         oldrepos = Repository.open(repos_url)
1709         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1710         dir = BzrDir.create("f")
1711         newrepos = dir.create_repository()
1712         oldrepos.copy_content_into(newrepos)
1713
1714         branch = Branch.open("%s/trunk" % repos_url)
1715         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")],
1716                          branch.revision_history())
1717
1718
1719
1720     def test_fetch_branch_downgrade(self):
1721         repos_url = self.make_client('d', 'dc')
1722
1723         self.build_tree({'dc/trunk/file': 'data'})
1724         self.client_add("dc/trunk")
1725         self.client_commit("dc", "trunk data")
1726
1727         self.build_tree({'dc/branches/mybranch': None})
1728         self.client_add("dc/branches")
1729         self.client_copy("dc/trunk", "dc/branches/mybranch/lib")
1730         self.client_commit("dc", "split out lib")
1731
1732         oldrepos = Repository.open(repos_url)
1733         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1734         dir = BzrDir.create("f")
1735         newrepos = dir.create_repository()
1736         oldrepos.copy_content_into(newrepos)
1737
1738     def test_fetch_all(self):
1739         repos_url = self.make_client('d', 'dc')
1740
1741         self.build_tree({'dc/trunk': None, 
1742                          'dc/trunk/hosts': 'hej1'})
1743         self.client_add("dc/trunk")
1744         self.client_commit("dc", "created trunk and added hosts") #1
1745
1746         self.build_tree({'dc/trunk/hosts': 'hej2'})
1747         self.client_commit("dc", "rev 2") #2
1748
1749         self.build_tree({'dc/trunk/hosts': 'hej3'})
1750         self.client_commit("dc", "rev 3") #3
1751
1752         self.build_tree({'dc/branches/foobranch/file': 'foohosts'})
1753         self.client_add("dc/branches")
1754         self.client_commit("dc", "foohosts") #4
1755
1756         oldrepos = Repository.open(repos_url)
1757         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1758         dir = BzrDir.create("f")
1759         newrepos = dir.create_repository()
1760         oldrepos.copy_content_into(newrepos)
1761
1762         self.assertTrue(newrepos.has_revision(
1763             oldrepos.generate_revision_id(1, "trunk")))
1764         self.assertTrue(newrepos.has_revision(
1765             oldrepos.generate_revision_id(2, "trunk")))
1766         self.assertTrue(newrepos.has_revision(
1767             oldrepos.generate_revision_id(3, "trunk")))
1768         self.assertTrue(newrepos.has_revision(
1769             oldrepos.generate_revision_id(4, "branches/foobranch")))
1770         self.assertFalse(newrepos.has_revision(
1771             oldrepos.generate_revision_id(4, "trunk")))
1772         self.assertFalse(newrepos.has_revision(
1773             oldrepos.generate_revision_id(2, "")))
1774
1775     def test_fetch_odd(self):
1776         repos_url = self.make_client('d', 'dc')
1777
1778         self.build_tree({'dc/trunk': None, 
1779                          'dc/trunk/hosts': 'hej1'})
1780         self.client_add("dc/trunk")
1781         self.client_commit("dc", "created trunk and added hosts") #1
1782
1783         self.build_tree({'dc/trunk/hosts': 'hej2'})
1784         self.client_commit("dc", "rev 2") #2
1785
1786         self.build_tree({'dc/trunk/hosts': 'hej3'})
1787         self.client_commit("dc", "rev 3") #3
1788
1789         self.build_tree({'dc/branches': None})
1790         self.client_add("dc/branches")
1791         self.client_commit("dc", "added branches") #4
1792
1793         self.client_copy("dc/trunk", "dc/branches/foobranch")
1794         self.client_commit("dc", "added branch foobranch") #5
1795
1796         self.build_tree({'dc/branches/foobranch/hosts': 'foohosts'})
1797         self.client_commit("dc", "foohosts") #6
1798
1799         repos = format.SvnRemoteAccess(SvnRaTransport("svn+"+repos_url), format.SvnFormat(), 
1800                                    TrunkBranchingScheme()).find_repository()
1801
1802         tree = repos.revision_tree(
1803              repos.generate_revision_id(6, "branches/foobranch"))
1804
1805     def test_fetch_consistent(self):
1806         repos_url = self.make_client('d', 'dc')
1807         self.build_tree({'dc/bla': "data"})
1808         self.client_add("dc/bla")
1809         self.client_set_prop("dc/bla", "svn:executable", "*")
1810         self.client_commit("dc", "My Message")
1811         oldrepos = Repository.open("svn+"+repos_url)
1812         dir1 = BzrDir.create("f")
1813         dir2 = BzrDir.create("g")
1814         newrepos1 = dir1.create_repository()
1815         newrepos2 = dir2.create_repository()
1816         oldrepos.copy_content_into(newrepos1)
1817         oldrepos.copy_content_into(newrepos2)
1818         inv1 = newrepos1.get_inventory(
1819                 oldrepos.generate_revision_id(1, ""))
1820         inv2 = newrepos2.get_inventory(
1821                 oldrepos.generate_revision_id(1, ""))
1822         self.assertEqual(inv1, inv2)
1823
1824     def test_fetch_executable(self):
1825         repos_url = self.make_client('d', 'dc')
1826         self.build_tree({'dc/bla': "data", 'dc/blie': "data2"})
1827         self.client_add("dc/bla")
1828         self.client_add("dc/blie")
1829         self.client_set_prop("dc/bla", "svn:executable", "*")
1830         self.client_set_prop("dc/blie", "svn:executable", "")
1831         self.client_commit("dc", "My Message")
1832         oldrepos = Repository.open("svn+"+repos_url)
1833         dir = BzrDir.create("f")
1834         newrepos = dir.create_repository()
1835         oldrepos.copy_content_into(newrepos)
1836         self.assertTrue(newrepos.has_revision(
1837             oldrepos.generate_revision_id(1, "")))
1838         inv1 = newrepos.get_inventory(
1839                 oldrepos.generate_revision_id(1, ""))
1840         self.assertTrue(inv1[inv1.path2id("bla")].executable)
1841         self.assertTrue(inv1[inv1.path2id("blie")].executable)
1842
1843     def test_fetch_symlink(self):
1844         repos_url = self.make_client('d', 'dc')
1845         self.build_tree({'dc/bla': "data"})
1846         os.symlink('bla', 'dc/mylink')
1847         self.client_add("dc/bla")
1848         self.client_add("dc/mylink")
1849         self.client_commit("dc", "My Message")
1850         oldrepos = Repository.open("svn+"+repos_url)
1851         dir = BzrDir.create("f")
1852         newrepos = dir.create_repository()
1853         oldrepos.copy_content_into(newrepos)
1854         self.assertTrue(newrepos.has_revision(
1855             oldrepos.generate_revision_id(1, "")))
1856         inv1 = newrepos.get_inventory(
1857                 oldrepos.generate_revision_id(1, ""))
1858         self.assertEqual('symlink', inv1[inv1.path2id("mylink")].kind)
1859         self.assertEqual('bla', inv1[inv1.path2id("mylink")].symlink_target)
1860
1861
1862     def test_fetch_executable_separate(self):
1863         repos_url = self.make_client('d', 'dc')
1864         self.build_tree({'dc/bla': "data"})
1865         self.client_add("dc/bla")
1866         self.client_commit("dc", "My Message")
1867         self.client_set_prop("dc/bla", "svn:executable", "*")
1868         self.client_commit("dc", "Make executable")
1869         oldrepos = Repository.open("svn+"+repos_url)
1870         dir = BzrDir.create("f")
1871         newrepos = dir.create_repository()
1872         oldrepos.copy_content_into(newrepos)
1873         self.assertTrue(newrepos.has_revision(
1874             oldrepos.generate_revision_id(1, "")))
1875         inv1 = newrepos.get_inventory(
1876                 oldrepos.generate_revision_id(1, ""))
1877         self.assertFalse(inv1[inv1.path2id("bla")].executable)
1878         inv2 = newrepos.get_inventory(
1879                 oldrepos.generate_revision_id(2, ""))
1880         self.assertTrue(inv2[inv2.path2id("bla")].executable)
1881         self.assertEqual(oldrepos.generate_revision_id(2, ""), 
1882                          inv2[inv2.path2id("bla")].revision)
1883
1884     def test_fetch_ghosts(self):
1885         repos_url = self.make_client('d', 'dc')
1886         self.build_tree({'dc/bla': "data"})
1887         self.client_add("dc/bla")
1888         self.client_set_prop("dc", "bzr:merge", "aghost\n")
1889         self.client_commit("dc", "My Message")
1890         oldrepos = Repository.open("svn+"+repos_url)
1891         dir = BzrDir.create("f")
1892         newrepos = dir.create_repository()
1893         oldrepos.copy_content_into(newrepos)
1894
1895         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, ""))
1896         self.assertTrue("aghost" in rev.parent_ids)
1897
1898     def test_fetch_invalid_ghosts(self):
1899         repos_url = self.make_client('d', 'dc')
1900         self.build_tree({'dc/bla': "data"})
1901         self.client_add("dc/bla")
1902         self.client_set_prop("dc", "bzr:merge", "a ghost\n")
1903         self.client_commit("dc", "My Message")
1904         oldrepos = Repository.open("svn+"+repos_url)
1905         dir = BzrDir.create("f")
1906         newrepos = dir.create_repository()
1907         oldrepos.copy_content_into(newrepos)
1908
1909         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, ""))
1910         self.assertEqual([], rev.parent_ids)
1911
1912     def test_set_branching_scheme(self):
1913         repos_url = self.make_client('d', 'dc')
1914         repos = Repository.open(repos_url)
1915         repos.set_branching_scheme(NoBranchingScheme())
1916
1917     def test_fetch_crosscopy(self):
1918         repos_url = self.make_client('d', 'dc')
1919         self.build_tree({'dc/trunk/adir/afile': "data", 
1920                          'dc/trunk/adir/stationary': None,
1921                          'dc/branches/abranch': None})
1922         self.client_add("dc/trunk")
1923         self.client_add("dc/branches")
1924         self.client_commit("dc", "Initial commit")
1925
1926         # copyrev
1927         self.client_copy("dc/trunk/adir", "dc/branches/abranch/bdir")
1928         self.client_commit("dc", "Cross copy commit")
1929
1930         # prevrev
1931         self.build_tree({"dc/branches/abranch/bdir/afile": "otherdata"})
1932         self.client_commit("dc", "Change data")
1933
1934         # lastrev
1935         self.build_tree({"dc/branches/abranch/bdir/bfile": "camel",
1936                       "dc/branches/abranch/bdir/stationary/traveller": "data"})
1937         self.client_add("dc/branches/abranch/bdir/bfile")
1938         self.client_add("dc/branches/abranch/bdir/stationary/traveller")
1939         self.client_commit("dc", "Change dir")
1940
1941         oldrepos = Repository.open("svn+"+repos_url)
1942         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1943         dir = BzrDir.create("f")
1944         newrepos = dir.create_repository()
1945         copyrev = oldrepos.generate_revision_id(2, "branches/abranch")
1946         prevrev = oldrepos.generate_revision_id(3, "branches/abranch")
1947         lastrev = oldrepos.generate_revision_id(4, "branches/abranch")
1948         oldrepos.copy_content_into(newrepos, lastrev)
1949
1950         inventory = newrepos.get_inventory(lastrev)
1951         self.assertEqual(prevrev, 
1952                          inventory[inventory.path2id("bdir/afile")].revision)
1953
1954         inventory = newrepos.get_inventory(prevrev)
1955         self.assertEqual(copyrev, 
1956                          inventory[inventory.path2id("bdir/stationary")].revision)
1957
1958 class TestSvnRevisionTree(TestCaseWithSubversionRepository):
1959     def setUp(self):
1960         super(TestSvnRevisionTree, self).setUp()
1961         repos_url = self.make_client('d', 'dc')
1962         self.build_tree({'dc/foo/bla': "data"})
1963         self.client_add("dc/foo")
1964         self.client_commit("dc", "My Message")
1965         self.repos = Repository.open(repos_url)
1966         self.inventory = self.repos.get_inventory(
1967                 self.repos.generate_revision_id(1, ""))
1968         self.tree = self.repos.revision_tree(
1969                 self.repos.generate_revision_id(1, ""))
1970
1971     def test_inventory(self):
1972         self.assertIsInstance(self.tree.inventory, Inventory)
1973         self.assertEqual(self.inventory, self.tree.inventory)
1974
1975     def test_get_parent_ids(self):
1976         self.assertEqual([], self.tree.get_parent_ids())
1977
1978     def test_get_revision_id(self):
1979         self.assertEqual(self.repos.generate_revision_id(1, ""),
1980                          self.tree.get_revision_id())
1981
1982     def test_get_file_lines(self):
1983         self.assertEqual(["data"], 
1984                 self.tree.get_file_lines(self.inventory.path2id("foo/bla")))
1985
1986     def test_executable(self):
1987         self.client_set_prop("dc/foo/bla", "svn:executable", "*")
1988         self.client_commit("dc", "My Message")
1989         
1990         inventory = self.repos.get_inventory(
1991                 self.repos.generate_revision_id(2, ""))
1992
1993         self.assertTrue(inventory[inventory.path2id("foo/bla")].executable)
1994
1995
1996     def test_symlink(self):
1997         os.symlink('foo/bla', 'dc/bar')
1998         self.client_add('dc/bar')
1999         self.client_commit("dc", "My Message")
2000         
2001         inventory = self.repos.get_inventory(
2002                 self.repos.generate_revision_id(2, ""))
2003
2004         self.assertEqual('symlink', inventory[inventory.path2id("bar")].kind)
2005         self.assertEqual('foo/bla', inventory[inventory.path2id("bar")].symlink_target)
2006
2007     def test_not_executable(self):
2008         self.assertFalse(self.inventory[
2009             self.inventory.path2id("foo/bla")].executable)
2010
2011 class RevisionIdMappingTest(TestCase):
2012     def test_generate_revid(self):
2013         self.assertEqual("svn-v%d-undefined:myuuid:branch:5" % MAPPING_VERSION, 
2014                          generate_svn_revision_id("myuuid", 5, "branch"))
2015
2016     def test_generate_revid_nested(self):
2017         self.assertEqual("svn-v%d-undefined:myuuid:branch%%2Fpath:5" % MAPPING_VERSION, 
2018                          generate_svn_revision_id("myuuid", 5, "branch/path"))
2019
2020     def test_generate_revid_special_char(self):
2021         self.assertEqual(u"svn-v%d-undefined:myuuid:branch%%2C:5" % MAPPING_VERSION, 
2022                          generate_svn_revision_id("myuuid", 5, u"branch\x2c"))
2023
2024     def test_generate_revid_special_char_ascii(self):
2025         self.assertEqual("svn-v%d-undefined:myuuid:branch%%2C:5" % MAPPING_VERSION, 
2026                          generate_svn_revision_id("myuuid", 5, "branch\x2c"))
2027
2028     def test_generate_revid_nordic(self):
2029         self.assertEqual("svn-v%d:5@myuuid-branch\xc3\xa6" % MAPPING_VERSION, 
2030                          generate_svn_revision_id("myuuid", 5, u"branch\xe6"))
2031
2032     def test_parse_revid_simple(self):
2033         self.assertEqual(("uuid", "", 4),
2034                          parse_svn_revision_id(
2035                              "svn-v%d-undefined:uuid::4" % MAPPING_VERSION))
2036
2037     def test_parse_revid_nested(self):
2038         self.assertEqual(("uuid", "bp/data", 4),
2039                          parse_svn_revision_id(
2040                              "svn-v%d-undefined:uuid:bp%%2Fdata:4" % MAPPING_VERSION))
2041
2042     def test_svk_revid_map_root(self):
2043         self.assertEqual("svn-v%d-undefined:auuid::6" % MAPPING_VERSION,
2044                          svk_feature_to_revision_id("auuid:/:6"))
2045
2046     def test_svk_revid_map_nested(self):
2047         self.assertEqual("svn-v%d-undefined:auuid:bp:6" % MAPPING_VERSION,
2048                          svk_feature_to_revision_id("auuid:/bp:6"))
2049
2050     def test_revid_svk_map(self):
2051         self.assertEqual("auuid:/:6", 
2052               revision_id_to_svk_feature("svn-v%d-undefined:auuid::6" % MAPPING_VERSION))
2053
2054
2055 class EscapeTest(TestCase):
2056     def test_escape_svn_path_none(self):      
2057         self.assertEqual("", escape_svn_path(""))
2058
2059     def test_escape_svn_path_simple(self):
2060         self.assertEqual("ab", escape_svn_path("ab"))
2061
2062     def test_escape_svn_path_percent(self):
2063         self.assertEqual("a%25b", escape_svn_path("a%b"))
2064
2065     def test_escape_svn_path_whitespace(self):
2066         self.assertEqual("foobar%20", escape_svn_path("foobar "))
2067
2068     def test_escape_svn_path_slash(self):
2069         self.assertEqual("foobar%2F", escape_svn_path("foobar/"))
2070
2071     def test_escape_svn_path_special_char(self):
2072         self.assertEqual("foobar%8A", escape_svn_path("foobar\x8a"))
2073
2074     def test_unescape_svn_path_slash(self):
2075         self.assertEqual("foobar/", unescape_svn_path("foobar%2F"))
2076
2077     def test_unescape_svn_path_none(self):
2078         self.assertEqual("foobar", unescape_svn_path("foobar"))
2079
2080     def test_unescape_svn_path_percent(self):
2081         self.assertEqual("foobar%b", unescape_svn_path("foobar%25b"))
2082
2083     def test_escape_svn_path_nordic(self):
2084         self.assertEqual(u"foobar\xe6".encode("utf-8"), escape_svn_path(u"foobar\xe6"))
2085
2086
2087 class SvnRepositoryFormatTests(TestCase):
2088     def setUp(self):
2089         self.format = SvnRepositoryFormat()
2090
2091     def test_initialize(self):
2092         self.assertRaises(UninitializableFormat, self.format.initialize, None)
2093
2094     def test_get_format_description(self):
2095         self.assertEqual("Subversion Repository", 
2096                          self.format.get_format_description())