extras: pylint updates
[git-cola.git] / test / git_test.py
blobc52661e0a67c222aa6a20a17b0d707a251f3cc7b
1 #!/usr/bin/env python
2 """Tests various operations using the cola.git module
3 """
4 from __future__ import absolute_import, division, unicode_literals
5 import os
6 import time
7 import unittest
9 try:
10 from unittest.mock import patch
11 except ImportError:
12 from mock import patch
14 from cola import git
15 from cola.compat import WIN32
16 from cola.git import STDOUT
19 class GitModuleTestCase(unittest.TestCase):
21 @patch('cola.git.is_git_dir')
22 def test_find_git_dir_None(self, is_git_dir):
24 paths = git.find_git_directory(None)
26 self.assertFalse(is_git_dir.called)
27 self.assertEqual(None, paths.git_dir)
28 self.assertEqual(None, paths.git_file)
29 self.assertEqual(None, paths.worktree)
31 @patch('cola.git.is_git_dir')
32 def test_find_git_dir_empty_string(self, is_git_dir):
34 paths = git.find_git_directory('')
36 self.assertFalse(is_git_dir.called)
37 self.assertEqual(None, paths.git_dir)
38 self.assertEqual(None, paths.git_file)
39 self.assertEqual(None, paths.worktree)
41 @patch('cola.git.is_git_dir')
42 def test_find_git_dir_never_found(self, is_git_dir):
43 is_git_dir.return_value = False
45 paths = git.find_git_directory('/does/not/exist')
47 self.assertTrue(is_git_dir.called)
48 self.assertEqual(None, paths.git_dir)
49 self.assertEqual(None, paths.git_file)
50 self.assertEqual(None, paths.worktree)
52 self.assertEqual(8, is_git_dir.call_count)
53 kwargs = {}
54 is_git_dir.assert_has_calls([
55 (('/does/not/exist',), kwargs),
56 (('/does/not/exist/.git',), kwargs),
57 (('/does/not',), kwargs),
58 (('/does/not/.git',), kwargs),
59 (('/does',), kwargs),
60 (('/does/.git',), kwargs),
61 (('/',), kwargs),
62 (('/.git',), kwargs),
65 @patch('cola.git.is_git_dir')
66 def test_find_git_dir_found_right_away(self, is_git_dir):
67 git_dir = '/seems/to/exist/.git'
68 worktree = '/seems/to/exist'
69 is_git_dir.return_value = True
71 paths = git.find_git_directory(git_dir)
73 self.assertTrue(is_git_dir.called)
74 self.assertEqual(git_dir, paths.git_dir)
75 self.assertEqual(None, paths.git_file)
76 self.assertEqual(worktree, paths.worktree)
78 @patch('cola.git.is_git_dir')
79 def test_find_git_does_discovery(self, is_git_dir):
80 git_dir = '/the/root/.git'
81 worktree = '/the/root'
82 is_git_dir.side_effect = lambda x: x == git_dir
84 paths = git.find_git_directory('/the/root/sub/dir')
86 self.assertEqual(git_dir, paths.git_dir)
87 self.assertEqual(None, paths.git_file)
88 self.assertEqual(worktree, paths.worktree)
90 @patch('cola.git.read_git_file')
91 @patch('cola.git.is_git_file')
92 @patch('cola.git.is_git_dir')
93 def test_find_git_honors_git_files(self,
94 is_git_dir,
95 is_git_file,
96 read_git_file):
97 git_file = '/the/root/.git'
98 worktree = '/the/root'
99 git_dir = '/super/module/.git/modules/root'
101 is_git_dir.side_effect = lambda x: x == git_file
102 is_git_file.side_effect = lambda x: x == git_file
103 read_git_file.return_value = git_dir
105 paths = git.find_git_directory('/the/root/sub/dir')
107 self.assertEqual(git_dir, paths.git_dir)
108 self.assertEqual(git_file, paths.git_file)
109 self.assertEqual(worktree, paths.worktree)
111 kwargs = {}
112 self.assertEqual(6, is_git_dir.call_count)
113 is_git_dir.assert_has_calls([
114 (('/the/root/sub/dir',), kwargs),
115 (('/the/root/sub/dir/.git',), kwargs),
116 (('/the/root/sub',), kwargs),
117 (('/the/root/sub/.git',), kwargs),
118 (('/the/root',), kwargs),
119 (('/the/root/.git',), kwargs),
121 read_git_file.assert_called_once_with('/the/root/.git')
123 @patch('cola.core.getenv')
124 @patch('cola.git.is_git_dir')
125 def test_find_git_honors_ceiling_dirs(self, is_git_dir, getenv):
127 git_dir = '/ceiling/.git'
128 ceiling = '/tmp:/ceiling:/other/ceiling'
129 is_git_dir.side_effect = lambda x: x == git_dir
131 def mock_getenv(k, v=None):
132 if k == 'GIT_CEILING_DIRECTORIES':
133 return ceiling
134 return v
136 getenv.side_effect = mock_getenv
138 paths = git.find_git_directory('/ceiling/sub/dir')
140 self.assertEqual(None, paths.git_dir)
141 self.assertEqual(None, paths.git_file)
142 self.assertEqual(None, paths.worktree)
144 self.assertEqual(4, is_git_dir.call_count)
145 kwargs = {}
146 is_git_dir.assert_has_calls([
147 (('/ceiling/sub/dir',), kwargs),
148 (('/ceiling/sub/dir/.git',), kwargs),
149 (('/ceiling/sub',), kwargs),
150 (('/ceiling/sub/.git',), kwargs),
153 @patch('cola.core.islink')
154 @patch('cola.core.isdir')
155 @patch('cola.core.isfile')
156 def test_is_git_dir_finds_linked_repository(self, isfile, isdir, islink):
157 dirs = set([
158 '/foo',
159 '/foo/.git',
160 '/foo/.git/refs',
161 '/foo/.git/objects',
162 '/foo/.git/worktrees',
163 '/foo/.git/worktrees/foo',
165 files = set([
166 '/foo/.git/HEAD',
167 '/foo/.git/worktrees/foo/HEAD',
168 '/foo/.git/worktrees/foo/index',
169 '/foo/.git/worktrees/foo/commondir',
170 '/foo/.git/worktrees/foo/gitdir',
172 islink.return_value = False
173 isfile.side_effect = lambda x: x in files
174 isdir.side_effect = lambda x: x in dirs
176 self.assertTrue(git.is_git_dir('/foo/.git/worktrees/foo'))
177 self.assertTrue(git.is_git_dir('/foo/.git'))
180 class GitCommandTest(unittest.TestCase):
181 """Runs tests using a git.Git instance"""
183 def setUp(self):
184 """Creates a git.Git instance for later use"""
185 self.git = git.Git()
187 def test_transform_kwargs_empty(self):
188 expect = []
189 actual = git.transform_kwargs(foo=None, bar=False)
190 self.assertEqual(expect, actual)
192 def test_transform_kwargs_single_dash_from_True(self):
193 """Single dash for one-character True"""
194 expect = ['-a']
195 actual = git.transform_kwargs(a=True)
196 self.assertEqual(expect, actual)
198 def test_transform_kwargs_no_single_dash_from_False(self):
199 """No single-dash for False"""
200 expect = []
201 actual = git.transform_kwargs(a=False)
202 self.assertEqual(expect, actual)
204 def test_transform_kwargs_double_dash_from_True(self):
205 """Double-dash for longer True"""
206 expect = ['--abc']
207 actual = git.transform_kwargs(abc=True)
208 self.assertEqual(expect, actual)
210 def test_transform_kwargs_no_double_dash_from_True(self):
211 """No double-dash for False"""
212 expect = []
213 actual = git.transform_kwargs(abc=False)
214 self.assertEqual(expect, actual)
216 def test_transform_kwargs_single_dash_int(self):
217 expect = ['-a1']
218 actual = git.transform_kwargs(a=1)
219 self.assertEqual(expect, actual)
221 def test_transform_kwargs_double_dash_int(self):
222 expect = ['--abc=1']
223 actual = git.transform_kwargs(abc=1)
224 self.assertEqual(expect, actual)
226 def test_transform_kwargs_single_dash_float(self):
227 expect = ['-a1.5']
228 actual = git.transform_kwargs(a=1.5)
229 self.assertEqual(expect, actual)
231 def test_transform_kwargs_double_dash_float(self):
232 expect = ['--abc=1.5']
233 actual = git.transform_kwargs(abc=1.5)
234 self.assertEqual(expect, actual)
236 def test_transform_kwargs_single_dash_string(self):
237 expect = ['-abc']
238 actual = git.transform_kwargs(a='bc')
239 self.assertEqual(expect, actual)
241 def test_transform_double_single_dash_string(self):
242 expect = ['--abc=def']
243 actual = git.transform_kwargs(abc='def')
244 self.assertEqual(expect, actual)
246 def test_version(self):
247 """Test running 'git version'"""
248 version = self.git.version()[STDOUT]
249 self.failUnless(version.startswith('git version'))
251 def test_stdout(self):
252 """Test overflowing the stdout buffer"""
253 # Write to stdout only
254 code = ('import sys;'
255 's = "\\0" * (1024 * 16 + 1);'
256 'sys.stdout.write(s);')
257 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
258 self.assertEqual(status, 0)
259 self.assertEqual(len(out), 1024 * 16 + 1)
260 self.assertEqual(len(err), 0)
262 def test_stderr(self):
263 """Test that stderr is seen"""
264 # Write to stderr and capture it
265 code = ('import sys;'
266 's = "\\0" * (1024 * 16 + 1);'
267 'sys.stderr.write(s);')
268 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
269 self.assertEqual(status, 0)
270 self.assertEqual(len(out), 0)
271 self.assertEqual(len(err), 1024 * 16 + 1)
273 def test_stdout_and_stderr(self):
274 """Test ignoring stderr when stdout+stderr are provided (v2)"""
275 # Write to stdout and stderr but only capture stdout
276 code = ('import sys;'
277 's = "\\0" * (1024 * 16 + 1);'
278 'sys.stdout.write(s);'
279 'sys.stderr.write(s);')
280 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
281 self.assertEqual(status, 0)
282 self.assertEqual(len(out), 1024 * 16 + 1)
283 self.assertEqual(len(err), 1024 * 16 + 1)
285 def test_it_doesnt_deadlock(self):
286 """Test that we don't deadlock with both stderr and stdout"""
287 # 16k+1 bytes to exhaust any output buffers
288 code = ('import sys;'
289 's = "\\0" * (1024 * 16 + 1);'
290 'sys.stderr.write(s);'
291 'sys.stdout.write(s);')
292 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
293 self.assertEqual(status, 0)
294 self.assertEqual(out, '\0' * (1024 * 16 + 1))
295 self.assertEqual(err, '\0' * (1024 * 16 + 1))
298 if __name__ == '__main__':
299 unittest.main()