Skip to content

Commit 04469b3

Browse files
authored
Merge pull request #124 from Lee-W/add-test-cases
Add test cases
2 parents aae0fbd + 98d6e93 commit 04469b3

13 files changed

+478
-374
lines changed

commitizen/cli.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ def main():
179179
parser.print_help(sys.stderr)
180180
raise SystemExit()
181181

182+
# This is for the command required constraint in 2.0
182183
try:
183184
args = parser.parse_args()
184185
except TypeError:
@@ -195,7 +196,7 @@ def main():
195196
"'cz --version' will be deprecated in next major version. "
196197
"Please use 'cz version' command from your scripts"
197198
)
198-
logging.getLogger("commitizen").setLevel(logging.DEBUG)
199+
args.func = commands.Version
199200

200201
if args.debug:
201202
warnings.warn(
@@ -205,7 +206,9 @@ def main():
205206
logging.getLogger("commitizen").setLevel(logging.DEBUG)
206207

207208
# TODO: This try block can be removed after command is required in 2.0
209+
# Handle the case that argument is given, but no command is provided
208210
try:
209211
args.func(conf, vars(args))()
210212
except AttributeError:
211213
out.error("Command is required")
214+
raise SystemExit()

commitizen/commands/bump.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ def __call__(self):
7070
try:
7171
current_version_instance: Version = Version(self.parameters["version"])
7272
except TypeError:
73-
out.error("[NO_VERSION_SPECIFIED]")
74-
out.error("Check if current version is specified in config file, like:")
75-
out.error("version = 0.4.3")
73+
out.error(
74+
"[NO_VERSION_SPECIFIED]\n"
75+
"Check if current version is specified in config file, like:\n"
76+
"version = 0.4.3\n"
77+
)
7678
raise SystemExit(NO_VERSION_SPECIFIED)
7779

7880
# Initialize values from sources (conf)
@@ -96,8 +98,7 @@ def __call__(self):
9698
# No commits, there is no need to create an empty tag.
9799
# Unless we previously had a prerelease.
98100
if not commits and not current_version_instance.is_prerelease:
99-
out.error("[NO_COMMITS_FOUND]")
100-
out.error("No new commits found.")
101+
out.error("[NO_COMMITS_FOUND]\n" "No new commits found.")
101102
raise SystemExit(NO_COMMITS_FOUND)
102103

103104
if increment is None:

tests/commands/conftest.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import pytest
2+
3+
from commitizen import defaults
4+
from commitizen.config import BaseConfig
5+
6+
7+
@pytest.fixture()
8+
def config():
9+
_config = BaseConfig()
10+
_config.settings.update({"name": defaults.name})
11+
return _config

tests/commands/test_bump_command.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import sys
2+
import uuid
3+
from pathlib import Path
4+
from typing import Optional
5+
6+
import pytest
7+
8+
from commitizen import cli, cmd, git
9+
10+
11+
@pytest.fixture(scope="function")
12+
def tmp_git_project(tmpdir):
13+
with tmpdir.as_cwd():
14+
with open("pyproject.toml", "w") as f:
15+
f.write("[tool.commitizen]\n" 'version="0.1.0"')
16+
17+
cmd.run("git init")
18+
19+
yield
20+
21+
22+
def create_file_and_commit(message: str, filename: Optional[str] = None):
23+
if not filename:
24+
filename = str(uuid.uuid4())
25+
26+
Path(f"./{filename}").touch()
27+
cmd.run("git add .")
28+
git.commit(message)
29+
30+
31+
@pytest.mark.usefixtures("tmp_git_project")
32+
def test_bump_command(mocker):
33+
# MINOR
34+
create_file_and_commit("feat: new file")
35+
36+
testargs = ["cz", "bump", "--yes"]
37+
mocker.patch.object(sys, "argv", testargs)
38+
cli.main()
39+
40+
tag_exists = git.tag_exist("0.2.0")
41+
assert tag_exists is True
42+
43+
# PATCH
44+
create_file_and_commit("fix: username exception")
45+
46+
testargs = ["cz", "bump"]
47+
mocker.patch.object(sys, "argv", testargs)
48+
cli.main()
49+
50+
tag_exists = git.tag_exist("0.2.1")
51+
assert tag_exists is True
52+
53+
# PRERELEASE
54+
create_file_and_commit("feat: location")
55+
56+
testargs = ["cz", "bump", "--prerelease", "alpha"]
57+
mocker.patch.object(sys, "argv", testargs)
58+
cli.main()
59+
60+
tag_exists = git.tag_exist("0.3.0a0")
61+
assert tag_exists is True
62+
63+
# PRERELEASE BUMP CREATES VERSION WITHOUT PRERELEASE
64+
testargs = ["cz", "bump"]
65+
mocker.patch.object(sys, "argv", testargs)
66+
cli.main()
67+
68+
tag_exists = git.tag_exist("0.3.0")
69+
assert tag_exists is True
70+
71+
# MAJOR
72+
create_file_and_commit(
73+
"feat: new user interface\n\nBREAKING CHANGE: age is no longer supported"
74+
)
75+
76+
testargs = ["cz", "bump"]
77+
mocker.patch.object(sys, "argv", testargs)
78+
cli.main()
79+
80+
tag_exists = git.tag_exist("1.0.0")
81+
assert tag_exists is True
82+
83+
84+
def test_bump_when_bumpping_is_not_support(mocker, capsys, tmpdir):
85+
with tmpdir.as_cwd():
86+
with open("./pyproject.toml", "w") as f:
87+
f.write("[tool.commitizen]\n" 'version="0.1.0"')
88+
89+
cmd.run("git init")
90+
create_file_and_commit(
91+
"feat: new user interface\n\nBREAKING CHANGE: age is no longer supported"
92+
)
93+
94+
testargs = ["cz", "-n", "cz_jira", "bump", "--yes"]
95+
mocker.patch.object(sys, "argv", testargs)
96+
97+
with pytest.raises(SystemExit):
98+
cli.main()
99+
100+
_, err = capsys.readouterr()
101+
assert "'cz_jira' rule does not support bump" in err
102+
103+
104+
def test_bump_is_not_specify(mocker, capsys, tmpdir):
105+
mocker.patch.object(sys, "argv", ["cz", "bump"])
106+
107+
with pytest.raises(SystemExit):
108+
with tmpdir.as_cwd():
109+
cli.main()
110+
111+
expected_error_message = (
112+
"[NO_VERSION_SPECIFIED]\n"
113+
"Check if current version is specified in config file, like:\n"
114+
"version = 0.4.3\n"
115+
)
116+
117+
_, err = capsys.readouterr()
118+
assert expected_error_message in err
119+
120+
121+
def test_bump_when_not_new_commit(mocker, capsys, tmp_git_project):
122+
testargs = ["cz", "bump", "--yes"]
123+
mocker.patch.object(sys, "argv", testargs)
124+
125+
with pytest.raises(SystemExit):
126+
cli.main()
127+
128+
expected_error_message = "[NO_COMMITS_FOUND]\n" "No new commits found."
129+
_, err = capsys.readouterr()
130+
assert expected_error_message in err

tests/test_check_command.py renamed to tests/commands/test_check_command.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44

55
from commitizen import cli
6+
from commitizen import commands
67

78

89
def test_check_jira_fails(mocker, capsys):
@@ -76,3 +77,34 @@ def test_check_conventional_commit_succeeds(mocker, capsys):
7677
cli.main()
7778
out, _ = capsys.readouterr()
7879
assert "Commit validation: successful!" in out
80+
81+
82+
def test_check_no_conventional_commit(config, mocker, tmpdir):
83+
with pytest.raises(SystemExit):
84+
error_mock = mocker.patch("commitizen.out.error")
85+
86+
tempfile = tmpdir.join("temp_commit_file")
87+
tempfile.write("no conventional commit")
88+
89+
check_cmd = commands.Check(
90+
config=config, arguments={"commit_msg_file": tempfile}
91+
)
92+
check_cmd()
93+
error_mock.assert_called_once()
94+
95+
96+
def test_check_conventional_commit(config, mocker, tmpdir):
97+
success_mock = mocker.patch("commitizen.out.success")
98+
99+
tempfile = tmpdir.join("temp_commit_file")
100+
tempfile.write("feat(lang): added polish language")
101+
102+
check_cmd = commands.Check(config=config, arguments={"commit_msg_file": tempfile})
103+
104+
check_cmd()
105+
success_mock.assert_called_once()
106+
107+
108+
def test_check_command_when_commit_file_not_found(config):
109+
with pytest.raises(FileNotFoundError):
110+
commands.Check(config=config, arguments={"commit_msg_file": ""})()

tests/commands/test_commit_command.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import os
2+
3+
import pytest
4+
5+
from commitizen import cmd, commands
6+
from commitizen.cz.exceptions import CzException
7+
8+
9+
@pytest.fixture
10+
def staging_is_clean(mocker):
11+
is_staging_clean_mock = mocker.patch("commitizen.git.is_staging_clean")
12+
is_staging_clean_mock.return_value = False
13+
14+
15+
@pytest.mark.usefixtures("staging_is_clean")
16+
def test_commit(config, mocker):
17+
prompt_mock = mocker.patch("questionary.prompt")
18+
prompt_mock.return_value = {
19+
"prefix": "feat",
20+
"subject": "user created",
21+
"scope": "",
22+
"is_breaking_change": False,
23+
"body": "",
24+
"footer": "",
25+
}
26+
27+
commit_mock = mocker.patch("commitizen.git.commit")
28+
commit_mock.return_value = cmd.Command("success", "", "", "")
29+
success_mock = mocker.patch("commitizen.out.success")
30+
31+
commands.Commit(config, {})()
32+
success_mock.assert_called_once()
33+
34+
35+
@pytest.mark.usefixtures("staging_is_clean")
36+
def test_commit_retry_fails_no_backup(config, mocker):
37+
commit_mock = mocker.patch("commitizen.git.commit")
38+
commit_mock.return_value = cmd.Command("success", "", "", "")
39+
40+
with pytest.raises(SystemExit):
41+
commands.Commit(config, {"retry": True})()
42+
43+
44+
@pytest.mark.usefixtures("staging_is_clean")
45+
def test_commit_retry_works(config, mocker):
46+
prompt_mock = mocker.patch("questionary.prompt")
47+
prompt_mock.return_value = {
48+
"prefix": "feat",
49+
"subject": "user created",
50+
"scope": "",
51+
"is_breaking_change": False,
52+
"body": "closes #21",
53+
"footer": "",
54+
}
55+
56+
commit_mock = mocker.patch("commitizen.git.commit")
57+
commit_mock.return_value = cmd.Command("", "error", "", "")
58+
error_mock = mocker.patch("commitizen.out.error")
59+
60+
with pytest.raises(SystemExit):
61+
commit_cmd = commands.Commit(config, {})
62+
temp_file = commit_cmd.temp_file
63+
commit_cmd()
64+
65+
prompt_mock.assert_called_once()
66+
error_mock.assert_called_once()
67+
assert os.path.isfile(temp_file)
68+
69+
# Previous commit failed, so retry should pick up the backup commit
70+
# commit_mock = mocker.patch("commitizen.git.commit")
71+
commit_mock.return_value = cmd.Command("success", "", "", "")
72+
success_mock = mocker.patch("commitizen.out.success")
73+
74+
commands.Commit(config, {"retry": True})()
75+
76+
commit_mock.assert_called_with("feat: user created\n\ncloses #21")
77+
prompt_mock.assert_called_once()
78+
success_mock.assert_called_once()
79+
assert not os.path.isfile(temp_file)
80+
81+
82+
@pytest.mark.usefixtures("staging_is_clean")
83+
def test_commit_command_with_dry_run_option(config, mocker):
84+
prompt_mock = mocker = mocker.patch("questionary.prompt")
85+
prompt_mock.return_value = {
86+
"prefix": "feat",
87+
"subject": "user created",
88+
"scope": "",
89+
"is_breaking_change": False,
90+
"body": "closes #57",
91+
"footer": "",
92+
}
93+
94+
with pytest.raises(SystemExit):
95+
commit_cmd = commands.Commit(config, {"dry_run": True})
96+
commit_cmd()
97+
98+
99+
def test_commit_when_nothing_to_commit(config, mocker):
100+
is_staging_clean_mock = mocker.patch("commitizen.git.is_staging_clean")
101+
is_staging_clean_mock.return_value = True
102+
103+
with pytest.raises(SystemExit) as err:
104+
commit_cmd = commands.Commit(config, {})
105+
commit_cmd()
106+
107+
assert err.value.code == commands.commit.NOTHING_TO_COMMIT
108+
109+
110+
@pytest.mark.usefixtures("staging_is_clean")
111+
def test_commit_when_customized_expected_raised(config, mocker, capsys):
112+
_err = ValueError()
113+
_err.__context__ = CzException("This is the root custom err")
114+
prompt_mock = mocker.patch("questionary.prompt")
115+
prompt_mock.side_effect = _err
116+
117+
with pytest.raises(SystemExit) as err:
118+
commit_cmd = commands.Commit(config, {})
119+
commit_cmd()
120+
121+
assert err.value.code == commands.commit.CUSTOM_ERROR
122+
123+
# Assert only the content in the formatted text
124+
captured = capsys.readouterr()
125+
assert "This is the root custom err" in captured.err

0 commit comments

Comments
 (0)