diff options
Diffstat (limited to 'git/test/test_repo.py')
-rw-r--r-- | git/test/test_repo.py | 332 |
1 files changed, 190 insertions, 142 deletions
diff --git a/git/test/test_repo.py b/git/test/test_repo.py index e24062c1..1d537e93 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -4,18 +4,15 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import glob +from io import BytesIO +import itertools +import os import pickle +import sys +import tempfile +from unittest.case import skipIf -from git.test.lib import ( - patch, - TestBase, - with_rw_repo, - fixture, - assert_false, - assert_equal, - assert_true, - raises -) from git import ( InvalidGitRepositoryError, Repo, @@ -33,24 +30,35 @@ from git import ( BadName, GitCommandError ) -from git.repo.fun import touch -from git.util import join_path_native +from git.compat import ( + PY3, + is_win, + string_types, + win_encode, +) from git.exc import ( BadObject, ) +from git.repo.fun import touch +from git.test.lib import ( + patch, + TestBase, + with_rw_repo, + fixture, + assert_false, + assert_equal, + assert_true, + raises +) +from git.test.lib.helper import HIDE_WINDOWS_KNOWN_ERRORS +from git.test.lib import with_rw_directory +from git.util import join_path_native, rmtree, rmfile from gitdb.util import bin_to_hex -from git.compat import string_types -from gitdb.test.lib import with_rw_directory - -import os -import sys -import tempfile -import shutil -import itertools -from io import BytesIO - from nose import SkipTest +import functools as fnt +import os.path as osp + def iter_flatten(lol): for items in lol: @@ -62,8 +70,26 @@ def flatten(lol): return list(iter_flatten(lol)) +_tc_lock_fpaths = osp.join(osp.dirname(__file__), '../../.git/*.lock') + + +def _rm_lock_files(): + for lfp in glob.glob(_tc_lock_fpaths): + rmfile(lfp) + + class TestRepo(TestBase): + def setUp(self): + _rm_lock_files() + + def tearDown(self): + for lfp in glob.glob(_tc_lock_fpaths): + if osp.isfile(lfp): + raise AssertionError('Previous TC left hanging git-lock file: %s', lfp) + import gc + gc.collect() + @raises(InvalidGitRepositoryError) def test_new_should_raise_on_invalid_repo_location(self): Repo(tempfile.gettempdir()) @@ -75,10 +101,10 @@ class TestRepo(TestBase): @with_rw_repo('0.3.2.1') def test_repo_creation_from_different_paths(self, rw_repo): r_from_gitdir = Repo(rw_repo.git_dir) - assert r_from_gitdir.git_dir == rw_repo.git_dir + self.assertEqual(r_from_gitdir.git_dir, rw_repo.git_dir) assert r_from_gitdir.git_dir.endswith('.git') assert not rw_repo.git.working_dir.endswith('.git') - assert r_from_gitdir.git.working_dir == rw_repo.git.working_dir + self.assertEqual(r_from_gitdir.git.working_dir, rw_repo.git.working_dir) def test_description(self): txt = "Test repository" @@ -92,32 +118,33 @@ class TestRepo(TestBase): def test_heads_should_populate_head_data(self): for head in self.rorepo.heads: assert head.name - assert isinstance(head.commit, Commit) + self.assertIsInstance(head.commit, Commit) # END for each head - assert isinstance(self.rorepo.heads.master, Head) - assert isinstance(self.rorepo.heads['master'], Head) + self.assertIsInstance(self.rorepo.heads.master, Head) + self.assertIsInstance(self.rorepo.heads['master'], Head) def test_tree_from_revision(self): tree = self.rorepo.tree('0.1.6') - assert len(tree.hexsha) == 40 - assert tree.type == "tree" - assert self.rorepo.tree(tree) == tree + self.assertEqual(len(tree.hexsha), 40) + self.assertEqual(tree.type, "tree") + self.assertEqual(self.rorepo.tree(tree), tree) # try from invalid revision that does not exist self.failUnlessRaises(BadName, self.rorepo.tree, 'hello world') - + def test_pickleable(self): pickle.loads(pickle.dumps(self.rorepo)) def test_commit_from_revision(self): commit = self.rorepo.commit('0.1.4') - assert commit.type == 'commit' - assert self.rorepo.commit(commit) == commit + self.assertEqual(commit.type, 'commit') + self.assertEqual(self.rorepo.commit(commit), commit) + def test_commits(self): mc = 10 commits = list(self.rorepo.iter_commits('0.1.6', max_count=mc)) - assert len(commits) == mc + self.assertEqual(len(commits), mc) c = commits[0] assert_equal('9a4b1d4d11eee3c5362a4152216376e634bd14cf', c.hexsha) @@ -134,23 +161,23 @@ class TestRepo(TestBase): assert_equal("Bumped version 0.1.6\n", c.message) c = commits[1] - assert isinstance(c.parents, tuple) + self.assertIsInstance(c.parents, tuple) def test_trees(self): mc = 30 num_trees = 0 for tree in self.rorepo.iter_trees('0.1.5', max_count=mc): num_trees += 1 - assert isinstance(tree, Tree) + self.assertIsInstance(tree, Tree) # END for each tree - assert num_trees == mc + self.assertEqual(num_trees, mc) def _assert_empty_repo(self, repo): # test all kinds of things with an empty, freshly initialized repo. # It should throw good errors # entries should be empty - assert len(repo.index.entries) == 0 + self.assertEqual(len(repo.index.entries), 0) # head is accessible assert repo.head @@ -182,7 +209,7 @@ class TestRepo(TestBase): # with specific path for path in (git_dir_rela, git_dir_abs): r = Repo.init(path=path, bare=True) - assert isinstance(r, Repo) + self.assertIsInstance(r, Repo) assert r.bare is True assert not r.has_separate_working_tree() assert os.path.isdir(r.git_dir) @@ -195,7 +222,7 @@ class TestRepo(TestBase): self._assert_empty_repo(rc) try: - shutil.rmtree(clone_path) + rmtree(clone_path) except OSError: # when relative paths are used, the clone may actually be inside # of the parent directory @@ -206,9 +233,9 @@ class TestRepo(TestBase): rc = Repo.clone_from(r.git_dir, clone_path) self._assert_empty_repo(rc) - shutil.rmtree(git_dir_abs) + rmtree(git_dir_abs) try: - shutil.rmtree(clone_path) + rmtree(clone_path) except OSError: # when relative paths are used, the clone may actually be inside # of the parent directory @@ -226,7 +253,7 @@ class TestRepo(TestBase): self._assert_empty_repo(r) finally: try: - shutil.rmtree(del_dir_abs) + rmtree(del_dir_abs) except OSError: pass os.chdir(prev_cwd) @@ -238,18 +265,18 @@ class TestRepo(TestBase): def test_daemon_export(self): orig_val = self.rorepo.daemon_export self.rorepo.daemon_export = not orig_val - assert self.rorepo.daemon_export == (not orig_val) + self.assertEqual(self.rorepo.daemon_export, (not orig_val)) self.rorepo.daemon_export = orig_val - assert self.rorepo.daemon_export == orig_val + self.assertEqual(self.rorepo.daemon_export, orig_val) def test_alternates(self): cur_alternates = self.rorepo.alternates # empty alternates self.rorepo.alternates = [] - assert self.rorepo.alternates == [] + self.assertEqual(self.rorepo.alternates, []) alts = ["other/location", "this/location"] self.rorepo.alternates = alts - assert alts == self.rorepo.alternates + self.assertEqual(alts, self.rorepo.alternates) self.rorepo.alternates = cur_alternates def test_repr(self): @@ -294,25 +321,27 @@ class TestRepo(TestBase): assert rwrepo.is_dirty(untracked_files=True, path="doc") is True def test_head(self): - assert self.rorepo.head.reference.object == self.rorepo.active_branch.object + self.assertEqual(self.rorepo.head.reference.object, self.rorepo.active_branch.object) def test_index(self): index = self.rorepo.index - assert isinstance(index, IndexFile) + self.assertIsInstance(index, IndexFile) def test_tag(self): assert self.rorepo.tag('refs/tags/0.1.5').commit def test_archive(self): tmpfile = tempfile.mktemp(suffix='archive-test') - stream = open(tmpfile, 'wb') - self.rorepo.archive(stream, '0.1.6', path='doc') - assert stream.tell() - stream.close() + with open(tmpfile, 'wb') as stream: + self.rorepo.archive(stream, '0.1.6', path='doc') + assert stream.tell() os.remove(tmpfile) @patch.object(Git, '_call_process') def test_should_display_blame_information(self, git): + if sys.version_info < (2, 7): + ## Skipped, not `assertRaisesRegexp` in py2.6 + return git.return_value = fixture('blame') b = self.rorepo.blame('master', 'lib/git.py') assert_equal(13, len(b)) @@ -340,7 +369,7 @@ class TestRepo(TestBase): # BINARY BLAME git.return_value = fixture('blame_binary') blames = self.rorepo.blame('master', 'rps') - assert len(blames) == 2 + self.assertEqual(len(blames), 2) def test_blame_real(self): c = 0 @@ -360,32 +389,35 @@ class TestRepo(TestBase): git.return_value = fixture('blame_incremental') blame_output = self.rorepo.blame_incremental('9debf6b0aafb6f7781ea9d1383c86939a1aacde3', 'AUTHORS') blame_output = list(blame_output) - assert len(blame_output) == 5 + self.assertEqual(len(blame_output), 5) # Check all outputted line numbers ranges = flatten([entry.linenos for entry in blame_output]) - assert ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(3, 14), range(15, 17)]), str(ranges) + self.assertEqual(ranges, flatten([range(2, 3), range(14, 15), range(1, 2), range(3, 14), range(15, 17)])) commits = [entry.commit.hexsha[:7] for entry in blame_output] - assert commits == ['82b8902', '82b8902', 'c76852d', 'c76852d', 'c76852d'], str(commits) + self.assertEqual(commits, ['82b8902', '82b8902', 'c76852d', 'c76852d', 'c76852d']) # Original filenames - assert all([entry.orig_path == u'AUTHORS' for entry in blame_output]) + self.assertSequenceEqual([entry.orig_path for entry in blame_output], [u'AUTHORS'] * len(blame_output)) # Original line numbers orig_ranges = flatten([entry.orig_linenos for entry in blame_output]) - assert orig_ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(2, 13), range(13, 15)]), str(orig_ranges) # noqa + self.assertEqual(orig_ranges, flatten([range(2, 3), range(14, 15), range(1, 2), range(2, 13), range(13, 15)])) # noqa E501 @patch.object(Git, '_call_process') def test_blame_complex_revision(self, git): git.return_value = fixture('blame_complex_revision') res = self.rorepo.blame("HEAD~10..HEAD", "README.md") - assert len(res) == 1 - assert len(res[0][1]) == 83, "Unexpected amount of parsed blame lines" + self.assertEqual(len(res), 1) + self.assertEqual(len(res[0][1]), 83, "Unexpected amount of parsed blame lines") @with_rw_repo('HEAD', bare=False) def test_untracked_files(self, rwrepo): - for (run, repo_add) in enumerate((rwrepo.index.add, rwrepo.git.add)): + for run, (repo_add, is_invoking_git) in enumerate(( + (rwrepo.index.add, False), + (rwrepo.git.add, True), + )): base = rwrepo.working_tree_dir files = (join_path_native(base, u"%i_test _myfile" % run), join_path_native(base, "%i_test_other_file" % run), @@ -394,9 +426,8 @@ class TestRepo(TestBase): num_recently_untracked = 0 for fpath in files: - fd = open(fpath, "wb") - fd.close() - # END for each filename + with open(fpath, "wb"): + pass untracked_files = rwrepo.untracked_files num_recently_untracked = len(untracked_files) @@ -404,10 +435,15 @@ class TestRepo(TestBase): num_test_untracked = 0 for utfile in untracked_files: num_test_untracked += join_path_native(base, utfile) in files - assert len(files) == num_test_untracked + self.assertEqual(len(files), num_test_untracked) + if is_win and not PY3 and is_invoking_git: + ## On Windows, shell needed when passing unicode cmd-args. + # + repo_add = fnt.partial(repo_add, shell=True) + untracked_files = [win_encode(f) for f in untracked_files] repo_add(untracked_files) - assert len(rwrepo.untracked_files) == (num_recently_untracked - len(files)) + self.assertEqual(len(rwrepo.untracked_files), (num_recently_untracked - len(files))) # end for each run def test_config_reader(self): @@ -419,19 +455,16 @@ class TestRepo(TestBase): def test_config_writer(self): for config_level in self.rorepo.config_level: try: - writer = self.rorepo.config_writer(config_level) - assert not writer.read_only - writer.release() + with self.rorepo.config_writer(config_level) as writer: + self.assertFalse(writer.read_only) except IOError: # its okay not to get a writer for some configuration files if we # have no permissions pass - # END for each config level def test_config_level_paths(self): for config_level in self.rorepo.config_level: assert self.rorepo._get_config_path(config_level) - # end for each config level def test_creation_deletion(self): # just a very quick test to assure it generally works. There are @@ -441,19 +474,20 @@ class TestRepo(TestBase): tag = self.rorepo.create_tag("new_tag", "HEAD~2") self.rorepo.delete_tag(tag) - writer = self.rorepo.config_writer() - writer.release() + with self.rorepo.config_writer(): + pass remote = self.rorepo.create_remote("new_remote", "git@server:repo.git") self.rorepo.delete_remote(remote) def test_comparison_and_hash(self): # this is only a preliminary test, more testing done in test_index - assert self.rorepo == self.rorepo and not (self.rorepo != self.rorepo) - assert len(set((self.rorepo, self.rorepo))) == 1 + self.assertEqual(self.rorepo, self.rorepo) + self.assertFalse(self.rorepo != self.rorepo) + self.assertEqual(len(set((self.rorepo, self.rorepo))), 1) @with_rw_directory def test_tilde_and_env_vars_in_repo_path(self, rw_dir): - ph = os.environ['HOME'] + ph = os.environ.get('HOME') try: os.environ['HOME'] = rw_dir Repo.init(os.path.join('~', 'test.git'), bare=True) @@ -461,8 +495,9 @@ class TestRepo(TestBase): os.environ['FOO'] = rw_dir Repo.init(os.path.join('$FOO', 'test.git'), bare=True) finally: - os.environ['HOME'] = ph - del os.environ['FOO'] + if ph: + os.environ['HOME'] = ph + del os.environ['FOO'] # end assure HOME gets reset to what it was def test_git_cmd(self): @@ -488,57 +523,59 @@ class TestRepo(TestBase): # readlines no limit s = mkfull() lines = s.readlines() - assert len(lines) == 3 and lines[-1].endswith(b'\n') - assert s._stream.tell() == len(d) # must have scrubbed to the end + self.assertEqual(len(lines), 3) + self.assertTrue(lines[-1].endswith(b'\n'), lines[-1]) + self.assertEqual(s._stream.tell(), len(d)) # must have scrubbed to the end # realines line limit s = mkfull() lines = s.readlines(5) - assert len(lines) == 1 + self.assertEqual(len(lines), 1) # readlines on tiny sections s = mktiny() lines = s.readlines() - assert len(lines) == 1 and lines[0] == l1p - assert s._stream.tell() == ts + 1 + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], l1p) + self.assertEqual(s._stream.tell(), ts + 1) # readline no limit s = mkfull() - assert s.readline() == l1 - assert s.readline() == l2 - assert s.readline() == l3 - assert s.readline() == b'' - assert s._stream.tell() == len(d) + self.assertEqual(s.readline(), l1) + self.assertEqual(s.readline(), l2) + self.assertEqual(s.readline(), l3) + self.assertEqual(s.readline(), b'') + self.assertEqual(s._stream.tell(), len(d)) # readline limit s = mkfull() - assert s.readline(5) == l1p - assert s.readline() == l1[5:] + self.assertEqual(s.readline(5), l1p) + self.assertEqual(s.readline(), l1[5:]) # readline on tiny section s = mktiny() - assert s.readline() == l1p - assert s.readline() == b'' - assert s._stream.tell() == ts + 1 + self.assertEqual(s.readline(), l1p) + self.assertEqual(s.readline(), b'') + self.assertEqual(s._stream.tell(), ts + 1) # read no limit s = mkfull() - assert s.read() == d[:-1] - assert s.read() == b'' - assert s._stream.tell() == len(d) + self.assertEqual(s.read(), d[:-1]) + self.assertEqual(s.read(), b'') + self.assertEqual(s._stream.tell(), len(d)) # read limit s = mkfull() - assert s.read(5) == l1p - assert s.read(6) == l1[5:] - assert s._stream.tell() == 5 + 6 # its not yet done + self.assertEqual(s.read(5), l1p) + self.assertEqual(s.read(6), l1[5:]) + self.assertEqual(s._stream.tell(), 5 + 6) # its not yet done # read tiny s = mktiny() - assert s.read(2) == l1[:2] - assert s._stream.tell() == 2 - assert s.read() == l1[2:ts] - assert s._stream.tell() == ts + 1 + self.assertEqual(s.read(2), l1[:2]) + self.assertEqual(s._stream.tell(), 2) + self.assertEqual(s.read(), l1[2:ts]) + self.assertEqual(s._stream.tell(), ts + 1) def _assert_rev_parse_types(self, name, rev_obj): rev_parse = self.rorepo.rev_parse @@ -548,11 +585,12 @@ class TestRepo(TestBase): # tree and blob type obj = rev_parse(name + '^{tree}') - assert obj == rev_obj.tree + self.assertEqual(obj, rev_obj.tree) obj = rev_parse(name + ':CHANGES') - assert obj.type == 'blob' and obj.path == 'CHANGES' - assert rev_obj.tree['CHANGES'] == obj + self.assertEqual(obj.type, 'blob') + self.assertEqual(obj.path, 'CHANGES') + self.assertEqual(rev_obj.tree['CHANGES'], obj) def _assert_rev_parse(self, name): """tries multiple different rev-parse syntaxes with the given name @@ -568,7 +606,7 @@ class TestRepo(TestBase): # try history rev = name + "~" obj2 = rev_parse(rev) - assert obj2 == obj.parents[0] + self.assertEqual(obj2, obj.parents[0]) self._assert_rev_parse_types(rev, obj2) # history with number @@ -581,20 +619,20 @@ class TestRepo(TestBase): for pn in range(11): rev = name + "~%i" % (pn + 1) obj2 = rev_parse(rev) - assert obj2 == history[pn] + self.assertEqual(obj2, history[pn]) self._assert_rev_parse_types(rev, obj2) # END history check # parent ( default ) rev = name + "^" obj2 = rev_parse(rev) - assert obj2 == obj.parents[0] + self.assertEqual(obj2, obj.parents[0]) self._assert_rev_parse_types(rev, obj2) # parent with number for pn, parent in enumerate(obj.parents): rev = name + "^%i" % (pn + 1) - assert rev_parse(rev) == parent + self.assertEqual(rev_parse(rev), parent) self._assert_rev_parse_types(rev, parent) # END for each parent @@ -610,7 +648,7 @@ class TestRepo(TestBase): rev_parse = self.rorepo.rev_parse # try special case: This one failed at some point, make sure its fixed - assert rev_parse("33ebe").hexsha == "33ebe7acec14b25c5f84f35a664803fcab2f7781" + self.assertEqual(rev_parse("33ebe").hexsha, "33ebe7acec14b25c5f84f35a664803fcab2f7781") # start from reference num_resolved = 0 @@ -621,7 +659,7 @@ class TestRepo(TestBase): path_section = '/'.join(path_tokens[-(pt + 1):]) try: obj = self._assert_rev_parse(path_section) - assert obj.type == ref.object.type + self.assertEqual(obj.type, ref.object.type) num_resolved += 1 except (BadName, BadObject): print("failed on %s" % path_section) @@ -636,31 +674,31 @@ class TestRepo(TestBase): # it works with tags ! tag = self._assert_rev_parse('0.1.4') - assert tag.type == 'tag' + self.assertEqual(tag.type, 'tag') # try full sha directly ( including type conversion ) - assert tag.object == rev_parse(tag.object.hexsha) + self.assertEqual(tag.object, rev_parse(tag.object.hexsha)) self._assert_rev_parse_types(tag.object.hexsha, tag.object) # multiple tree types result in the same tree: HEAD^{tree}^{tree}:CHANGES rev = '0.1.4^{tree}^{tree}' - assert rev_parse(rev) == tag.object.tree - assert rev_parse(rev + ':CHANGES') == tag.object.tree['CHANGES'] + self.assertEqual(rev_parse(rev), tag.object.tree) + self.assertEqual(rev_parse(rev + ':CHANGES'), tag.object.tree['CHANGES']) # try to get parents from first revision - it should fail as no such revision # exists first_rev = "33ebe7acec14b25c5f84f35a664803fcab2f7781" commit = rev_parse(first_rev) - assert len(commit.parents) == 0 - assert commit.hexsha == first_rev + self.assertEqual(len(commit.parents), 0) + self.assertEqual(commit.hexsha, first_rev) self.failUnlessRaises(BadName, rev_parse, first_rev + "~") self.failUnlessRaises(BadName, rev_parse, first_rev + "^") # short SHA1 commit2 = rev_parse(first_rev[:20]) - assert commit2 == commit + self.assertEqual(commit2, commit) commit2 = rev_parse(first_rev[:5]) - assert commit2 == commit + self.assertEqual(commit2, commit) # todo: dereference tag into a blob 0.1.7^{blob} - quite a special one # needs a tag which points to a blob @@ -668,13 +706,13 @@ class TestRepo(TestBase): # ref^0 returns commit being pointed to, same with ref~0, and ^{} tag = rev_parse('0.1.4') for token in (('~0', '^0', '^{}')): - assert tag.object == rev_parse('0.1.4%s' % token) + self.assertEqual(tag.object, rev_parse('0.1.4%s' % token)) # END handle multiple tokens # try partial parsing max_items = 40 for i, binsha in enumerate(self.rorepo.odb.sha_iter()): - assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha == binsha + self.assertEqual(rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha, binsha) if i > max_items: # this is rather slow currently, as rev_parse returns an object # which requires accessing packs, it has some additional overhead @@ -695,13 +733,13 @@ class TestRepo(TestBase): self.failUnlessRaises(BadObject, rev_parse, "%s@{0}" % head.commit.hexsha) # uses HEAD.ref by default - assert rev_parse('@{0}') == head.commit + self.assertEqual(rev_parse('@{0}'), head.commit) if not head.is_detached: refspec = '%s@{0}' % head.ref.name - assert rev_parse(refspec) == head.ref.commit + self.assertEqual(rev_parse(refspec), head.ref.commit) # all additional specs work as well - assert rev_parse(refspec + "^{tree}") == head.commit.tree - assert rev_parse(refspec + ":CHANGES").type == 'blob' + self.assertEqual(rev_parse(refspec + "^{tree}"), head.commit.tree) + self.assertEqual(rev_parse(refspec + ":CHANGES").type, 'blob') # END operate on non-detached head # position doesn't exist @@ -717,13 +755,13 @@ class TestRepo(TestBase): target_type = GitCmdObjectDB if sys.version_info[:2] < (2, 5): target_type = GitCmdObjectDB - assert isinstance(self.rorepo.odb, target_type) + self.assertIsInstance(self.rorepo.odb, target_type) def test_submodules(self): - assert len(self.rorepo.submodules) == 1 # non-recursive - assert len(list(self.rorepo.iter_submodules())) >= 2 + self.assertEqual(len(self.rorepo.submodules), 1) # non-recursive + self.assertGreaterEqual(len(list(self.rorepo.iter_submodules())), 2) - assert isinstance(self.rorepo.submodule("gitdb"), Submodule) + self.assertIsInstance(self.rorepo.submodule("gitdb"), Submodule) self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") @with_rw_repo('HEAD', bare=False) @@ -736,7 +774,7 @@ class TestRepo(TestBase): # test create submodule sm = rwrepo.submodules[0] sm = rwrepo.create_submodule("my_new_sub", "some_path", join_path_native(self.rorepo.working_tree_dir, sm.path)) - assert isinstance(sm, Submodule) + self.assertIsInstance(sm, Submodule) # note: the rest of this functionality is tested in test_submodule @@ -746,17 +784,21 @@ class TestRepo(TestBase): real_path_abs = os.path.abspath(join_path_native(rwrepo.working_tree_dir, '.real')) os.rename(rwrepo.git_dir, real_path_abs) git_file_path = join_path_native(rwrepo.working_tree_dir, '.git') - open(git_file_path, 'wb').write(fixture('git_file')) + with open(git_file_path, 'wb') as fp: + fp.write(fixture('git_file')) # Create a repo and make sure it's pointing to the relocated .git directory. git_file_repo = Repo(rwrepo.working_tree_dir) - assert os.path.abspath(git_file_repo.git_dir) == real_path_abs + self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) # Test using an absolute gitdir path in the .git file. - open(git_file_path, 'wb').write(('gitdir: %s\n' % real_path_abs).encode('ascii')) + with open(git_file_path, 'wb') as fp: + fp.write(('gitdir: %s\n' % real_path_abs).encode('ascii')) git_file_repo = Repo(rwrepo.working_tree_dir) - assert os.path.abspath(git_file_repo.git_dir) == real_path_abs + self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) + @skipIf(HIDE_WINDOWS_KNOWN_ERRORS and PY3, + "FIXME: smmp fails with: TypeError: Can't convert 'bytes' object to str implicitly") def test_file_handle_leaks(self): def last_commit(repo, rev, path): commit = next(repo.iter_commits(rev, path, max_count=1)) @@ -767,7 +809,7 @@ class TestRepo(TestBase): # And we expect to set max handles to a low value, like 64 # You should set ulimit -n X, see .travis.yml # The loops below would easily create 500 handles if these would leak (4 pipes + multiple mapped files) - for i in range(64): + for _ in range(64): for repo_type in (GitCmdObjectDB, GitDB): repo = Repo(self.rorepo.working_tree_dir, odbt=repo_type) last_commit(repo, 'master', 'git/test/test_base.py') @@ -776,7 +818,7 @@ class TestRepo(TestBase): def test_remote_method(self): self.failUnlessRaises(ValueError, self.rorepo.remote, 'foo-blue') - assert isinstance(self.rorepo.remote(name='origin'), Remote) + self.assertIsInstance(self.rorepo.remote(name='origin'), Remote) @with_rw_directory def test_empty_repo(self, rw_dir): @@ -784,7 +826,7 @@ class TestRepo(TestBase): r = Repo.init(rw_dir, mkdir=False) # It's ok not to be able to iterate a commit, as there is none self.failUnlessRaises(ValueError, r.iter_commits) - assert r.active_branch.name == 'master' + self.assertEqual(r.active_branch.name, 'master') assert not r.active_branch.is_valid(), "Branch is yet to be born" # actually, when trying to create a new branch without a commit, git itself fails @@ -824,12 +866,15 @@ class TestRepo(TestBase): # two commit merge-base res = repo.merge_base(c1, c2) - assert isinstance(res, list) and len(res) == 1 and isinstance(res[0], Commit) - assert res[0].hexsha.startswith('3936084') + self.assertIsInstance(res, list) + self.assertEqual(len(res), 1) + self.assertIsInstance(res[0], Commit) + self.assertTrue(res[0].hexsha.startswith('3936084')) for kw in ('a', 'all'): res = repo.merge_base(c1, c2, c3, **{kw: True}) - assert isinstance(res, list) and len(res) == 1 + self.assertIsInstance(res, list) + self.assertEqual(len(res), 1) # end for each keyword signalling all merge-bases to be returned # Test for no merge base - can't do as we have @@ -852,6 +897,9 @@ class TestRepo(TestBase): for i, j in itertools.permutations([c1, 'ffffff', ''], r=2): self.assertRaises(GitCommandError, repo.is_ancestor, i, j) + # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, + # "FIXME: helper.wrapper fails with: PermissionError: [WinError 5] Access is denied: " + # "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx") # noqa E501 @with_rw_directory def test_work_tree_unsupported(self, rw_dir): git = Git(rw_dir) |