1
1
import subprocess
2
+ from typing import Callable
2
3
3
- from bumpversion .config import Config
4
- from bumpversion .hooks import run_setup_hooks
5
- from tests .conftest import get_config_data
4
+ import pytest
5
+ from pytest import param
6
+ from bumpversion .hooks import run_setup_hooks , run_pre_commit_hooks , run_post_commit_hooks
7
+ from bumpversion .versioning .models import Version
8
+ from tests .conftest import get_config_data , get_semver
6
9
7
10
8
- def setup_hook_env ( config : Config ) -> dict :
11
+ def get_hook_env ( * args , ** kwargs ) -> dict :
9
12
"""Mocked function for the environment setup"""
10
13
return {}
11
14
@@ -15,19 +18,102 @@ def run_command(script: str, env: dict) -> subprocess.CompletedProcess:
15
18
return subprocess .CompletedProcess (args = script , returncode = 0 )
16
19
17
20
18
- def test_run_setup_hooks_calls_each_hook (mocker ):
19
- """The run_setup_hooks function runs each hook."""
20
- # Assemble
21
- setup_hook_env_mock = mocker .patch ("bumpversion.hooks.setup_hook_env" , side_effect = setup_hook_env )
22
- run_command_mock = mocker .patch ("bumpversion.hooks.run_command" , side_effect = run_command )
21
+ CURRENT_VERSION = get_semver ("1.0.0" )
22
+ NEW_VERSION = get_semver ("1.1.0" )
23
23
24
- config , _ , _ = get_config_data ({"current_version" : "0.1.0" , "setup_hooks" : ["script1" , "script2" ]})
25
24
26
- # Act
27
- result = run_setup_hooks ( config )
25
+ class TestHookSuites :
26
+ """Run each hook suite through the same set of tests."""
28
27
29
- # Asserts for function's behavior
30
- setup_hook_env_mock .assert_called_once_with (config )
31
- assert run_command_mock .call_count == len (config .setup_hooks )
32
- run_command_mock .assert_any_call ("script1" , {})
33
- run_command_mock .assert_any_call ("script2" , {})
28
+ suites = (
29
+ param ("setup" , run_setup_hooks , (CURRENT_VERSION ,), id = "setup" ),
30
+ param (
31
+ "pre_commit" ,
32
+ run_pre_commit_hooks ,
33
+ (
34
+ CURRENT_VERSION ,
35
+ NEW_VERSION ,
36
+ ),
37
+ id = "pre_commit" ,
38
+ ),
39
+ param (
40
+ "post_commit" ,
41
+ run_post_commit_hooks ,
42
+ (
43
+ CURRENT_VERSION ,
44
+ NEW_VERSION ,
45
+ ),
46
+ id = "post_commit" ,
47
+ ),
48
+ )
49
+
50
+ @pytest .mark .parametrize (["suite_name" , "suite_func" , "suite_args" ], suites )
51
+ def test_calls_each_hook (self , mocker , suite_name : str , suite_func : Callable , suite_args : tuple ):
52
+ """The suite hook runs each hook."""
53
+ # Assemble
54
+ env = {"var" : "value" }
55
+ mock_env = mocker .patch (f"bumpversion.hooks.get_{ suite_name } _hook_env" )
56
+ mock_env .return_value = env
57
+ mock_run_command = mocker .patch ("bumpversion.hooks.run_command" )
58
+ mock_run_command .return_value = mocker .MagicMock (stdout = "output" , stderr = "error" , returncode = 0 )
59
+ mock_logger = mocker .patch ("bumpversion.hooks.logger" )
60
+
61
+ config , _ , _ = get_config_data ({"current_version" : "1.0.0" , f"{ suite_name } _hooks" : ["script1" , "script2" ]})
62
+
63
+ # Act
64
+ suite_func (config , * suite_args )
65
+
66
+ # Assert
67
+ mock_logger .info .assert_called_once_with (f"Running { suite_name } hooks:" .replace ("_" , "-" ))
68
+ mock_env .assert_called_once_with (config , * suite_args )
69
+ expected_run_command_calls = [
70
+ mocker .call ("script1" , env ),
71
+ mocker .call ("script2" , env ),
72
+ ]
73
+ mock_run_command .assert_has_calls (expected_run_command_calls )
74
+
75
+ @pytest .mark .parametrize (["suite_name" , "suite_func" , "suite_args" ], suites )
76
+ def test_does_not_run_hooks_if_none_are_specified (
77
+ self , mocker , suite_name : str , suite_func : Callable , suite_args : tuple
78
+ ):
79
+ """If no setup_hooks are defined, nothing is run."""
80
+ # Assemble
81
+ env = {"var" : "value" }
82
+ mock_env = mocker .patch (f"bumpversion.hooks.get_{ suite_name } _hook_env" )
83
+ mock_env .return_value = env
84
+ mock_run_command = mocker .patch ("bumpversion.hooks.run_command" )
85
+ mock_run_command .return_value = mocker .MagicMock (stdout = "output" , stderr = "error" , returncode = 0 )
86
+ mock_logger = mocker .patch ("bumpversion.hooks.logger" )
87
+
88
+ config , _ , _ = get_config_data ({"current_version" : "1.0.0" , f"{ suite_name } _hooks" : []})
89
+
90
+ # Act
91
+ suite_func (config , * suite_args )
92
+
93
+ # Asserts
94
+ mock_logger .info .assert_called_once_with (f"No { suite_name } hooks defined" .replace ("_" , "-" ))
95
+ mock_env .assert_called_once_with (config , * suite_args )
96
+ assert mock_run_command .call_count == 0
97
+
98
+ @pytest .mark .parametrize (["suite_name" , "suite_func" , "suite_args" ], suites )
99
+ def test_does_not_run_hooks_if_dry_run_is_true (
100
+ self , mocker , suite_name : str , suite_func : Callable , suite_args : tuple
101
+ ):
102
+ """If dry_run is True, nothing is run."""
103
+ # Assemble
104
+ env = {"var" : "value" }
105
+ mock_env = mocker .patch (f"bumpversion.hooks.get_{ suite_name } _hook_env" )
106
+ mock_env .return_value = env
107
+ mock_run_command = mocker .patch ("bumpversion.hooks.run_hooks" )
108
+ mock_logger = mocker .patch ("bumpversion.hooks.logger" )
109
+
110
+ config , _ , _ = get_config_data ({"current_version" : "1.0.0" , f"{ suite_name } _hooks" : ["script1" , "script2" ]})
111
+
112
+ # Act
113
+ args = [* suite_args , True ]
114
+ suite_func (config , * args )
115
+
116
+ # Asserts
117
+ mock_logger .info .assert_called_once_with (f"Would run { suite_name } hooks:" .replace ("_" , "-" ))
118
+ mock_env .assert_called_once_with (config , * suite_args )
119
+ assert mock_run_command .call_count == 1
0 commit comments