github/workflows: use a virtualenv for setuptools
[git-cola.git] / test / helper.py
blob0666e139d045d11e59e4c8e8bc4023f17205bc13
1 from __future__ import absolute_import, division, print_function, unicode_literals
2 import os
3 import shutil
4 import stat
5 import tempfile
7 import pytest
8 try:
9 from unittest.mock import Mock, patch # noqa pylint: disable=unused-import
10 except ImportError:
11 from mock import Mock, patch # noqa pylint: disable=unused-import
13 from cola import core
14 from cola import git
15 from cola import gitcfg
16 from cola import gitcmds
17 from cola.models import main
20 def tmp_path(*paths):
21 """Returns a path relative to the test/tmp directory"""
22 dirname = core.decode(os.path.dirname(__file__))
23 return os.path.join(dirname, 'tmp', *paths)
26 def fixture(*paths):
27 dirname = core.decode(os.path.dirname(__file__))
28 return os.path.join(dirname, 'fixtures', *paths)
31 # shutil.rmtree() can't remove read-only files on Windows. This onerror
32 # handler, adapted from <http://stackoverflow.com/a/1889686/357338>, works
33 # around this by changing such files to be writable and then re-trying.
34 def remove_readonly(func, path, _exc_info):
35 if func is os.remove and not os.access(path, os.W_OK):
36 os.chmod(path, stat.S_IWRITE)
37 func(path)
38 else:
39 raise AssertionError('Should not happen')
42 def touch(*paths):
43 """Open and close a file to either create it or update its mtime"""
44 for path in paths:
45 open(path, 'a').close()
48 def write_file(path, content):
49 """Write content to the specified file path"""
50 with open(path, 'w') as f:
51 f.write(content)
54 def append_file(path, content):
55 """Open a file in append mode and write content to it"""
56 with open(path, 'a') as f:
57 f.write(content)
60 def run_git(*args):
61 """Run git with the specified arguments"""
62 status, out, _ = core.run_command(['git'] + list(args))
63 assert status == 0
64 return out
67 def commit_files():
68 """Commit the current state as the initial commit"""
69 run_git('commit', '-m', 'initial commit')
72 def initialize_repo():
73 """Initialize a git repository in the current directory"""
74 run_git('init')
75 run_git('symbolic-ref', 'HEAD', 'refs/heads/main')
76 run_git('config', '--local', 'user.name', 'Your Name')
77 run_git('config', '--local', 'user.email', 'you@example.com')
78 run_git('config', '--local', 'commit.gpgsign', 'false')
79 run_git('config', '--local', 'tag.gpgsign', 'false')
80 touch('A', 'B')
81 run_git('add', 'A', 'B')
84 @pytest.fixture
85 def app_context():
86 """Create a repository in a temporary directory and return its ApplicationContext"""
87 tmp_directory = tempfile.mkdtemp('-cola-test')
88 current_directory = os.getcwd()
89 os.chdir(tmp_directory)
91 initialize_repo()
92 context = Mock()
93 context.git = git.create()
94 context.git.set_worktree(core.getcwd())
95 context.cfg = gitcfg.create(context)
96 context.model = main.create(context)
98 context.cfg.reset()
99 gitcmds.reset()
101 yield context
103 os.chdir(current_directory)
104 shutil.rmtree(tmp_directory, onerror=remove_readonly)