-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconftest.py
106 lines (84 loc) · 4.5 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""conftest.py: local per-directory plugins / per-directory configuration
It is used in thiis project to provide variables and fixtures common
to all the tests in 'tests/' directory.
https://docs.pytest.org/en/stable/how-to/writing_plugins.html#pluginorder
https://docs.pytest.org/en/stable/how-to/writing_plugins.html#localplugin
https://docs.pytest.org/en/stable/reference/fixtures.html#conftest-py-sharing-fixtures-across-multiple-files
"""
import os
import subprocess
from pathlib import Path
import pytest
from diffannotator.utils.git import GitRepo
# global variable, common for all tests
default_branch = 'main'
## ----------------------------------------------------------------------
## fixtures
@pytest.fixture(scope="module") # like unittest.setUpClass()
def example_repo(tmp_path_factory: pytest.TempPathFactory) -> GitRepo:
"""Prepare Git repository for testing `utils.git` module
Uses GitRepo.create_tag() for creating one of lightweight tags,
so that test_list_tags() test also tests GitRepo.create_tag().
"""
tmp_path = tmp_path_factory.mktemp('repos')
repo_name = 'test_utils_git-repo'
repo_path = str(tmp_path / repo_name)
# initialize repository and configure it
subprocess.run(['git', 'init', repo_path], check=True, stdout=subprocess.DEVNULL) # noisy
subprocess.run(['git', '-C', repo_path, 'config', 'user.name', 'A U Thor'], check=True)
subprocess.run(['git', '-C', repo_path, 'config', 'user.email', '[email protected]'], check=True)
subprocess.run(['git', '-C', repo_path, 'branch', '-m', default_branch], check=True)
# create files, and initial commit
Path(repo_path).joinpath('example_file').write_text('example\n2\n3\n4\n5\n')
Path(repo_path).joinpath('subdir').mkdir()
Path(repo_path).joinpath('subdir', 'subfile').write_text('subfile')
subprocess.run(['git', '-C', repo_path, 'add', '.'], check=True)
subprocess.run(['git', '-C', repo_path, 'commit', '-m', 'Initial commit'],
check=True, stdout=subprocess.DEVNULL) # noisy
subprocess.run(['git', '-C', repo_path, 'tag', 'v1'])
# intermediate commit, for testing blame
Path(repo_path).joinpath('subdir', 'subfile').write_text('subfile\n')
subprocess.run(['git', '-C', repo_path, 'commit', '-a', '-m', 'Change subdir/subfile'],
check=True, stdout=subprocess.DEVNULL) # noisy
subprocess.run(['git', '-C', repo_path, 'tag', 'v1.5'])
# add new file
Path(repo_path).joinpath('new_file').write_text(''.join([f"{i}\n" for i in range(10)]))
subprocess.run(['git', '-C', repo_path, 'add', 'new_file'], check=True)
# change file
Path(repo_path).joinpath('subdir', 'subfile').write_text('subfile\nsubfile\n')
# rename file, and change it a bit
Path(repo_path).joinpath('example_file').write_text('example\n2\n3\n4b\n5\n')
subprocess.run(['git', '-C', repo_path, 'mv',
'example_file', 'renamed_file'], check=True)
# commit changes
subprocess.run(['git', '-C', repo_path, 'commit', '-a',
'-m', 'Change some files\n\n* one renamed file\n* one new file'],
env=dict(
# inherit environment variables
os.environ,
# configure git-commit behavior
# see https://git-scm.com/docs/git-commit#_commit_information
GIT_AUTHOR_NAME='Joe Random',
GIT_AUTHOR_EMAIL='[email protected]',
GIT_AUTHOR_DATE='1693605193 -0600',
),
check=True, stdout=subprocess.DEVNULL) # noisy
# tag for easy access
subprocess.run(['git', '-C', repo_path, 'tag', 'v2'])
return GitRepo(repo_path)
## ----------------------------------------------------------------------
## helper functions
def count_pm_lines(changes_data: dict) -> tuple[int, int]:
"""Count number of '-' and '+' lines in changes part of annotation data
:param changes_data: information about changes extracted from annotation data;
in the v2 data format this data is available at the 'changes' key
:return: (total number of '-' lines, total number of '+' lines)
"""
total_p = total_m = 0
for file_name, file_data in changes_data.items(): # we are not interested in file names here
for data_key, data_value in file_data.items():
if data_key == '-':
total_m += len(data_value)
elif data_key == '+':
total_p += len(data_value)
return total_m, total_p