14
14
from tests .conftest import inside_dir
15
15
16
16
17
+ @pytest .fixture
18
+ def git_instance (scm_config : SCMConfig ) -> Git :
19
+ """Return a Git instance."""
20
+ return Git (config = scm_config )
21
+
22
+
17
23
class TestGit :
18
24
"""Tests related to Git."""
19
25
20
26
class TestIsAvailable :
21
27
"""Tests related to Git.is_available."""
22
28
23
- def test_recognizes_a_git_repo (self , git_repo : Path , scm_config : SCMConfig ) -> None :
29
+ def test_recognizes_a_git_repo (self , git_repo : Path , git_instance : Git ) -> None :
24
30
"""Should return true if git is available, and it is a git repo."""
25
31
with inside_dir (git_repo ):
26
- git_tool = Git (scm_config )
27
- assert git_tool .is_available ()
32
+ assert git_instance .is_available ()
28
33
29
- def test_recognizes_not_a_git_repo (self , tmp_path : Path , scm_config : SCMConfig ) -> None :
34
+ def test_recognizes_not_a_git_repo (self , tmp_path : Path , git_instance : Git ) -> None :
30
35
"""Should return false if it is not a git repo."""
31
36
with inside_dir (tmp_path ):
32
- git_tool = Git (scm_config )
33
- assert not git_tool .is_available ()
37
+ assert not git_instance .is_available ()
34
38
35
39
class TestLatestTagInfo :
36
40
"""Test for the Git.latest_tag_info() function."""
37
41
38
- def test_returns_default_if_not_available (self , tmp_path : Path , scm_config : SCMConfig ) -> None :
42
+ def test_returns_default_if_not_available (self , tmp_path : Path , git_instance : Git ) -> None :
39
43
"""If git is not available, it returns the default LatestTagInfo object, with all None values."""
40
44
# Arrange
41
45
expected = LatestTagInfo ()
42
- tool = Git (scm_config )
43
46
44
47
# Act
45
48
with inside_dir (tmp_path ):
46
- info = tool .latest_tag_info ()
49
+ info = git_instance .latest_tag_info ()
47
50
48
51
# Assert
49
52
assert info == expected
50
53
51
- def test_returns_correct_commit_and_tag_info (self , git_repo : Path , scm_config : SCMConfig ) -> None :
54
+ def test_returns_correct_commit_and_tag_info (self , git_repo : Path , git_instance : Git ) -> None :
52
55
"""Should return information that it is a git repo."""
53
56
# Arrange
54
57
tag_prefix = "app/"
55
58
readme = git_repo .joinpath ("readme.md" )
56
59
readme .touch ()
57
- scm_config .tag_name = f"{ tag_prefix } {{new_version}}"
60
+ git_instance . config .tag_name = f"{ tag_prefix } {{new_version}}"
58
61
59
62
# Act
60
63
with inside_dir (git_repo ):
61
64
commit_readme ("first" )
62
65
tag (f"{ tag_prefix } 0.1.0" , sign = False , message = "bumpversion" )
63
- tag_info = Git ( scm_config ) .latest_tag_info ()
66
+ tag_info = git_instance .latest_tag_info ()
64
67
65
68
# Assert
66
69
assert tag_info .commit_sha is not None
@@ -79,7 +82,7 @@ class TestGitAddPath:
79
82
@patch ("bumpversion.scm.git.Git.latest_tag_info" )
80
83
@patch ("bumpversion.scm.git.is_subpath" )
81
84
def test_valid_subpath_is_added (
82
- self , mock_is_subpath , mock_latest_tag_info , mock_run_command , scm_config : SCMConfig , tmp_path : Path
85
+ self , mock_is_subpath , mock_latest_tag_info , mock_run_command , git_instance : Git , tmp_path : Path
83
86
):
84
87
"""A path that is a subpath of the repository root should be added."""
85
88
# Arrange
@@ -89,7 +92,6 @@ def test_valid_subpath_is_added(
89
92
mock_latest_tag_info .return_value .repository_root = repository_root
90
93
mock_is_subpath .return_value = True
91
94
mock_run_command .return_value = None
92
- git_instance = Git (scm_config )
93
95
94
96
# Act
95
97
with inside_dir (repository_root ):
@@ -102,7 +104,7 @@ def test_valid_subpath_is_added(
102
104
@patch ("bumpversion.scm.git.Git.latest_tag_info" )
103
105
@patch ("bumpversion.scm.git.is_subpath" )
104
106
def test_invalid_subpath_is_not_added (
105
- self , mock_is_subpath , mock_latest_tag_info , mock_run_command , scm_config , tmp_path : Path
107
+ self , mock_is_subpath , mock_latest_tag_info , mock_run_command , git_instance : Git , tmp_path : Path
106
108
):
107
109
"""A path that is not a subpath of the repository root should not be added."""
108
110
# Arrange
@@ -111,7 +113,6 @@ def test_invalid_subpath_is_not_added(
111
113
path_to_add = repository_root / "file.txt"
112
114
mock_latest_tag_info .return_value .repository_root = repository_root
113
115
mock_is_subpath .return_value = False
114
- git_instance = Git (scm_config )
115
116
116
117
# Act
117
118
git_instance .add_path (path_to_add )
@@ -123,7 +124,7 @@ def test_invalid_subpath_is_not_added(
123
124
@patch ("bumpversion.scm.git.Git.latest_tag_info" )
124
125
@patch ("bumpversion.scm.git.is_subpath" )
125
126
def test_raises_error_on_command_failure (
126
- self , mock_is_subpath , mock_latest_tag_info , mock_run_command , scm_config : SCMConfig , tmp_path : Path
127
+ self , mock_is_subpath , mock_latest_tag_info , mock_run_command , git_instance : Git , tmp_path : Path
127
128
):
128
129
"""If the git command fails, a BumpVersionError should be raised."""
129
130
# Arrange
@@ -133,13 +134,101 @@ def test_raises_error_on_command_failure(
133
134
mock_latest_tag_info .return_value .repository_root = repository_root
134
135
mock_is_subpath .return_value = True
135
136
mock_run_command .side_effect = subprocess .CalledProcessError (returncode = 1 , cmd = "git add" )
136
- git_instance = Git (scm_config )
137
137
138
138
# Act / Assert
139
139
with inside_dir (repository_root ):
140
140
with pytest .raises (BumpVersionError ):
141
141
git_instance .add_path (path_to_add )
142
142
143
+ class TestGitCommitAndTag :
144
+ """Tests for the commit_and_tag() method."""
145
+
146
+ def test_dry_run_skips_method (self , git_instance : Git , mocker ):
147
+ """If dry_run is True, the method is short-circuited."""
148
+ # Arrange
149
+ files = ["file1.txt" , "file2.txt" ]
150
+ context = {"new_version" : "1.0.0" , "new_major" : "1" , "current_version" : "0.1.0" }
151
+ mock_add_path = mocker .patch .object (git_instance , "add_path" )
152
+ mock_commit = mocker .patch .object (git_instance , "commit" )
153
+ mock_tag = mocker .patch ("bumpversion.scm.git.tag" )
154
+ mock_moveable_tag = mocker .patch ("bumpversion.scm.git.moveable_tag" )
155
+
156
+ # Act
157
+ git_instance .commit_and_tag (files , context , dry_run = True )
158
+
159
+ # Assert
160
+ mock_add_path .assert_not_called ()
161
+ mock_commit .assert_not_called ()
162
+ mock_tag .assert_not_called ()
163
+ mock_moveable_tag .assert_not_called ()
164
+
165
+ def test_commits_and_tags_when_configured (self , git_instance : Git , mocker ):
166
+ """Does both commit and tag functions when they are configured."""
167
+ # Arrange
168
+ files = ["file1.txt" , "file2.txt" ]
169
+ context = {"new_version" : "1.0.0" , "new_major" : "1" , "current_version" : "0.1.0" }
170
+ git_instance .config .moveable_tags = ["v{new_major}" ]
171
+ git_instance .config .tag = True
172
+ git_instance .config .commit = True
173
+ mock_add_path = mocker .patch .object (git_instance , "add_path" )
174
+ mock_commit = mocker .patch .object (git_instance , "commit" )
175
+ mock_tag = mocker .patch ("bumpversion.scm.git.tag" )
176
+ mock_moveable_tag = mocker .patch ("bumpversion.scm.git.moveable_tag" )
177
+
178
+ # Act
179
+ git_instance .commit_and_tag (files , context , dry_run = False )
180
+
181
+ # Assert
182
+ assert mock_add_path .call_count == len (files )
183
+ mock_add_path .assert_any_call ("file1.txt" )
184
+ mock_add_path .assert_any_call ("file2.txt" )
185
+ mock_commit .assert_called_once_with (context )
186
+ mock_tag .assert_called_once_with ("v1.0.0" , sign = False , message = "Bump version: 0.1.0 → 1.0.0" )
187
+ mock_moveable_tag .assert_called_once_with ("v1" )
188
+
189
+ def test_tags_when_commit_is_false (self , git_instance : Git , mocker ):
190
+ """The method only tags when commit is False."""
191
+ # Arrange
192
+ files = ["file1.txt" ]
193
+ context = {"new_version" : "1.0.0" , "new_major" : "1" , "current_version" : "0.1.0" }
194
+ git_instance .config .moveable_tags = ["v{new_major}" ]
195
+ git_instance .config .commit = False
196
+ git_instance .config .tag = True
197
+ mock_add_path = mocker .patch .object (git_instance , "add_path" )
198
+ mock_commit = mocker .patch .object (git_instance , "commit" )
199
+ mock_tag = mocker .patch ("bumpversion.scm.git.tag" )
200
+ mock_moveable_tag = mocker .patch ("bumpversion.scm.git.moveable_tag" )
201
+
202
+ # Act
203
+ git_instance .commit_and_tag (files , context , dry_run = False )
204
+
205
+ # Assert
206
+ mock_add_path .assert_not_called ()
207
+ mock_commit .assert_not_called ()
208
+ mock_tag .assert_called_once_with ("v1.0.0" , sign = False , message = "Bump version: 0.1.0 → 1.0.0" )
209
+ mock_moveable_tag .assert_called_once_with ("v1" )
210
+
211
+ def test_commits_when_tag_is_false (self , git_instance : Git , mocker ):
212
+ """The method only commits when tag is False."""
213
+ # Arrange
214
+ files = ["file1.txt" ]
215
+ context = {"new_version" : "1.0.0" , "new_major" : "1" , "current_version" : "0.1.0" }
216
+ git_instance .config .moveable_tags = ["v{new_major}" ]
217
+ git_instance .config .tag = False
218
+ git_instance .config .commit = True
219
+ mock_add_path = mocker .patch .object (git_instance , "add_path" )
220
+ mock_commit = mocker .patch .object (git_instance , "commit" )
221
+ mock_tag = mocker .patch ("bumpversion.scm.git.tag" )
222
+ mock_moveable_tag = mocker .patch ("bumpversion.scm.git.moveable_tag" )
223
+
224
+ # Act
225
+ git_instance .commit_and_tag (files , context , dry_run = False )
226
+
227
+ mock_add_path .assert_called_with ("file1.txt" )
228
+ mock_commit .assert_called_once_with (context )
229
+ mock_tag .assert_not_called ()
230
+ mock_moveable_tag .assert_not_called ()
231
+
143
232
144
233
class TestRevisionInfo :
145
234
"""Tests for the revision_info function."""
0 commit comments