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
):
18 @patch('cola.git.is_git_dir')
19 def test_find_git_dir_None(self
, is_git_dir
):
21 paths
= git
.find_git_directory(None)
23 self
.assertFalse(is_git_dir
.called
)
24 self
.assertEqual(None, paths
.git_dir
)
25 self
.assertEqual(None, paths
.git_file
)
26 self
.assertEqual(None, paths
.worktree
)
28 @patch('cola.git.is_git_dir')
29 def test_find_git_dir_empty_string(self
, is_git_dir
):
31 paths
= git
.find_git_directory('')
33 self
.assertFalse(is_git_dir
.called
)
34 self
.assertEqual(None, paths
.git_dir
)
35 self
.assertEqual(None, paths
.git_file
)
36 self
.assertEqual(None, paths
.worktree
)
38 @patch('cola.git.is_git_dir')
39 def test_find_git_dir_never_found(self
, is_git_dir
):
40 is_git_dir
.return_value
= False
42 paths
= git
.find_git_directory('/does/not/exist')
44 self
.assertTrue(is_git_dir
.called
)
45 self
.assertEqual(None, paths
.git_dir
)
46 self
.assertEqual(None, paths
.git_file
)
47 self
.assertEqual(None, paths
.worktree
)
49 self
.assertEqual(8, is_git_dir
.call_count
)
51 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
),
62 @patch('cola.git.is_git_dir')
63 def test_find_git_dir_found_right_away(self
, is_git_dir
):
64 git_dir
= '/seems/to/exist/.git'
65 worktree
= '/seems/to/exist'
66 is_git_dir
.return_value
= True
68 paths
= git
.find_git_directory(git_dir
)
70 self
.assertTrue(is_git_dir
.called
)
71 self
.assertEqual(git_dir
, paths
.git_dir
)
72 self
.assertEqual(None, paths
.git_file
)
73 self
.assertEqual(worktree
, paths
.worktree
)
75 @patch('cola.git.is_git_dir')
76 def test_find_git_does_discovery(self
, is_git_dir
):
77 git_dir
= '/the/root/.git'
78 worktree
= '/the/root'
79 is_git_dir
.side_effect
= lambda x
: x
== git_dir
81 paths
= git
.find_git_directory('/the/root/sub/dir')
83 self
.assertEqual(git_dir
, paths
.git_dir
)
84 self
.assertEqual(None, paths
.git_file
)
85 self
.assertEqual(worktree
, paths
.worktree
)
87 @patch('cola.git.read_git_file')
88 @patch('cola.git.is_git_file')
89 @patch('cola.git.is_git_dir')
90 def test_find_git_honors_git_files(self
,
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 self
.assertEqual(git_dir
, paths
.git_dir
)
105 self
.assertEqual(git_file
, paths
.git_file
)
106 self
.assertEqual(worktree
, paths
.worktree
)
109 self
.assertEqual(6, is_git_dir
.call_count
)
110 is_git_dir
.assert_has_calls([
111 (('/the/root/sub/dir',), kwargs
),
112 (('/the/root/sub/dir/.git',), kwargs
),
113 (('/the/root/sub',), kwargs
),
114 (('/the/root/sub/.git',), kwargs
),
115 (('/the/root',), kwargs
),
116 (('/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([
144 (('/ceiling/sub/dir',), kwargs
),
145 (('/ceiling/sub/dir/.git',), kwargs
),
146 (('/ceiling/sub',), kwargs
),
147 (('/ceiling/sub/.git',), kwargs
),
150 @patch('cola.core.islink')
151 @patch('cola.core.isdir')
152 @patch('cola.core.isfile')
153 def test_is_git_dir_finds_linked_repository(self
, isfile
, isdir
, islink
):
159 '/foo/.git/worktrees',
160 '/foo/.git/worktrees/foo',
164 '/foo/.git/worktrees/foo/HEAD',
165 '/foo/.git/worktrees/foo/index',
166 '/foo/.git/worktrees/foo/commondir',
167 '/foo/.git/worktrees/foo/gitdir',
169 islink
.return_value
= False
170 isfile
.side_effect
= lambda x
: x
in files
171 isdir
.side_effect
= lambda x
: x
in dirs
173 self
.assertTrue(git
.is_git_dir('/foo/.git/worktrees/foo'))
174 self
.assertTrue(git
.is_git_dir('/foo/.git'))
177 class GitCommandTest(unittest
.TestCase
):
178 """Runs tests using a git.Git instance"""
181 """Creates a git.Git instance for later use"""
184 def test_transform_kwargs_empty(self
):
186 actual
= git
.transform_kwargs(foo
=None, bar
=False)
187 self
.assertEqual(expect
, actual
)
189 def test_transform_kwargs_single_dash_from_True(self
):
190 """Single dash for one-character True"""
192 actual
= git
.transform_kwargs(a
=True)
193 self
.assertEqual(expect
, actual
)
195 def test_transform_kwargs_no_single_dash_from_False(self
):
196 """No single-dash for False"""
198 actual
= git
.transform_kwargs(a
=False)
199 self
.assertEqual(expect
, actual
)
201 def test_transform_kwargs_double_dash_from_True(self
):
202 """Double-dash for longer True"""
204 actual
= git
.transform_kwargs(abc
=True)
205 self
.assertEqual(expect
, actual
)
207 def test_transform_kwargs_no_double_dash_from_True(self
):
208 """No double-dash for False"""
210 actual
= git
.transform_kwargs(abc
=False)
211 self
.assertEqual(expect
, actual
)
213 def test_transform_kwargs_single_dash_int(self
):
215 actual
= git
.transform_kwargs(a
=1)
216 self
.assertEqual(expect
, actual
)
218 def test_transform_kwargs_double_dash_int(self
):
220 actual
= git
.transform_kwargs(abc
=1)
221 self
.assertEqual(expect
, actual
)
223 def test_transform_kwargs_single_dash_float(self
):
225 actual
= git
.transform_kwargs(a
=1.5)
226 self
.assertEqual(expect
, actual
)
228 def test_transform_kwargs_double_dash_float(self
):
229 expect
= ['--abc=1.5']
230 actual
= git
.transform_kwargs(abc
=1.5)
231 self
.assertEqual(expect
, actual
)
233 def test_transform_kwargs_single_dash_string(self
):
235 actual
= git
.transform_kwargs(a
='bc')
236 self
.assertEqual(expect
, actual
)
238 def test_transform_double_single_dash_string(self
):
239 expect
= ['--abc=def']
240 actual
= git
.transform_kwargs(abc
='def')
241 self
.assertEqual(expect
, actual
)
243 def test_version(self
):
244 """Test running 'git version'"""
245 version
= self
.git
.version()[STDOUT
]
246 self
.failUnless(version
.startswith('git version'))
248 def test_stdout(self
):
249 """Test overflowing the stdout buffer"""
250 # Write to stdout only
251 code
= ('import sys;'
252 's = "\\0" * (1024 * 16 + 1);'
253 'sys.stdout.write(s);')
254 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
255 self
.assertEqual(status
, 0)
256 self
.assertEqual(len(out
), 1024 * 16 + 1)
257 self
.assertEqual(len(err
), 0)
259 def test_stderr(self
):
260 """Test that stderr is seen"""
261 # Write to stderr and capture it
262 code
= ('import sys;'
263 's = "\\0" * (1024 * 16 + 1);'
264 'sys.stderr.write(s);')
265 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
266 self
.assertEqual(status
, 0)
267 self
.assertEqual(len(out
), 0)
268 self
.assertEqual(len(err
), 1024 * 16 + 1)
270 def test_stdout_and_stderr(self
):
271 """Test ignoring stderr when stdout+stderr are provided (v2)"""
272 # Write to stdout and stderr but only capture stdout
273 code
= ('import sys;'
274 's = "\\0" * (1024 * 16 + 1);'
275 'sys.stdout.write(s);'
276 'sys.stderr.write(s);')
277 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
278 self
.assertEqual(status
, 0)
279 self
.assertEqual(len(out
), 1024 * 16 + 1)
280 self
.assertEqual(len(err
), 1024 * 16 + 1)
282 def test_it_doesnt_deadlock(self
):
283 """Test that we don't deadlock with both stderr and stdout"""
284 # 16k+1 bytes to exhaust any output buffers
285 code
= ('import sys;'
286 's = "\\0" * (1024 * 16 + 1);'
287 'sys.stderr.write(s);'
288 'sys.stdout.write(s);')
289 status
, out
, err
= git
.Git
.execute(['python', '-c', code
], _raw
=True)
290 self
.assertEqual(status
, 0)
291 self
.assertEqual(out
, '\0' * (1024 * 16 + 1))
292 self
.assertEqual(err
, '\0' * (1024 * 16 + 1))
295 if __name__
== '__main__':