1 """Test the cola.git module"""
2 # pylint: disable=redefined-outer-name
3 from __future__
import absolute_import
, division
, print_function
, unicode_literals
6 from cola
.git
import STDOUT
8 from .helper
import patch
11 # 16k+1 bytes to exhaust any output buffers.
12 BUFFER_SIZE
= (16 * 1024) + 1
15 @patch('cola.git.is_git_dir')
16 def test_find_git_dir_None(is_git_dir
):
17 paths
= git
.find_git_directory(None)
19 assert not is_git_dir
.called
20 assert paths
.git_dir
is None
21 assert paths
.git_file
is None
22 assert paths
.worktree
is None
25 @patch('cola.git.is_git_dir')
26 def test_find_git_dir_empty_string(is_git_dir
):
27 paths
= git
.find_git_directory('')
29 assert not is_git_dir
.called
30 assert paths
.git_dir
is None
31 assert paths
.git_file
is None
32 assert paths
.worktree
is None
35 @patch('cola.git.is_git_dir')
36 def test_find_git_dir_never_found(is_git_dir
):
37 is_git_dir
.return_value
= False
39 paths
= git
.find_git_directory('/does/not/exist')
41 assert is_git_dir
.called
42 assert paths
.git_dir
is None
43 assert paths
.git_file
is None
44 assert paths
.worktree
is None
47 actual
= is_git_dir
.call_count
48 assert expect
== actual
49 is_git_dir
.assert_has_calls(
51 (('/does/not/exist',), {}),
52 (('/does/not/exist/.git',), {}),
54 (('/does/not/.git',), {}),
56 (('/does/.git',), {}),
63 @patch('cola.git.is_git_dir')
64 def test_find_git_dir_found_right_away(is_git_dir
):
65 git_dir
= '/seems/to/exist/.git'
66 worktree
= '/seems/to/exist'
67 is_git_dir
.return_value
= True
69 paths
= git
.find_git_directory(git_dir
)
71 assert is_git_dir
.called
72 assert git_dir
== paths
.git_dir
73 assert paths
.git_file
is None
74 assert worktree
== paths
.worktree
77 @patch('cola.git.is_git_dir')
78 def test_find_git_does_discovery(is_git_dir
):
79 git_dir
= '/the/root/.git'
80 worktree
= '/the/root'
81 is_git_dir
.side_effect
= lambda x
: x
== git_dir
83 paths
= git
.find_git_directory('/the/root/sub/dir')
85 assert git_dir
== paths
.git_dir
86 assert paths
.git_file
is None
87 assert 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(is_git_dir
, is_git_file
, read_git_file
):
94 git_file
= '/the/root/.git'
95 worktree
= '/the/root'
96 git_dir
= '/super/module/.git/modules/root'
98 is_git_dir
.side_effect
= lambda x
: x
== git_file
99 is_git_file
.side_effect
= lambda x
: x
== git_file
100 read_git_file
.return_value
= git_dir
102 paths
= git
.find_git_directory('/the/root/sub/dir')
104 assert git_dir
== paths
.git_dir
105 assert git_file
== paths
.git_file
106 assert worktree
== paths
.worktree
109 actual
= is_git_dir
.call_count
110 assert expect
== actual
111 is_git_dir
.assert_has_calls(
113 (('/the/root/sub/dir',), {}),
114 (('/the/root/sub/dir/.git',), {}),
115 (('/the/root/sub',), {}),
116 (('/the/root/sub/.git',), {}),
117 (('/the/root',), {}),
118 (('/the/root/.git',), {}),
121 read_git_file
.assert_called_once_with('/the/root/.git')
124 @patch('cola.core.getenv')
125 @patch('cola.git.is_git_dir')
126 def test_find_git_honors_ceiling_dirs(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':
136 getenv
.side_effect
= mock_getenv
138 paths
= git
.find_git_directory('/ceiling/sub/dir')
140 assert paths
.git_dir
is None
141 assert paths
.git_file
is None
142 assert paths
.worktree
is None
143 assert is_git_dir
.call_count
== 4
144 is_git_dir
.assert_has_calls(
146 (('/ceiling/sub/dir',), {}),
147 (('/ceiling/sub/dir/.git',), {}),
148 (('/ceiling/sub',), {}),
149 (('/ceiling/sub/.git',), {}),
154 @patch('cola.core.islink')
155 @patch('cola.core.isdir')
156 @patch('cola.core.isfile')
157 def test_is_git_dir_finds_linked_repository(isfile
, isdir
, islink
):
164 '/foo/.git/worktrees',
165 '/foo/.git/worktrees/foo',
171 '/foo/.git/worktrees/foo/HEAD',
172 '/foo/.git/worktrees/foo/index',
173 '/foo/.git/worktrees/foo/commondir',
174 '/foo/.git/worktrees/foo/gitdir',
177 islink
.return_value
= False
178 isfile
.side_effect
= lambda x
: x
in files
179 isdir
.side_effect
= lambda x
: x
in dirs
181 assert git
.is_git_dir('/foo/.git/worktrees/foo')
182 assert git
.is_git_dir('/foo/.git')
185 @patch('cola.core.getenv')
186 @patch('cola.git.is_git_dir')
187 def test_find_git_worktree_from_GIT_DIR(is_git_dir
, getenv
):
188 git_dir
= '/repo/.git'
190 is_git_dir
.return_value
= True
191 getenv
.side_effect
= lambda x
: x
== 'GIT_DIR' and '/repo/.git' or None
193 paths
= git
.find_git_directory(git_dir
)
194 assert is_git_dir
.called
195 assert git_dir
== paths
.git_dir
196 assert paths
.git_file
is None
197 assert worktree
== paths
.worktree
200 @patch('cola.git.is_git_dir')
201 def test_finds_no_worktree_from_bare_repo(is_git_dir
):
202 git_dir
= '/repos/bare.git'
204 is_git_dir
.return_value
= True
206 paths
= git
.find_git_directory(git_dir
)
207 assert is_git_dir
.called
208 assert git_dir
== paths
.git_dir
209 assert paths
.git_file
is None
210 assert worktree
== paths
.worktree
213 @patch('cola.core.getenv')
214 @patch('cola.git.is_git_dir')
215 def test_find_git_directory_uses_GIT_WORK_TREE(is_git_dir
, getenv
):
216 git_dir
= '/repo/worktree/.git'
217 worktree
= '/repo/worktree'
219 def is_git_dir_func(path
):
220 return path
== git_dir
222 is_git_dir
.side_effect
= is_git_dir_func
224 def getenv_func(name
):
225 if name
== 'GIT_WORK_TREE':
229 getenv
.side_effect
= getenv_func
231 paths
= git
.find_git_directory(worktree
)
232 assert is_git_dir
.called
233 assert git_dir
== paths
.git_dir
234 assert paths
.git_file
is None
235 assert worktree
== paths
.worktree
238 @patch('cola.core.getenv')
239 @patch('cola.git.is_git_dir')
240 def test_uses_cwd_for_worktree_with_GIT_DIR(is_git_dir
, getenv
):
241 git_dir
= '/repo/.yadm/repo.git'
244 def getenv_func(name
):
245 if name
== 'GIT_DIR':
249 getenv
.side_effect
= getenv_func
251 def is_git_dir_func(path
):
252 return path
== git_dir
254 is_git_dir
.side_effect
= is_git_dir_func
256 paths
= git
.find_git_directory(worktree
)
257 assert is_git_dir
.called
259 assert git_dir
== paths
.git_dir
260 assert paths
.git_file
is None
261 assert worktree
== paths
.worktree
264 def test_transform_kwargs_empty():
266 actual
= git
.transform_kwargs(foo
=None, bar
=False)
267 assert expect
== actual
270 def test_transform_kwargs_single_dash_from_True():
271 """Single dash for one-character True"""
273 actual
= git
.transform_kwargs(a
=True)
274 assert expect
== actual
277 def test_transform_kwargs_no_single_dash_from_False():
278 """No single-dash for False"""
280 actual
= git
.transform_kwargs(a
=False)
281 assert expect
== actual
284 def test_transform_kwargs_double_dash_from_True():
285 """Double-dash for longer True"""
287 actual
= git
.transform_kwargs(abc
=True)
288 assert expect
== actual
291 def test_transform_kwargs_no_double_dash_from_True():
292 """No double-dash for False"""
294 actual
= git
.transform_kwargs(abc
=False)
295 assert expect
== actual
298 def test_transform_kwargs_single_dash_int():
300 actual
= git
.transform_kwargs(a
=1)
301 assert expect
== actual
304 def test_transform_kwargs_double_dash_int():
306 actual
= git
.transform_kwargs(abc
=1)
307 assert expect
== actual
310 def test_transform_kwargs_single_dash_float():
312 actual
= git
.transform_kwargs(a
=1.5)
313 assert expect
== actual
316 def test_transform_kwargs_double_dash_float():
317 expect
= ['--abc=1.5']
318 actual
= git
.transform_kwargs(abc
=1.5)
319 assert expect
== actual
322 def test_transform_kwargs_single_dash_string():
324 actual
= git
.transform_kwargs(a
='bc')
325 assert expect
== actual
328 def test_transform_double_single_dash_string():
329 expect
= ['--abc=def']
330 actual
= git
.transform_kwargs(abc
='def')
331 assert expect
== actual
335 """Test running 'git version'"""
337 version
= gitcmd
.version()[STDOUT
]
338 assert version
.startswith('git version')
342 """Test overflowing the stdout buffer"""
343 # Write to stdout only
344 code
= r
'import sys; value = "\0" * %d; sys.stdout.write(value);' % BUFFER_SIZE
345 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
350 assert expect
== actual
354 assert expect
== actual
358 """Test that stderr is seen"""
359 # Write to stderr and capture it
361 r
'import sys;' r
'value = "\0" * %d;' r
'sys.stderr.write(value);'
364 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
368 assert expect
== actual
372 assert expect
== actual
376 assert expect
== actual
379 def test_stdout_and_stderr():
380 """Test ignoring stderr when stdout+stderr are provided (v2)"""
381 # Write to stdout and stderr but only capture stdout
384 r
'value = "\0" * %d;'
385 r
'sys.stdout.write(value);'
386 r
'sys.stderr.write(value);'
389 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
393 assert expect
== actual
397 assert expect
== actual
400 assert expect
== actual
403 def test_it_doesnt_deadlock():
404 """Test that we don't deadlock with both stderr and stdout"""
407 r
'value = "\0" * %d;'
408 r
'sys.stderr.write(value);'
409 r
'sys.stdout.write(value);'
412 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
416 assert expect
== actual
418 expect
= '\0' * BUFFER_SIZE
420 assert expect
== actual
423 assert expect
== actual