4 from cStringIO
import StringIO
6 from StringIO
import StringIO
8 from svn
import core
, repos
, fs
9 from svn
.core
import SubversionException
11 from trac
.versioncontrol
.tests
.svn_fs
import REPOS_PATH
14 """ Proxy object for a revision range, used for comparison. """
16 def __init__(self
, start
, end
):
20 class SubversionMergeinfoTestCase(unittest
.TestCase
):
21 """Test cases for mergeinfo"""
23 # Some textual mergeinfo.
24 TEXT_MERGEINFO1
= "/trunk:3-9,27,42*"
25 TEXT_MERGEINFO2
= "/trunk:27-29,41-43*"
27 # Meta data used in conjunction with this mergeinfo.
28 MERGEINFO_SRC
= "/trunk"
29 MERGEINFO_NBR_REV_RANGES
= 3
32 """Load the mergeinfo-full Subversion repository. This dumpfile is
33 created by dumping the repository generated for command line log
34 tests 16. If it needs to be updated (mergeinfo format changes, for
35 example), we can go there to get a new version."""
36 dumpfile
= open(os
.path
.join(os
.path
.split(__file__
)[0],
37 'data', 'mergeinfo.dump'))
38 # Remove any existing repository to ensure a fresh start
40 self
.repos
= repos
.svn_repos_create(REPOS_PATH
, '', '', None, None)
41 repos
.svn_repos_load_fs2(self
.repos
, dumpfile
, StringIO(),
42 repos
.svn_repos_load_uuid_default
, '',
44 self
.fs
= repos
.fs(self
.repos
)
45 self
.rev
= fs
.youngest_rev(self
.fs
)
48 if os
.path
.exists(REPOS_PATH
):
49 repos
.delete(REPOS_PATH
)
51 def test_mergeinfo_parse(self
):
52 """Test svn_mergeinfo_parse()"""
53 mergeinfo
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO1
)
54 self
.inspect_mergeinfo_dict(mergeinfo
, self
.MERGEINFO_SRC
,
55 self
.MERGEINFO_NBR_REV_RANGES
)
57 def test_rangelist_merge(self
):
58 mergeinfo1
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO1
)
59 mergeinfo2
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO2
)
60 rangelist1
= mergeinfo1
.get(self
.MERGEINFO_SRC
)
61 rangelist2
= mergeinfo2
.get(self
.MERGEINFO_SRC
)
62 rangelist3
= core
.svn_rangelist_merge(rangelist1
, rangelist2
)
63 self
.inspect_rangelist_tuple(rangelist3
, 3)
65 def test_mergeinfo_merge(self
):
66 """Test svn_mergeinfo_merge()"""
67 mergeinfo1
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO1
)
68 mergeinfo2
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO2
)
69 mergeinfo3
= core
.svn_mergeinfo_merge(mergeinfo1
, mergeinfo2
)
70 self
.inspect_mergeinfo_dict(mergeinfo3
, self
.MERGEINFO_SRC
,
71 self
.MERGEINFO_NBR_REV_RANGES
)
73 def test_rangelist_reverse(self
):
74 mergeinfo
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO1
)
75 rangelist
= mergeinfo
.get(self
.MERGEINFO_SRC
)
76 reversed = core
.svn_rangelist_reverse(rangelist
)
77 expected_ranges
= ((42, 41), (27, 26), (9, 2))
78 for i
in range(0, len(reversed)):
79 self
.assertEquals(reversed[i
].start
, expected_ranges
[i
][0],
80 "Unexpected range start: %d" % reversed[i
].start
)
81 self
.assertEquals(reversed[i
].end
, expected_ranges
[i
][1],
82 "Unexpected range end: %d" % reversed[i
].end
)
84 def test_mergeinfo_sort(self
):
85 mergeinfo
= core
.svn_mergeinfo_parse(self
.TEXT_MERGEINFO1
)
87 # Swap the order of two revision ranges to misorder the contents
89 rangelist
= mergeinfo
.get(self
.MERGEINFO_SRC
)
90 rev_range
= rangelist
[0]
91 rangelist
[0] = rangelist
[1]
92 rangelist
[1] = rev_range
94 mergeinfo
= core
.svn_mergeinfo_sort(mergeinfo
)
95 self
.inspect_mergeinfo_dict(mergeinfo
, self
.MERGEINFO_SRC
,
96 self
.MERGEINFO_NBR_REV_RANGES
)
98 def test_mergeinfo_get(self
):
99 mergeinfo
= repos
.fs_get_mergeinfo(self
.repos
, ['/trunk'], self
.rev
,
100 core
.svn_mergeinfo_inherited
,
102 expected_mergeinfo
= \
104 { 'branches/a' : [RevRange(2, 11)],
105 'branches/b' : [RevRange(9, 13)],
106 'branches/c' : [RevRange(2, 16)],
107 'trunk' : [RevRange(1, 9)], },
109 self
.compare_mergeinfo_catalogs(mergeinfo
, expected_mergeinfo
)
111 def inspect_mergeinfo_dict(self
, mergeinfo
, merge_source
, nbr_rev_ranges
):
112 rangelist
= mergeinfo
.get(merge_source
)
113 self
.inspect_rangelist_tuple(rangelist
, nbr_rev_ranges
)
115 def inspect_rangelist_tuple(self
, rangelist
, nbr_rev_ranges
):
116 self
.assert_(rangelist
is not None,
117 "Rangelist for '%s' not parsed" % self
.MERGEINFO_SRC
)
118 self
.assertEquals(len(rangelist
), nbr_rev_ranges
,
119 "Wrong number of revision ranges parsed")
120 self
.assertEquals(rangelist
[0].inheritable
, True,
121 "Unexpected revision range 'non-inheritable' flag: %s" %
122 rangelist
[0].inheritable
)
123 self
.assertEquals(rangelist
[1].start
, 26,
124 "Unexpected revision range end: %d" % rangelist
[1].start
)
125 self
.assertEquals(rangelist
[2].inheritable
, False,
126 "Missing revision range 'non-inheritable' flag")
128 def compare_mergeinfo_catalogs(self
, catalog1
, catalog2
):
129 keys1
= catalog1
.keys()
131 keys2
= catalog2
.keys()
133 self
.assertEqual(keys1
, keys2
)
135 for k
in catalog1
.keys():
136 self
.compare_mergeinfos(catalog1
[k
], catalog2
[k
])
138 def compare_mergeinfos(self
, mergeinfo1
, mergeinfo2
):
139 keys1
= mergeinfo1
.keys()
141 keys2
= mergeinfo2
.keys()
143 self
.assertEqual(keys1
, keys2
)
145 for k
in mergeinfo1
.keys():
146 self
.compare_rangelists(mergeinfo1
[k
], mergeinfo2
[k
])
148 def compare_rangelists(self
, rangelist1
, rangelist2
):
149 self
.assertEqual(len(rangelist1
), len(rangelist2
))
150 for r1
, r2
in zip(rangelist1
, rangelist2
):
151 self
.assertEqual(r1
.start
, r2
.start
)
152 self
.assertEqual(r1
.end
, r2
.end
)
156 return unittest
.makeSuite(SubversionMergeinfoTestCase
, 'test')
158 if __name__
== '__main__':
159 runner
= unittest
.TextTestRunner()