contrib: remove all references to Python 2.6 and travis-build
[git-cola.git] / test / git_test.py
blob06b59c0521e5db0924d5e37b14db747bcfa5a82c
1 """Tests various operations using the cola.git module
2 """
3 # pylint: disable=redefined-outer-name
4 from __future__ import absolute_import, division, unicode_literals
6 from cola import git
7 from cola.git import STDOUT
9 from .helper import patch
12 # 16k+1 bytes to exhaust any output buffers.
13 BUFFER_SIZE = (16 * 1024) + 1
16 @patch('cola.git.is_git_dir')
17 def test_find_git_dir_None(is_git_dir):
18 paths = git.find_git_directory(None)
20 assert not is_git_dir.called
21 assert paths.git_dir is None
22 assert paths.git_file is None
23 assert paths.worktree is None
26 @patch('cola.git.is_git_dir')
27 def test_find_git_dir_empty_string(is_git_dir):
28 paths = git.find_git_directory('')
30 assert not is_git_dir.called
31 assert paths.git_dir is None
32 assert paths.git_file is None
33 assert paths.worktree is None
36 @patch('cola.git.is_git_dir')
37 def test_find_git_dir_never_found(is_git_dir):
38 is_git_dir.return_value = False
40 paths = git.find_git_directory('/does/not/exist')
42 assert is_git_dir.called
43 assert paths.git_dir is None
44 assert paths.git_file is None
45 assert paths.worktree is None
47 expect = 8
48 actual = is_git_dir.call_count
49 assert expect == actual
50 is_git_dir.assert_has_calls(
52 (('/does/not/exist',), {}),
53 (('/does/not/exist/.git',), {}),
54 (('/does/not',), {}),
55 (('/does/not/.git',), {}),
56 (('/does',), {}),
57 (('/does/.git',), {}),
58 (('/',), {}),
59 (('/.git',), {}),
64 @patch('cola.git.is_git_dir')
65 def test_find_git_dir_found_right_away(is_git_dir):
66 git_dir = '/seems/to/exist/.git'
67 worktree = '/seems/to/exist'
68 is_git_dir.return_value = True
70 paths = git.find_git_directory(git_dir)
72 assert is_git_dir.called
73 assert git_dir == paths.git_dir
74 assert paths.git_file is None
75 assert worktree == paths.worktree
78 @patch('cola.git.is_git_dir')
79 def test_find_git_does_discovery(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 assert git_dir == paths.git_dir
87 assert paths.git_file is None
88 assert worktree == paths.worktree
91 @patch('cola.git.read_git_file')
92 @patch('cola.git.is_git_file')
93 @patch('cola.git.is_git_dir')
94 def test_find_git_honors_git_files(is_git_dir, is_git_file, read_git_file):
95 git_file = '/the/root/.git'
96 worktree = '/the/root'
97 git_dir = '/super/module/.git/modules/root'
99 is_git_dir.side_effect = lambda x: x == git_file
100 is_git_file.side_effect = lambda x: x == git_file
101 read_git_file.return_value = git_dir
103 paths = git.find_git_directory('/the/root/sub/dir')
105 assert git_dir == paths.git_dir
106 assert git_file == paths.git_file
107 assert worktree == paths.worktree
109 expect = 6
110 actual = is_git_dir.call_count
111 assert expect == actual
112 is_git_dir.assert_has_calls(
114 (('/the/root/sub/dir',), {}),
115 (('/the/root/sub/dir/.git',), {}),
116 (('/the/root/sub',), {}),
117 (('/the/root/sub/.git',), {}),
118 (('/the/root',), {}),
119 (('/the/root/.git',), {}),
122 read_git_file.assert_called_once_with('/the/root/.git')
125 @patch('cola.core.getenv')
126 @patch('cola.git.is_git_dir')
127 def test_find_git_honors_ceiling_dirs(is_git_dir, getenv):
129 git_dir = '/ceiling/.git'
130 ceiling = '/tmp:/ceiling:/other/ceiling'
131 is_git_dir.side_effect = lambda x: x == git_dir
133 def mock_getenv(k, v=None):
134 if k == 'GIT_CEILING_DIRECTORIES':
135 return ceiling
136 return v
138 getenv.side_effect = mock_getenv
140 paths = git.find_git_directory('/ceiling/sub/dir')
142 assert paths.git_dir is None
143 assert paths.git_file is None
144 assert paths.worktree is None
145 assert is_git_dir.call_count == 4
146 is_git_dir.assert_has_calls(
148 (('/ceiling/sub/dir',), {}),
149 (('/ceiling/sub/dir/.git',), {}),
150 (('/ceiling/sub',), {}),
151 (('/ceiling/sub/.git',), {}),
156 @patch('cola.core.islink')
157 @patch('cola.core.isdir')
158 @patch('cola.core.isfile')
159 def test_is_git_dir_finds_linked_repository(isfile, isdir, islink):
160 dirs = set(
162 '/foo',
163 '/foo/.git',
164 '/foo/.git/refs',
165 '/foo/.git/objects',
166 '/foo/.git/worktrees',
167 '/foo/.git/worktrees/foo',
170 files = set(
172 '/foo/.git/HEAD',
173 '/foo/.git/worktrees/foo/HEAD',
174 '/foo/.git/worktrees/foo/index',
175 '/foo/.git/worktrees/foo/commondir',
176 '/foo/.git/worktrees/foo/gitdir',
179 islink.return_value = False
180 isfile.side_effect = lambda x: x in files
181 isdir.side_effect = lambda x: x in dirs
183 assert git.is_git_dir('/foo/.git/worktrees/foo')
184 assert git.is_git_dir('/foo/.git')
187 @patch('cola.core.getenv')
188 @patch('cola.git.is_git_dir')
189 def test_find_git_worktree_from_GIT_DIR(is_git_dir, getenv):
190 git_dir = '/repo/.git'
191 worktree = '/repo'
192 is_git_dir.return_value = True
193 getenv.side_effect = lambda x: x == 'GIT_DIR' and '/repo/.git' or None
195 paths = git.find_git_directory(git_dir)
196 assert is_git_dir.called
197 assert git_dir == paths.git_dir
198 assert paths.git_file is None
199 assert worktree == paths.worktree
202 @patch('cola.git.is_git_dir')
203 def test_finds_no_worktree_from_bare_repo(is_git_dir):
204 git_dir = '/repos/bare.git'
205 worktree = None
206 is_git_dir.return_value = True
208 paths = git.find_git_directory(git_dir)
209 assert is_git_dir.called
210 assert git_dir == paths.git_dir
211 assert paths.git_file is None
212 assert worktree == paths.worktree
215 @patch('cola.core.getenv')
216 @patch('cola.git.is_git_dir')
217 def test_find_git_directory_uses_GIT_WORK_TREE(is_git_dir, getenv):
218 git_dir = '/repo/worktree/.git'
219 worktree = '/repo/worktree'
221 def is_git_dir_fn(path):
222 return path == git_dir
224 is_git_dir.side_effect = is_git_dir_fn
226 def getenv_fn(name):
227 if name == 'GIT_WORK_TREE':
228 return worktree
229 return None
231 getenv.side_effect = getenv_fn
233 paths = git.find_git_directory(worktree)
234 assert is_git_dir.called
235 assert git_dir == paths.git_dir
236 assert paths.git_file is None
237 assert worktree == paths.worktree
240 @patch('cola.core.getenv')
241 @patch('cola.git.is_git_dir')
242 def test_uses_cwd_for_worktree_with_GIT_DIR(is_git_dir, getenv):
243 git_dir = '/repo/.yadm/repo.git'
244 worktree = '/repo'
246 def getenv_fn(name):
247 if name == 'GIT_DIR':
248 return git_dir
249 return None
251 getenv.side_effect = getenv_fn
253 def is_git_dir_fn(path):
254 return path == git_dir
256 is_git_dir.side_effect = is_git_dir_fn
258 paths = git.find_git_directory(worktree)
259 assert is_git_dir.called
260 assert getenv.called
261 assert git_dir == paths.git_dir
262 assert paths.git_file is None
263 assert worktree == paths.worktree
266 def test_transform_kwargs_empty():
267 expect = []
268 actual = git.transform_kwargs(foo=None, bar=False)
269 assert expect == actual
272 def test_transform_kwargs_single_dash_from_True():
273 """Single dash for one-character True"""
274 expect = ['-a']
275 actual = git.transform_kwargs(a=True)
276 assert expect == actual
279 def test_transform_kwargs_no_single_dash_from_False():
280 """No single-dash for False"""
281 expect = []
282 actual = git.transform_kwargs(a=False)
283 assert expect == actual
286 def test_transform_kwargs_double_dash_from_True():
287 """Double-dash for longer True"""
288 expect = ['--abc']
289 actual = git.transform_kwargs(abc=True)
290 assert expect == actual
293 def test_transform_kwargs_no_double_dash_from_True():
294 """No double-dash for False"""
295 expect = []
296 actual = git.transform_kwargs(abc=False)
297 assert expect == actual
300 def test_transform_kwargs_single_dash_int():
301 expect = ['-a1']
302 actual = git.transform_kwargs(a=1)
303 assert expect == actual
306 def test_transform_kwargs_double_dash_int():
307 expect = ['--abc=1']
308 actual = git.transform_kwargs(abc=1)
309 assert expect == actual
312 def test_transform_kwargs_single_dash_float():
313 expect = ['-a1.5']
314 actual = git.transform_kwargs(a=1.5)
315 assert expect == actual
318 def test_transform_kwargs_double_dash_float():
319 expect = ['--abc=1.5']
320 actual = git.transform_kwargs(abc=1.5)
321 assert expect == actual
324 def test_transform_kwargs_single_dash_string():
325 expect = ['-abc']
326 actual = git.transform_kwargs(a='bc')
327 assert expect == actual
330 def test_transform_double_single_dash_string():
331 expect = ['--abc=def']
332 actual = git.transform_kwargs(abc='def')
333 assert expect == actual
336 def test_version():
337 """Test running 'git version'"""
338 gitcmd = git.Git()
339 version = gitcmd.version()[STDOUT]
340 assert version.startswith('git version')
343 def test_stdout():
344 """Test overflowing the stdout buffer"""
345 # Write to stdout only
346 code = (
347 r'import sys;'
348 r'value = "\0" * %d;'
349 r'sys.stdout.write(value);'
350 ) % BUFFER_SIZE
352 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
354 assert status == 0
355 expect = BUFFER_SIZE
356 actual = len(out)
357 assert expect == actual
359 expect = 0
360 actual = len(err)
361 assert expect == actual
364 def test_stderr():
365 """Test that stderr is seen"""
366 # Write to stderr and capture it
367 code = (
368 r'import sys;'
369 r'value = "\0" * %d;'
370 r'sys.stderr.write(value);'
371 ) % BUFFER_SIZE
373 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
375 expect = 0
376 actual = status
377 assert expect == actual
379 expect = 0
380 actual = len(out)
381 assert expect == actual
383 expect = BUFFER_SIZE
384 actual = len(err)
385 assert expect == actual
388 def test_stdout_and_stderr():
389 """Test ignoring stderr when stdout+stderr are provided (v2)"""
390 # Write to stdout and stderr but only capture stdout
391 code = (
392 r'import sys;'
393 r'value = "\0" * %d;'
394 r'sys.stdout.write(value);'
395 r'sys.stderr.write(value);'
396 ) % BUFFER_SIZE
398 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
400 expect = 0
401 actual = status
402 assert expect == actual
404 expect = BUFFER_SIZE
405 actual = len(out)
406 assert expect == actual
408 actual = len(err)
409 assert expect == actual
412 def test_it_doesnt_deadlock():
413 """Test that we don't deadlock with both stderr and stdout"""
414 code = (
415 r'import sys;'
416 r'value = "\0" * %d;'
417 r'sys.stderr.write(value);'
418 r'sys.stdout.write(value);'
419 ) % BUFFER_SIZE
421 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
423 expect = 0
424 actual = status
425 assert expect == actual
427 expect = '\0' * BUFFER_SIZE
428 actual = out
429 assert expect == actual
431 actual = err
432 assert expect == actual