##// END OF EJS Templates
tests: update _BackendTestMixin to py.test and convert tests using it from self.assert to plain py.test style asserts
Branko Majic -
r7046:4c46ebbc default
parent child Browse files
Show More
@@ -1,108 +1,106 b''
1 1 """
2 2 Module providing backend independent mixin class. It requires that
3 3 InMemoryChangeset class is working properly at backend class.
4 4 """
5 5 import os
6 6 import time
7 7 import shutil
8 8 import datetime
9 9
10 10 from kallithea.lib import vcs
11 from kallithea.lib.vcs.utils.compat import unittest
12 11 from kallithea.lib.vcs.nodes import FileNode
13 12
14 13 from kallithea.tests.vcs.conf import SCM_TESTS, get_new_dir
15 14
16 15
17 16 class _BackendTestMixin(object):
18 17 """
19 18 This is a backend independent test case class which should be created
20 19 with ``type`` method.
21 20
22 21 It is required to set following attributes at subclass:
23 22
24 23 - ``backend_alias``: alias of used backend (see ``vcs.BACKENDS``)
25 24 - ``repo_path``: path to the repository which would be created for set of
26 25 tests
27 26 - ``recreate_repo_per_test``: If set to ``False``, repo would NOT be created
28 27 before every single test. Defaults to ``True``.
29 28 """
30 29 recreate_repo_per_test = True
31 30
32 31 @classmethod
33 32 def get_backend(cls):
34 33 return vcs.get_backend(cls.backend_alias)
35 34
36 35 @classmethod
37 36 def _get_commits(cls):
38 37 commits = [
39 38 {
40 39 'message': u'Initial commit',
41 40 'author': u'Joe Doe <joe.doe@example.com>',
42 41 'date': datetime.datetime(2010, 1, 1, 20),
43 42 'added': [
44 43 FileNode('foobar', content='Foobar'),
45 44 FileNode('foobar2', content='Foobar II'),
46 45 FileNode('foo/bar/baz', content='baz here!'),
47 46 ],
48 47 },
49 48 {
50 49 'message': u'Changes...',
51 50 'author': u'Jane Doe <jane.doe@example.com>',
52 51 'date': datetime.datetime(2010, 1, 1, 21),
53 52 'added': [
54 53 FileNode('some/new.txt', content='news...'),
55 54 ],
56 55 'changed': [
57 56 FileNode('foobar', 'Foobar I'),
58 57 ],
59 58 'removed': [],
60 59 },
61 60 ]
62 61 return commits
63 62
64 63 @classmethod
65 def setUpClass(cls):
64 def setup_class(cls):
66 65 Backend = cls.get_backend()
67 66 cls.backend_class = Backend
68 67 cls.repo_path = get_new_dir(str(time.time()))
69 68 cls.repo = Backend(cls.repo_path, create=True)
70 69 cls.imc = cls.repo.in_memory_changeset
71 70 cls.default_branch = cls.repo.DEFAULT_BRANCH_NAME
72 71
73 72 for commit in cls._get_commits():
74 73 for node in commit.get('added', []):
75 74 cls.imc.add(FileNode(node.path, content=node.content))
76 75 for node in commit.get('changed', []):
77 76 cls.imc.change(FileNode(node.path, content=node.content))
78 77 for node in commit.get('removed', []):
79 78 cls.imc.remove(FileNode(node.path))
80 79
81 80 cls.tip = cls.imc.commit(message=unicode(commit['message']),
82 81 author=unicode(commit['author']),
83 82 date=commit['date'])
84 83
85 84 @classmethod
86 def tearDownClass(cls):
85 def teardown_class(cls):
87 86 if not getattr(cls, 'recreate_repo_per_test', False) and \
88 87 'VCS_REMOVE_TEST_DIRS' in os.environ:
89 88 shutil.rmtree(cls.repo_path)
90 89
91 def setUp(self):
90 def setup_method(self, method):
92 91 if getattr(self, 'recreate_repo_per_test', False):
93 self.__class__.setUpClass()
92 self.__class__.setup_class()
94 93
95 def tearDown(self):
94 def teardown_method(self, method):
96 95 if getattr(self, 'recreate_repo_per_test', False) and \
97 96 'VCS_REMOVE_TEST_DIRS' in os.environ:
98 97 shutil.rmtree(self.repo_path)
99 98
100 99
101 100 # For each backend create test case class
102 101 for alias in SCM_TESTS:
103 102 attrs = {
104 103 'backend_alias': alias,
105 104 }
106 105 cls_name = ''.join(('%s base backend test' % alias).title().split())
107 bases = (_BackendTestMixin, unittest.TestCase)
108 globals()[cls_name] = type(cls_name, bases, attrs)
106 globals()[cls_name] = type(cls_name, (_BackendTestMixin,), attrs)
@@ -1,113 +1,106 b''
1 1 import os
2 2 import tarfile
3 3 import zipfile
4 4 import datetime
5 5 import tempfile
6 6 import StringIO
7 7
8 from kallithea.lib.vcs.utils.compat import unittest
8 import pytest
9 9
10 10 from kallithea.lib.vcs.exceptions import VCSError
11 11 from kallithea.lib.vcs.nodes import FileNode
12 12
13 13 from kallithea.tests.vcs.base import _BackendTestMixin
14 14 from kallithea.tests.vcs.conf import SCM_TESTS, TESTS_TMP_PATH
15 15
16 16
17 17 class ArchivesTestCaseMixin(_BackendTestMixin):
18 18
19 19 @classmethod
20 20 def _get_commits(cls):
21 21 start_date = datetime.datetime(2010, 1, 1, 20)
22 22 for x in xrange(5):
23 23 yield {
24 24 'message': 'Commit %d' % x,
25 25 'author': 'Joe Doe <joe.doe@example.com>',
26 26 'date': start_date + datetime.timedelta(hours=12 * x),
27 27 'added': [
28 28 FileNode('%d/file_%d.txt' % (x, x),
29 29 content='Foobar %d' % x),
30 30 ],
31 31 }
32 32
33 33 def test_archive_zip(self):
34 34 path = tempfile.mkstemp(dir=TESTS_TMP_PATH, prefix='test_archive_zip-')[1]
35 35 with open(path, 'wb') as f:
36 36 self.tip.fill_archive(stream=f, kind='zip', prefix='repo')
37 37 out = zipfile.ZipFile(path)
38 38
39 39 for x in xrange(5):
40 40 node_path = '%d/file_%d.txt' % (x, x)
41 41 decompressed = StringIO.StringIO()
42 42 decompressed.write(out.read('repo/' + node_path))
43 self.assertEqual(
44 decompressed.getvalue(),
45 self.tip.get_node(node_path).content)
43 assert decompressed.getvalue() == self.tip.get_node(node_path).content
46 44
47 45 def test_archive_tgz(self):
48 46 path = tempfile.mkstemp(dir=TESTS_TMP_PATH, prefix='test_archive_tgz-')[1]
49 47 with open(path, 'wb') as f:
50 48 self.tip.fill_archive(stream=f, kind='tgz', prefix='repo')
51 49 outdir = tempfile.mkdtemp(dir=TESTS_TMP_PATH, prefix='test_archive_tgz-', suffix='-outdir')
52 50
53 51 outfile = tarfile.open(path, 'r|gz')
54 52 outfile.extractall(outdir)
55 53
56 54 for x in xrange(5):
57 55 node_path = '%d/file_%d.txt' % (x, x)
58 self.assertEqual(
59 open(os.path.join(outdir, 'repo/' + node_path)).read(),
60 self.tip.get_node(node_path).content)
56 assert open(os.path.join(outdir, 'repo/' + node_path)).read() == self.tip.get_node(node_path).content
61 57
62 58 def test_archive_tbz2(self):
63 59 path = tempfile.mkstemp(dir=TESTS_TMP_PATH, prefix='test_archive_tbz2-')[1]
64 60 with open(path, 'w+b') as f:
65 61 self.tip.fill_archive(stream=f, kind='tbz2', prefix='repo')
66 62 outdir = tempfile.mkdtemp(dir=TESTS_TMP_PATH, prefix='test_archive_tbz2-', suffix='-outdir')
67 63
68 64 outfile = tarfile.open(path, 'r|bz2')
69 65 outfile.extractall(outdir)
70 66
71 67 for x in xrange(5):
72 68 node_path = '%d/file_%d.txt' % (x, x)
73 self.assertEqual(
74 open(os.path.join(outdir, 'repo/' + node_path)).read(),
75 self.tip.get_node(node_path).content)
69 assert open(os.path.join(outdir, 'repo/' + node_path)).read() == self.tip.get_node(node_path).content
76 70
77 71 def test_archive_default_stream(self):
78 72 tmppath = tempfile.mkstemp(dir=TESTS_TMP_PATH, prefix='test_archive_default_stream-')[1]
79 73 with open(tmppath, 'wb') as stream:
80 74 self.tip.fill_archive(stream=stream)
81 75 mystream = StringIO.StringIO()
82 76 self.tip.fill_archive(stream=mystream)
83 77 mystream.seek(0)
84 78 with open(tmppath, 'rb') as f:
85 79 file_content = f.read()
86 80 stringio_content = mystream.read()
87 81 # the gzip header contains a MTIME header
88 82 # because is takes a little bit of time from one fill_archive call to the next
89 83 # this part may differ so don't include that part in the comparison
90 self.assertEqual(file_content[:4], stringio_content[:4])
91 self.assertEqual(file_content[8:], stringio_content[8:])
84 assert file_content[:4] == stringio_content[:4]
85 assert file_content[8:] == stringio_content[8:]
92 86
93 87 def test_archive_wrong_kind(self):
94 with self.assertRaises(VCSError):
88 with pytest.raises(VCSError):
95 89 self.tip.fill_archive(kind='wrong kind')
96 90
97 91 def test_archive_empty_prefix(self):
98 with self.assertRaises(VCSError):
92 with pytest.raises(VCSError):
99 93 self.tip.fill_archive(prefix='')
100 94
101 95 def test_archive_prefix_with_leading_slash(self):
102 with self.assertRaises(VCSError):
96 with pytest.raises(VCSError):
103 97 self.tip.fill_archive(prefix='/any')
104 98
105 99
106 100 # For each backend create test case class
107 101 for alias in SCM_TESTS:
108 102 attrs = {
109 103 'backend_alias': alias,
110 104 }
111 cls_name = ''.join(('%s archive test' % alias).title().split())
112 bases = (ArchivesTestCaseMixin, unittest.TestCase)
113 globals()[cls_name] = type(cls_name, bases, attrs)
105 cls_name = ''.join(('test %s archive' % alias).title().split())
106 globals()[cls_name] = type(cls_name, (ArchivesTestCaseMixin,), attrs)
@@ -1,111 +1,108 b''
1 1 import datetime
2 2 from kallithea.lib import vcs
3 from kallithea.lib.vcs.utils.compat import unittest
4 3 from kallithea.lib.vcs.nodes import FileNode
5 4
6 5 from kallithea.tests.vcs.base import _BackendTestMixin
7 6 from kallithea.tests.vcs.conf import SCM_TESTS
8 7
9 8
10 9 class BranchesTestCaseMixin(_BackendTestMixin):
11 10
12 11 @classmethod
13 12 def _get_commits(cls):
14 13 commits = [
15 14 {
16 15 'message': 'Initial commit',
17 16 'author': 'Joe Doe <joe.doe@example.com>',
18 17 'date': datetime.datetime(2010, 1, 1, 20),
19 18 'added': [
20 19 FileNode('foobar', content='Foobar'),
21 20 FileNode('foobar2', content='Foobar II'),
22 21 FileNode('foo/bar/baz', content='baz here!'),
23 22 ],
24 23 },
25 24 {
26 25 'message': 'Changes...',
27 26 'author': 'Jane Doe <jane.doe@example.com>',
28 27 'date': datetime.datetime(2010, 1, 1, 21),
29 28 'added': [
30 29 FileNode('some/new.txt', content='news...'),
31 30 ],
32 31 'changed': [
33 32 FileNode('foobar', 'Foobar I'),
34 33 ],
35 34 'removed': [],
36 35 },
37 36 ]
38 37 return commits
39 38
40 39 def test_simple(self):
41 40 tip = self.repo.get_changeset()
42 self.assertEqual(tip.date, datetime.datetime(2010, 1, 1, 21))
41 assert tip.date == datetime.datetime(2010, 1, 1, 21)
43 42
44 43 def test_new_branch(self):
45 44 # This check must not be removed to ensure the 'branches' LazyProperty
46 45 # gets hit *before* the new 'foobar' branch got created:
47 self.assertFalse('foobar' in self.repo.branches)
46 assert 'foobar' not in self.repo.branches
48 47 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
49 48 content='Documentation\n'))
50 49 foobar_tip = self.imc.commit(
51 50 message=u'New branch: foobar',
52 51 author=u'joe',
53 52 branch='foobar',
54 53 )
55 self.assertTrue('foobar' in self.repo.branches)
56 self.assertEqual(foobar_tip.branch, 'foobar')
54 assert 'foobar' in self.repo.branches
55 assert foobar_tip.branch == 'foobar'
57 56
58 57 def test_new_head(self):
59 58 tip = self.repo.get_changeset()
60 59 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
61 60 content='Documentation\n'))
62 61 foobar_tip = self.imc.commit(
63 62 message=u'New branch: foobar',
64 63 author=u'joe',
65 64 branch='foobar',
66 65 parents=[tip],
67 66 )
68 67 self.imc.change(vcs.nodes.FileNode('docs/index.txt',
69 68 content='Documentation\nand more...\n'))
70 69 newtip = self.imc.commit(
71 70 message=u'At default branch',
72 71 author=u'joe',
73 72 branch=foobar_tip.branch,
74 73 parents=[foobar_tip],
75 74 )
76 75
77 76 newest_tip = self.imc.commit(
78 77 message=u'Merged with %s' % foobar_tip.raw_id,
79 78 author=u'joe',
80 79 branch=self.backend_class.DEFAULT_BRANCH_NAME,
81 80 parents=[newtip, foobar_tip],
82 81 )
83 82
84 self.assertEqual(newest_tip.branch,
85 self.backend_class.DEFAULT_BRANCH_NAME)
83 assert newest_tip.branch == self.backend_class.DEFAULT_BRANCH_NAME
86 84
87 85 def test_branch_with_slash_in_name(self):
88 86 self.imc.add(vcs.nodes.FileNode('extrafile', content='Some data\n'))
89 87 self.imc.commit(u'Branch with a slash!', author=u'joe',
90 88 branch='issue/123')
91 self.assertTrue('issue/123' in self.repo.branches)
89 assert 'issue/123' in self.repo.branches
92 90
93 91 def test_branch_with_slash_in_name_and_similar_without(self):
94 92 self.imc.add(vcs.nodes.FileNode('extrafile', content='Some data\n'))
95 93 self.imc.commit(u'Branch with a slash!', author=u'joe',
96 94 branch='issue/123')
97 95 self.imc.add(vcs.nodes.FileNode('extrafile II', content='Some data\n'))
98 96 self.imc.commit(u'Branch without a slash...', author=u'joe',
99 97 branch='123')
100 self.assertIn('issue/123', self.repo.branches)
101 self.assertIn('123', self.repo.branches)
98 assert 'issue/123' in self.repo.branches
99 assert '123' in self.repo.branches
102 100
103 101
104 102 # For each backend create test case class
105 103 for alias in SCM_TESTS:
106 104 attrs = {
107 105 'backend_alias': alias,
108 106 }
109 cls_name = ''.join(('%s branches test' % alias).title().split())
110 bases = (BranchesTestCaseMixin, unittest.TestCase)
111 globals()[cls_name] = type(cls_name, bases, attrs)
107 cls_name = ''.join(('test %s branches' % alias).title().split())
108 globals()[cls_name] = type(cls_name, (BranchesTestCaseMixin,), attrs)
@@ -1,392 +1,390 b''
1 1 # encoding: utf8
2 2
3 3 import time
4 4 import datetime
5 5
6 from kallithea.lib.vcs.utils.compat import unittest
6 import pytest
7 7
8 8 from kallithea.lib import vcs
9 9
10 10 from kallithea.lib.vcs.backends.base import BaseChangeset
11 11 from kallithea.lib.vcs.nodes import (
12 12 FileNode, AddedFileNodesGenerator,
13 13 ChangedFileNodesGenerator, RemovedFileNodesGenerator
14 14 )
15 15 from kallithea.lib.vcs.exceptions import (
16 16 BranchDoesNotExistError, ChangesetDoesNotExistError,
17 17 RepositoryError, EmptyRepositoryError
18 18 )
19 19
20 20 from kallithea.tests.vcs.base import _BackendTestMixin
21 21 from kallithea.tests.vcs.conf import SCM_TESTS, get_new_dir
22 22
23 23
24 class TestBaseChangeset(unittest.TestCase):
24 class TestBaseChangeset(object):
25 25
26 26 def test_as_dict(self):
27 27 changeset = BaseChangeset()
28 28 changeset.id = 'ID'
29 29 changeset.raw_id = 'RAW_ID'
30 30 changeset.short_id = 'SHORT_ID'
31 31 changeset.revision = 1009
32 32 changeset.date = datetime.datetime(2011, 1, 30, 1, 45)
33 33 changeset.message = 'Message of a commit'
34 34 changeset.author = 'Joe Doe <joe.doe@example.com>'
35 35 changeset.added = [FileNode('foo/bar/baz'), FileNode(u'foobar'), FileNode(u'blΓ₯bΓ¦rgrΓΈd')]
36 36 changeset.changed = []
37 37 changeset.removed = []
38 self.assertEqual(changeset.as_dict(), {
38 assert changeset.as_dict() == {
39 39 'id': 'ID',
40 40 'raw_id': 'RAW_ID',
41 41 'short_id': 'SHORT_ID',
42 42 'revision': 1009,
43 43 'date': datetime.datetime(2011, 1, 30, 1, 45),
44 44 'message': 'Message of a commit',
45 45 'author': {
46 46 'name': 'Joe Doe',
47 47 'email': 'joe.doe@example.com',
48 48 },
49 49 'added': ['foo/bar/baz', 'foobar', u'bl\xe5b\xe6rgr\xf8d'],
50 50 'changed': [],
51 51 'removed': [],
52 })
52 }
53 53
54 54
55 55 class _ChangesetsWithCommitsTestCaseixin(_BackendTestMixin):
56 56 recreate_repo_per_test = True
57 57
58 58 @classmethod
59 59 def _get_commits(cls):
60 60 start_date = datetime.datetime(2010, 1, 1, 20)
61 61 for x in xrange(5):
62 62 yield {
63 63 'message': 'Commit %d' % x,
64 64 'author': 'Joe Doe <joe.doe@example.com>',
65 65 'date': start_date + datetime.timedelta(hours=12 * x),
66 66 'added': [
67 67 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
68 68 ],
69 69 }
70 70
71 71 def test_new_branch(self):
72 72 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
73 73 content='Documentation\n'))
74 74 foobar_tip = self.imc.commit(
75 75 message=u'New branch: foobar',
76 76 author=u'joe',
77 77 branch='foobar',
78 78 )
79 self.assertTrue('foobar' in self.repo.branches)
80 self.assertEqual(foobar_tip.branch, 'foobar')
79 assert 'foobar' in self.repo.branches
80 assert foobar_tip.branch == 'foobar'
81 81 # 'foobar' should be the only branch that contains the new commit
82 self.assertNotEqual(*self.repo.branches.values())
82 branches = self.repo.branches.values()
83 assert branches[0] != branches[1]
83 84
84 85 def test_new_head_in_default_branch(self):
85 86 tip = self.repo.get_changeset()
86 87 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
87 88 content='Documentation\n'))
88 89 foobar_tip = self.imc.commit(
89 90 message=u'New branch: foobar',
90 91 author=u'joe',
91 92 branch='foobar',
92 93 parents=[tip],
93 94 )
94 95 self.imc.change(vcs.nodes.FileNode('docs/index.txt',
95 96 content='Documentation\nand more...\n'))
96 97 newtip = self.imc.commit(
97 98 message=u'At default branch',
98 99 author=u'joe',
99 100 branch=foobar_tip.branch,
100 101 parents=[foobar_tip],
101 102 )
102 103
103 104 newest_tip = self.imc.commit(
104 105 message=u'Merged with %s' % foobar_tip.raw_id,
105 106 author=u'joe',
106 107 branch=self.backend_class.DEFAULT_BRANCH_NAME,
107 108 parents=[newtip, foobar_tip],
108 109 )
109 110
110 self.assertEqual(newest_tip.branch,
111 self.backend_class.DEFAULT_BRANCH_NAME)
111 assert newest_tip.branch == self.backend_class.DEFAULT_BRANCH_NAME
112 112
113 113 def test_get_changesets_respects_branch_name(self):
114 114 tip = self.repo.get_changeset()
115 115 self.imc.add(vcs.nodes.FileNode('docs/index.txt',
116 116 content='Documentation\n'))
117 117 doc_changeset = self.imc.commit(
118 118 message=u'New branch: docs',
119 119 author=u'joe',
120 120 branch='docs',
121 121 )
122 122 self.imc.add(vcs.nodes.FileNode('newfile', content=''))
123 123 self.imc.commit(
124 124 message=u'Back in default branch',
125 125 author=u'joe',
126 126 parents=[tip],
127 127 )
128 128 default_branch_changesets = self.repo.get_changesets(
129 129 branch_name=self.repo.DEFAULT_BRANCH_NAME)
130 self.assertNotIn(doc_changeset, default_branch_changesets)
130 assert doc_changeset not in default_branch_changesets
131 131
132 132 def test_get_changeset_by_branch(self):
133 133 for branch, sha in self.repo.branches.iteritems():
134 self.assertEqual(sha, self.repo.get_changeset(branch).raw_id)
134 assert sha == self.repo.get_changeset(branch).raw_id
135 135
136 136 def test_get_changeset_by_tag(self):
137 137 for tag, sha in self.repo.tags.iteritems():
138 self.assertEqual(sha, self.repo.get_changeset(tag).raw_id)
138 assert sha == self.repo.get_changeset(tag).raw_id
139 139
140 140 def test_get_changeset_parents(self):
141 141 for test_rev in [1, 2, 3]:
142 142 sha = self.repo.get_changeset(test_rev-1)
143 self.assertEqual([sha], self.repo.get_changeset(test_rev).parents)
143 assert [sha] == self.repo.get_changeset(test_rev).parents
144 144
145 145 def test_get_changeset_children(self):
146 146 for test_rev in [1, 2, 3]:
147 147 sha = self.repo.get_changeset(test_rev+1)
148 self.assertEqual([sha], self.repo.get_changeset(test_rev).children)
148 assert [sha] == self.repo.get_changeset(test_rev).children
149 149
150 150
151 151 class _ChangesetsTestCaseMixin(_BackendTestMixin):
152 152 recreate_repo_per_test = False
153 153
154 154 @classmethod
155 155 def _get_commits(cls):
156 156 start_date = datetime.datetime(2010, 1, 1, 20)
157 157 for x in xrange(5):
158 158 yield {
159 159 'message': u'Commit %d' % x,
160 160 'author': u'Joe Doe <joe.doe@example.com>',
161 161 'date': start_date + datetime.timedelta(hours=12 * x),
162 162 'added': [
163 163 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
164 164 ],
165 165 }
166 166
167 167 def test_simple(self):
168 168 tip = self.repo.get_changeset()
169 self.assertEqual(tip.date, datetime.datetime(2010, 1, 3, 20))
169 assert tip.date == datetime.datetime(2010, 1, 3, 20)
170 170
171 171 def test_get_changesets_is_ordered_by_date(self):
172 172 changesets = list(self.repo.get_changesets())
173 173 ordered_by_date = sorted(changesets,
174 174 key=lambda cs: cs.date)
175 self.assertItemsEqual(changesets, ordered_by_date)
175
176 assert changesets == ordered_by_date
176 177
177 178 def test_get_changesets_respects_start(self):
178 179 second_id = self.repo.revisions[1]
179 180 changesets = list(self.repo.get_changesets(start=second_id))
180 self.assertEqual(len(changesets), 4)
181 assert len(changesets) == 4
181 182
182 183 def test_get_changesets_numerical_id_respects_start(self):
183 184 second_id = 1
184 185 changesets = list(self.repo.get_changesets(start=second_id))
185 self.assertEqual(len(changesets), 4)
186 assert len(changesets) == 4
186 187
187 188 def test_get_changesets_includes_start_changeset(self):
188 189 second_id = self.repo.revisions[1]
189 190 changesets = list(self.repo.get_changesets(start=second_id))
190 self.assertEqual(changesets[0].raw_id, second_id)
191 assert changesets[0].raw_id == second_id
191 192
192 193 def test_get_changesets_respects_end(self):
193 194 second_id = self.repo.revisions[1]
194 195 changesets = list(self.repo.get_changesets(end=second_id))
195 self.assertEqual(changesets[-1].raw_id, second_id)
196 self.assertEqual(len(changesets), 2)
196 assert changesets[-1].raw_id == second_id
197 assert len(changesets) == 2
197 198
198 199 def test_get_changesets_numerical_id_respects_end(self):
199 200 second_id = 1
200 201 changesets = list(self.repo.get_changesets(end=second_id))
201 self.assertEqual(changesets.index(changesets[-1]), second_id)
202 self.assertEqual(len(changesets), 2)
202 assert changesets.index(changesets[-1]) == second_id
203 assert len(changesets) == 2
203 204
204 205 def test_get_changesets_respects_both_start_and_end(self):
205 206 second_id = self.repo.revisions[1]
206 207 third_id = self.repo.revisions[2]
207 208 changesets = list(self.repo.get_changesets(start=second_id,
208 209 end=third_id))
209 self.assertEqual(len(changesets), 2)
210 assert len(changesets) == 2
210 211
211 212 def test_get_changesets_numerical_id_respects_both_start_and_end(self):
212 213 changesets = list(self.repo.get_changesets(start=2, end=3))
213 self.assertEqual(len(changesets), 2)
214 assert len(changesets) == 2
214 215
215 216 def test_get_changesets_on_empty_repo_raises_EmptyRepository_error(self):
216 217 Backend = self.get_backend()
217 218 repo_path = get_new_dir(str(time.time()))
218 219 repo = Backend(repo_path, create=True)
219 220
220 with self.assertRaises(EmptyRepositoryError):
221 with pytest.raises(EmptyRepositoryError):
221 222 list(repo.get_changesets(start='foobar'))
222 223
223 224 def test_get_changesets_includes_end_changeset(self):
224 225 second_id = self.repo.revisions[1]
225 226 changesets = list(self.repo.get_changesets(end=second_id))
226 self.assertEqual(changesets[-1].raw_id, second_id)
227 assert changesets[-1].raw_id == second_id
227 228
228 229 def test_get_changesets_respects_start_date(self):
229 230 start_date = datetime.datetime(2010, 2, 1)
230 231 for cs in self.repo.get_changesets(start_date=start_date):
231 self.assertGreaterEqual(cs.date, start_date)
232 assert cs.date >= start_date
232 233
233 234 def test_get_changesets_respects_end_date(self):
234 235 start_date = datetime.datetime(2010, 1, 1)
235 236 end_date = datetime.datetime(2010, 2, 1)
236 237 for cs in self.repo.get_changesets(start_date=start_date,
237 238 end_date=end_date):
238 self.assertGreaterEqual(cs.date, start_date)
239 self.assertLessEqual(cs.date, end_date)
239 assert cs.date >= start_date
240 assert cs.date <= end_date
240 241
241 242 def test_get_changesets_respects_start_date_and_end_date(self):
242 243 end_date = datetime.datetime(2010, 2, 1)
243 244 for cs in self.repo.get_changesets(end_date=end_date):
244 self.assertLessEqual(cs.date, end_date)
245 assert cs.date <= end_date
245 246
246 247 def test_get_changesets_respects_reverse(self):
247 248 changesets_id_list = [cs.raw_id for cs in
248 249 self.repo.get_changesets(reverse=True)]
249 self.assertItemsEqual(changesets_id_list, reversed(self.repo.revisions))
250 assert changesets_id_list == list(reversed(self.repo.revisions))
250 251
251 252 def test_get_filenodes_generator(self):
252 253 tip = self.repo.get_changeset()
253 254 filepaths = [node.path for node in tip.get_filenodes_generator()]
254 self.assertItemsEqual(filepaths, ['file_%d.txt' % x for x in xrange(5)])
255 assert filepaths == ['file_%d.txt' % x for x in xrange(5)]
255 256
256 257 def test_size(self):
257 258 tip = self.repo.get_changeset()
258 259 size = 5 * len('Foobar N') # Size of 5 files
259 self.assertEqual(tip.size, size)
260 assert tip.size == size
260 261
261 262 def test_author(self):
262 263 tip = self.repo.get_changeset()
263 self.assertEqual(tip.author, u'Joe Doe <joe.doe@example.com>')
264 assert tip.author == u'Joe Doe <joe.doe@example.com>'
264 265
265 266 def test_author_name(self):
266 267 tip = self.repo.get_changeset()
267 self.assertEqual(tip.author_name, u'Joe Doe')
268 assert tip.author_name == u'Joe Doe'
268 269
269 270 def test_author_email(self):
270 271 tip = self.repo.get_changeset()
271 self.assertEqual(tip.author_email, u'joe.doe@example.com')
272 assert tip.author_email == u'joe.doe@example.com'
272 273
273 274 def test_get_changesets_raise_changesetdoesnotexist_for_wrong_start(self):
274 with self.assertRaises(ChangesetDoesNotExistError):
275 with pytest.raises(ChangesetDoesNotExistError):
275 276 list(self.repo.get_changesets(start='foobar'))
276 277
277 278 def test_get_changesets_raise_changesetdoesnotexist_for_wrong_end(self):
278 with self.assertRaises(ChangesetDoesNotExistError):
279 with pytest.raises(ChangesetDoesNotExistError):
279 280 list(self.repo.get_changesets(end='foobar'))
280 281
281 282 def test_get_changesets_raise_branchdoesnotexist_for_wrong_branch_name(self):
282 with self.assertRaises(BranchDoesNotExistError):
283 with pytest.raises(BranchDoesNotExistError):
283 284 list(self.repo.get_changesets(branch_name='foobar'))
284 285
285 286 def test_get_changesets_raise_repositoryerror_for_wrong_start_end(self):
286 287 start = self.repo.revisions[-1]
287 288 end = self.repo.revisions[0]
288 with self.assertRaises(RepositoryError):
289 with pytest.raises(RepositoryError):
289 290 list(self.repo.get_changesets(start=start, end=end))
290 291
291 292 def test_get_changesets_numerical_id_reversed(self):
292 with self.assertRaises(RepositoryError):
293 with pytest.raises(RepositoryError):
293 294 [x for x in self.repo.get_changesets(start=3, end=2)]
294 295
295 296 def test_get_changesets_numerical_id_respects_both_start_and_end_last(self):
296 with self.assertRaises(RepositoryError):
297 with pytest.raises(RepositoryError):
297 298 last = len(self.repo.revisions)
298 299 list(self.repo.get_changesets(start=last-1, end=last-2))
299 300
300 301 def test_get_changesets_numerical_id_last_zero_error(self):
301 with self.assertRaises(RepositoryError):
302 with pytest.raises(RepositoryError):
302 303 last = len(self.repo.revisions)
303 304 list(self.repo.get_changesets(start=last-1, end=0))
304 305
305 306
306 307 class _ChangesetsChangesTestCaseMixin(_BackendTestMixin):
307 308 recreate_repo_per_test = False
308 309
309 310 @classmethod
310 311 def _get_commits(cls):
311 312 return [
312 313 {
313 314 'message': u'Initial',
314 315 'author': u'Joe Doe <joe.doe@example.com>',
315 316 'date': datetime.datetime(2010, 1, 1, 20),
316 317 'added': [
317 318 FileNode('foo/bar', content='foo'),
318 319 FileNode('foo/baΕ‚', content='foo'),
319 320 FileNode('foobar', content='foo'),
320 321 FileNode('qwe', content='foo'),
321 322 ],
322 323 },
323 324 {
324 325 'message': u'Massive changes',
325 326 'author': u'Joe Doe <joe.doe@example.com>',
326 327 'date': datetime.datetime(2010, 1, 1, 22),
327 328 'added': [FileNode('fallout', content='War never changes')],
328 329 'changed': [
329 330 FileNode('foo/bar', content='baz'),
330 331 FileNode('foobar', content='baz'),
331 332 ],
332 333 'removed': [FileNode('qwe')],
333 334 },
334 335 ]
335 336
336 337 def test_initial_commit(self):
337 338 changeset = self.repo.get_changeset(0)
338 self.assertItemsEqual(changeset.added, [
339 assert sorted(list(changeset.added)) == sorted([
339 340 changeset.get_node('foo/bar'),
340 341 changeset.get_node('foo/baΕ‚'),
341 342 changeset.get_node('foobar'),
342 343 changeset.get_node('qwe'),
343 344 ])
344 self.assertItemsEqual(changeset.changed, [])
345 self.assertItemsEqual(changeset.removed, [])
345 assert list(changeset.changed) == []
346 assert list(changeset.removed) == []
346 347 assert u'foo/ba\u0142' in changeset.as_dict()['added']
347 348 assert u'foo/ba\u0142' in changeset.__json__(with_file_list=True)['added']
348 349
349 350 def test_head_added(self):
350 351 changeset = self.repo.get_changeset()
351 self.assertTrue(isinstance(changeset.added, AddedFileNodesGenerator))
352 self.assertItemsEqual(changeset.added, [
352 assert isinstance(changeset.added, AddedFileNodesGenerator)
353 assert list(changeset.added) == [
353 354 changeset.get_node('fallout'),
354 ])
355 self.assertTrue(isinstance(changeset.changed, ChangedFileNodesGenerator))
356 self.assertItemsEqual(changeset.changed, [
355 ]
356 assert isinstance(changeset.changed, ChangedFileNodesGenerator)
357 assert list(changeset.changed) == [
357 358 changeset.get_node('foo/bar'),
358 359 changeset.get_node('foobar'),
359 ])
360 self.assertTrue(isinstance(changeset.removed, RemovedFileNodesGenerator))
361 self.assertEqual(len(changeset.removed), 1)
362 self.assertEqual(list(changeset.removed)[0].path, 'qwe')
360 ]
361 assert isinstance(changeset.removed, RemovedFileNodesGenerator)
362 assert len(changeset.removed) == 1
363 assert list(changeset.removed)[0].path == 'qwe'
363 364
364 365 def test_get_filemode(self):
365 366 changeset = self.repo.get_changeset()
366 self.assertEqual(33188, changeset.get_file_mode('foo/bar'))
367 assert 33188 == changeset.get_file_mode('foo/bar')
367 368
368 369 def test_get_filemode_non_ascii(self):
369 370 changeset = self.repo.get_changeset()
370 self.assertEqual(33188, changeset.get_file_mode('foo/baΕ‚'))
371 self.assertEqual(33188, changeset.get_file_mode(u'foo/baΕ‚'))
371 assert 33188 == changeset.get_file_mode('foo/baΕ‚')
372 assert 33188 == changeset.get_file_mode(u'foo/baΕ‚')
372 373
373 374
374 375 # For each backend create test case class
375 376 for alias in SCM_TESTS:
376 377 attrs = {
377 378 'backend_alias': alias,
378 379 }
379 380 # tests with additional commits
380 cls_name = alias.title() + 'ChangesetsWithCommitsTest'
381 bases = (_ChangesetsWithCommitsTestCaseixin, unittest.TestCase)
382 globals()[cls_name] = type(cls_name, bases, attrs)
381 cls_name = 'Test' + alias.title() + 'ChangesetsWithCommits'
382 globals()[cls_name] = type(cls_name, (_ChangesetsWithCommitsTestCaseixin,), attrs)
383 383
384 384 # tests without additional commits
385 cls_name = alias.title() + 'ChangesetsTest'
386 bases = (_ChangesetsTestCaseMixin, unittest.TestCase)
387 globals()[cls_name] = type(cls_name, bases, attrs)
385 cls_name = 'Test' + alias.title() + 'Changesets'
386 globals()[cls_name] = type(cls_name, (_ChangesetsTestCaseMixin,), attrs)
388 387
389 388 # tests changes
390 cls_name = alias.title() + 'ChangesetsChangesTest'
391 bases = (_ChangesetsChangesTestCaseMixin, unittest.TestCase)
392 globals()[cls_name] = type(cls_name, bases, attrs)
389 cls_name = 'Test' + alias.title() + 'ChangesetsChanges'
390 globals()[cls_name] = type(cls_name, (_ChangesetsChangesTestCaseMixin,), attrs)
@@ -1,43 +1,43 b''
1 1 # encoding: utf8
2 2
3 3 import datetime
4 4
5 5 from kallithea.lib.vcs.nodes import FileNode
6 6 from kallithea.tests.vcs.test_inmemchangesets import BackendBaseTestCase
7 7 from kallithea.tests.vcs.conf import SCM_TESTS
8 8
9 9
10 10 class FileNodeUnicodePathTestsMixin(object):
11 11
12 12 fname = 'Δ…Ε›Γ°Δ…Δ™Ε‚Δ…Δ‡.txt'
13 13 ufname = (fname).decode('utf-8')
14 14
15 15 def get_commits(self):
16 16 self.nodes = [
17 17 FileNode(self.fname, content='Foobar'),
18 18 ]
19 19
20 20 commits = [
21 21 {
22 22 'message': 'Initial commit',
23 23 'author': 'Joe Doe <joe.doe@example.com>',
24 24 'date': datetime.datetime(2010, 1, 1, 20),
25 25 'added': self.nodes,
26 26 },
27 27 ]
28 28 return commits
29 29
30 30 def test_filenode_path(self):
31 31 node = self.tip.get_node(self.fname)
32 32 unode = self.tip.get_node(self.ufname)
33 self.assertEqual(node, unode)
33 assert node == unode
34 34
35 35
36 36 for alias in SCM_TESTS:
37 37 attrs = {
38 38 'backend_alias': alias,
39 39 }
40 cls_name = ''.join(('%s file node unicode path test' % alias).title()
40 cls_name = ''.join(('test %s file node unicode path' % alias).title()
41 41 .split())
42 42 bases = (FileNodeUnicodePathTestsMixin, BackendBaseTestCase)
43 43 globals()[cls_name] = type(cls_name, bases, attrs)
@@ -1,39 +1,37 b''
1 1 import datetime
2 2
3 3 from kallithea.tests.vcs.base import _BackendTestMixin
4 4 from kallithea.tests.vcs.conf import SCM_TESTS
5 5 from kallithea.lib.vcs.nodes import FileNode
6 from kallithea.lib.vcs.utils.compat import unittest
7 6
8 7
9 8 class GetitemTestCaseMixin(_BackendTestMixin):
10 9
11 10 @classmethod
12 11 def _get_commits(cls):
13 12 start_date = datetime.datetime(2010, 1, 1, 20)
14 13 for x in xrange(5):
15 14 yield {
16 15 'message': 'Commit %d' % x,
17 16 'author': 'Joe Doe <joe.doe@example.com>',
18 17 'date': start_date + datetime.timedelta(hours=12 * x),
19 18 'added': [
20 19 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
21 20 ],
22 21 }
23 22
24 23 def test__getitem__last_item_is_tip(self):
25 self.assertEqual(self.repo[-1], self.repo.get_changeset())
24 assert self.repo[-1] == self.repo.get_changeset()
26 25
27 26 def test__getitem__returns_correct_items(self):
28 27 changesets = [self.repo[x] for x in xrange(len(self.repo.revisions))]
29 self.assertEqual(changesets, list(self.repo.get_changesets()))
28 assert changesets == list(self.repo.get_changesets())
30 29
31 30
32 31 # For each backend create test case class
33 32 for alias in SCM_TESTS:
34 33 attrs = {
35 34 'backend_alias': alias,
36 35 }
37 cls_name = ''.join(('%s getitem test' % alias).title().split())
38 bases = (GetitemTestCaseMixin, unittest.TestCase)
39 globals()[cls_name] = type(cls_name, bases, attrs)
36 cls_name = ''.join(('test %s getitem' % alias).title().split())
37 globals()[cls_name] = type(cls_name, (GetitemTestCaseMixin,), attrs)
@@ -1,53 +1,46 b''
1 1 import datetime
2 2
3 3 from kallithea.lib.vcs.nodes import FileNode
4 4
5 from kallithea.lib.vcs.utils.compat import unittest
6
7 5 from kallithea.tests.vcs.base import _BackendTestMixin
8 6 from kallithea.tests.vcs.conf import SCM_TESTS
9 7
10 8
11 9 class GetsliceTestCaseMixin(_BackendTestMixin):
12 10
13 11 @classmethod
14 12 def _get_commits(cls):
15 13 start_date = datetime.datetime(2010, 1, 1, 20)
16 14 for x in xrange(5):
17 15 yield {
18 16 'message': 'Commit %d' % x,
19 17 'author': 'Joe Doe <joe.doe@example.com>',
20 18 'date': start_date + datetime.timedelta(hours=12 * x),
21 19 'added': [
22 20 FileNode('file_%d.txt' % x, content='Foobar %d' % x),
23 21 ],
24 22 }
25 23
26 24 def test__getslice__last_item_is_tip(self):
27 self.assertEqual(list(self.repo[-1:])[0], self.repo.get_changeset())
25 assert list(self.repo[-1:])[0] == self.repo.get_changeset()
28 26
29 27 def test__getslice__respects_start_index(self):
30 self.assertEqual(list(self.repo[2:]),
31 [self.repo.get_changeset(rev) for rev in self.repo.revisions[2:]])
28 assert list(self.repo[2:]) == [self.repo.get_changeset(rev) for rev in self.repo.revisions[2:]]
32 29
33 30 def test__getslice__respects_negative_start_index(self):
34 self.assertEqual(list(self.repo[-2:]),
35 [self.repo.get_changeset(rev) for rev in self.repo.revisions[-2:]])
31 assert list(self.repo[-2:]) == [self.repo.get_changeset(rev) for rev in self.repo.revisions[-2:]]
36 32
37 33 def test__getslice__respects_end_index(self):
38 self.assertEqual(list(self.repo[:2]),
39 [self.repo.get_changeset(rev) for rev in self.repo.revisions[:2]])
34 assert list(self.repo[:2]) == [self.repo.get_changeset(rev) for rev in self.repo.revisions[:2]]
40 35
41 36 def test__getslice__respects_negative_end_index(self):
42 self.assertEqual(list(self.repo[:-2]),
43 [self.repo.get_changeset(rev) for rev in self.repo.revisions[:-2]])
37 assert list(self.repo[:-2]) == [self.repo.get_changeset(rev) for rev in self.repo.revisions[:-2]]
44 38
45 39
46 40 # For each backend create test case class
47 41 for alias in SCM_TESTS:
48 42 attrs = {
49 43 'backend_alias': alias,
50 44 }
51 cls_name = ''.join(('%s getslice test' % alias).title().split())
52 bases = (GetsliceTestCaseMixin, unittest.TestCase)
53 globals()[cls_name] = type(cls_name, bases, attrs)
45 cls_name = ''.join(('test %s getslice' % alias).title().split())
46 globals()[cls_name] = type(cls_name, (GetsliceTestCaseMixin,), attrs)
@@ -1,847 +1,828 b''
1 1 import os
2 2 import sys
3 3 import mock
4 4 import datetime
5 5 import urllib2
6 6
7 7 import pytest
8 8
9 9 from kallithea.lib.vcs.backends.git import GitRepository, GitChangeset
10 10 from kallithea.lib.vcs.exceptions import RepositoryError, VCSError, NodeDoesNotExistError
11 11 from kallithea.lib.vcs.nodes import NodeKind, FileNode, DirNode, NodeState
12 from kallithea.lib.vcs.utils.compat import unittest
13 12 from kallithea.model.scm import ScmModel
14 13
15 14 from kallithea.tests.vcs.base import _BackendTestMixin
16 15 from kallithea.tests.vcs.conf import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, TESTS_TMP_PATH, get_new_dir
17 16
18 17
19 class GitRepositoryTest(unittest.TestCase):
18 class TestGitRepository(object):
20 19
21 20 def __check_for_existing_repo(self):
22 21 if os.path.exists(TEST_GIT_REPO_CLONE):
23 22 pytest.fail('Cannot test git clone repo as location %s already '
24 23 'exists. You should manually remove it first.'
25 24 % TEST_GIT_REPO_CLONE)
26 25
27 def setUp(self):
26 def setup_method(self):
28 27 self.repo = GitRepository(TEST_GIT_REPO)
29 28
30 29 def test_wrong_repo_path(self):
31 30 wrong_repo_path = os.path.join(TESTS_TMP_PATH, 'errorrepo')
32 self.assertRaises(RepositoryError, GitRepository, wrong_repo_path)
31 with pytest.raises(RepositoryError):
32 GitRepository(wrong_repo_path)
33 33
34 34 def test_git_cmd_injection(self):
35 35 repo_inject_path = TEST_GIT_REPO + '; echo "Cake";'
36 with self.assertRaises(urllib2.URLError):
36 with pytest.raises(urllib2.URLError):
37 37 # Should fail because URL will contain the parts after ; too
38 38 GitRepository(get_new_dir('injection-repo'), src_url=repo_inject_path, update_after_clone=True, create=True)
39 39
40 with self.assertRaises(RepositoryError):
40 with pytest.raises(RepositoryError):
41 41 # Should fail on direct clone call, which as of this writing does not happen outside of class
42 42 clone_fail_repo = GitRepository(get_new_dir('injection-repo'), create=True)
43 43 clone_fail_repo.clone(repo_inject_path, update_after_clone=True,)
44 44
45 45 # Verify correct quoting of evil characters that should work on posix file systems
46 46 if sys.platform == 'win32':
47 47 # windows does not allow '"' in dir names
48 48 # and some versions of the git client don't like ` and '
49 49 tricky_path = get_new_dir("tricky-path-repo-$")
50 50 else:
51 51 tricky_path = get_new_dir("tricky-path-repo-$'\"`")
52 52 successfully_cloned = GitRepository(tricky_path, src_url=TEST_GIT_REPO, update_after_clone=True, create=True)
53 53 # Repo should have been created
54 self.assertFalse(successfully_cloned._repo.bare)
54 assert not successfully_cloned._repo.bare
55 55
56 56 if sys.platform == 'win32':
57 57 # windows does not allow '"' in dir names
58 58 # and some versions of the git client don't like ` and '
59 59 tricky_path_2 = get_new_dir("tricky-path-2-repo-$")
60 60 else:
61 61 tricky_path_2 = get_new_dir("tricky-path-2-repo-$'\"`")
62 62 successfully_cloned2 = GitRepository(tricky_path_2, src_url=tricky_path, bare=True, create=True)
63 63 # Repo should have been created and thus used correct quoting for clone
64 self.assertTrue(successfully_cloned2._repo.bare)
64 assert successfully_cloned2._repo.bare
65 65
66 66 # Should pass because URL has been properly quoted
67 67 successfully_cloned.pull(tricky_path_2)
68 68 successfully_cloned2.fetch(tricky_path)
69 69
70 70 def test_repo_create_with_spaces_in_path(self):
71 71 repo_path = get_new_dir("path with spaces")
72 72 repo = GitRepository(repo_path, src_url=None, bare=True, create=True)
73 73 # Repo should have been created
74 self.assertTrue(repo._repo.bare)
74 assert repo._repo.bare
75 75
76 76 def test_repo_clone(self):
77 77 self.__check_for_existing_repo()
78 78 repo = GitRepository(TEST_GIT_REPO)
79 79 repo_clone = GitRepository(TEST_GIT_REPO_CLONE,
80 80 src_url=TEST_GIT_REPO, create=True, update_after_clone=True)
81 self.assertEqual(len(repo.revisions), len(repo_clone.revisions))
81 assert len(repo.revisions) == len(repo_clone.revisions)
82 82 # Checking hashes of changesets should be enough
83 83 for changeset in repo.get_changesets():
84 84 raw_id = changeset.raw_id
85 self.assertEqual(raw_id, repo_clone.get_changeset(raw_id).raw_id)
85 assert raw_id == repo_clone.get_changeset(raw_id).raw_id
86 86
87 87 def test_repo_clone_with_spaces_in_path(self):
88 88 repo_path = get_new_dir("path with spaces")
89 89 successfully_cloned = GitRepository(repo_path, src_url=TEST_GIT_REPO, update_after_clone=True, create=True)
90 90 # Repo should have been created
91 self.assertFalse(successfully_cloned._repo.bare)
91 assert not successfully_cloned._repo.bare
92 92
93 93 successfully_cloned.pull(TEST_GIT_REPO)
94 94 self.repo.fetch(repo_path)
95 95
96 96 def test_repo_clone_without_create(self):
97 self.assertRaises(RepositoryError, GitRepository,
98 TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
97 with pytest.raises(RepositoryError):
98 GitRepository(TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
99 99
100 100 def test_repo_clone_with_update(self):
101 101 repo = GitRepository(TEST_GIT_REPO)
102 102 clone_path = TEST_GIT_REPO_CLONE + '_with_update'
103 103 repo_clone = GitRepository(clone_path,
104 104 create=True, src_url=TEST_GIT_REPO, update_after_clone=True)
105 self.assertEqual(len(repo.revisions), len(repo_clone.revisions))
105 assert len(repo.revisions) == len(repo_clone.revisions)
106 106
107 107 # check if current workdir was updated
108 108 fpath = os.path.join(clone_path, 'MANIFEST.in')
109 self.assertEqual(True, os.path.isfile(fpath),
110 'Repo was cloned and updated but file %s could not be found'
111 % fpath)
109 assert os.path.isfile(fpath) == True, 'Repo was cloned and updated but file %s could not be found' % fpath
112 110
113 111 def test_repo_clone_without_update(self):
114 112 repo = GitRepository(TEST_GIT_REPO)
115 113 clone_path = TEST_GIT_REPO_CLONE + '_without_update'
116 114 repo_clone = GitRepository(clone_path,
117 115 create=True, src_url=TEST_GIT_REPO, update_after_clone=False)
118 self.assertEqual(len(repo.revisions), len(repo_clone.revisions))
116 assert len(repo.revisions) == len(repo_clone.revisions)
119 117 # check if current workdir was *NOT* updated
120 118 fpath = os.path.join(clone_path, 'MANIFEST.in')
121 119 # Make sure it's not bare repo
122 self.assertFalse(repo_clone._repo.bare)
123 self.assertEqual(False, os.path.isfile(fpath),
124 'Repo was cloned and updated but file %s was found'
125 % fpath)
120 assert not repo_clone._repo.bare
121 assert os.path.isfile(fpath) == False, 'Repo was cloned and updated but file %s was found' % fpath
126 122
127 123 def test_repo_clone_into_bare_repo(self):
128 124 repo = GitRepository(TEST_GIT_REPO)
129 125 clone_path = TEST_GIT_REPO_CLONE + '_bare.git'
130 126 repo_clone = GitRepository(clone_path, create=True,
131 127 src_url=repo.path, bare=True)
132 self.assertTrue(repo_clone._repo.bare)
128 assert repo_clone._repo.bare
133 129
134 130 def test_create_repo_is_not_bare_by_default(self):
135 131 repo = GitRepository(get_new_dir('not-bare-by-default'), create=True)
136 self.assertFalse(repo._repo.bare)
132 assert not repo._repo.bare
137 133
138 134 def test_create_bare_repo(self):
139 135 repo = GitRepository(get_new_dir('bare-repo'), create=True, bare=True)
140 self.assertTrue(repo._repo.bare)
136 assert repo._repo.bare
141 137
142 138 def test_revisions(self):
143 139 # there are 112 revisions (by now)
144 140 # so we can assume they would be available from now on
145 141 subset = set([
146 142 'c1214f7e79e02fc37156ff215cd71275450cffc3',
147 143 '38b5fe81f109cb111f549bfe9bb6b267e10bc557',
148 144 'fa6600f6848800641328adbf7811fd2372c02ab2',
149 145 '102607b09cdd60e2793929c4f90478be29f85a17',
150 146 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
151 147 '2d1028c054665b962fa3d307adfc923ddd528038',
152 148 'd7e0d30fbcae12c90680eb095a4f5f02505ce501',
153 149 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
154 150 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
155 151 '8430a588b43b5d6da365400117c89400326e7992',
156 152 'd955cd312c17b02143c04fa1099a352b04368118',
157 153 'f67b87e5c629c2ee0ba58f85197e423ff28d735b',
158 154 'add63e382e4aabc9e1afdc4bdc24506c269b7618',
159 155 'f298fe1189f1b69779a4423f40b48edf92a703fc',
160 156 'bd9b619eb41994cac43d67cf4ccc8399c1125808',
161 157 '6e125e7c890379446e98980d8ed60fba87d0f6d1',
162 158 'd4a54db9f745dfeba6933bf5b1e79e15d0af20bd',
163 159 '0b05e4ed56c802098dfc813cbe779b2f49e92500',
164 160 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
165 161 '45223f8f114c64bf4d6f853e3c35a369a6305520',
166 162 'ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
167 163 'f5ea29fc42ef67a2a5a7aecff10e1566699acd68',
168 164 '27d48942240f5b91dfda77accd2caac94708cc7d',
169 165 '622f0eb0bafd619d2560c26f80f09e3b0b0d78af',
170 166 'e686b958768ee96af8029fe19c6050b1a8dd3b2b'])
171 self.assertTrue(subset.issubset(set(self.repo.revisions)))
167 assert subset.issubset(set(self.repo.revisions))
172 168
173 169 def test_slicing(self):
174 170 # 4 1 5 10 95
175 171 for sfrom, sto, size in [(0, 4, 4), (1, 2, 1), (10, 15, 5),
176 172 (10, 20, 10), (5, 100, 95)]:
177 173 revs = list(self.repo[sfrom:sto])
178 self.assertEqual(len(revs), size)
179 self.assertEqual(revs[0], self.repo.get_changeset(sfrom))
180 self.assertEqual(revs[-1], self.repo.get_changeset(sto - 1))
174 assert len(revs) == size
175 assert revs[0] == self.repo.get_changeset(sfrom)
176 assert revs[-1] == self.repo.get_changeset(sto - 1)
181 177
182 178 def test_branches(self):
183 179 # TODO: Need more tests here
184 180 # Removed (those are 'remotes' branches for cloned repo)
185 #self.assertTrue('master' in self.repo.branches)
186 #self.assertTrue('gittree' in self.repo.branches)
187 #self.assertTrue('web-branch' in self.repo.branches)
181 #assert 'master' in self.repo.branches
182 #assert 'gittree' in self.repo.branches
183 #assert 'web-branch' in self.repo.branches
188 184 for name, id in self.repo.branches.items():
189 self.assertTrue(isinstance(
190 self.repo.get_changeset(id), GitChangeset))
185 assert isinstance(self.repo.get_changeset(id), GitChangeset)
191 186
192 187 def test_tags(self):
193 188 # TODO: Need more tests here
194 self.assertTrue('v0.1.1' in self.repo.tags)
195 self.assertTrue('v0.1.2' in self.repo.tags)
189 assert 'v0.1.1' in self.repo.tags
190 assert 'v0.1.2' in self.repo.tags
196 191 for name, id in self.repo.tags.items():
197 self.assertTrue(isinstance(
198 self.repo.get_changeset(id), GitChangeset))
192 assert isinstance(self.repo.get_changeset(id), GitChangeset)
199 193
200 194 def _test_single_changeset_cache(self, revision):
201 195 chset = self.repo.get_changeset(revision)
202 self.assertTrue(revision in self.repo.changesets)
203 self.assertTrue(chset is self.repo.changesets[revision])
196 assert revision in self.repo.changesets
197 assert chset is self.repo.changesets[revision]
204 198
205 199 def test_initial_changeset(self):
206 200 id = self.repo.revisions[0]
207 201 init_chset = self.repo.get_changeset(id)
208 self.assertEqual(init_chset.message, 'initial import\n')
209 self.assertEqual(init_chset.author,
210 'Marcin Kuzminski <marcin@python-blog.com>')
202 assert init_chset.message == 'initial import\n'
203 assert init_chset.author == 'Marcin Kuzminski <marcin@python-blog.com>'
211 204 for path in ('vcs/__init__.py',
212 205 'vcs/backends/BaseRepository.py',
213 206 'vcs/backends/__init__.py'):
214 self.assertTrue(isinstance(init_chset.get_node(path), FileNode))
207 assert isinstance(init_chset.get_node(path), FileNode)
215 208 for path in ('', 'vcs', 'vcs/backends'):
216 self.assertTrue(isinstance(init_chset.get_node(path), DirNode))
209 assert isinstance(init_chset.get_node(path), DirNode)
217 210
218 self.assertRaises(NodeDoesNotExistError, init_chset.get_node, path='foobar')
211 with pytest.raises(NodeDoesNotExistError):
212 init_chset.get_node(path='foobar')
219 213
220 214 node = init_chset.get_node('vcs/')
221 self.assertTrue(hasattr(node, 'kind'))
222 self.assertEqual(node.kind, NodeKind.DIR)
215 assert hasattr(node, 'kind')
216 assert node.kind == NodeKind.DIR
223 217
224 218 node = init_chset.get_node('vcs')
225 self.assertTrue(hasattr(node, 'kind'))
226 self.assertEqual(node.kind, NodeKind.DIR)
219 assert hasattr(node, 'kind')
220 assert node.kind == NodeKind.DIR
227 221
228 222 node = init_chset.get_node('vcs/__init__.py')
229 self.assertTrue(hasattr(node, 'kind'))
230 self.assertEqual(node.kind, NodeKind.FILE)
223 assert hasattr(node, 'kind')
224 assert node.kind == NodeKind.FILE
231 225
232 226 def test_not_existing_changeset(self):
233 self.assertRaises(RepositoryError, self.repo.get_changeset,
234 'f' * 40)
227 with pytest.raises(RepositoryError):
228 self.repo.get_changeset('f' * 40)
235 229
236 230 def test_changeset10(self):
237 231
238 232 chset10 = self.repo.get_changeset(self.repo.revisions[9])
239 233 readme = """===
240 234 VCS
241 235 ===
242 236
243 237 Various Version Control System management abstraction layer for Python.
244 238
245 239 Introduction
246 240 ------------
247 241
248 242 TODO: To be written...
249 243
250 244 """
251 245 node = chset10.get_node('README.rst')
252 self.assertEqual(node.kind, NodeKind.FILE)
253 self.assertEqual(node.content, readme)
246 assert node.kind == NodeKind.FILE
247 assert node.content == readme
254 248
255 249
256 class GitChangesetTest(unittest.TestCase):
250 class TestGitChangeset(object):
257 251
258 def setUp(self):
252 def setup_method(self):
259 253 self.repo = GitRepository(TEST_GIT_REPO)
260 254
261 255 def test_default_changeset(self):
262 256 tip = self.repo.get_changeset()
263 self.assertEqual(tip, self.repo.get_changeset(None))
264 self.assertEqual(tip, self.repo.get_changeset('tip'))
257 assert tip == self.repo.get_changeset(None)
258 assert tip == self.repo.get_changeset('tip')
265 259
266 260 def test_root_node(self):
267 261 tip = self.repo.get_changeset()
268 self.assertTrue(tip.root is tip.get_node(''))
262 assert tip.root is tip.get_node('')
269 263
270 264 def test_lazy_fetch(self):
271 265 """
272 266 Test if changeset's nodes expands and are cached as we walk through
273 267 the revision. This test is somewhat hard to write as order of tests
274 268 is a key here. Written by running command after command in a shell.
275 269 """
276 270 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
277 self.assertTrue(commit_id in self.repo.revisions)
271 assert commit_id in self.repo.revisions
278 272 chset = self.repo.get_changeset(commit_id)
279 self.assertTrue(len(chset.nodes) == 0)
273 assert len(chset.nodes) == 0
280 274 root = chset.root
281 self.assertTrue(len(chset.nodes) == 1)
282 self.assertTrue(len(root.nodes) == 8)
275 assert len(chset.nodes) == 1
276 assert len(root.nodes) == 8
283 277 # accessing root.nodes updates chset.nodes
284 self.assertTrue(len(chset.nodes) == 9)
278 assert len(chset.nodes) == 9
285 279
286 280 docs = root.get_node('docs')
287 281 # we haven't yet accessed anything new as docs dir was already cached
288 self.assertTrue(len(chset.nodes) == 9)
289 self.assertTrue(len(docs.nodes) == 8)
282 assert len(chset.nodes) == 9
283 assert len(docs.nodes) == 8
290 284 # accessing docs.nodes updates chset.nodes
291 self.assertTrue(len(chset.nodes) == 17)
285 assert len(chset.nodes) == 17
292 286
293 self.assertTrue(docs is chset.get_node('docs'))
294 self.assertTrue(docs is root.nodes[0])
295 self.assertTrue(docs is root.dirs[0])
296 self.assertTrue(docs is chset.get_node('docs'))
287 assert docs is chset.get_node('docs')
288 assert docs is root.nodes[0]
289 assert docs is root.dirs[0]
290 assert docs is chset.get_node('docs')
297 291
298 292 def test_nodes_with_changeset(self):
299 293 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
300 294 chset = self.repo.get_changeset(commit_id)
301 295 root = chset.root
302 296 docs = root.get_node('docs')
303 self.assertTrue(docs is chset.get_node('docs'))
297 assert docs is chset.get_node('docs')
304 298 api = docs.get_node('api')
305 self.assertTrue(api is chset.get_node('docs/api'))
299 assert api is chset.get_node('docs/api')
306 300 index = api.get_node('index.rst')
307 self.assertTrue(index is chset.get_node('docs/api/index.rst'))
308 self.assertTrue(index is chset.get_node('docs') \
309 .get_node('api') \
310 .get_node('index.rst'))
301 assert index is chset.get_node('docs/api/index.rst')
302 assert index is chset.get_node('docs') \
303 .get_node('api') \
304 .get_node('index.rst')
311 305
312 306 def test_branch_and_tags(self):
313 307 """
314 308 rev0 = self.repo.revisions[0]
315 309 chset0 = self.repo.get_changeset(rev0)
316 self.assertEqual(chset0.branch, 'master')
317 self.assertEqual(chset0.tags, [])
310 assert chset0.branch == 'master'
311 assert chset0.tags == []
318 312
319 313 rev10 = self.repo.revisions[10]
320 314 chset10 = self.repo.get_changeset(rev10)
321 self.assertEqual(chset10.branch, 'master')
322 self.assertEqual(chset10.tags, [])
315 assert chset10.branch == 'master'
316 assert chset10.tags == []
323 317
324 318 rev44 = self.repo.revisions[44]
325 319 chset44 = self.repo.get_changeset(rev44)
326 self.assertEqual(chset44.branch, 'web-branch')
320 assert chset44.branch == 'web-branch'
327 321
328 322 tip = self.repo.get_changeset('tip')
329 self.assertTrue('tip' in tip.tags)
323 assert 'tip' in tip.tags
330 324 """
331 325 # Those tests would fail - branches are now going
332 326 # to be changed at main API in order to support git backend
333 327 pass
334 328
335 329 def _test_slices(self, limit, offset):
336 330 count = self.repo.count()
337 331 changesets = self.repo.get_changesets(limit=limit, offset=offset)
338 332 idx = 0
339 333 for changeset in changesets:
340 334 rev = offset + idx
341 335 idx += 1
342 336 rev_id = self.repo.revisions[rev]
343 337 if idx > limit:
344 338 pytest.fail("Exceeded limit already (getting revision %s, "
345 339 "there are %s total revisions, offset=%s, limit=%s)"
346 340 % (rev_id, count, offset, limit))
347 self.assertEqual(changeset, self.repo.get_changeset(rev_id))
341 assert changeset == self.repo.get_changeset(rev_id)
348 342 result = list(self.repo.get_changesets(limit=limit, offset=offset))
349 343 start = offset
350 344 end = limit and offset + limit or None
351 345 sliced = list(self.repo[start:end])
352 346 pytest.failUnlessEqual(result, sliced,
353 347 msg="Comparison failed for limit=%s, offset=%s"
354 348 "(get_changeset returned: %s and sliced: %s"
355 349 % (limit, offset, result, sliced))
356 350
357 351 def _test_file_size(self, revision, path, size):
358 352 node = self.repo.get_changeset(revision).get_node(path)
359 self.assertTrue(node.is_file())
360 self.assertEqual(node.size, size)
353 assert node.is_file()
354 assert node.size == size
361 355
362 356 def test_file_size(self):
363 357 to_check = (
364 358 ('c1214f7e79e02fc37156ff215cd71275450cffc3',
365 359 'vcs/backends/BaseRepository.py', 502),
366 360 ('d7e0d30fbcae12c90680eb095a4f5f02505ce501',
367 361 'vcs/backends/hg.py', 854),
368 362 ('6e125e7c890379446e98980d8ed60fba87d0f6d1',
369 363 'setup.py', 1068),
370 364 ('d955cd312c17b02143c04fa1099a352b04368118',
371 365 'vcs/backends/base.py', 2921),
372 366 ('ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
373 367 'vcs/backends/base.py', 3936),
374 368 ('f50f42baeed5af6518ef4b0cb2f1423f3851a941',
375 369 'vcs/backends/base.py', 6189),
376 370 )
377 371 for revision, path, size in to_check:
378 372 self._test_file_size(revision, path, size)
379 373
380 374 def _test_dir_size(self, revision, path, size):
381 375 node = self.repo.get_changeset(revision).get_node(path)
382 self.assertEqual(node.size, size)
376 assert node.size == size
383 377
384 378 def test_dir_size(self):
385 379 to_check = (
386 380 ('5f2c6ee195929b0be80749243c18121c9864a3b3', '/', 674076),
387 381 ('7ab37bc680b4aa72c34d07b230c866c28e9fc204', '/', 674049),
388 382 ('6892503fb8f2a552cef5f4d4cc2cdbd13ae1cd2f', '/', 671830),
389 383 )
390 384 for revision, path, size in to_check:
391 385 self._test_dir_size(revision, path, size)
392 386
393 387 def test_repo_size(self):
394 self.assertEqual(self.repo.size, 674076)
388 assert self.repo.size == 674076
395 389
396 390 def test_file_history(self):
397 391 # we can only check if those revisions are present in the history
398 392 # as we cannot update this test every time file is changed
399 393 files = {
400 394 'setup.py': [
401 395 '54386793436c938cff89326944d4c2702340037d',
402 396 '51d254f0ecf5df2ce50c0b115741f4cf13985dab',
403 397 '998ed409c795fec2012b1c0ca054d99888b22090',
404 398 '5e0eb4c47f56564395f76333f319d26c79e2fb09',
405 399 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
406 400 '7cb3fd1b6d8c20ba89e2264f1c8baebc8a52d36e',
407 401 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
408 402 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
409 403 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
410 404 ],
411 405 'vcs/nodes.py': [
412 406 '33fa3223355104431402a888fa77a4e9956feb3e',
413 407 'fa014c12c26d10ba682fadb78f2a11c24c8118e1',
414 408 'e686b958768ee96af8029fe19c6050b1a8dd3b2b',
415 409 'ab5721ca0a081f26bf43d9051e615af2cc99952f',
416 410 'c877b68d18e792a66b7f4c529ea02c8f80801542',
417 411 '4313566d2e417cb382948f8d9d7c765330356054',
418 412 '6c2303a793671e807d1cfc70134c9ca0767d98c2',
419 413 '54386793436c938cff89326944d4c2702340037d',
420 414 '54000345d2e78b03a99d561399e8e548de3f3203',
421 415 '1c6b3677b37ea064cb4b51714d8f7498f93f4b2b',
422 416 '2d03ca750a44440fb5ea8b751176d1f36f8e8f46',
423 417 '2a08b128c206db48c2f0b8f70df060e6db0ae4f8',
424 418 '30c26513ff1eb8e5ce0e1c6b477ee5dc50e2f34b',
425 419 'ac71e9503c2ca95542839af0ce7b64011b72ea7c',
426 420 '12669288fd13adba2a9b7dd5b870cc23ffab92d2',
427 421 '5a0c84f3e6fe3473e4c8427199d5a6fc71a9b382',
428 422 '12f2f5e2b38e6ff3fbdb5d722efed9aa72ecb0d5',
429 423 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
430 424 'f50f42baeed5af6518ef4b0cb2f1423f3851a941',
431 425 'd7e390a45f6aa96f04f5e7f583ad4f867431aa25',
432 426 'f15c21f97864b4f071cddfbf2750ec2e23859414',
433 427 'e906ef056cf539a4e4e5fc8003eaf7cf14dd8ade',
434 428 'ea2b108b48aa8f8c9c4a941f66c1a03315ca1c3b',
435 429 '84dec09632a4458f79f50ddbbd155506c460b4f9',
436 430 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
437 431 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
438 432 '3bf1c5868e570e39569d094f922d33ced2fa3b2b',
439 433 'b8d04012574729d2c29886e53b1a43ef16dd00a1',
440 434 '6970b057cffe4aab0a792aa634c89f4bebf01441',
441 435 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
442 436 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
443 437 ],
444 438 'vcs/backends/git.py': [
445 439 '4cf116ad5a457530381135e2f4c453e68a1b0105',
446 440 '9a751d84d8e9408e736329767387f41b36935153',
447 441 'cb681fb539c3faaedbcdf5ca71ca413425c18f01',
448 442 '428f81bb652bcba8d631bce926e8834ff49bdcc6',
449 443 '180ab15aebf26f98f714d8c68715e0f05fa6e1c7',
450 444 '2b8e07312a2e89e92b90426ab97f349f4bce2a3a',
451 445 '50e08c506174d8645a4bb517dd122ac946a0f3bf',
452 446 '54000345d2e78b03a99d561399e8e548de3f3203',
453 447 ],
454 448 }
455 449 for path, revs in files.items():
456 450 node = self.repo.get_changeset(revs[0]).get_node(path)
457 451 node_revs = [chset.raw_id for chset in node.history]
458 self.assertTrue(set(revs).issubset(set(node_revs)),
459 "We assumed that %s is subset of revisions for which file %s "
460 "has been changed, and history of that node returned: %s"
461 % (revs, path, node_revs))
452 assert set(revs).issubset(set(node_revs)), "We assumed that %s is subset of revisions for which file %s " \
453 "has been changed, and history of that node returned: %s" \
454 % (revs, path, node_revs)
462 455
463 456 def test_file_annotate(self):
464 457 files = {
465 458 'vcs/backends/__init__.py': {
466 459 'c1214f7e79e02fc37156ff215cd71275450cffc3': {
467 460 'lines_no': 1,
468 461 'changesets': [
469 462 'c1214f7e79e02fc37156ff215cd71275450cffc3',
470 463 ],
471 464 },
472 465 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647': {
473 466 'lines_no': 21,
474 467 'changesets': [
475 468 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
476 469 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
477 470 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
478 471 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
479 472 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
480 473 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
481 474 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
482 475 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
483 476 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
484 477 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
485 478 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
486 479 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
487 480 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
488 481 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
489 482 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
490 483 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
491 484 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
492 485 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
493 486 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
494 487 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
495 488 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
496 489 ],
497 490 },
498 491 'e29b67bd158580fc90fc5e9111240b90e6e86064': {
499 492 'lines_no': 32,
500 493 'changesets': [
501 494 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
502 495 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
503 496 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
504 497 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
505 498 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
506 499 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
507 500 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
508 501 '54000345d2e78b03a99d561399e8e548de3f3203',
509 502 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
510 503 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
511 504 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
512 505 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
513 506 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
514 507 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
515 508 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
516 509 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
517 510 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
518 511 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
519 512 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
520 513 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
521 514 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
522 515 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
523 516 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
524 517 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
525 518 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
526 519 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
527 520 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
528 521 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
529 522 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
530 523 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
531 524 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
532 525 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
533 526 ],
534 527 },
535 528 },
536 529 }
537 530
538 531 for fname, revision_dict in files.items():
539 532 for rev, data in revision_dict.items():
540 533 cs = self.repo.get_changeset(rev)
541 534
542 535 l1_1 = [x[1] for x in cs.get_file_annotate(fname)]
543 536 l1_2 = [x[2]().raw_id for x in cs.get_file_annotate(fname)]
544 self.assertEqual(l1_1, l1_2)
537 assert l1_1 == l1_2
545 538 l1 = l1_1
546 539 l2 = files[fname][rev]['changesets']
547 self.assertTrue(l1 == l2, "The lists of revision for %s@rev %s"
548 "from annotation list should match each other, "
549 "got \n%s \nvs \n%s " % (fname, rev, l1, l2))
540 assert l1 == l2, "The lists of revision for %s@rev %s" \
541 "from annotation list should match each other, " \
542 "got \n%s \nvs \n%s " % (fname, rev, l1, l2)
550 543
551 544 def test_files_state(self):
552 545 """
553 546 Tests state of FileNodes.
554 547 """
555 548 node = self.repo \
556 549 .get_changeset('e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0') \
557 550 .get_node('vcs/utils/diffs.py')
558 self.assertTrue(node.state, NodeState.ADDED)
559 self.assertTrue(node.added)
560 self.assertFalse(node.changed)
561 self.assertFalse(node.not_changed)
562 self.assertFalse(node.removed)
551 assert node.state, NodeState.ADDED
552 assert node.added
553 assert not node.changed
554 assert not node.not_changed
555 assert not node.removed
563 556
564 557 node = self.repo \
565 558 .get_changeset('33fa3223355104431402a888fa77a4e9956feb3e') \
566 559 .get_node('.hgignore')
567 self.assertTrue(node.state, NodeState.CHANGED)
568 self.assertFalse(node.added)
569 self.assertTrue(node.changed)
570 self.assertFalse(node.not_changed)
571 self.assertFalse(node.removed)
560 assert node.state, NodeState.CHANGED
561 assert not node.added
562 assert node.changed
563 assert not node.not_changed
564 assert not node.removed
572 565
573 566 node = self.repo \
574 567 .get_changeset('e29b67bd158580fc90fc5e9111240b90e6e86064') \
575 568 .get_node('setup.py')
576 self.assertTrue(node.state, NodeState.NOT_CHANGED)
577 self.assertFalse(node.added)
578 self.assertFalse(node.changed)
579 self.assertTrue(node.not_changed)
580 self.assertFalse(node.removed)
569 assert node.state, NodeState.NOT_CHANGED
570 assert not node.added
571 assert not node.changed
572 assert node.not_changed
573 assert not node.removed
581 574
582 575 # If node has REMOVED state then trying to fetch it would raise
583 576 # ChangesetError exception
584 577 chset = self.repo.get_changeset(
585 578 'fa6600f6848800641328adbf7811fd2372c02ab2')
586 579 path = 'vcs/backends/BaseRepository.py'
587 self.assertRaises(NodeDoesNotExistError, chset.get_node, path)
580 with pytest.raises(NodeDoesNotExistError):
581 chset.get_node(path)
588 582 # but it would be one of ``removed`` (changeset's attribute)
589 self.assertTrue(path in [rf.path for rf in chset.removed])
583 assert path in [rf.path for rf in chset.removed]
590 584
591 585 chset = self.repo.get_changeset(
592 586 '54386793436c938cff89326944d4c2702340037d')
593 587 changed = ['setup.py', 'tests/test_nodes.py', 'vcs/backends/hg.py',
594 588 'vcs/nodes.py']
595 self.assertEqual(set(changed), set([f.path for f in chset.changed]))
589 assert set(changed) == set([f.path for f in chset.changed])
596 590
597 591 def test_commit_message_is_unicode(self):
598 592 for cs in self.repo:
599 self.assertEqual(type(cs.message), unicode)
593 assert type(cs.message) == unicode
600 594
601 595 def test_changeset_author_is_unicode(self):
602 596 for cs in self.repo:
603 self.assertEqual(type(cs.author), unicode)
597 assert type(cs.author) == unicode
604 598
605 599 def test_repo_files_content_is_unicode(self):
606 600 changeset = self.repo.get_changeset()
607 601 for node in changeset.get_node('/'):
608 602 if node.is_file():
609 self.assertEqual(type(node.content), unicode)
603 assert type(node.content) == unicode
610 604
611 605 def test_wrong_path(self):
612 606 # There is 'setup.py' in the root dir but not there:
613 607 path = 'foo/bar/setup.py'
614 608 tip = self.repo.get_changeset()
615 self.assertRaises(VCSError, tip.get_node, path)
609 with pytest.raises(VCSError):
610 tip.get_node(path)
616 611
617 612 def test_author_email(self):
618 self.assertEqual('marcin@python-blog.com',
619 self.repo.get_changeset('c1214f7e79e02fc37156ff215cd71275450cffc3') \
620 .author_email)
621 self.assertEqual('lukasz.balcerzak@python-center.pl',
622 self.repo.get_changeset('ff7ca51e58c505fec0dd2491de52c622bb7a806b') \
623 .author_email)
624 self.assertEqual('',
625 self.repo.get_changeset('8430a588b43b5d6da365400117c89400326e7992') \
626 .author_email)
613 assert 'marcin@python-blog.com' == self.repo.get_changeset('c1214f7e79e02fc37156ff215cd71275450cffc3').author_email
614 assert 'lukasz.balcerzak@python-center.pl' == self.repo.get_changeset('ff7ca51e58c505fec0dd2491de52c622bb7a806b').author_email
615 assert '' == self.repo.get_changeset('8430a588b43b5d6da365400117c89400326e7992').author_email
627 616
628 617 def test_author_username(self):
629 self.assertEqual('Marcin Kuzminski',
630 self.repo.get_changeset('c1214f7e79e02fc37156ff215cd71275450cffc3') \
631 .author_name)
632 self.assertEqual('Lukasz Balcerzak',
633 self.repo.get_changeset('ff7ca51e58c505fec0dd2491de52c622bb7a806b') \
634 .author_name)
635 self.assertEqual('marcink none@none',
636 self.repo.get_changeset('8430a588b43b5d6da365400117c89400326e7992') \
637 .author_name)
618 assert 'Marcin Kuzminski' == self.repo.get_changeset('c1214f7e79e02fc37156ff215cd71275450cffc3').author_name
619 assert 'Lukasz Balcerzak' == self.repo.get_changeset('ff7ca51e58c505fec0dd2491de52c622bb7a806b').author_name
620 assert 'marcink none@none' == self.repo.get_changeset('8430a588b43b5d6da365400117c89400326e7992').author_name
638 621
639 622
640 class GitSpecificTest(unittest.TestCase):
623 class TestGitSpecific():
641 624
642 625 def test_error_is_raised_for_added_if_diff_name_status_is_wrong(self):
643 626 repo = mock.MagicMock()
644 627 changeset = GitChangeset(repo, 'foobar')
645 628 changeset._diff_name_status = 'foobar'
646 with self.assertRaises(VCSError):
629 with pytest.raises(VCSError):
647 630 changeset.added
648 631
649 632 def test_error_is_raised_for_changed_if_diff_name_status_is_wrong(self):
650 633 repo = mock.MagicMock()
651 634 changeset = GitChangeset(repo, 'foobar')
652 635 changeset._diff_name_status = 'foobar'
653 with self.assertRaises(VCSError):
636 with pytest.raises(VCSError):
654 637 changeset.added
655 638
656 639 def test_error_is_raised_for_removed_if_diff_name_status_is_wrong(self):
657 640 repo = mock.MagicMock()
658 641 changeset = GitChangeset(repo, 'foobar')
659 642 changeset._diff_name_status = 'foobar'
660 with self.assertRaises(VCSError):
643 with pytest.raises(VCSError):
661 644 changeset.added
662 645
663 646
664 class GitSpecificWithRepoTest(_BackendTestMixin, unittest.TestCase):
647 class TestGitSpecificWithRepo(_BackendTestMixin):
665 648 backend_alias = 'git'
666 649
667 650 @classmethod
668 651 def _get_commits(cls):
669 652 return [
670 653 {
671 654 'message': 'Initial',
672 655 'author': 'Joe Doe <joe.doe@example.com>',
673 656 'date': datetime.datetime(2010, 1, 1, 20),
674 657 'added': [
675 658 FileNode('foobar/static/js/admin/base.js', content='base'),
676 659 FileNode('foobar/static/admin', content='admin',
677 660 mode=0120000), # this is a link
678 661 FileNode('foo', content='foo'),
679 662 ],
680 663 },
681 664 {
682 665 'message': 'Second',
683 666 'author': 'Joe Doe <joe.doe@example.com>',
684 667 'date': datetime.datetime(2010, 1, 1, 22),
685 668 'added': [
686 669 FileNode('foo2', content='foo2'),
687 670 ],
688 671 },
689 672 ]
690 673
691 674 def test_paths_slow_traversing(self):
692 675 cs = self.repo.get_changeset()
693 self.assertEqual(cs.get_node('foobar').get_node('static').get_node('js')
694 .get_node('admin').get_node('base.js').content, 'base')
676 assert cs.get_node('foobar').get_node('static').get_node('js').get_node('admin').get_node('base.js').content == 'base'
695 677
696 678 def test_paths_fast_traversing(self):
697 679 cs = self.repo.get_changeset()
698 self.assertEqual(cs.get_node('foobar/static/js/admin/base.js').content,
699 'base')
680 assert cs.get_node('foobar/static/js/admin/base.js').content == 'base'
700 681
701 682 def test_workdir_get_branch(self):
702 683 self.repo.run_git_command(['checkout', '-b', 'production'])
703 684 # Regression test: one of following would fail if we don't check
704 685 # .git/HEAD file
705 686 self.repo.run_git_command(['checkout', 'production'])
706 self.assertEqual(self.repo.workdir.get_branch(), 'production')
687 assert self.repo.workdir.get_branch() == 'production'
707 688 self.repo.run_git_command(['checkout', 'master'])
708 self.assertEqual(self.repo.workdir.get_branch(), 'master')
689 assert self.repo.workdir.get_branch() == 'master'
709 690
710 691 def test_get_diff_runs_git_command_with_hashes(self):
711 692 self.repo.run_git_command = mock.Mock(return_value=['', ''])
712 693 self.repo.get_diff(0, 1)
713 694 self.repo.run_git_command.assert_called_once_with(
714 695 ['diff', '-U3', '--full-index', '--binary', '-p', '-M', '--abbrev=40',
715 696 self.repo._get_revision(0), self.repo._get_revision(1)])
716 697
717 698 def test_get_diff_runs_git_command_with_str_hashes(self):
718 699 self.repo.run_git_command = mock.Mock(return_value=['', ''])
719 700 self.repo.get_diff(self.repo.EMPTY_CHANGESET, 1)
720 701 self.repo.run_git_command.assert_called_once_with(
721 702 ['show', '-U3', '--full-index', '--binary', '-p', '-M', '--abbrev=40',
722 703 self.repo._get_revision(1)])
723 704
724 705 def test_get_diff_runs_git_command_with_path_if_its_given(self):
725 706 self.repo.run_git_command = mock.Mock(return_value=['', ''])
726 707 self.repo.get_diff(0, 1, 'foo')
727 708 self.repo.run_git_command.assert_called_once_with(
728 709 ['diff', '-U3', '--full-index', '--binary', '-p', '-M', '--abbrev=40',
729 710 self.repo._get_revision(0), self.repo._get_revision(1), '--', 'foo'])
730 711
731 712
732 class GitRegressionTest(_BackendTestMixin, unittest.TestCase):
713 class TestGitRegression(_BackendTestMixin):
733 714 backend_alias = 'git'
734 715
735 716 @classmethod
736 717 def _get_commits(cls):
737 718 return [
738 719 {
739 720 'message': 'Initial',
740 721 'author': 'Joe Doe <joe.doe@example.com>',
741 722 'date': datetime.datetime(2010, 1, 1, 20),
742 723 'added': [
743 724 FileNode('bot/__init__.py', content='base'),
744 725 FileNode('bot/templates/404.html', content='base'),
745 726 FileNode('bot/templates/500.html', content='base'),
746 727 ],
747 728 },
748 729 {
749 730 'message': 'Second',
750 731 'author': 'Joe Doe <joe.doe@example.com>',
751 732 'date': datetime.datetime(2010, 1, 1, 22),
752 733 'added': [
753 734 FileNode('bot/build/migrations/1.py', content='foo2'),
754 735 FileNode('bot/build/migrations/2.py', content='foo2'),
755 736 FileNode('bot/build/static/templates/f.html', content='foo2'),
756 737 FileNode('bot/build/static/templates/f1.html', content='foo2'),
757 738 FileNode('bot/build/templates/err.html', content='foo2'),
758 739 FileNode('bot/build/templates/err2.html', content='foo2'),
759 740 ],
760 741 },
761 742 ]
762 743
763 744 def test_similar_paths(self):
764 745 cs = self.repo.get_changeset()
765 746 paths = lambda *n: [x.path for x in n]
766 self.assertEqual(paths(*cs.get_nodes('bot')), ['bot/build', 'bot/templates', 'bot/__init__.py'])
767 self.assertEqual(paths(*cs.get_nodes('bot/build')), ['bot/build/migrations', 'bot/build/static', 'bot/build/templates'])
768 self.assertEqual(paths(*cs.get_nodes('bot/build/static')), ['bot/build/static/templates'])
747 assert paths(*cs.get_nodes('bot')) == ['bot/build', 'bot/templates', 'bot/__init__.py']
748 assert paths(*cs.get_nodes('bot/build')) == ['bot/build/migrations', 'bot/build/static', 'bot/build/templates']
749 assert paths(*cs.get_nodes('bot/build/static')) == ['bot/build/static/templates']
769 750 # this get_nodes below causes troubles !
770 self.assertEqual(paths(*cs.get_nodes('bot/build/static/templates')), ['bot/build/static/templates/f.html', 'bot/build/static/templates/f1.html'])
771 self.assertEqual(paths(*cs.get_nodes('bot/build/templates')), ['bot/build/templates/err.html', 'bot/build/templates/err2.html'])
772 self.assertEqual(paths(*cs.get_nodes('bot/templates/')), ['bot/templates/404.html', 'bot/templates/500.html'])
751 assert paths(*cs.get_nodes('bot/build/static/templates')) == ['bot/build/static/templates/f.html', 'bot/build/static/templates/f1.html']
752 assert paths(*cs.get_nodes('bot/build/templates')) == ['bot/build/templates/err.html', 'bot/build/templates/err2.html']
753 assert paths(*cs.get_nodes('bot/templates/')) == ['bot/templates/404.html', 'bot/templates/500.html']
773 754
774 755
775 class GitHooksTest(unittest.TestCase):
756 class TestGitHooks(object):
776 757 """
777 758 Tests related to hook functionality of Git repositories.
778 759 """
779 760
780 def setUp(self):
761 def setup_method(self):
781 762 # For each run we want a fresh repo.
782 763 self.repo_directory = get_new_dir("githookrepo")
783 764 self.repo = GitRepository(self.repo_directory, create=True)
784 765
785 766 # Create a dictionary where keys are hook names, and values are paths to
786 767 # them. Deduplicates code in tests a bit.
787 768 self.hook_directory = self.repo.get_hook_location()
788 769 self.kallithea_hooks = dict((h, os.path.join(self.hook_directory, h)) for h in ("pre-receive", "post-receive"))
789 770
790 771 def test_hooks_created_if_missing(self):
791 772 """
792 773 Tests if hooks are installed in repository if they are missing.
793 774 """
794 775
795 776 for hook, hook_path in self.kallithea_hooks.iteritems():
796 777 if os.path.exists(hook_path):
797 778 os.remove(hook_path)
798 779
799 780 ScmModel().install_git_hooks(repo=self.repo)
800 781
801 782 for hook, hook_path in self.kallithea_hooks.iteritems():
802 self.assertTrue(os.path.exists(hook_path))
783 assert os.path.exists(hook_path)
803 784
804 785 def test_kallithea_hooks_updated(self):
805 786 """
806 787 Tests if hooks are updated if they are Kallithea hooks already.
807 788 """
808 789
809 790 for hook, hook_path in self.kallithea_hooks.iteritems():
810 791 with open(hook_path, "w") as f:
811 792 f.write("KALLITHEA_HOOK_VER=0.0.0\nJUST_BOGUS")
812 793
813 794 ScmModel().install_git_hooks(repo=self.repo)
814 795
815 796 for hook, hook_path in self.kallithea_hooks.iteritems():
816 797 with open(hook_path) as f:
817 self.assertNotIn("JUST_BOGUS", f.read())
798 assert "JUST_BOGUS" not in f.read()
818 799
819 800 def test_custom_hooks_untouched(self):
820 801 """
821 802 Tests if hooks are left untouched if they are not Kallithea hooks.
822 803 """
823 804
824 805 for hook, hook_path in self.kallithea_hooks.iteritems():
825 806 with open(hook_path, "w") as f:
826 807 f.write("#!/bin/bash\n#CUSTOM_HOOK")
827 808
828 809 ScmModel().install_git_hooks(repo=self.repo)
829 810
830 811 for hook, hook_path in self.kallithea_hooks.iteritems():
831 812 with open(hook_path) as f:
832 self.assertIn("CUSTOM_HOOK", f.read())
813 assert "CUSTOM_HOOK" in f.read()
833 814
834 815 def test_custom_hooks_forced_update(self):
835 816 """
836 817 Tests if hooks are forcefully updated even though they are custom hooks.
837 818 """
838 819
839 820 for hook, hook_path in self.kallithea_hooks.iteritems():
840 821 with open(hook_path, "w") as f:
841 822 f.write("#!/bin/bash\n#CUSTOM_HOOK")
842 823
843 824 ScmModel().install_git_hooks(repo=self.repo, force_create=True)
844 825
845 826 for hook, hook_path in self.kallithea_hooks.iteritems():
846 827 with open(hook_path) as f:
847 self.assertIn("KALLITHEA_HOOK_VER", f.read())
828 assert "KALLITHEA_HOOK_VER" in f.read()
@@ -1,95 +1,93 b''
1 1 import datetime
2 2
3 from kallithea.lib.vcs.utils.compat import unittest
3 import pytest
4 4
5 5 from kallithea.lib.vcs.nodes import FileNode
6 6
7 7 from kallithea.tests.vcs.base import _BackendTestMixin
8 8 from kallithea.tests.vcs.conf import SCM_TESTS
9 9
10 10
11 11 class WorkdirTestCaseMixin(_BackendTestMixin):
12 12
13 13 @classmethod
14 14 def _get_commits(cls):
15 15 commits = [
16 16 {
17 17 'message': u'Initial commit',
18 18 'author': u'Joe Doe <joe.doe@example.com>',
19 19 'date': datetime.datetime(2010, 1, 1, 20),
20 20 'added': [
21 21 FileNode('foobar', content='Foobar'),
22 22 FileNode('foobar2', content='Foobar II'),
23 23 FileNode('foo/bar/baz', content='baz here!'),
24 24 ],
25 25 },
26 26 {
27 27 'message': u'Changes...',
28 28 'author': u'Jane Doe <jane.doe@example.com>',
29 29 'date': datetime.datetime(2010, 1, 1, 21),
30 30 'added': [
31 31 FileNode('some/new.txt', content='news...'),
32 32 ],
33 33 'changed': [
34 34 FileNode('foobar', 'Foobar I'),
35 35 ],
36 36 'removed': [],
37 37 },
38 38 ]
39 39 return commits
40 40
41 41 def test_get_branch_for_default_branch(self):
42 self.assertEqual(self.repo.workdir.get_branch(),
43 self.repo.DEFAULT_BRANCH_NAME)
42 assert self.repo.workdir.get_branch() == self.repo.DEFAULT_BRANCH_NAME
44 43
45 44 def test_get_branch_after_adding_one(self):
46 45 self.imc.add(FileNode('docs/index.txt',
47 46 content='Documentation\n'))
48 47 self.imc.commit(
49 48 message=u'New branch: foobar',
50 49 author=u'joe',
51 50 branch='foobar',
52 51 )
53 self.assertEqual(self.repo.workdir.get_branch(), self.default_branch)
52 assert self.repo.workdir.get_branch() == self.default_branch
54 53
55 54 def test_get_changeset(self):
56 55 old_head = self.repo.get_changeset()
57 56 self.imc.add(FileNode('docs/index.txt',
58 57 content='Documentation\n'))
59 58 head = self.imc.commit(
60 59 message=u'New branch: foobar',
61 60 author=u'joe',
62 61 branch='foobar',
63 62 )
64 self.assertEqual(self.repo.workdir.get_branch(), self.default_branch)
63 assert self.repo.workdir.get_branch() == self.default_branch
65 64 self.repo.workdir.checkout_branch('foobar')
66 self.assertEqual(self.repo.workdir.get_changeset(), head)
65 assert self.repo.workdir.get_changeset() == head
67 66
68 67 # Make sure that old head is still there after update to default branch
69 68 self.repo.workdir.checkout_branch(self.default_branch)
70 self.assertEqual(self.repo.workdir.get_changeset(), old_head)
69 assert self.repo.workdir.get_changeset() == old_head
71 70
72 71 def test_checkout_branch(self):
73 72 from kallithea.lib.vcs.exceptions import BranchDoesNotExistError
74 73 # first, 'foobranch' does not exist.
75 self.assertRaises(BranchDoesNotExistError, self.repo.workdir.checkout_branch,
76 branch='foobranch')
74 with pytest.raises(BranchDoesNotExistError):
75 self.repo.workdir.checkout_branch(branch='foobranch')
77 76 # create new branch 'foobranch'.
78 77 self.imc.add(FileNode('file1', content='blah'))
79 78 self.imc.commit(message=u'asd', author=u'john', branch='foobranch')
80 79 # go back to the default branch
81 80 self.repo.workdir.checkout_branch()
82 self.assertEqual(self.repo.workdir.get_branch(), self.backend_class.DEFAULT_BRANCH_NAME)
81 assert self.repo.workdir.get_branch() == self.backend_class.DEFAULT_BRANCH_NAME
83 82 # checkout 'foobranch'
84 83 self.repo.workdir.checkout_branch('foobranch')
85 self.assertEqual(self.repo.workdir.get_branch(), 'foobranch')
84 assert self.repo.workdir.get_branch() == 'foobranch'
86 85
87 86
88 87 # For each backend create test case class
89 88 for alias in SCM_TESTS:
90 89 attrs = {
91 90 'backend_alias': alias,
92 91 }
93 cls_name = ''.join(('%s branch test' % alias).title().split())
94 bases = (WorkdirTestCaseMixin, unittest.TestCase)
95 globals()[cls_name] = type(cls_name, bases, attrs)
92 cls_name = ''.join(('test %s branch' % alias).title().split())
93 globals()[cls_name] = type(cls_name, (WorkdirTestCaseMixin, ), attrs)
General Comments 0
You need to be logged in to leave comments. Login now