Skip to content

Commit

Permalink
Start work on making refresh tests restore state
Browse files Browse the repository at this point in the history
+ Test a successful refresh with a relative path, which will be
  safer to do once the refresh tests restore changed state.

See gitpython-developers#1811. This addresses it incompletely, because while it is
probably not necessary while running the test suite to preserve an
old False value of git.GIT_OK (most tests can't work if that
happens anyway), the value of Git.GIT_PYTHON_GIT_EXECUTABLE is not
the only other global state that effects the behavior of
subsequently run tests and that may be changed as a result of the
refresh tests.

1. After the git.refresh function calls git.cmd.Git.refresh, it
   calls git.remote.FetchInfo.refresh, which rebinds the
   git.remote.FetchInfo._flag_map attribute.

2. Future changes to git.cmd.Git.refresh may mutate other state in
   the Git class, and ideally the coupling would be loose enough
   that the refresh tests wouldn't have to be updated for that if
   the behavior being tested does not change.

3. Future changes to git.refresh may perform other refreshing
   actions, and ideally it would be easy (and obvious) what has to
   be done to patch it back. In particular, it will likely call
   another Git method that mutates class-wide state due to gitpython-developers#1791,
   and for such state that is also of the Git class, ideally no
   further changes would have to be made to the code that restores
   state after the refresh tests.

If we assume git.refresh is working at least in the case that it is
called with no arguments, then the cleanup can just be a call to
git.refresh(). Otherwise, sufficiently general cleanup may be more
complicated.
  • Loading branch information
EliahKagan committed Jan 25, 2024
1 parent 3a34dee commit 5ad7cb2
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions test/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ def _patch_out_env(name):
os.environ[name] = old_value


@contextlib.contextmanager
def _restore_git_executable():
old_git_executable = Git.GIT_PYTHON_GIT_EXECUTABLE
try:
yield old_git_executable # Let test code run that may rebind the attribute.
finally:
Git.GIT_PYTHON_GIT_EXECUTABLE = old_git_executable


@ddt.ddt
class TestGit(TestBase):
@classmethod
Expand Down Expand Up @@ -309,20 +318,36 @@ def test_cmd_override(self):
def test_refresh_bad_absolute_git_path(self):
absolute_path = str(Path("yada").absolute())
expected_pattern = rf"\n[ \t]*cmdline: {re.escape(absolute_path)}\Z"
with self.assertRaisesRegex(GitCommandNotFound, expected_pattern):
refresh(absolute_path)

with _restore_git_executable() as old_git_executable:
with self.assertRaisesRegex(GitCommandNotFound, expected_pattern):
refresh(absolute_path)
self.assertEqual(self.git.GIT_PYTHON_GIT_EXECUTABLE, old_git_executable)

def test_refresh_bad_relative_git_path(self):
relative_path = "yada"
absolute_path = str(Path(relative_path).absolute())
absolute_path = str(Path("yada").absolute())
expected_pattern = rf"\n[ \t]*cmdline: {re.escape(absolute_path)}\Z"
with self.assertRaisesRegex(GitCommandNotFound, expected_pattern):
refresh(relative_path)

with _restore_git_executable() as old_git_executable:
with self.assertRaisesRegex(GitCommandNotFound, expected_pattern):
refresh("yada")
self.assertEqual(self.git.GIT_PYTHON_GIT_EXECUTABLE, old_git_executable)

def test_refresh_good_absolute_git_path(self):
absolute_path = shutil.which("git")
refresh(absolute_path)
self.assertEqual(self.git.GIT_PYTHON_GIT_EXECUTABLE, absolute_path)

with _restore_git_executable():
refresh(absolute_path)
self.assertEqual(self.git.GIT_PYTHON_GIT_EXECUTABLE, absolute_path)

def test_refresh_good_relative_git_path(self):
absolute_path = shutil.which("git")
dirname, basename = osp.split(absolute_path)

with cwd(dirname):
with _restore_git_executable():
refresh(basename)
self.assertEqual(self.git.GIT_PYTHON_GIT_EXECUTABLE, absolute_path)

def test_options_are_passed_to_git(self):
# This works because any command after git --version is ignored.
Expand Down

0 comments on commit 5ad7cb2

Please sign in to comment.