comparison rhodecode/tests/vcs/test_changesets.py @ 2451:402a96fcfa22 beta

Added vcs testsuite for better integration tests + added fetching of two new repos into test env for rhodecode
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 13 Jun 2012 23:27:33 +0200
parents
children 03a770980b55
comparison
equal deleted inserted replaced
2450:26193dba1f0e 2451:402a96fcfa22
1 from __future__ import with_statement
2
3 from rhodecode.lib import vcs
4 import datetime
5 from base import BackendTestMixin
6 from conf import SCM_TESTS
7 from rhodecode.lib.vcs.backends.base import BaseChangeset
8 from rhodecode.lib.vcs.nodes import FileNode
9 from rhodecode.lib.vcs.exceptions import BranchDoesNotExistError
10 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
11 from rhodecode.lib.vcs.exceptions import RepositoryError
12 from rhodecode.lib.vcs.utils.compat import unittest
13
14
15 class TestBaseChangeset(unittest.TestCase):
16
17 def test_as_dict(self):
18 changeset = BaseChangeset()
19 changeset.id = 'ID'
20 changeset.raw_id = 'RAW_ID'
21 changeset.short_id = 'SHORT_ID'
22 changeset.revision = 1009
23 changeset.date = datetime.datetime(2011, 1, 30, 1, 45)
24 changeset.message = 'Message of a commit'
25 changeset.author = 'Joe Doe <joe.doe@example.com>'
26 changeset.added = [FileNode('foo/bar/baz'), FileNode('foobar')]
27 changeset.changed = []
28 changeset.removed = []
29 self.assertEqual(changeset.as_dict(), {
30 'id': 'ID',
31 'raw_id': 'RAW_ID',
32 'short_id': 'SHORT_ID',
33 'revision': 1009,
34 'date': datetime.datetime(2011, 1, 30, 1, 45),
35 'message': 'Message of a commit',
36 'author': {
37 'name': 'Joe Doe',
38 'email': 'joe.doe@example.com',
39 },
40 'added': ['foo/bar/baz', 'foobar'],
41 'changed': [],
42 'removed': [],
43 })
44
45 class ChangesetsWithCommitsTestCaseixin(BackendTestMixin):
46 recreate_repo_per_test = True
47
48 @classmethod
49 def _get_commits(cls):
50 start_date = datetime.datetime(2010, 1, 1, 20)
51 for x in xrange(5):
52 yield {
53 'message': 'Commit %d' % x,
54 'author': 'Joe Doe <joe.doe@example.com>',
55 'date': start_date + datetime.timedelta(hours=12 * x),
56 'added': [
57 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
58 ],
59 }
60
61 def test_new_branch(self):
62 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
63 content='Documentation\n'))
64 foobar_tip = self.imc.commit(
65 message=u'New branch: foobar',
66 author=u'joe',
67 branch='foobar',
68 )
69 self.assertTrue('foobar' in self.repo.branches)
70 self.assertEqual(foobar_tip.branch, 'foobar')
71 # 'foobar' should be the only branch that contains the new commit
72 self.assertNotEqual(*self.repo.branches.values())
73
74 def test_new_head_in_default_branch(self):
75 tip = self.repo.get_changeset()
76 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
77 content='Documentation\n'))
78 foobar_tip = self.imc.commit(
79 message=u'New branch: foobar',
80 author=u'joe',
81 branch='foobar',
82 parents=[tip],
83 )
84 self.imc.change(vcs.nodes.FileNode('docs/index.txt',
85 content='Documentation\nand more...\n'))
86 newtip = self.imc.commit(
87 message=u'At default branch',
88 author=u'joe',
89 branch=foobar_tip.branch,
90 parents=[foobar_tip],
91 )
92
93 newest_tip = self.imc.commit(
94 message=u'Merged with %s' % foobar_tip.raw_id,
95 author=u'joe',
96 branch=self.backend_class.DEFAULT_BRANCH_NAME,
97 parents=[newtip, foobar_tip],
98 )
99
100 self.assertEqual(newest_tip.branch,
101 self.backend_class.DEFAULT_BRANCH_NAME)
102
103 def test_get_changesets_respects_branch_name(self):
104 tip = self.repo.get_changeset()
105 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
106 content='Documentation\n'))
107 doc_changeset = self.imc.commit(
108 message=u'New branch: docs',
109 author=u'joe',
110 branch='docs',
111 )
112 self.imc.add(vcs.nodes.FileNode('newfile', content=''))
113 self.imc.commit(
114 message=u'Back in default branch',
115 author=u'joe',
116 parents=[tip],
117 )
118 default_branch_changesets = self.repo.get_changesets(
119 branch_name=self.repo.DEFAULT_BRANCH_NAME)
120 self.assertNotIn(doc_changeset, default_branch_changesets)
121
122
123 class ChangesetsTestCaseMixin(BackendTestMixin):
124 recreate_repo_per_test = False
125
126 @classmethod
127 def _get_commits(cls):
128 start_date = datetime.datetime(2010, 1, 1, 20)
129 for x in xrange(5):
130 yield {
131 'message': u'Commit %d' % x,
132 'author': u'Joe Doe <joe.doe@example.com>',
133 'date': start_date + datetime.timedelta(hours=12 * x),
134 'added': [
135 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
136 ],
137 }
138
139 def test_simple(self):
140 tip = self.repo.get_changeset()
141 self.assertEqual(tip.date, datetime.datetime(2010, 1, 3, 20))
142
143 def test_get_changesets_is_ordered_by_date(self):
144 changesets = list(self.repo.get_changesets())
145 ordered_by_date = sorted(changesets,
146 key=lambda cs: cs.date)
147 self.assertItemsEqual(changesets, ordered_by_date)
148
149 def test_get_changesets_respects_start(self):
150 second_id = self.repo.revisions[1]
151 changesets = list(self.repo.get_changesets(start=second_id))
152 self.assertEqual(len(changesets), 4)
153
154 def test_get_changesets_numerical_id_respects_start(self):
155 second_id = 1
156 changesets = list(self.repo.get_changesets(start=second_id))
157 self.assertEqual(len(changesets), 4)
158
159 def test_get_changesets_includes_start_changeset(self):
160 second_id = self.repo.revisions[1]
161 changesets = list(self.repo.get_changesets(start=second_id))
162 self.assertEqual(changesets[0].raw_id, second_id)
163
164 def test_get_changesets_respects_end(self):
165 second_id = self.repo.revisions[1]
166 changesets = list(self.repo.get_changesets(end=second_id))
167 self.assertEqual(changesets[-1].raw_id, second_id)
168 self.assertEqual(len(changesets), 2)
169
170 def test_get_changesets_numerical_id_respects_end(self):
171 second_id = 1
172 changesets = list(self.repo.get_changesets(end=second_id))
173 self.assertEqual(changesets.index(changesets[-1]), second_id)
174 self.assertEqual(len(changesets), 2)
175
176 def test_get_changesets_respects_both_start_and_end(self):
177 second_id = self.repo.revisions[1]
178 third_id = self.repo.revisions[2]
179 changesets = list(self.repo.get_changesets(start=second_id,
180 end=third_id))
181 self.assertEqual(len(changesets), 2)
182
183 def test_get_changesets_numerical_id_respects_both_start_and_end(self):
184 changesets = list(self.repo.get_changesets(start=2, end=3))
185 self.assertEqual(len(changesets), 2)
186
187 def test_get_changesets_includes_end_changeset(self):
188 second_id = self.repo.revisions[1]
189 changesets = list(self.repo.get_changesets(end=second_id))
190 self.assertEqual(changesets[-1].raw_id, second_id)
191
192 def test_get_changesets_respects_start_date(self):
193 start_date = datetime.datetime(2010, 2, 1)
194 for cs in self.repo.get_changesets(start_date=start_date):
195 self.assertGreaterEqual(cs.date, start_date)
196
197 def test_get_changesets_respects_end_date(self):
198 end_date = datetime.datetime(2010, 2, 1)
199 for cs in self.repo.get_changesets(end_date=end_date):
200 self.assertLessEqual(cs.date, end_date)
201
202 def test_get_changesets_respects_reverse(self):
203 changesets_id_list = [cs.raw_id for cs in
204 self.repo.get_changesets(reverse=True)]
205 self.assertItemsEqual(changesets_id_list, reversed(self.repo.revisions))
206
207 def test_get_filenodes_generator(self):
208 tip = self.repo.get_changeset()
209 filepaths = [node.path for node in tip.get_filenodes_generator()]
210 self.assertItemsEqual(filepaths, ['file_%d.txt' % x for x in xrange(5)])
211
212 def test_size(self):
213 tip = self.repo.get_changeset()
214 size = 5 * len('Foobar N') # Size of 5 files
215 self.assertEqual(tip.size, size)
216
217 def test_author(self):
218 tip = self.repo.get_changeset()
219 self.assertEqual(tip.author, u'Joe Doe <joe.doe@example.com>')
220
221 def test_author_name(self):
222 tip = self.repo.get_changeset()
223 self.assertEqual(tip.author_name, u'Joe Doe')
224
225 def test_author_email(self):
226 tip = self.repo.get_changeset()
227 self.assertEqual(tip.author_email, u'joe.doe@example.com')
228
229 def test_get_changesets_raise_changesetdoesnotexist_for_wrong_start(self):
230 with self.assertRaises(ChangesetDoesNotExistError):
231 list(self.repo.get_changesets(start='foobar'))
232
233 def test_get_changesets_raise_changesetdoesnotexist_for_wrong_end(self):
234 with self.assertRaises(ChangesetDoesNotExistError):
235 list(self.repo.get_changesets(end='foobar'))
236
237 def test_get_changesets_raise_branchdoesnotexist_for_wrong_branch_name(self):
238 with self.assertRaises(BranchDoesNotExistError):
239 list(self.repo.get_changesets(branch_name='foobar'))
240
241 def test_get_changesets_raise_repositoryerror_for_wrong_start_end(self):
242 start = self.repo.revisions[-1]
243 end = self.repo.revisions[0]
244 with self.assertRaises(RepositoryError):
245 list(self.repo.get_changesets(start=start, end=end))
246
247 def test_get_changesets_numerical_id_reversed(self):
248 with self.assertRaises(RepositoryError):
249 [x for x in self.repo.get_changesets(start=3, end=2)]
250
251 def test_get_changesets_numerical_id_respects_both_start_and_end_last(self):
252 with self.assertRaises(RepositoryError):
253 last = len(self.repo.revisions)
254 list(self.repo.get_changesets(start=last-1, end=last-2))
255
256 def test_get_changesets_numerical_id_last_zero_error(self):
257 with self.assertRaises(RepositoryError):
258 last = len(self.repo.revisions)
259 list(self.repo.get_changesets(start=last-1, end=0))
260
261
262 class ChangesetsChangesTestCaseMixin(BackendTestMixin):
263 recreate_repo_per_test = False
264
265 @classmethod
266 def _get_commits(cls):
267 return [
268 {
269 'message': u'Initial',
270 'author': u'Joe Doe <joe.doe@example.com>',
271 'date': datetime.datetime(2010, 1, 1, 20),
272 'added': [
273 FileNode('foo/bar', content='foo'),
274 FileNode('foobar', content='foo'),
275 FileNode('qwe', content='foo'),
276 ],
277 },
278 {
279 'message': u'Massive changes',
280 'author': u'Joe Doe <joe.doe@example.com>',
281 'date': datetime.datetime(2010, 1, 1, 22),
282 'added': [FileNode('fallout', content='War never changes')],
283 'changed': [
284 FileNode('foo/bar', content='baz'),
285 FileNode('foobar', content='baz'),
286 ],
287 'removed': [FileNode('qwe')],
288 },
289 ]
290
291 def test_initial_commit(self):
292 changeset = self.repo.get_changeset(0)
293 self.assertItemsEqual(changeset.added, [
294 changeset.get_node('foo/bar'),
295 changeset.get_node('foobar'),
296 changeset.get_node('qwe'),
297 ])
298 self.assertItemsEqual(changeset.changed, [])
299 self.assertItemsEqual(changeset.removed, [])
300
301 def test_head_added(self):
302 changeset = self.repo.get_changeset()
303 self.assertItemsEqual(changeset.added, [
304 changeset.get_node('fallout'),
305 ])
306 self.assertItemsEqual(changeset.changed, [
307 changeset.get_node('foo/bar'),
308 changeset.get_node('foobar'),
309 ])
310 self.assertEqual(len(changeset.removed), 1)
311 self.assertEqual(list(changeset.removed)[0].path, 'qwe')
312
313
314 # For each backend create test case class
315 for alias in SCM_TESTS:
316 attrs = {
317 'backend_alias': alias,
318 }
319 # tests with additional commits
320 cls_name = ''.join(('%s changesets with commits test' % alias).title().split())
321 bases = (ChangesetsWithCommitsTestCaseixin, unittest.TestCase)
322 globals()[cls_name] = type(cls_name, bases, attrs)
323
324 # tests without additional commits
325 cls_name = ''.join(('%s changesets test' % alias).title().split())
326 bases = (ChangesetsTestCaseMixin, unittest.TestCase)
327 globals()[cls_name] = type(cls_name, bases, attrs)
328
329 # tests changes
330 cls_name = ''.join(('%s changesets changes test' % alias).title().split())
331 bases = (ChangesetsChangesTestCaseMixin, unittest.TestCase)
332 globals()[cls_name] = type(cls_name, bases, attrs)
333
334
335 if __name__ == '__main__':
336 unittest.main()