2 """Tests various operations using the cola.git module
4 from __future__
import absolute_import
, division
, unicode_literals
8 from unittest
.mock
import patch
10 from mock
import patch
13 from cola
.git
import STDOUT
16 class GitModuleTestCase(unittest
.TestCase
):
17 @patch('cola.git.is_git_dir')
18 def test_find_git_dir_None(self
, is_git_dir
):
20 paths
= git
.find_git_directory(None)
22 self
.assertFalse(is_git_dir
.called
)
23 self
.assertEqual(None, paths
.git_dir
)
24 self
.assertEqual(None, paths
.git_file
)
25 self
.assertEqual(None, paths
.worktree
)
27 @patch('cola.git.is_git_dir')
28 def test_find_git_dir_empty_string(self
, is_git_dir
):
30 paths
= git
.find_git_directory('')
32 self
.assertFalse(is_git_dir
.called
)
33 self
.assertEqual(None, paths
.git_dir
)
34 self
.assertEqual(None, paths
.git_file
)
35 self
.assertEqual(None, paths
.worktree
)
37 @patch('cola.git.is_git_dir')
38 def test_find_git_dir_never_found(self
, is_git_dir
):
39 is_git_dir
.return_value
= False
41 paths
= git
.find_git_directory('/does/not/exist')
43 self
.assertTrue(is_git_dir
.called
)
44 self
.assertEqual(None, paths
.git_dir
)
45 self
.assertEqual(None, paths
.git_file
)
46 self
.assertEqual(None, paths
.worktree
)
48 self
.assertEqual(8, is_git_dir
.call_count
)
50 is_git_dir
.assert_has_calls(
52 (('/does/not/exist',), kwargs
),
53 (('/does/not/exist/.git',), kwargs
),
54 (('/does/not',), kwargs
),
55 (('/does/not/.git',), kwargs
),
57 (('/does/.git',), kwargs
),
63 @patch('cola.git.is_git_dir')
64 def test_find_git_dir_found_right_away(self
, 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 self
.assertTrue(is_git_dir
.called
)
72 self
.assertEqual(git_dir
, paths
.git_dir
)
73 self
.assertEqual(None, paths
.git_file
)
74 self
.assertEqual(worktree
, paths
.worktree
)
76 @patch('cola.git.is_git_dir')
77 def test_find_git_does_discovery(self
, is_git_dir
):
78 git_dir
= '/the/root/.git'
79 worktree
= '/the/root'
80 is_git_dir
.side_effect
= lambda x
: x
== git_dir
82 paths
= git
.find_git_directory('/the/root/sub/dir')
84 self
.assertEqual(git_dir
, paths
.git_dir
)
85 self
.assertEqual(None, paths
.git_file
)
86 self
.assertEqual(worktree
, paths
.worktree
)
88 @patch('cola.git.read_git_file')
89 @patch('cola.git.is_git_file')
90 @patch('cola.git.is_git_dir')
91 def test_find_git_honors_git_files(self
, is_git_dir
, is_git_file
, read_git_file
):
92 git_file
= '/the/root/.git'
93 worktree
= '/the/root'
94 git_dir
= '/super/module/.git/modules/root'
96 is_git_dir
.side_effect
= lambda x
: x
== git_file
97 is_git_file
.side_effect
= lambda x
: x
== git_file
98 read_git_file
.return_value
= git_dir
100 paths
= git
.find_git_directory('/the/root/sub/dir')
102 self
.assertEqual(git_dir
, paths
.git_dir
)
103 self
.assertEqual(git_file
, paths
.git_file
)
104 self
.assertEqual(worktree
, paths
.worktree
)
107 self
.assertEqual(6, is_git_dir
.call_count
)
108 is_git_dir
.assert_has_calls(
110 (('/the/root/sub/dir',), kwargs
),
111 (('/the/root/sub/dir/.git',), kwargs
),
112 (('/the/root/sub',), kwargs
),
113 (('/the/root/sub/.git',), kwargs
),
114 (('/the/root',), kwargs
),
115 (('/the/root/.git',), kwargs
),
118 read_git_file
.assert_called_once_with('/the/root/.git')
120 @patch('cola.core.getenv')
121 @patch('cola.git.is_git_dir')
122 def test_find_git_honors_ceiling_dirs(self
, is_git_dir
, getenv
):
124 git_dir
= '/ceiling/.git'
125 ceiling
= '/tmp:/ceiling:/other/ceiling'
126 is_git_dir
.side_effect
= lambda x
: x
== git_dir
128 def mock_getenv(k
, v
=None):
129 if k
== 'GIT_CEILING_DIRECTORIES':
133 getenv
.side_effect
= mock_getenv
135 paths
= git
.find_git_directory('/ceiling/sub/dir')
137 self
.assertEqual(None, paths
.git_dir
)
138 self
.assertEqual(None, paths
.git_file
)
139 self
.assertEqual(None, paths
.worktree
)
141 self
.assertEqual(4, is_git_dir
.call_count
)
143 is_git_dir
.assert_has_calls(
145 (('/ceiling/sub/dir',), kwargs
),
146 (('/ceiling/sub/dir/.git',), kwargs
),
147 (('/ceiling/sub',), kwargs
),
148 (('/ceiling/sub/.git',), kwargs
),
152 @patch('cola.core.islink')
153 @patch('cola.core.isdir')
154 @patch('cola.core.isfile')
155 def test_is_git_dir_finds_linked_repository(self
, isfile
, isdir
, islink
):
162 '/foo/.git/worktrees',
163 '/foo/.git/worktrees/foo',
169 '/foo/.git/worktrees/foo/HEAD',
170 '/foo/.git/worktrees/foo/index',
171 '/foo/.git/worktrees/foo/commondir',
172 '/foo/.git/worktrees/foo/gitdir',
175 islink
.return_value
= False
176 isfile
.side_effect
= lambda x
: x
in files
177 isdir
.side_effect
= lambda x
: x
in dirs
179 self
.assertTrue(git
.is_git_dir('/foo/.git/worktrees/foo'))
180 self
.assertTrue(git
.is_git_dir('/foo/.git'))
182 @patch('cola.core.getenv')
183 @patch('cola.git.is_git_dir')
184 def test_find_git_worktree_from_GIT_DIR(self
, is_git_dir
, getenv
):
185 git_dir
= '/repo/.git'
187 is_git_dir
.return_value
= True
188 getenv
.side_effect
= lambda x
: x
== 'GIT_DIR' and '/repo/.git' or None
190 paths
= git
.find_git_directory(git_dir
)
191 self
.assertTrue(is_git_dir
.called
)
192 self
.assertEqual(git_dir
, paths
.git_dir
)
193 self
.assertEqual(None, paths
.git_file
)
194 self
.assertEqual(worktree
, paths
.worktree
)
196 @patch('cola.git.is_git_dir')
197 def test_finds_no_worktree_from_bare_repo(self
, is_git_dir
):
198 git_dir
= '/repos/bare.git'
200 is_git_dir
.return_value
= True
202 paths
= git
.find_git_directory(git_dir
)
203 self
.assertTrue(is_git_dir
.called
)
204 self
.assertEqual(git_dir
, paths
.git_dir
)
205 self
.assertEqual(None, paths
.git_file
)
206 self
.assertEqual(worktree
, paths
.worktree
)
208 @patch('cola.core.getenv')
209 @patch('cola.git.is_git_dir')
210 def test_find_git_directory_uses_GIT_WORK_TREE(self
, is_git_dir
, getenv
):
211 git_dir
= '/repo/worktree/.git'
212 worktree
= '/repo/worktree'
214 def is_git_dir_fn(path
):
215 return path
== git_dir
217 is_git_dir
.side_effect
= is_git_dir_fn
220 if name
== 'GIT_WORK_TREE':
224 getenv
.side_effect
= getenv_fn
226 paths
= git
.find_git_directory(worktree
)
227 self
.assertTrue(is_git_dir
.called
)
228 self
.assertEqual(git_dir
, paths
.git_dir
)
229 self
.assertEqual(None, paths
.git_file
)
230 self
.assertEqual(worktree
, paths
.worktree
)
232 @patch('cola.core.getenv')
233 @patch('cola.git.is_git_dir')
234 def test_uses_cwd_for_worktree_with_GIT_DIR(self
, is_git_dir
, getenv
):
235 git_dir
= '/repo/.yadm/repo.git'
239 if name
== 'GIT_DIR':
243 getenv
.side_effect
= getenv_fn
245 def is_git_dir_fn(path
):
246 return path
== git_dir
248 is_git_dir
.side_effect
= is_git_dir_fn
250 paths
= git
.find_git_directory(worktree
)
251 self
.assertTrue(is_git_dir
.called
)
252 self
.assertTrue(getenv
.called
)
253 self
.assertEqual(git_dir
, paths
.git_dir
)
254 self
.assertEqual(None, paths
.git_file
)
255 self
.assertEqual(worktree
, paths
.worktree
)
258 class GitCommandTest(unittest
.TestCase
):
259 """Runs tests using a git.Git instance"""
262 """Creates a git.Git instance for later use"""
265 def test_transform_kwargs_empty(self
):
267 actual
= git
.transform_kwargs(foo
=None, bar
=False)
268 self
.assertEqual(expect
, actual
)
270 def test_transform_kwargs_single_dash_from_True(self
):
271 """Single dash for one-character True"""
273 actual
= git
.transform_kwargs(a
=True)
274 self
.assertEqual(expect
, actual
)
276 def test_transform_kwargs_no_single_dash_from_False(self
):
277 """No single-dash for False"""
279 actual
= git
.transform_kwargs(a
=False)
280 self
.assertEqual(expect
, actual
)
282 def test_transform_kwargs_double_dash_from_True(self
):
283 """Double-dash for longer True"""
285 actual
= git
.transform_kwargs(abc
=True)
286 self
.assertEqual(expect
, actual
)
288 def test_transform_kwargs_no_double_dash_from_True(self
):
289 """No double-dash for False"""
291 actual
= git
.transform_kwargs(abc
=False)
292 self
.assertEqual(expect
, actual
)
294 def test_transform_kwargs_single_dash_int(self
):
296 actual
= git
.transform_kwargs(a
=1)
297 self
.assertEqual(expect
, actual
)
299 def test_transform_kwargs_double_dash_int(self
):
301 actual
= git
.transform_kwargs(abc
=1)
302 self
.assertEqual(expect
, actual
)
304 def test_transform_kwargs_single_dash_float(self
):
306 actual
= git
.transform_kwargs(a
=1.5)
307 self
.assertEqual(expect
, actual
)
309 def test_transform_kwargs_double_dash_float(self
):
310 expect
= ['--abc=1.5']
311 actual
= git
.transform_kwargs(abc
=1.5)
312 self
.assertEqual(expect
, actual
)
314 def test_transform_kwargs_single_dash_string(self
):
316 actual
= git
.transform_kwargs(a
='bc')
317 self
.assertEqual(expect
, actual
)
319 def test_transform_double_single_dash_string(self
):
320 expect
= ['--abc=def']
321 actual
= git
.transform_kwargs(abc
='def')
322 self
.assertEqual(expect
, actual
)
324 def test_version(self
):
325 """Test running 'git version'"""
326 version
= self
.git
.version()[STDOUT
]
327 self
.assertTrue(version
.startswith('git version'))
329 def test_stdout(self
):
330 """Test overflowing the stdout buffer"""
331 # Write to stdout only
332 code
= 'import sys;' 's = "\\0" * (1024 * 16 + 1);' 'sys.stdout.write(s);'
333 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
334 self
.assertEqual(status
, 0)
335 self
.assertEqual(len(out
), 1024 * 16 + 1)
336 self
.assertEqual(len(err
), 0)
338 def test_stderr(self
):
339 """Test that stderr is seen"""
340 # Write to stderr and capture it
341 code
= 'import sys;' 's = "\\0" * (1024 * 16 + 1);' 'sys.stderr.write(s);'
342 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
343 self
.assertEqual(status
, 0)
344 self
.assertEqual(len(out
), 0)
345 self
.assertEqual(len(err
), 1024 * 16 + 1)
347 def test_stdout_and_stderr(self
):
348 """Test ignoring stderr when stdout+stderr are provided (v2)"""
349 # Write to stdout and stderr but only capture stdout
352 's = "\\0" * (1024 * 16 + 1);'
353 'sys.stdout.write(s);'
354 'sys.stderr.write(s);'
356 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
357 self
.assertEqual(status
, 0)
358 self
.assertEqual(len(out
), 1024 * 16 + 1)
359 self
.assertEqual(len(err
), 1024 * 16 + 1)
361 def test_it_doesnt_deadlock(self
):
362 """Test that we don't deadlock with both stderr and stdout"""
363 # 16k+1 bytes to exhaust any output buffers
366 's = "\\0" * (1024 * 16 + 1);'
367 'sys.stderr.write(s);'
368 'sys.stdout.write(s);'
370 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
371 self
.assertEqual(status
, 0)
372 self
.assertEqual(out
, '\0' * (1024 * 16 + 1))
373 self
.assertEqual(err
, '\0' * (1024 * 16 + 1))
376 if __name__
== '__main__':