about: update contributors for v3.2
[git-cola.git] / test / git_test.py
blob97fae079584a0e2855bbb4f24cd5d1c2c7c845fa
1 #!/usr/bin/env python
2 """Tests various operations using the cola.git module
3 """
4 from __future__ import absolute_import, division, unicode_literals
6 import os
7 import time
8 import unittest
10 try:
11 from unittest.mock import patch
12 except ImportError:
13 from mock import patch
15 from cola import git
16 from cola.compat import WIN32
17 from cola.git import STDOUT
20 class GitModuleTestCase(unittest.TestCase):
22 @patch('cola.git.is_git_dir')
23 def test_find_git_dir_None(self, is_git_dir):
25 paths = git.find_git_directory(None)
27 self.assertFalse(is_git_dir.called)
28 self.assertEqual(None, paths.git_dir)
29 self.assertEqual(None, paths.git_file)
30 self.assertEqual(None, paths.worktree)
32 @patch('cola.git.is_git_dir')
33 def test_find_git_dir_empty_string(self, is_git_dir):
35 paths = git.find_git_directory('')
37 self.assertFalse(is_git_dir.called)
38 self.assertEqual(None, paths.git_dir)
39 self.assertEqual(None, paths.git_file)
40 self.assertEqual(None, paths.worktree)
42 @patch('cola.git.is_git_dir')
43 def test_find_git_dir_never_found(self, is_git_dir):
44 is_git_dir.return_value = False
46 paths = git.find_git_directory('/does/not/exist')
48 self.assertTrue(is_git_dir.called)
49 self.assertEqual(None, paths.git_dir)
50 self.assertEqual(None, paths.git_file)
51 self.assertEqual(None, paths.worktree)
53 self.assertEqual(8, is_git_dir.call_count)
54 kwargs = {}
55 is_git_dir.assert_has_calls([
56 (('/does/not/exist',), kwargs),
57 (('/does/not/exist/.git',), kwargs),
58 (('/does/not',), kwargs),
59 (('/does/not/.git',), kwargs),
60 (('/does',), kwargs),
61 (('/does/.git',), kwargs),
62 (('/',), kwargs),
63 (('/.git',), kwargs),
66 @patch('cola.git.is_git_dir')
67 def test_find_git_dir_found_right_away(self, is_git_dir):
68 git_dir = '/seems/to/exist/.git'
69 worktree = '/seems/to/exist'
70 is_git_dir.return_value = True
72 paths = git.find_git_directory(git_dir)
74 self.assertTrue(is_git_dir.called)
75 self.assertEqual(git_dir, paths.git_dir)
76 self.assertEqual(None, paths.git_file)
77 self.assertEqual(worktree, paths.worktree)
79 @patch('cola.git.is_git_dir')
80 def test_find_git_does_discovery(self, is_git_dir):
81 git_dir = '/the/root/.git'
82 worktree = '/the/root'
83 is_git_dir.side_effect = lambda x: x == git_dir
85 paths = git.find_git_directory('/the/root/sub/dir')
87 self.assertEqual(git_dir, paths.git_dir)
88 self.assertEqual(None, paths.git_file)
89 self.assertEqual(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(self,
95 is_git_dir,
96 is_git_file,
97 read_git_file):
98 git_file = '/the/root/.git'
99 worktree = '/the/root'
100 git_dir = '/super/module/.git/modules/root'
102 is_git_dir.side_effect = lambda x: x == git_file
103 is_git_file.side_effect = lambda x: x == git_file
104 read_git_file.return_value = git_dir
106 paths = git.find_git_directory('/the/root/sub/dir')
108 self.assertEqual(git_dir, paths.git_dir)
109 self.assertEqual(git_file, paths.git_file)
110 self.assertEqual(worktree, paths.worktree)
112 kwargs = {}
113 self.assertEqual(6, is_git_dir.call_count)
114 is_git_dir.assert_has_calls([
115 (('/the/root/sub/dir',), kwargs),
116 (('/the/root/sub/dir/.git',), kwargs),
117 (('/the/root/sub',), kwargs),
118 (('/the/root/sub/.git',), kwargs),
119 (('/the/root',), kwargs),
120 (('/the/root/.git',), kwargs),
122 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(self, is_git_dir, getenv):
128 git_dir = '/ceiling/.git'
129 ceiling = '/tmp:/ceiling:/other/ceiling'
130 is_git_dir.side_effect = lambda x: x == git_dir
132 def mock_getenv(k, v=None):
133 if k == 'GIT_CEILING_DIRECTORIES':
134 return ceiling
135 return v
137 getenv.side_effect = mock_getenv
139 paths = git.find_git_directory('/ceiling/sub/dir')
141 self.assertEqual(None, paths.git_dir)
142 self.assertEqual(None, paths.git_file)
143 self.assertEqual(None, paths.worktree)
145 self.assertEqual(4, is_git_dir.call_count)
146 kwargs = {}
147 is_git_dir.assert_has_calls([
148 (('/ceiling/sub/dir',), kwargs),
149 (('/ceiling/sub/dir/.git',), kwargs),
150 (('/ceiling/sub',), kwargs),
151 (('/ceiling/sub/.git',), kwargs),
154 @patch('cola.core.islink')
155 @patch('cola.core.isdir')
156 @patch('cola.core.isfile')
157 def test_is_git_dir_finds_linked_repository(self, isfile, isdir, islink):
158 dirs = set([
159 '/foo',
160 '/foo/.git',
161 '/foo/.git/refs',
162 '/foo/.git/objects',
163 '/foo/.git/worktrees',
164 '/foo/.git/worktrees/foo',
166 files = set([
167 '/foo/.git/HEAD',
168 '/foo/.git/worktrees/foo/HEAD',
169 '/foo/.git/worktrees/foo/index',
170 '/foo/.git/worktrees/foo/commondir',
171 '/foo/.git/worktrees/foo/gitdir',
173 islink.return_value = False
174 isfile.side_effect = lambda x: x in files
175 isdir.side_effect = lambda x: x in dirs
177 self.assertTrue(git.is_git_dir('/foo/.git/worktrees/foo'))
178 self.assertTrue(git.is_git_dir('/foo/.git'))
181 class GitCommandTest(unittest.TestCase):
182 """Runs tests using a git.Git instance"""
184 def setUp(self):
185 """Creates a git.Git instance for later use"""
186 self.git = git.Git()
188 def test_transform_kwargs_empty(self):
189 expect = []
190 actual = git.transform_kwargs(foo=None, bar=False)
191 self.assertEqual(expect, actual)
193 def test_transform_kwargs_single_dash_from_True(self):
194 """Single dash for one-character True"""
195 expect = ['-a']
196 actual = git.transform_kwargs(a=True)
197 self.assertEqual(expect, actual)
199 def test_transform_kwargs_no_single_dash_from_False(self):
200 """No single-dash for False"""
201 expect = []
202 actual = git.transform_kwargs(a=False)
203 self.assertEqual(expect, actual)
205 def test_transform_kwargs_double_dash_from_True(self):
206 """Double-dash for longer True"""
207 expect = ['--abc']
208 actual = git.transform_kwargs(abc=True)
209 self.assertEqual(expect, actual)
211 def test_transform_kwargs_no_double_dash_from_True(self):
212 """No double-dash for False"""
213 expect = []
214 actual = git.transform_kwargs(abc=False)
215 self.assertEqual(expect, actual)
217 def test_transform_kwargs_single_dash_int(self):
218 expect = ['-a1']
219 actual = git.transform_kwargs(a=1)
220 self.assertEqual(expect, actual)
222 def test_transform_kwargs_double_dash_int(self):
223 expect = ['--abc=1']
224 actual = git.transform_kwargs(abc=1)
225 self.assertEqual(expect, actual)
227 def test_transform_kwargs_single_dash_float(self):
228 expect = ['-a1.5']
229 actual = git.transform_kwargs(a=1.5)
230 self.assertEqual(expect, actual)
232 def test_transform_kwargs_double_dash_float(self):
233 expect = ['--abc=1.5']
234 actual = git.transform_kwargs(abc=1.5)
235 self.assertEqual(expect, actual)
237 def test_transform_kwargs_single_dash_string(self):
238 expect = ['-abc']
239 actual = git.transform_kwargs(a='bc')
240 self.assertEqual(expect, actual)
242 def test_transform_double_single_dash_string(self):
243 expect = ['--abc=def']
244 actual = git.transform_kwargs(abc='def')
245 self.assertEqual(expect, actual)
247 def test_version(self):
248 """Test running 'git version'"""
249 version = self.git.version()[STDOUT]
250 self.failUnless(version.startswith('git version'))
252 def test_stdout(self):
253 """Test overflowing the stdout buffer"""
254 # Write to stdout only
255 code = ('import sys;'
256 's = "\\0" * (1024 * 16 + 1);'
257 'sys.stdout.write(s);')
258 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
259 self.assertEqual(status, 0)
260 self.assertEqual(len(out), 1024 * 16 + 1)
261 self.assertEqual(len(err), 0)
263 def test_stderr(self):
264 """Test that stderr is seen"""
265 # Write to stderr and capture it
266 code = ('import sys;'
267 's = "\\0" * (1024 * 16 + 1);'
268 'sys.stderr.write(s);')
269 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
270 self.assertEqual(status, 0)
271 self.assertEqual(len(out), 0)
272 self.assertEqual(len(err), 1024 * 16 + 1)
274 def test_stdout_and_stderr(self):
275 """Test ignoring stderr when stdout+stderr are provided (v2)"""
276 # Write to stdout and stderr but only capture stdout
277 code = ('import sys;'
278 's = "\\0" * (1024 * 16 + 1);'
279 'sys.stdout.write(s);'
280 'sys.stderr.write(s);')
281 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
282 self.assertEqual(status, 0)
283 self.assertEqual(len(out), 1024 * 16 + 1)
284 self.assertEqual(len(err), 1024 * 16 + 1)
286 def test_it_doesnt_deadlock(self):
287 """Test that we don't deadlock with both stderr and stdout"""
288 # 16k+1 bytes to exhaust any output buffers
289 code = ('import sys;'
290 's = "\\0" * (1024 * 16 + 1);'
291 'sys.stderr.write(s);'
292 'sys.stdout.write(s);')
293 status, out, err = git.Git.execute(['python', '-c', code], _raw=True)
294 self.assertEqual(status, 0)
295 self.assertEqual(out, '\0' * (1024 * 16 + 1))
296 self.assertEqual(err, '\0' * (1024 * 16 + 1))
299 if __name__ == '__main__':
300 unittest.main()