From 460b1bb74eb77005d61a44b08a27e319359d57ae Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Mon, 5 Jan 2026 14:20:22 +0100 Subject: [PATCH] test(utils): uses `util` fixture for all git operations and cli executions --- tests/commands/test_bump_command.py | 740 +++++++++-------------- tests/commands/test_changelog_command.py | 15 +- tests/commands/test_check_command.py | 121 ++-- tests/commands/test_common_command.py | 10 +- tests/providers/test_scm_provider.py | 76 +-- tests/test_bump_create_commit_message.py | 35 +- tests/test_cli.py | 60 +- tests/test_git.py | 237 ++++---- tests/utils.py | 54 +- 9 files changed, 521 insertions(+), 827 deletions(-) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index d8cac56f75..c781e25263 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -2,7 +2,6 @@ import inspect import re -import sys from pathlib import Path from textwrap import dedent from typing import TYPE_CHECKING @@ -11,7 +10,7 @@ import pytest import commitizen.commands.bump as bump -from commitizen import cli, cmd, defaults, git, hooks +from commitizen import cmd, defaults, git, hooks from commitizen.config.base_config import BaseConfig from commitizen.exceptions import ( BumpTagFailedError, @@ -28,7 +27,6 @@ NotAllowed, NoVersionSpecifiedError, ) -from tests.utils import create_file_and_commit, create_tag if TYPE_CHECKING: import py @@ -36,6 +34,7 @@ from commitizen.changelog_formats import ChangelogFormat from commitizen.cz.base import BaseCommitizen + from tests.utils import UtilFixture @pytest.mark.parametrize( @@ -50,22 +49,18 @@ ), ) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_patch_increment(commit_msg, mocker: MockFixture): - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_patch_increment(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.1.1") assert tag_exists is True @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_minor_increment(commit_msg, mocker: MockFixture): - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_minor_increment(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") cmd_res = cmd.run('git for-each-ref refs/tags --format "%(objecttype):%(refname)"') assert tag_exists is True and "commit:refs/tags/0.2.0\n" in cmd_res.out @@ -73,11 +68,9 @@ def test_bump_minor_increment(commit_msg, mocker: MockFixture): @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_minor_increment_annotated(commit_msg, mocker: MockFixture): - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes", "--annotated-tag"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_minor_increment_annotated(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes", "--annotated-tag") tag_exists = git.tag_exist("0.2.0") cmd_res = cmd.run('git for-each-ref refs/tags --format "%(objecttype):%(refname)"') assert tag_exists is True and "tag:refs/tags/0.2.0\n" in cmd_res.out @@ -88,11 +81,9 @@ def test_bump_minor_increment_annotated(commit_msg, mocker: MockFixture): @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) @pytest.mark.usefixtures("tmp_commitizen_project_with_gpg") -def test_bump_minor_increment_signed(commit_msg, mocker: MockFixture): - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes", "--gpg-sign"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_minor_increment_signed(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes", "--gpg-sign") tag_exists = git.tag_exist("0.2.0") cmd_res = cmd.run('git for-each-ref refs/tags --format "%(objecttype):%(refname)"') assert tag_exists is True and "tag:refs/tags/0.2.0\n" in cmd_res.out @@ -103,16 +94,14 @@ def test_bump_minor_increment_signed(commit_msg, mocker: MockFixture): @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) def test_bump_minor_increment_annotated_config_file( - commit_msg, mocker: MockFixture, tmp_commitizen_project + commit_msg: str, util: UtilFixture, tmp_commitizen_project ): tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") tmp_commitizen_cfg_file.write( f"{tmp_commitizen_cfg_file.read()}\nannotated_tag = 1" ) - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") cmd_res = cmd.run('git for-each-ref refs/tags --format "%(objecttype):%(refname)"') assert tag_exists is True and "tag:refs/tags/0.2.0\n" in cmd_res.out @@ -123,14 +112,12 @@ def test_bump_minor_increment_annotated_config_file( @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) def test_bump_minor_increment_signed_config_file( - commit_msg, mocker: MockFixture, tmp_commitizen_project_with_gpg + commit_msg: str, util: UtilFixture, tmp_commitizen_project_with_gpg ): tmp_commitizen_cfg_file = tmp_commitizen_project_with_gpg.join("pyproject.toml") tmp_commitizen_cfg_file.write(f"{tmp_commitizen_cfg_file.read()}\ngpg_sign = 1") - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") cmd_res = cmd.run('git for-each-ref refs/tags --format "%(objecttype):%(refname)"') assert tag_exists is True and "tag:refs/tags/0.2.0\n" in cmd_res.out @@ -153,12 +140,10 @@ def test_bump_minor_increment_signed_config_file( "BREAKING-CHANGE: age is no longer supported", ), ) -def test_bump_major_increment(commit_msg, mocker: MockFixture): - create_file_and_commit(commit_msg) +def test_bump_major_increment(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("1.0.0") assert tag_exists is True @@ -178,12 +163,10 @@ def test_bump_major_increment(commit_msg, mocker: MockFixture): "BREAKING-CHANGE: age is no longer supported", ), ) -def test_bump_major_increment_major_version_zero(commit_msg, mocker): - create_file_and_commit(commit_msg) +def test_bump_major_increment_major_version_zero(commit_msg: str, util: UtilFixture): + util.create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes", "--major-version-zero"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes", "--major-version-zero") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -200,43 +183,35 @@ def test_bump_major_increment_major_version_zero(commit_msg, mocker): ], ) def test_bump_command_increment_option( - commit_msg, increment, expected_tag, mocker: MockFixture + commit_msg: str, increment: str, expected_tag: str, util: UtilFixture ): - create_file_and_commit(commit_msg) + util.create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--increment", increment, "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--increment", increment, "--yes") tag_exists = git.tag_exist(expected_tag) assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prerelease(mocker: MockFixture): - create_file_and_commit("feat: location") +def test_bump_command_prerelease(util: UtilFixture): + util.create_file_and_commit("feat: location") # Create an alpha pre-release. - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0a0") assert tag_exists is True # Create a beta pre-release. - testargs = ["cz", "bump", "--prerelease", "beta", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "beta", "--yes") tag_exists = git.tag_exist("0.2.0b0") assert tag_exists is True # With a current beta pre-release, bumping alpha must bump beta # because we can't bump "backwards". - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0a1") assert tag_exists is False @@ -244,17 +219,13 @@ def test_bump_command_prerelease(mocker: MockFixture): assert tag_exists is True # Create a rc pre-release. - testargs = ["cz", "bump", "--prerelease", "rc", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "rc", "--yes") tag_exists = git.tag_exist("0.2.0rc0") assert tag_exists is True # With a current rc pre-release, bumping alpha must bump rc. - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0a1") assert tag_exists is False @@ -264,9 +235,7 @@ def test_bump_command_prerelease(mocker: MockFixture): assert tag_exists is True # With a current rc pre-release, bumping beta must bump rc. - testargs = ["cz", "bump", "--prerelease", "beta", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "beta", "--yes") tag_exists = git.tag_exist("0.2.0a2") assert tag_exists is False @@ -276,115 +245,81 @@ def test_bump_command_prerelease(mocker: MockFixture): assert tag_exists is True # Create a final release from the current pre-release. - testargs = ["cz", "bump"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prerelease_increment(mocker: MockFixture): +def test_bump_command_prerelease_increment(util: UtilFixture): # FINAL RELEASE - create_file_and_commit("fix: location") + util.create_file_and_commit("fix: location") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") assert git.tag_exist("0.1.1") # PRERELEASE - create_file_and_commit("fix: location") + util.create_file_and_commit("fix: location") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") assert git.tag_exist("0.1.2a0") - create_file_and_commit("feat: location") + util.create_file_and_commit("feat: location") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") assert git.tag_exist("0.2.0a0") - create_file_and_commit("feat!: breaking") + util.create_file_and_commit("feat!: breaking") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") assert git.tag_exist("1.0.0a0") @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prerelease_exact_mode(mocker: MockFixture): +def test_bump_command_prerelease_exact_mode(util: UtilFixture): # PRERELEASE - create_file_and_commit("feat: location") + util.create_file_and_commit("feat: location") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0a0") assert tag_exists is True # PRERELEASE + PATCH BUMP - testargs = [ - "cz", - "bump", - "--prerelease", - "alpha", - "--yes", - "--increment-mode=exact", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() - + util.run_cli("bump", "--prerelease", "alpha", "--yes", "--increment-mode=exact") tag_exists = git.tag_exist("0.2.0a1") assert tag_exists is True # PRERELEASE + MINOR BUMP # --increment-mode allows the minor version to bump, and restart the prerelease - create_file_and_commit("feat: location") + util.create_file_and_commit("feat: location") - testargs = [ - "cz", - "bump", - "--prerelease", - "alpha", - "--yes", - "--increment-mode=exact", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes", "--increment-mode=exact") tag_exists = git.tag_exist("0.3.0a0") assert tag_exists is True # PRERELEASE + MAJOR BUMP # --increment-mode=exact allows the major version to bump, and restart the prerelease - testargs = [ - "cz", + util.run_cli( "bump", "--prerelease", "alpha", "--yes", "--increment=MAJOR", "--increment-mode=exact", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() + ) tag_exists = git.tag_exist("1.0.0a0") assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): +def test_bump_on_git_with_hooks_no_verify_disabled(util: UtilFixture): """Bump commit without --no-verify""" cmd.run("mkdir .git/hooks") with open(".git/hooks/pre-commit", "w", encoding="utf-8") as f: @@ -392,103 +327,84 @@ def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): cmd.run("chmod +x .git/hooks/pre-commit") # MINOR - create_file_and_commit("feat: new file") - - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat: new file") - cli.main() + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_tag_exists_raises_exception(mocker: MockFixture): +def test_bump_tag_exists_raises_exception(util: UtilFixture): cmd.run("mkdir .git/hooks") with open(".git/hooks/post-commit", "w", encoding="utf-8") as f: f.write("#!/usr/bin/env bash\nexit 9") cmd.run("chmod +x .git/hooks/post-commit") # MINOR - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") git.tag("0.2.0") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - with pytest.raises(BumpTagFailedError) as excinfo: - cli.main() + util.run_cli("bump", "--yes") assert "0.2.0" in str(excinfo.value) # This should be a fatal error @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_on_git_with_hooks_no_verify_enabled(mocker: MockFixture): +def test_bump_on_git_with_hooks_no_verify_enabled(util: UtilFixture): cmd.run("mkdir .git/hooks") with open(".git/hooks/pre-commit", "w", encoding="utf-8") as f: f.write('#!/usr/bin/env bash\necho "0.1.0"') cmd.run("chmod +x .git/hooks/pre-commit") # MINOR - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes", "--no-verify"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes", "--no-verify") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_when_bumping_is_not_support(mocker: MockFixture): - create_file_and_commit( +def test_bump_when_bumping_is_not_support(util: UtilFixture): + util.create_file_and_commit( "feat: new user interface\n\nBREAKING CHANGE: age is no longer supported" ) - testargs = ["cz", "-n", "cz_jira", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - with pytest.raises(NoPatternMapError) as excinfo: - cli.main() + util.run_cli("-n", "cz_jira", "bump", "--yes") assert "'cz_jira' rule does not support bump" in str(excinfo.value) @pytest.mark.usefixtures("tmp_git_project") -def test_bump_when_version_is_not_specify(mocker: MockFixture): - mocker.patch.object(sys, "argv", ["cz", "bump"]) - +def test_bump_when_version_is_not_specify(util: UtilFixture): with pytest.raises(NoVersionSpecifiedError) as excinfo: - cli.main() + util.run_cli("bump") assert NoVersionSpecifiedError.message in str(excinfo.value) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_when_no_new_commit(mocker: MockFixture): +def test_bump_when_no_new_commit(util: UtilFixture): """bump without any commits since the last bump.""" # We need this first commit otherwise the revision is invalid. - create_file_and_commit("feat: initial") - - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat: initial") - # First bump. - # The next bump should fail since - # there is not a commit between the two bumps. - cli.main() + util.run_cli("bump", "--yes") # bump without a new commit. with pytest.raises(NoCommitsFoundError) as excinfo: - cli.main() + util.run_cli("bump", "--yes") expected_error_message = "[NO_COMMITS_FOUND]\nNo new commits found." assert expected_error_message in str(excinfo.value) def test_bump_when_version_inconsistent_in_version_files( - tmp_commitizen_project, mocker: MockFixture + tmp_commitizen_project, util: UtilFixture ): tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_version_file.write("100.999.10000") @@ -499,19 +415,18 @@ def test_bump_when_version_inconsistent_in_version_files( f'version_files = ["{tmp_version_file_string}"]' ) - create_file_and_commit("feat: new file") - - testargs = ["cz", "bump", "--yes", "--check-consistency"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat: new file") with pytest.raises(CurrentVersionNotFoundError) as excinfo: - cli.main() + util.run_cli("bump", "--yes", "--check-consistency") partial_expected_error_message = "Current version 0.1.0 is not found in" assert partial_expected_error_message in str(excinfo.value) -def test_bump_major_version_zero_when_major_is_not_zero(mocker, tmp_commitizen_project): +def test_bump_major_version_zero_when_major_is_not_zero( + tmp_commitizen_project, util: UtilFixture +): tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_version_file.write("1.0.0") tmp_version_file_string = str(tmp_version_file).replace("\\", "/") @@ -524,15 +439,12 @@ def test_bump_major_version_zero_when_major_is_not_zero(mocker, tmp_commitizen_p tmp_changelog_file = tmp_commitizen_project.join("CHANGELOG.md") tmp_changelog_file.write("## v1.0.0") - create_file_and_commit("feat(user): new file") - create_tag("v1.0.0") - create_file_and_commit("feat(user)!: new file") - - testargs = ["cz", "bump", "--yes", "--major-version-zero"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat(user): new file") + util.create_tag("v1.0.0") + util.create_file_and_commit("feat(user)!: new file") with pytest.raises(NotAllowed) as excinfo: - cli.main() + util.run_cli("bump", "--yes", "--major-version-zero") expected_error_message = ( "--major-version-zero is meaningless for current version 1.0.0" @@ -540,7 +452,7 @@ def test_bump_major_version_zero_when_major_is_not_zero(mocker, tmp_commitizen_p assert expected_error_message in str(excinfo.value) -def test_bump_files_only(mocker: MockFixture, tmp_commitizen_project): +def test_bump_files_only(tmp_commitizen_project, util: UtilFixture): tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_version_file.write("0.1.0") tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") @@ -550,18 +462,14 @@ def test_bump_files_only(mocker: MockFixture, tmp_commitizen_project): f'version_files = ["{tmp_version_file_string}"]' ) - create_file_and_commit("feat: new user interface") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat: new user interface") + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True - create_file_and_commit("feat: another new feature") - testargs = ["cz", "bump", "--yes", "--files-only"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat: another new feature") with pytest.raises(ExpectedExit): - cli.main() + util.run_cli("bump", "--yes", "--files-only") tag_exists = git.tag_exist("0.3.0") assert tag_exists is False @@ -573,7 +481,7 @@ def test_bump_files_only(mocker: MockFixture, tmp_commitizen_project): assert "0.3.0" in f.read() -def test_bump_local_version(mocker: MockFixture, tmp_commitizen_project): +def test_bump_local_version(tmp_commitizen_project, util: UtilFixture): tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_version_file.write("4.5.1+0.1.0") tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") @@ -584,10 +492,8 @@ def test_bump_local_version(mocker: MockFixture, tmp_commitizen_project): f'version_files = ["{tmp_version_file_string}"]' ) - create_file_and_commit("feat: new user interface") - testargs = ["cz", "bump", "--yes", "--local-version"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat: new user interface") + util.run_cli("bump", "--yes", "--local-version") tag_exists = git.tag_exist("4.5.1+0.2.0") assert tag_exists is True @@ -596,13 +502,11 @@ def test_bump_local_version(mocker: MockFixture, tmp_commitizen_project): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_dry_run(mocker: MockFixture, capsys): - create_file_and_commit("feat: new file") +def test_bump_dry_run(util: UtilFixture, capsys): + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes", "--dry-run"] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(DryRunExit): - cli.main() + util.run_cli("bump", "--yes", "--dry-run") out, _ = capsys.readouterr() assert "0.2.0" in out @@ -611,14 +515,11 @@ def test_bump_dry_run(mocker: MockFixture, capsys): assert tag_exists is False -def test_bump_in_non_git_project(tmpdir, config, mocker: MockFixture): - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - +def test_bump_in_non_git_project(tmpdir, config, util: UtilFixture): with tmpdir.as_cwd(): with pytest.raises(NotAGitProjectError): with pytest.raises(ExpectedExit): - cli.main() + util.run_cli("bump", "--yes") def test_none_increment_exit_should_be_a_class(): @@ -639,11 +540,9 @@ def test_none_increment_exit_is_exception(): @pytest.mark.usefixtures("tmp_commitizen_project") def test_none_increment_should_not_call_git_tag_and_error_code_is_not_zero( - mocker: MockFixture, + mocker: MockFixture, util: UtilFixture ): - create_file_and_commit("test(test_get_all_droplets): fix bad comparison test") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("test(test_get_all_droplets): fix bad comparison test") # stash git.tag for later restore stashed_git_tag = git.tag @@ -651,7 +550,7 @@ def test_none_increment_should_not_call_git_tag_and_error_code_is_not_zero( git.tag = MagicMock(return_value=dummy_value) with pytest.raises(NoneIncrementExit) as e: - cli.main() + util.run_cli("bump", "--yes") git.tag.assert_not_called() assert e.value.exit_code == ExitCode.NO_INCREMENT @@ -661,11 +560,9 @@ def test_none_increment_should_not_call_git_tag_and_error_code_is_not_zero( @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_with_changelog_arg(mocker: MockFixture, changelog_path): - create_file_and_commit("feat(user): new file") - testargs = ["cz", "bump", "--yes", "--changelog"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_with_changelog_arg(util: UtilFixture, changelog_path): + util.create_file_and_commit("feat(user): new file") + util.run_cli("bump", "--yes", "--changelog") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -676,14 +573,12 @@ def test_bump_with_changelog_arg(mocker: MockFixture, changelog_path): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_with_changelog_config(mocker: MockFixture, changelog_path, config_path): - create_file_and_commit("feat(user): new file") +def test_bump_with_changelog_config(util: UtilFixture, changelog_path, config_path): + util.create_file_and_commit("feat(user): new file") with open(config_path, "a", encoding="utf-8") as fp: fp.write("update_changelog_on_bump = true\n") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -694,23 +589,18 @@ def test_bump_with_changelog_config(mocker: MockFixture, changelog_path, config_ @pytest.mark.usefixtures("tmp_commitizen_project") -def test_prevent_prerelease_when_no_increment_detected(mocker: MockFixture, capsys): - create_file_and_commit("feat: new file") - - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) +def test_prevent_prerelease_when_no_increment_detected(util: UtilFixture, capsys): + util.create_file_and_commit("feat: new file") - cli.main() + util.run_cli("bump", "--yes") out, _ = capsys.readouterr() assert "0.2.0" in out - create_file_and_commit("test: new file") - testargs = ["cz", "bump", "-pr", "beta"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("test: new file") with pytest.raises(NoCommitsFoundError) as excinfo: - cli.main() + util.run_cli("bump", "-pr", "beta") expected_error_message = ( "[NO_COMMITS_FOUND]\nNo commits found to generate a pre-release." @@ -719,11 +609,9 @@ def test_prevent_prerelease_when_no_increment_detected(mocker: MockFixture, caps @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_with_changelog_to_stdout_arg(mocker: MockFixture, capsys, changelog_path): - create_file_and_commit("feat(user): this should appear in stdout") - testargs = ["cz", "bump", "--yes", "--changelog-to-stdout"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_with_changelog_to_stdout_arg(util: UtilFixture, capsys, changelog_path): + util.create_file_and_commit("feat(user): this should appear in stdout") + util.run_cli("bump", "--yes", "--changelog-to-stdout") out, _ = capsys.readouterr() assert "this should appear in stdout" in out @@ -738,15 +626,13 @@ def test_bump_with_changelog_to_stdout_arg(mocker: MockFixture, capsys, changelo @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_with_changelog_to_stdout_dry_run_arg( - mocker: MockFixture, capsys, changelog_path + util: UtilFixture, capsys, changelog_path ): - create_file_and_commit( + util.create_file_and_commit( "feat(user): this should appear in stdout with dry-run enabled" ) - testargs = ["cz", "bump", "--yes", "--changelog-to-stdout", "--dry-run"] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(DryRunExit): - cli.main() + util.run_cli("bump", "--yes", "--changelog-to-stdout", "--dry-run") out, _ = capsys.readouterr() tag_exists = git.tag_exist("0.2.0") @@ -757,11 +643,9 @@ def test_bump_with_changelog_to_stdout_dry_run_arg( @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_without_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_path): - create_file_and_commit("feat(user): this should appear in stdout") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_without_git_to_stdout_arg(util: UtilFixture, capsys, changelog_path): + util.create_file_and_commit("feat(user): this should appear in stdout") + util.run_cli("bump", "--yes") out, _ = capsys.readouterr() assert ( @@ -771,11 +655,9 @@ def test_bump_without_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_p @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_with_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_path): - create_file_and_commit("feat(user): this should appear in stdout") - testargs = ["cz", "bump", "--yes", "--git-output-to-stderr"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_bump_with_git_to_stdout_arg(util: UtilFixture, capsys, changelog_path): + util.create_file_and_commit("feat(user): this should appear in stdout") + util.run_cli("bump", "--yes", "--git-output-to-stderr") out, _ = capsys.readouterr() assert ( @@ -831,9 +713,8 @@ def test_bump_with_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_path @pytest.mark.parametrize( "cli_bump_changelog_args", [ - ("cz", "bump", "--changelog", "--yes"), + ("bump", "--changelog", "--yes"), ( - "cz", "bump", "--changelog", "--changelog-to-stdout", @@ -842,11 +723,13 @@ def test_bump_with_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_path "--yes", ), ], - ids=lambda cmd_tuple: " ".join(cmd_tuple), + ids=lambda cmd_tuple: " ".join(["cz", *cmd_tuple]) + if isinstance(cmd_tuple, tuple) + else cmd_tuple, ) def test_bump_changelog_command_commits_untracked_changelog_and_version_files( tmp_commitizen_project, - mocker, + util: UtilFixture, cli_bump_changelog_args: tuple[str, ...], version_filepath: str, version_regex: str, @@ -872,10 +755,9 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files( ) as version_file: version_file.write(version_file_content) - create_file_and_commit("fix: some test commit") + util.create_file_and_commit("fix: some test commit") - mocker.patch.object(sys, "argv", cli_bump_changelog_args) - cli.main() + util.run_cli(*cli_bump_changelog_args) commit_file_names = git.get_filenames_in_commit() assert "CHANGELOG.md" in commit_file_names @@ -885,21 +767,19 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files( @pytest.mark.parametrize( "testargs", [ - ["cz", "bump", "--local-version", "1.2.3"], - ["cz", "bump", "--prerelease", "rc", "1.2.3"], - ["cz", "bump", "--devrelease", "0", "1.2.3"], - ["cz", "bump", "--devrelease", "1", "1.2.3"], - ["cz", "bump", "--increment", "PATCH", "1.2.3"], - ["cz", "bump", "--build-metadata=a.b.c", "1.2.3"], - ["cz", "bump", "--local-version", "--build-metadata=a.b.c"], + ["--local-version", "1.2.3"], + ["--prerelease", "rc", "1.2.3"], + ["--devrelease", "0", "1.2.3"], + ["--devrelease", "1", "1.2.3"], + ["--increment", "PATCH", "1.2.3"], + ["--build-metadata=a.b.c", "1.2.3"], + ["--local-version", "--build-metadata=a.b.c"], ], ) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_invalid_manual_args_raises_exception(mocker, testargs): - mocker.patch.object(sys, "argv", testargs) - +def test_bump_invalid_manual_args_raises_exception(util: UtilFixture, testargs): with pytest.raises(NotAllowed): - cli.main() + util.run_cli("bump", *testargs) @pytest.mark.usefixtures("tmp_commitizen_project") @@ -910,14 +790,13 @@ def test_bump_invalid_manual_args_raises_exception(mocker, testargs): "1.2..3", ], ) -def test_bump_invalid_manual_version_raises_exception(mocker, manual_version): - create_file_and_commit("feat: new file") - - testargs = ["cz", "bump", "--yes", manual_version] - mocker.patch.object(sys, "argv", testargs) +def test_bump_invalid_manual_version_raises_exception( + util: UtilFixture, manual_version +): + util.create_file_and_commit("feat: new file") with pytest.raises(InvalidManualVersion) as excinfo: - cli.main() + util.run_cli("bump", "--yes", manual_version) expected_error_message = ( f"[INVALID_MANUAL_VERSION]\nInvalid manual version: '{manual_version}'" @@ -939,26 +818,22 @@ def test_bump_invalid_manual_version_raises_exception(mocker, manual_version): "1.0.0", ], ) -def test_bump_manual_version(mocker, manual_version): - create_file_and_commit("feat: new file") +def test_bump_manual_version(util: UtilFixture, manual_version): + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes", manual_version] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes", manual_version) tag_exists = git.tag_exist(manual_version) assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_manual_version_disallows_major_version_zero(mocker): - create_file_and_commit("feat: new file") +def test_bump_manual_version_disallows_major_version_zero(util: UtilFixture): + util.create_file_and_commit("feat: new file") manual_version = "0.2.0" - testargs = ["cz", "bump", "--yes", "--major-version-zero", manual_version] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(NotAllowed) as excinfo: - cli.main() + util.run_cli("bump", "--yes", "--major-version-zero", manual_version) expected_error_message = ( "--major-version-zero cannot be combined with MANUAL_VERSION" @@ -968,7 +843,7 @@ def test_bump_manual_version_disallows_major_version_zero(mocker): @pytest.mark.parametrize("commit_msg", ("feat: new file", "feat(user): new file")) def test_bump_with_pre_bump_hooks( - commit_msg, mocker: MockFixture, tmp_commitizen_project + commit_msg, mocker: MockFixture, tmp_commitizen_project, util: UtilFixture ): pre_bump_hook = "scripts/pre_bump_hook.sh" post_bump_hook = "scripts/post_bump_hook.sh" @@ -983,10 +858,8 @@ def test_bump_with_pre_bump_hooks( run_mock = mocker.Mock() mocker.patch.object(hooks, "run", run_mock) - create_file_and_commit(commit_msg) - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit(commit_msg) + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -1021,7 +894,9 @@ def test_bump_with_pre_bump_hooks( ) -def test_bump_with_hooks_and_increment(mocker: MockFixture, tmp_commitizen_project): +def test_bump_with_hooks_and_increment( + mocker: MockFixture, tmp_commitizen_project, util: UtilFixture +): pre_bump_hook = "scripts/pre_bump_hook.sh" post_bump_hook = "scripts/post_bump_hook.sh" @@ -1035,28 +910,23 @@ def test_bump_with_hooks_and_increment(mocker: MockFixture, tmp_commitizen_proje run_mock = mocker.Mock() mocker.patch.object(hooks, "run", run_mock) - create_file_and_commit("test: some test") - testargs = ["cz", "bump", "--yes", "--increment", "MINOR"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("test: some test") + util.run_cli("bump", "--yes", "--increment", "MINOR") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @pytest.mark.usefixtures("tmp_git_project") -def test_bump_use_version_provider(mocker: MockFixture): +def test_bump_use_version_provider(mocker: MockFixture, util: UtilFixture): mock = mocker.MagicMock(name="provider") mock.get_version.return_value = "0.0.0" get_provider = mocker.patch( "commitizen.commands.bump.get_provider", return_value=mock ) - create_file_and_commit("fix: fake commit") - testargs = ["cz", "bump", "--yes", "--changelog"] - mocker.patch.object(sys, "argv", testargs) - - cli.main() + util.create_file_and_commit("fix: fake commit") + util.run_cli("bump", "--yes", "--changelog") assert git.tag_exist("0.0.1") get_provider.assert_called_once() @@ -1065,23 +935,20 @@ def test_bump_use_version_provider(mocker: MockFixture): def test_bump_command_prerelease_scheme_via_cli( - tmp_commitizen_project_initial, mocker: MockFixture + tmp_commitizen_project_initial, util: UtilFixture ): tmp_commitizen_project = tmp_commitizen_project_initial() tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") - testargs = [ - "cz", + util.run_cli( "bump", "--prerelease", "alpha", "--yes", "--version-scheme", "semver", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() + ) tag_exists = git.tag_exist("0.2.0-a0") assert tag_exists is True @@ -1091,9 +958,7 @@ def test_bump_command_prerelease_scheme_via_cli( assert "0.2.0-a0" in f.read() # PRERELEASE BUMP CREATES VERSION WITHOUT PRERELEASE - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -1104,7 +969,7 @@ def test_bump_command_prerelease_scheme_via_cli( def test_bump_command_prerelease_scheme_via_config( - tmp_commitizen_project_initial, mocker: MockFixture + tmp_commitizen_project_initial, util: UtilFixture ): tmp_commitizen_project = tmp_commitizen_project_initial( config_extra='version_scheme = "semver"\n', @@ -1112,9 +977,7 @@ def test_bump_command_prerelease_scheme_via_config( tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0-a0") assert tag_exists is True @@ -1123,9 +986,7 @@ def test_bump_command_prerelease_scheme_via_config( with open(version_file) as f: assert "0.2.0-a0" in f.read() - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("0.2.0-a1") assert tag_exists is True @@ -1135,9 +996,7 @@ def test_bump_command_prerelease_scheme_via_config( assert "0.2.0-a1" in f.read() # PRERELEASE BUMP CREATES VERSION WITHOUT PRERELEASE - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") tag_exists = git.tag_exist("0.2.0") assert tag_exists is True @@ -1148,7 +1007,7 @@ def test_bump_command_prerelease_scheme_via_config( def test_bump_command_prerelease_scheme_check_old_tags( - tmp_commitizen_project_initial, mocker: MockFixture + tmp_commitizen_project_initial, util: UtilFixture ): tmp_commitizen_project = tmp_commitizen_project_initial( config_extra=('tag_format = "v$version"\nversion_scheme = "semver"\n'), @@ -1156,9 +1015,7 @@ def test_bump_command_prerelease_scheme_check_old_tags( tmp_version_file = tmp_commitizen_project.join("__version__.py") tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha", "--yes") tag_exists = git.tag_exist("v0.2.0-a0") assert tag_exists is True @@ -1167,9 +1024,7 @@ def test_bump_command_prerelease_scheme_check_old_tags( with open(version_file) as f: assert "0.2.0-a0" in f.read() - testargs = ["cz", "bump", "--prerelease", "alpha"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--prerelease", "alpha") tag_exists = git.tag_exist("v0.2.0-a1") assert tag_exists is True @@ -1179,9 +1034,7 @@ def test_bump_command_prerelease_scheme_check_old_tags( assert "0.2.0-a1" in f.read() # PRERELEASE BUMP CREATES VERSION WITHOUT PRERELEASE - testargs = ["cz", "bump"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump") tag_exists = git.tag_exist("v0.2.0") assert tag_exists is True @@ -1201,12 +1054,10 @@ def test_bump_command_prerelease_scheme_check_old_tags( ("major: bug affecting users", "1.0.0"), ], ) -def test_bump_with_plugin(mocker: MockFixture, message: str, expected_tag: str): - create_file_and_commit(message) +def test_bump_with_plugin(util: UtilFixture, message: str, expected_tag: str): + util.create_file_and_commit(message) - testargs = ["cz", "--name", "cz_semver", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("--name", "cz_semver", "bump", "--yes") tag_exists = git.tag_exist(expected_tag) assert tag_exists is True @@ -1223,56 +1074,48 @@ def test_bump_with_plugin(mocker: MockFixture, message: str, expected_tag: str): ], ) def test_bump_with_major_version_zero_with_plugin( - mocker: MockFixture, message: str, expected_tag: str + util: UtilFixture, message: str, expected_tag: str ): - create_file_and_commit(message) + util.create_file_and_commit(message) - testargs = ["cz", "--name", "cz_semver", "bump", "--yes", "--major-version-zero"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("--name", "cz_semver", "bump", "--yes", "--major-version-zero") tag_exists = git.tag_exist(expected_tag) assert tag_exists is True @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_version_type_deprecation(mocker: MockFixture): - create_file_and_commit("feat: check deprecation on --version-type") +def test_bump_command_version_type_deprecation(util: UtilFixture): + util.create_file_and_commit("feat: check deprecation on --version-type") - testargs = [ - "cz", - "bump", - "--prerelease", - "alpha", - "--yes", - "--version-type", - "semver", - ] - mocker.patch.object(sys, "argv", testargs) with pytest.warns(DeprecationWarning): - cli.main() + util.run_cli( + "bump", + "--prerelease", + "alpha", + "--yes", + "--version-type", + "semver", + ) assert git.tag_exist("0.2.0-a0") @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_version_scheme_priority_over_version_type(mocker: MockFixture): - create_file_and_commit("feat: check deprecation on --version-type") +def test_bump_command_version_scheme_priority_over_version_type(util: UtilFixture): + util.create_file_and_commit("feat: check deprecation on --version-type") - testargs = [ - "cz", - "bump", - "--prerelease", - "alpha", - "--yes", - "--version-type", - "semver", - "--version-scheme", - "pep440", - ] - mocker.patch.object(sys, "argv", testargs) with pytest.warns(DeprecationWarning): - cli.main() + util.run_cli( + "bump", + "--prerelease", + "alpha", + "--yes", + "--version-type", + "semver", + "--version-scheme", + "pep440", + ) assert git.tag_exist("0.2.0a0") @@ -1288,8 +1131,8 @@ def test_bump_command_version_scheme_priority_over_version_type(mocker: MockFixt ), ) def test_bump_template_option_precedence( - mocker: MockFixture, tmp_commitizen_project: Path, + util: UtilFixture, any_changelog_format: ChangelogFormat, arg: str, cfg: str, @@ -1305,7 +1148,7 @@ def test_bump_template_option_precedence( cmd_template.write_text("from cmd") default_template.write_text("default") - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") if cfg: pyproject = project_root / "pyproject.toml" @@ -1319,19 +1162,19 @@ def test_bump_template_option_precedence( ) ) - testargs = ["cz", "bump", "--yes", "--changelog"] + args = ["bump", "--yes", "--changelog"] if arg: - testargs.append(arg) - mocker.patch.object(sys, "argv", testargs + ["0.1.1"]) - cli.main() + args.append(arg) + args.append("0.1.1") + util.run_cli(*args) out = changelog.read_text() assert out == expected def test_bump_template_extras_precedence( - mocker: MockFixture, tmp_commitizen_project: Path, + util: UtilFixture, any_changelog_format: ChangelogFormat, mock_plugin: BaseCommitizen, ): @@ -1356,37 +1199,33 @@ def test_bump_template_extras_precedence( ) ) - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") - testargs = [ - "cz", + util.run_cli( "bump", "--yes", "--changelog", "--extra", "first=from-command", "0.1.1", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() + ) changelog = project_root / any_changelog_format.default_changelog_file assert changelog.read_text() == "from-command - from-config - from-plugin" def test_bump_template_extra_quotes( - mocker: MockFixture, tmp_commitizen_project: Path, + util: UtilFixture, any_changelog_format: ChangelogFormat, ): project_root = Path(tmp_commitizen_project) changelog_tpl = project_root / any_changelog_format.template changelog_tpl.write_text("{{first}} - {{second}} - {{third}}") - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") - testargs = [ - "cz", + util.run_cli( "bump", "--changelog", "--yes", @@ -1397,15 +1236,15 @@ def test_bump_template_extra_quotes( "-e", 'third="double quotes"', "0.1.1", - ] - mocker.patch.object(sys, "argv", testargs) - cli.main() + ) changelog = project_root / any_changelog_format.default_changelog_file assert changelog.read_text() == "no-quote - single quotes - double quotes" -def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, capsys): +def test_bump_changelog_contains_increment_only( + tmp_commitizen_project, util: UtilFixture, capsys +): """Issue 1024""" # Initialize commitizen up to v1.0.0 project_root = Path(tmp_commitizen_project) @@ -1415,23 +1254,19 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, ) tmp_changelog_file = project_root / "CHANGELOG.md" tmp_changelog_file.write_text("## v1.0.0") - create_file_and_commit("feat(user): new file") - create_tag("v1.0.0") + util.create_file_and_commit("feat(user): new file") + util.create_tag("v1.0.0") # Add a commit and bump to v2.0.0 - create_file_and_commit("feat(user)!: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat(user)!: new file") + util.run_cli("bump", "--yes") _ = capsys.readouterr() # Add a commit and create the incremental changelog to v3.0.0 # it should only include v3 changes - create_file_and_commit("feat(next)!: next version") - testargs = ["cz", "bump", "--yes", "--files-only", "--changelog-to-stdout"] - mocker.patch.object(sys, "argv", testargs) + util.create_file_and_commit("feat(next)!: next version") with pytest.raises(ExpectedExit): - cli.main() + util.run_cli("bump", "--yes", "--files-only", "--changelog-to-stdout") out, _ = capsys.readouterr() assert "3.0.0" in out @@ -1439,13 +1274,11 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_get_next(mocker: MockFixture, capsys): - create_file_and_commit("feat: new file") +def test_bump_get_next(util: UtilFixture, capsys): + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes", "--get-next"] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(DryRunExit): - cli.main() + util.run_cli("bump", "--yes", "--get-next") out, _ = capsys.readouterr() assert "0.2.0" in out @@ -1455,17 +1288,13 @@ def test_bump_get_next(mocker: MockFixture, capsys): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_get_next_update_changelog_on_bump( - mocker: MockFixture, capsys, config_path -): - create_file_and_commit("feat: new file") +def test_bump_get_next_update_changelog_on_bump(util: UtilFixture, capsys, config_path): + util.create_file_and_commit("feat: new file") with open(config_path, "a", encoding="utf-8") as fp: fp.write("update_changelog_on_bump = true\n") - testargs = ["cz", "bump", "--yes", "--get-next"] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(DryRunExit): - cli.main() + util.run_cli("bump", "--yes", "--get-next") out, _ = capsys.readouterr() assert "0.2.0" in out @@ -1475,119 +1304,96 @@ def test_bump_get_next_update_changelog_on_bump( @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_get_next__no_eligible_commits_raises(mocker: MockFixture): - create_file_and_commit("chore: new commit") - - testargs = ["cz", "bump", "--yes", "--get-next"] - mocker.patch.object(sys, "argv", testargs) +def test_bump_get_next__no_eligible_commits_raises(util: UtilFixture): + util.create_file_and_commit("chore: new commit") with pytest.raises(NoneIncrementExit): - cli.main() + util.run_cli("bump", "--yes", "--get-next") -def test_bump_allow_no_commit_with_no_commit(mocker, tmp_commitizen_project, capsys): +def test_bump_allow_no_commit_with_no_commit( + tmp_commitizen_project, util: UtilFixture, capsys +): with tmp_commitizen_project.as_cwd(): # Create the first commit and bump to 1.0.0 - create_file_and_commit("feat(user)!: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat(user)!: new file") + util.run_cli("bump", "--yes") # Verify NoCommitsFoundError should be raised # when there's no new commit and "--allow-no-commit" is not set with pytest.raises(NoCommitsFoundError): - testargs = ["cz", "bump"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump") # bump to 1.0.1 with new commit when "--allow-no-commit" is set - testargs = ["cz", "bump", "--allow-no-commit"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--allow-no-commit") out, _ = capsys.readouterr() assert "bump: version 1.0.0 → 1.0.1" in out def test_bump_allow_no_commit_with_no_eligible_commit( - mocker, tmp_commitizen_project, capsys + tmp_commitizen_project, util: UtilFixture, capsys ): with tmp_commitizen_project.as_cwd(): # Create the first commit and bump to 1.0.0 - create_file_and_commit("feat(user)!: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat(user)!: new file") + util.run_cli("bump", "--yes") # Create a commit that is ineligible to bump - create_file_and_commit("docs(bump): add description for allow no commit") + util.create_file_and_commit("docs(bump): add description for allow no commit") # Verify NoneIncrementExit should be raised # when there's no eligible bumping commit and "--allow-no-commit" is not set with pytest.raises(NoneIncrementExit): - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") # bump to 1.0.1 with ineligible commit when "--allow-no-commit" is set - testargs = ["cz", "bump", "--allow-no-commit"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--allow-no-commit") out, _ = capsys.readouterr() assert "bump: version 1.0.0 → 1.0.1" in out -def test_bump_allow_no_commit_with_increment(mocker, tmp_commitizen_project, capsys): +def test_bump_allow_no_commit_with_increment( + tmp_commitizen_project, util: UtilFixture, capsys +): with tmp_commitizen_project.as_cwd(): # # Create the first commit and bump to 1.0.0 - create_file_and_commit("feat(user)!: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat(user)!: new file") + util.run_cli("bump", "--yes") # Verify NoCommitsFoundError should be raised # when there's no new commit and "--allow-no-commit" is not set with pytest.raises(NoCommitsFoundError): - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") # bump to 1.1.0 with no new commit when "--allow-no-commit" is set # and increment is specified - testargs = ["cz", "bump", "--yes", "--allow-no-commit", "--increment", "MINOR"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes", "--allow-no-commit", "--increment", "MINOR") out, _ = capsys.readouterr() assert "bump: version 1.0.0 → 1.1.0" in out def test_bump_allow_no_commit_with_manual_version( - mocker, tmp_commitizen_project, capsys + tmp_commitizen_project, util: UtilFixture, capsys ): with tmp_commitizen_project.as_cwd(): # # Create the first commit and bump to 1.0.0 - create_file_and_commit("feat(user)!: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.create_file_and_commit("feat(user)!: new file") + util.run_cli("bump", "--yes") # Verify NoCommitsFoundError should be raised # when there's no new commit and "--allow-no-commit" is not set with pytest.raises(NoCommitsFoundError): - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes") # bump to 1.1.0 with no new commit when "--allow-no-commit" is set # and increment is specified - testargs = ["cz", "bump", "--yes", "--allow-no-commit", "2.0.0"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--yes", "--allow-no-commit", "2.0.0") out, _ = capsys.readouterr() assert "bump: version 1.0.0 → 2.0.0" in out def test_bump_detect_legacy_tags_from_scm( - tmp_commitizen_project: py.path.local, mocker: MockFixture + tmp_commitizen_project: py.path.local, util: UtilFixture ): project_root = Path(tmp_commitizen_project) tmp_commitizen_cfg_file = project_root / "pyproject.toml" @@ -1603,20 +1409,18 @@ def test_bump_detect_legacy_tags_from_scm( ] ), ) - create_file_and_commit("feat: new file") - create_tag("legacy-0.4.2") - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") + util.create_tag("legacy-0.4.2") + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--increment", "patch", "--changelog"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--increment", "patch", "--changelog") assert git.tag_exist("v0.4.3") def test_bump_warn_but_dont_fail_on_invalid_tags( tmp_commitizen_project: py.path.local, - mocker: MockFixture, + util: UtilFixture, capsys: pytest.CaptureFixture, ): project_root = Path(tmp_commitizen_project) @@ -1630,15 +1434,13 @@ def test_bump_warn_but_dont_fail_on_invalid_tags( ] ), ) - create_file_and_commit("feat: new file") - create_tag("0.4.2") - create_file_and_commit("feat: new file") - create_tag("0.4.3.deadbeaf") - create_file_and_commit("feat: new file") + util.create_file_and_commit("feat: new file") + util.create_tag("0.4.2") + util.create_file_and_commit("feat: new file") + util.create_tag("0.4.3.deadbeaf") + util.create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--increment", "patch", "--changelog"] - mocker.patch.object(sys, "argv", testargs) - cli.main() + util.run_cli("bump", "--increment", "patch", "--changelog") _, err = capsys.readouterr() @@ -1646,10 +1448,10 @@ def test_bump_warn_but_dont_fail_on_invalid_tags( assert git.tag_exist("0.4.3") -def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): +def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project, util: UtilFixture): """Test the _is_initial_tag method behavior.""" # Create a commit but no tags - create_file_and_commit("feat: initial commit") + util.create_file_and_commit("feat: initial commit") # Initialize Bump with minimal config config = BaseConfig() diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 1094e62766..08a2b6cf78 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1,7 +1,6 @@ from __future__ import annotations import itertools -import sys from pathlib import Path from textwrap import dedent from typing import TYPE_CHECKING @@ -9,7 +8,7 @@ import pytest from jinja2 import FileSystemLoader -from commitizen import cli, git +from commitizen import git from commitizen.commands.changelog import Changelog from commitizen.exceptions import ( DryRunExit, @@ -1692,6 +1691,7 @@ def test_export_changelog_template_from_plugin( mock_plugin: BaseCommitizen, changelog_format: ChangelogFormat, tmp_path: Path, + util: UtilFixture, ): project_root = Path(tmp_commitizen_project) target = project_root / "changelog.jinja" @@ -1700,10 +1700,7 @@ def test_export_changelog_template_from_plugin( src.write_text(tpl) mock_plugin.template_loader = FileSystemLoader(tmp_path) - args = ["cz", "changelog", "--export-template", str(target)] - - mocker.patch.object(sys, "argv", args) - cli.main() + util.run_cli("changelog", "--export-template", str(target)) assert target.exists() assert target.read_text() == tpl @@ -1712,6 +1709,7 @@ def test_export_changelog_template_from_plugin( def test_export_changelog_template_fails_when_template_has_no_filename( mocker: MockFixture, tmp_commitizen_project: Path, + util: UtilFixture, ): project_root = Path(tmp_commitizen_project) target = project_root / "changelog.jinja" @@ -1725,11 +1723,8 @@ class FakeTemplate: "commitizen.changelog.get_changelog_template", return_value=FakeTemplate() ) - args = ["cz", "changelog", "--export-template", str(target)] - mocker.patch.object(sys, "argv", args) - with pytest.raises(NotAllowed) as exc_info: - cli.main() + util.run_cli("changelog", "--export-template", str(target)) assert not target.exists() assert "Template filename is not set" in str(exc_info.value) diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index 47dd3fe12c..382814892b 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -1,12 +1,11 @@ from __future__ import annotations -import sys from io import StringIO from typing import TYPE_CHECKING, Any import pytest -from commitizen import cli, commands, git +from commitizen import commands, git from commitizen.cz import registry from commitizen.cz.base import BaseCommitizen, ValidationResult from commitizen.exceptions import ( @@ -15,7 +14,6 @@ InvalidCommitMessageError, NoCommitsFoundError, ) -from tests.utils import create_file_and_commit if TYPE_CHECKING: import re @@ -23,7 +21,10 @@ from pytest_mock import MockFixture + from commitizen.config.base_config import BaseConfig from commitizen.question import CzQuestion + from tests.utils import UtilFixture + COMMIT_LOG = [ "refactor: A code change that neither fixes a bug nor adds a feature", @@ -68,74 +69,70 @@ def _build_fake_git_commits(commit_msgs: list[str]) -> list[git.GitCommit]: return [git.GitCommit("test_rev", commit_msg) for commit_msg in commit_msgs] -def test_check_jira_fails(mocker: MockFixture): - testargs = ["cz", "-n", "cz_jira", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_jira_fails(mocker: MockFixture, util: UtilFixture): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="random message for J-2 #fake_command blah"), ) with pytest.raises(InvalidCommitMessageError) as excinfo: - cli.main() + util.run_cli("-n", "cz_jira", "check", "--commit-msg-file", "some_file") assert "commit validation: failed!" in str(excinfo.value) -def test_check_jira_command_after_issue_one_space(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_jira_command_after_issue_one_space( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="JR-23 #command some arguments etc"), ) - cli.main() + util.run_cli("-n", "cz_jira", "check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_jira_command_after_issue_two_spaces(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_jira_command_after_issue_two_spaces( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="JR-2 #command some arguments etc"), ) - cli.main() + util.run_cli("-n", "cz_jira", "check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_jira_text_between_issue_and_command(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_jira_text_between_issue_and_command( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="JR-234 some text #command some arguments etc"), ) - cli.main() + util.run_cli("-n", "cz_jira", "check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_jira_multiple_commands(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_jira_multiple_commands(mocker: MockFixture, capsys, util: UtilFixture): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="JRA-23 some text #command1 args #command2 args"), ) - cli.main() + util.run_cli("-n", "cz_jira", "check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_conventional_commit_succeeds(mocker: MockFixture, capsys): - testargs = ["cz", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_conventional_commit_succeeds( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="fix(scope): some commit message"), ) - cli.main() + util.run_cli("check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out @@ -234,9 +231,9 @@ def test_check_command_with_invalid_argument(config): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_check_command_with_empty_range(config, mocker: MockFixture): +def test_check_command_with_empty_range(config: BaseConfig, util: UtilFixture): # must initialize git with a commit - create_file_and_commit("feat: initial") + util.create_file_and_commit("feat: initial") check_cmd = commands.Check(config=config, arguments={"rev_range": "master..master"}) with pytest.raises(NoCommitsFoundError) as excinfo: @@ -356,29 +353,29 @@ def test_check_command_override_allowed_prefixes_config(config, mocker: MockFixt error_mock.assert_called_once() -def test_check_command_with_pipe_message(mocker: MockFixture, capsys): - testargs = ["cz", "check"] - mocker.patch.object(sys, "argv", testargs) +def test_check_command_with_pipe_message( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch("sys.stdin", StringIO("fix(scope): some commit message")) - cli.main() + util.run_cli("check") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_command_with_pipe_message_and_failed(mocker: MockFixture): - testargs = ["cz", "check"] - mocker.patch.object(sys, "argv", testargs) +def test_check_command_with_pipe_message_and_failed( + mocker: MockFixture, util: UtilFixture +): mocker.patch("sys.stdin", StringIO("bad commit message")) with pytest.raises(InvalidCommitMessageError) as excinfo: - cli.main() + util.run_cli("check") assert "commit validation: failed!" in str(excinfo.value) -def test_check_command_with_comment_in_message_file(mocker: MockFixture, capsys): - testargs = ["cz", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) +def test_check_command_with_comment_in_message_file( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open( @@ -391,12 +388,14 @@ def test_check_command_with_comment_in_message_file(mocker: MockFixture, capsys) "This pre-commit hook will check our commits automatically." ), ) - cli.main() + util.run_cli("check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out -def test_check_conventional_commit_succeed_with_git_diff(mocker, capsys): +def test_check_conventional_commit_succeed_with_git_diff( + mocker, capsys, util: UtilFixture +): commit_msg = ( "feat: This is a test commit\n" "# Please enter the commit message for your changes. Lines starting\n" @@ -416,13 +415,11 @@ def test_check_conventional_commit_succeed_with_git_diff(mocker, capsys): "@@ -92,3 +92,4 @@ class Command(BaseCommand):\n" '+ "this is a test"\n' ) - testargs = ["cz", "check", "--commit-msg-file", "some_file"] - mocker.patch.object(sys, "argv", testargs) mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data=commit_msg), ) - cli.main() + util.run_cli("check", "--commit-msg-file", "some_file") out, _ = capsys.readouterr() assert "Commit validation: successful!" in out @@ -600,36 +597,24 @@ def use_cz_custom_validator(mocker): @pytest.mark.usefixtures("use_cz_custom_validator") -def test_check_command_with_custom_validator_succeed(mocker: MockFixture, capsys): - testargs = [ - "cz", - "--name", - "cz_custom_validator", - "check", - "--commit-msg-file", - "some_file", - ] - mocker.patch.object(sys, "argv", testargs) +def test_check_command_with_custom_validator_succeed( + mocker: MockFixture, capsys, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open(read_data="ABC-123: add commitizen pre-commit hook"), ) - cli.main() + util.run_cli( + "--name", "cz_custom_validator", "check", "--commit-msg-file", "some_file" + ) out, _ = capsys.readouterr() assert "Commit validation: successful!" in out @pytest.mark.usefixtures("use_cz_custom_validator") -def test_check_command_with_custom_validator_failed(mocker: MockFixture): - testargs = [ - "cz", - "--name", - "cz_custom_validator", - "check", - "--commit-msg-file", - "some_file", - ] - mocker.patch.object(sys, "argv", testargs) +def test_check_command_with_custom_validator_failed( + mocker: MockFixture, util: UtilFixture +): mocker.patch( "commitizen.commands.check.open", mocker.mock_open( @@ -637,7 +622,9 @@ def test_check_command_with_custom_validator_failed(mocker: MockFixture): ), ) with pytest.raises(InvalidCommitMessageError) as excinfo: - cli.main() + util.run_cli( + "--name", "cz_custom_validator", "check", "--commit-msg-file", "some_file" + ) assert "commit validation: failed!" in str(excinfo.value), ( "Pattern validation unexpectedly passed" ) diff --git a/tests/commands/test_common_command.py b/tests/commands/test_common_command.py index bb9de90bbe..7a5a26b6b2 100644 --- a/tests/commands/test_common_command.py +++ b/tests/commands/test_common_command.py @@ -1,10 +1,8 @@ -import sys - import pytest from pytest_mock import MockFixture -from commitizen import cli from commitizen.commands import Example, Info, ListCz, Schema +from tests.utils import UtilFixture @pytest.mark.parametrize( @@ -24,11 +22,11 @@ ) @pytest.mark.usefixtures("python_version") def test_command_shows_description_when_use_help_option( - mocker: MockFixture, capsys, file_regression, monkeypatch: pytest.MonkeyPatch, command: str, + util: UtilFixture, ): """Test that the command shows the description when the help option is used. @@ -42,10 +40,8 @@ def test_command_shows_description_when_use_help_option( monkeypatch.setenv("NO_COLOR", "1") monkeypatch.setenv("PAGER", "cat") - testargs = ["cz", command, "--help"] - mocker.patch.object(sys, "argv", testargs) with pytest.raises(SystemExit): - cli.main() + util.run_cli(command, "--help") out, _ = capsys.readouterr() file_regression.check(out, extension=".txt") diff --git a/tests/providers/test_scm_provider.py b/tests/providers/test_scm_provider.py index e28a6782ab..1de4bf8fb9 100644 --- a/tests/providers/test_scm_provider.py +++ b/tests/providers/test_scm_provider.py @@ -6,16 +6,10 @@ from commitizen.providers import get_provider from commitizen.providers.scm_provider import ScmProvider -from tests.utils import ( - create_branch, - create_file_and_commit, - create_tag, - merge_branch, - switch_branch, -) if TYPE_CHECKING: from commitizen.config.base_config import BaseConfig + from tests.utils import UtilFixture @pytest.mark.parametrize( @@ -46,12 +40,16 @@ ) @pytest.mark.usefixtures("tmp_git_project") def test_scm_provider( - config: BaseConfig, tag_format: str, tag: str, expected_version: str + config: BaseConfig, + tag_format: str, + tag: str, + expected_version: str, + util: UtilFixture, ): - create_file_and_commit("test: fake commit") - create_tag(tag) - create_file_and_commit("test: fake commit") - create_tag("should-not-match") + util.create_file_and_commit("test: fake commit") + util.create_tag(tag) + util.create_file_and_commit("test: fake commit") + util.create_tag("should-not-match") config.settings["version_provider"] = "scm" config.settings["tag_format"] = tag_format @@ -75,52 +73,54 @@ def test_scm_provider_default_without_commits_and_tags(config: BaseConfig): @pytest.mark.usefixtures("tmp_git_project") -def test_scm_provider_default_with_commits_and_tags(config: BaseConfig): +def test_scm_provider_default_with_commits_and_tags( + config: BaseConfig, util: UtilFixture +): config.settings["version_provider"] = "scm" provider = get_provider(config) assert isinstance(provider, ScmProvider) assert provider.get_version() == "0.0.0" - create_file_and_commit("Initial state") - create_tag("1.0.0") + util.create_file_and_commit("Initial state") + util.create_tag("1.0.0") # create develop - create_branch("develop") - switch_branch("develop") + util.create_branch("develop") + util.switch_branch("develop") # add a feature to develop - create_file_and_commit("develop: add beta feature1") + util.create_file_and_commit("develop: add beta feature1") assert provider.get_version() == "1.0.0" - create_tag("1.1.0b0") + util.create_tag("1.1.0b0") # create staging - create_branch("staging") - switch_branch("staging") - create_file_and_commit("staging: Starting release candidate") + util.create_branch("staging") + util.switch_branch("staging") + util.create_file_and_commit("staging: Starting release candidate") assert provider.get_version() == "1.1.0b0" - create_tag("1.1.0rc0") + util.create_tag("1.1.0rc0") # add another feature to develop - switch_branch("develop") - create_file_and_commit("develop: add beta feature2") + util.switch_branch("develop") + util.create_file_and_commit("develop: add beta feature2") assert provider.get_version() == "1.1.0b0" - create_tag("1.2.0b0") + util.create_tag("1.2.0b0") # add a hotfix to master - switch_branch("master") - create_file_and_commit("master: add hotfix") + util.switch_branch("master") + util.create_file_and_commit("master: add hotfix") assert provider.get_version() == "1.0.0" - create_tag("1.0.1") + util.create_tag("1.0.1") # merge the hotfix to staging - switch_branch("staging") - merge_branch("master") + util.switch_branch("staging") + util.merge_branch("master") assert provider.get_version() == "1.1.0rc0" @pytest.mark.usefixtures("tmp_git_project") -def test_scm_provider_detect_legacy_tags(config: BaseConfig): +def test_scm_provider_detect_legacy_tags(config: BaseConfig, util: UtilFixture): config.settings["version_provider"] = "scm" config.settings["tag_format"] = "v${version}" config.settings["legacy_tag_formats"] = [ @@ -129,14 +129,14 @@ def test_scm_provider_detect_legacy_tags(config: BaseConfig): ] provider = get_provider(config) - create_file_and_commit("test: fake commit") - create_tag("old-0.4.1") + util.create_file_and_commit("test: fake commit") + util.create_tag("old-0.4.1") assert provider.get_version() == "0.4.1" - create_file_and_commit("test: fake commit") - create_tag("legacy-0.4.2") + util.create_file_and_commit("test: fake commit") + util.create_tag("legacy-0.4.2") assert provider.get_version() == "0.4.2" - create_file_and_commit("test: fake commit") - create_tag("v0.5.0") + util.create_file_and_commit("test: fake commit") + util.create_tag("v0.5.0") assert provider.get_version() == "0.5.0" diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 0002659396..0477b5eeb9 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -3,9 +3,9 @@ from textwrap import dedent import pytest -from pytest_mock import MockFixture -from commitizen import bump, cli, cmd, exceptions +from commitizen import bump, cmd, exceptions +from tests.utils import UtilFixture conversion = [ ( @@ -38,14 +38,13 @@ def test_create_tag(test_input, expected): ), ) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_pre_commit_changelog(mocker: MockFixture, freezer, retry): - freezer.move_to("2022-04-01") - testargs = ["cz", "bump", "--changelog", "--yes"] +def test_bump_pre_commit_changelog(util: UtilFixture, retry): + util.freezer.move_to("2022-04-01") + bump_args = ["bump", "--changelog", "--yes"] if retry: - testargs.append("--retry") + bump_args.append("--retry") else: pytest.xfail("it will fail because pre-commit will reformat CHANGELOG.md") - mocker.patch.object(sys, "argv", testargs) # Configure prettier as a pre-commit hook Path(".pre-commit-config.yaml").write_text( dedent( @@ -71,7 +70,7 @@ def test_bump_pre_commit_changelog(mocker: MockFixture, freezer, retry): cmd.run("git add -A") cmd.run('git commit -m "fix: _test"') cmd.run("pre-commit install") - cli.main() + util.run_cli(*bump_args) # Pre-commit fixed last line adding extra indent and "\" char assert Path("CHANGELOG.md").read_text() == dedent( """\ @@ -86,12 +85,11 @@ def test_bump_pre_commit_changelog(mocker: MockFixture, freezer, retry): @pytest.mark.parametrize("retry", (True, False)) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_pre_commit_changelog_fails_always(mocker: MockFixture, freezer, retry): - freezer.move_to("2022-04-01") - testargs = ["cz", "bump", "--changelog", "--yes"] +def test_bump_pre_commit_changelog_fails_always(util: UtilFixture, retry): + util.freezer.move_to("2022-04-01") + bump_args = ["bump", "--changelog", "--yes"] if retry: - testargs.append("--retry") - mocker.patch.object(sys, "argv", testargs) + bump_args.append("--retry") Path(".pre-commit-config.yaml").write_text( dedent( """\ @@ -110,20 +108,19 @@ def test_bump_pre_commit_changelog_fails_always(mocker: MockFixture, freezer, re cmd.run('git commit -m "feat: forbid changelogs"') cmd.run("pre-commit install") with pytest.raises(exceptions.BumpCommitFailedError): - cli.main() + util.run_cli(*bump_args) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_with_build_metadata(mocker: MockFixture, freezer): +def test_bump_with_build_metadata(util: UtilFixture): def _add_entry(test_str: str, args: list): Path(test_str).write_text("") cmd.run("git add -A") cmd.run(f'git commit -m "fix: test-{test_str}"') - cz_args = ["cz", "bump", "--changelog", "--yes"] + args - mocker.patch.object(sys, "argv", cz_args) - cli.main() + cz_args = ["bump", "--changelog", "--yes"] + args + util.run_cli(*cz_args) - freezer.move_to("2024-01-01") + util.freezer.move_to("2024-01-01") _add_entry("a", ["--build-metadata", "a.b.c"]) _add_entry("b", []) diff --git a/tests/test_cli.py b/tests/test_cli.py index f91a27373a..9a362e81e0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -15,69 +15,51 @@ NoCommandFoundError, NotAGitProjectError, ) +from tests.utils import UtilFixture -def test_sysexit_no_argv(mocker: MockFixture, capsys): - testargs = ["cz"] - mocker.patch.object(sys, "argv", testargs) - +def test_sysexit_no_argv(util: UtilFixture, capsys): with pytest.raises(ExpectedExit): - cli.main() + util.run_cli() out, _ = capsys.readouterr() assert out.startswith("usage") -def test_cz_config_file_without_correct_file_path(mocker: MockFixture, capsys): - testargs = ["cz", "--config", "./config/pyproject.toml", "example"] - mocker.patch.object(sys, "argv", testargs) - +def test_cz_config_file_without_correct_file_path(util: UtilFixture, capsys): with pytest.raises(ConfigFileNotFound) as excinfo: - cli.main() + util.run_cli("--config", "./config/pyproject.toml", "example") assert "Cannot found the config file" in str(excinfo.value) -def test_cz_with_arg_but_without_command(mocker: MockFixture): - testargs = ["cz", "--name", "cz_jira"] - mocker.patch.object(sys, "argv", testargs) - +def test_cz_with_arg_but_without_command(util: UtilFixture): with pytest.raises(NoCommandFoundError) as excinfo: - cli.main() + util.run_cli("--name", "cz_jira") assert "Command is required" in str(excinfo.value) -def test_name(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "example"] - mocker.patch.object(sys, "argv", testargs) - - cli.main() +def test_name(util: UtilFixture, capsys): + util.run_cli("-n", "cz_jira", "example") out, _ = capsys.readouterr() assert out.startswith("JRA") @pytest.mark.usefixtures("tmp_git_project") -def test_name_default_value(mocker: MockFixture, capsys): - testargs = ["cz", "example"] - mocker.patch.object(sys, "argv", testargs) - - cli.main() +def test_name_default_value(util: UtilFixture, capsys): + util.run_cli("example") out, _ = capsys.readouterr() assert out.startswith("fix: correct minor typos in code") -def test_ls(mocker: MockFixture, capsys): - testargs = ["cz", "-n", "cz_jira", "ls"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_ls(util: UtilFixture, capsys): + util.run_cli("-n", "cz_jira", "ls") out, err = capsys.readouterr() assert "cz_conventional_commits" in out assert isinstance(out, str) -def test_arg_debug(mocker: MockFixture): - testargs = ["cz", "--debug", "info"] - mocker.patch.object(sys, "argv", testargs) - cli.main() +def test_arg_debug(util: UtilFixture): + util.run_cli("--debug", "info") excepthook = sys.excepthook # `sys.excepthook` is replaced by a `partial` in `cli.main` # it's not a normal function @@ -167,19 +149,15 @@ def test_parse_no_raise_mix_invalid_arg_is_skipped(): assert result == [1, 2, 4] -def test_unknown_args_raises(mocker: MockFixture): - testargs = ["cz", "c", "-this_arg_is_not_supported"] - mocker.patch.object(sys, "argv", testargs) +def test_unknown_args_raises(util: UtilFixture): with pytest.raises(InvalidCommandArgumentError) as excinfo: - cli.main() + util.run_cli("c", "-this_arg_is_not_supported") assert "Invalid commitizen arguments were found" in str(excinfo.value) -def test_unknown_args_before_double_dash_raises(mocker: MockFixture): - testargs = ["cz", "c", "-this_arg_is_not_supported", "--"] - mocker.patch.object(sys, "argv", testargs) +def test_unknown_args_before_double_dash_raises(util: UtilFixture): with pytest.raises(InvalidCommandArgumentError) as excinfo: - cli.main() + util.run_cli("c", "-this_arg_is_not_supported", "--") assert "Invalid commitizen arguments were found before -- separator" in str( excinfo.value ) diff --git a/tests/test_git.py b/tests/test_git.py index 12c0e2ad82..3fb25a8e65 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -9,18 +9,13 @@ from commitizen import cmd, git from commitizen.exceptions import GitCommandError -from tests.utils import ( - FakeCommand, - create_branch, - create_file_and_commit, - create_tag, - switch_branch, -) if TYPE_CHECKING: from pytest_gitconfig import GitConfig from pytest_mock import MockFixture + from tests.utils import UtilFixture + @pytest.mark.parametrize("date", ["2020-01-21", "1970-01-01"]) def test_git_tag_date(date: str): @@ -39,13 +34,13 @@ def test_git_object_eq(): assert git_commit != "sha1-code" -def test_get_tags(mocker: MockFixture): +def test_get_tags(util: UtilFixture): tag_str = ( "v1.0.0---inner_delimiter---333---inner_delimiter---2020-01-20---inner_delimiter---\n" "v0.5.0---inner_delimiter---222---inner_delimiter---2020-01-17---inner_delimiter---\n" "v0.0.1---inner_delimiter---111---inner_delimiter---2020-01-17---inner_delimiter---\n" ) - mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) + util.mock_cmd(out=tag_str) git_tags = git.get_tags() latest_git_tag = git_tags[0] @@ -53,55 +48,49 @@ def test_get_tags(mocker: MockFixture): assert latest_git_tag.name == "v1.0.0" assert latest_git_tag.date == "2020-01-20" - mocker.patch( - "commitizen.cmd.run", return_value=FakeCommand(out="", err="No tag available") - ) + util.mock_cmd(out="", err="No tag available") assert git.get_tags() == [] -def test_get_reachable_tags(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - create_file_and_commit("Initial state") - create_tag("1.0.0") - # create develop - create_branch("develop") - switch_branch("develop") +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_get_reachable_tags(util: UtilFixture): + util.create_file_and_commit("Initial state") + util.create_tag("1.0.0") + # create develop + util.create_branch("develop") + util.switch_branch("develop") - # add a feature to develop - create_file_and_commit("develop") - create_tag("1.1.0b0") + # add a feature to develop + util.create_file_and_commit("develop") + util.create_tag("1.1.0b0") - # create staging - switch_branch("master") - create_file_and_commit("master") - create_tag("1.0.1") + # create staging + util.switch_branch("master") + util.create_file_and_commit("master") + util.create_tag("1.0.1") - tags = git.get_tags(reachable_only=True) - tag_names = set([t.name for t in tags]) - # 1.1.0b0 is not present - assert tag_names == {"1.0.0", "1.0.1"} + tags = git.get_tags(reachable_only=True) + tag_names = set([t.name for t in tags]) + # 1.1.0b0 is not present + assert tag_names == {"1.0.0", "1.0.1"} +@pytest.mark.usefixtures("tmp_commitizen_project") @pytest.mark.parametrize("locale", ["en_US", "fr_FR"]) -def test_get_reachable_tags_with_commits( - tmp_commitizen_project, locale: str, monkeypatch: pytest.MonkeyPatch -): +def test_get_reachable_tags_with_commits(locale: str, monkeypatch: pytest.MonkeyPatch): monkeypatch.setenv("LANG", f"{locale}.UTF-8") monkeypatch.setenv("LANGUAGE", f"{locale}.UTF-8") monkeypatch.setenv("LC_ALL", f"{locale}.UTF-8") - with tmp_commitizen_project.as_cwd(): - assert git.get_tags(reachable_only=True) == [] + assert git.get_tags(reachable_only=True) == [] -def test_get_tag_names(mocker: MockFixture): +def test_get_tag_names(util: UtilFixture): tag_str = "v1.0.0\nv0.5.0\nv0.0.1\n" - mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) + util.mock_cmd(out=tag_str) assert git.get_tag_names() == ["v1.0.0", "v0.5.0", "v0.0.1"] - mocker.patch( - "commitizen.cmd.run", return_value=FakeCommand(out="", err="No tag available") - ) + util.mock_cmd(out="", err="No tag available") assert git.get_tag_names() == [] @@ -126,23 +115,23 @@ def test_get_log_as_str_list_empty(): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_get_commits(): - create_file_and_commit("feat(users): add username") - create_file_and_commit("fix: username exception") +def test_get_commits(util: UtilFixture): + util.create_file_and_commit("feat(users): add username") + util.create_file_and_commit("fix: username exception") commits = git.get_commits() assert len(commits) == 2 @pytest.mark.usefixtures("tmp_commitizen_project") -def test_get_commits_author_and_email(): - create_file_and_commit("fix: username exception") +def test_get_commits_author_and_email(util: UtilFixture): + util.create_file_and_commit("fix: username exception") commit = git.get_commits()[0] assert commit.author != "" assert "@" in commit.author_email -def test_get_commits_without_email(mocker: MockFixture): +def test_get_commits_without_email(util: UtilFixture): raw_commit = ( "a515bb8f71c403f6f7d1c17b9d8ebf2ce3959395\n" "95bbfc703eb99cb49ba0d6ffd8469911303dbe63 12d3b4bdaa996ea7067a07660bb5df4772297bdd\n" @@ -157,7 +146,7 @@ def test_get_commits_without_email(mocker: MockFixture): "\n" "----------commit-delimiter----------\n" ) - mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=raw_commit)) + util.mock_cmd(out=raw_commit) commits = git.get_commits() @@ -171,7 +160,7 @@ def test_get_commits_without_email(mocker: MockFixture): assert commits[1].title == "feat(users): add username" -def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture): +def test_get_commits_without_breakline_in_each_commit(util: UtilFixture): raw_commit = ( "ae9ba6fc5526cf478f52ef901418d85505109744\n" "ff2f56ca844de72a9d59590831087bf5a97bac84\n" @@ -192,7 +181,7 @@ def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture): "user@email.edu\n" "----------commit-delimiter----------\n" ) - mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=raw_commit)) + util.mock_cmd(out=raw_commit) commits = git.get_commits() @@ -211,7 +200,7 @@ def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture): ) -def test_get_commits_with_and_without_parents(mocker: MockFixture): +def test_get_commits_with_and_without_parents(util: UtilFixture): raw_commit = ( "4206e661bacf9643373255965f34bbdb382cb2b9\n" "ae9ba6fc5526cf478f52ef901418d85505109744 bf8479e7aa1a5b9d2f491b79e3a4d4015519903e\n" @@ -232,7 +221,7 @@ def test_get_commits_with_and_without_parents(mocker: MockFixture): "user@email.com\n" "----------commit-delimiter----------\n" ) - mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=raw_commit)) + util.mock_cmd(out=raw_commit) commits = git.get_commits() @@ -280,93 +269,86 @@ def test_get_tag_names_has_correct_arrow_annotation(): assert arrow_annotation == "list[str]" -def test_get_latest_tag_name(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - tag_name = git.get_latest_tag_name() - assert tag_name is None +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_get_latest_tag_name(util: UtilFixture): + tag_name = git.get_latest_tag_name() + assert tag_name is None - create_file_and_commit("feat(test): test") - cmd.run("git tag 1.0") - tag_name = git.get_latest_tag_name() - assert tag_name == "1.0" + util.create_file_and_commit("feat(test): test") + util.create_tag("1.0") + tag_name = git.get_latest_tag_name() + assert tag_name == "1.0" -def test_is_staging_clean_when_adding_file(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - assert git.is_staging_clean() is True +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_is_staging_clean_when_adding_file(): + assert git.is_staging_clean() is True - cmd.run("touch test_file") + cmd.run("touch test_file") - assert git.is_staging_clean() is True + assert git.is_staging_clean() is True - cmd.run("git add test_file") + cmd.run("git add test_file") - assert git.is_staging_clean() is False + assert git.is_staging_clean() is False -def test_is_staging_clean_when_updating_file(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - assert git.is_staging_clean() is True +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_is_staging_clean_when_updating_file(): + assert git.is_staging_clean() is True - cmd.run("touch test_file") - cmd.run("git add test_file") - if os.name == "nt": - cmd.run('git commit -m "add test_file"') - else: - cmd.run("git commit -m 'add test_file'") - cmd.run("echo 'test' > test_file") + cmd.run("touch test_file") + cmd.run("git add test_file") + if os.name == "nt": + cmd.run('git commit -m "add test_file"') + else: + cmd.run("git commit -m 'add test_file'") + cmd.run("echo 'test' > test_file") - assert git.is_staging_clean() is True + assert git.is_staging_clean() is True - cmd.run("git add test_file") + cmd.run("git add test_file") - assert git.is_staging_clean() is False + assert git.is_staging_clean() is False -def test_get_eol_for_open(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - assert git.EOLType.for_open() == os.linesep +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_get_eol_for_open(): + assert git.EOLType.for_open() == os.linesep - cmd.run("git config core.eol lf") - assert git.EOLType.for_open() == "\n" + cmd.run("git config core.eol lf") + assert git.EOLType.for_open() == "\n" - cmd.run("git config core.eol crlf") - assert git.EOLType.for_open() == "\r\n" + cmd.run("git config core.eol crlf") + assert git.EOLType.for_open() == "\r\n" - cmd.run("git config core.eol native") - assert git.EOLType.for_open() == os.linesep + cmd.run("git config core.eol native") + assert git.EOLType.for_open() == os.linesep -def test_get_core_editor(mocker): - mocker.patch.dict(os.environ, {"GIT_EDITOR": "nano"}) +def test_get_core_editor(monkeypatch: pytest.MonkeyPatch, util: UtilFixture): + monkeypatch.setenv("GIT_EDITOR", "nano") assert git.get_core_editor() == "nano" - mocker.patch.dict(os.environ, clear=True) - mocker.patch( - "commitizen.cmd.run", - return_value=cmd.Command( - out="vim", err="", stdout=b"", stderr=b"", return_code=0 - ), - ) + monkeypatch.delenv("GIT_EDITOR") + + util.mock_cmd(out="vim") assert git.get_core_editor() == "vim" - mocker.patch( - "commitizen.cmd.run", - return_value=cmd.Command(out="", err="", stdout=b"", stderr=b"", return_code=1), - ) + util.mock_cmd() assert git.get_core_editor() is None -def test_create_tag_with_message(tmp_commitizen_project): - with tmp_commitizen_project.as_cwd(): - create_file_and_commit("feat(test): test") - tag_name = "1.0" - tag_message = "test message" - create_tag(tag_name, tag_message) - assert git.get_latest_tag_name() == tag_name - assert git.get_tag_message(tag_name) == ( - tag_message if platform.system() != "Windows" else f"'{tag_message}'" - ) +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_create_tag_with_message(util: UtilFixture): + util.create_file_and_commit("feat(test): test") + tag_name = "1.0" + tag_message = "test message" + util.create_tag(tag_name, tag_message) + assert git.get_latest_tag_name() == tag_name + assert git.get_tag_message(tag_name) == ( + tag_message if platform.system() != "Windows" else f"'{tag_message}'" + ) @pytest.mark.parametrize( @@ -391,8 +373,10 @@ def test_create_tag_with_message(tmp_commitizen_project): "Path does not contain spaces", ], ) -def test_commit_with_spaces_in_path(mocker, file_path, expected_cmd): - mock_run = mocker.patch("commitizen.cmd.run", return_value=FakeCommand()) +def test_commit_with_spaces_in_path( + mocker: MockFixture, file_path: str, expected_cmd: str, util: UtilFixture +): + mock_run = util.mock_cmd() mock_unlink = mocker.patch("os.unlink") mock_temp_file = mocker.patch("commitizen.git.NamedTemporaryFile") mock_temp_file.return_value.name = file_path @@ -403,12 +387,9 @@ def test_commit_with_spaces_in_path(mocker, file_path, expected_cmd): mock_unlink.assert_called_once_with(file_path) -def test_get_filenames_in_commit_error(mocker: MockFixture): +def test_get_filenames_in_commit_error(util: UtilFixture): """Test that GitCommandError is raised when git command fails.""" - mocker.patch( - "commitizen.cmd.run", - return_value=FakeCommand(out="", err="fatal: bad object HEAD", return_code=1), - ) + util.mock_cmd(err="fatal: bad object HEAD", return_code=1) with pytest.raises(GitCommandError) as excinfo: git.get_filenames_in_commit() assert str(excinfo.value) == "fatal: bad object HEAD" @@ -475,27 +456,23 @@ def test_git_commit_from_rev_and_commit(): ("posix", None, 'git commit -F "temp.txt"'), ], ) -def test_create_commit_cmd_string(mocker, os_name, committer_date, expected_cmd): +def test_create_commit_cmd_string( + mocker: MockFixture, os_name: str, committer_date: str, expected_cmd: str +): """Test the OS-specific behavior of _create_commit_cmd_string""" mocker.patch("os.name", os_name) result = git._create_commit_cmd_string("", committer_date, "temp.txt") assert result == expected_cmd -def test_get_default_branch_success(mocker: MockFixture): - mocker.patch( - "commitizen.cmd.run", return_value=FakeCommand(out="refs/remotes/origin/main\n") - ) +def test_get_default_branch_success(util: UtilFixture): + util.mock_cmd(out="refs/remotes/origin/main\n") assert git.get_default_branch() == "refs/remotes/origin/main" -def test_get_default_branch_error(mocker: MockFixture): - mocker.patch( - "commitizen.cmd.run", - return_value=FakeCommand( - err="fatal: ref refs/remotes/origin/HEAD is not a symbolic ref", - return_code=1, - ), +def test_get_default_branch_error(util: UtilFixture): + util.mock_cmd( + err="fatal: ref refs/remotes/origin/HEAD is not a symbolic ref", return_code=1 ) with pytest.raises(GitCommandError): git.get_default_branch() diff --git a/tests/utils.py b/tests/utils.py index 57161d83b1..bca565f78c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,8 +10,11 @@ import pytest from commitizen import cli, cmd, exceptions, git +from commitizen.cmd import Command if TYPE_CHECKING: + from unittest.mock import Mock + from freezegun.api import FrozenDateTimeFactory from pytest_mock import MockerFixture @@ -26,52 +29,6 @@ class VersionSchemeTestArgs(NamedTuple): devrelease: int | None -class FakeCommand: - def __init__(self, out=None, err=None, return_code=0): - self.out = out - self.err = err - self.return_code = return_code - - -def create_file_and_commit( - message: str, filename: str | None = None, committer_date: str | None = None -): - if not filename: - filename = str(uuid.uuid4()) - - Path(filename).touch() - c = cmd.run("git add .") - if c.return_code != 0: - raise exceptions.CommitError(c.err) - c = git.commit(message, committer_date=committer_date) - if c.return_code != 0: - raise exceptions.CommitError(c.err) - - -def create_branch(name: str): - c = cmd.run(f"git branch {name}") - if c.return_code != 0: - raise exceptions.GitCommandError(c.err) - - -def switch_branch(branch: str): - c = cmd.run(f"git switch {branch}") - if c.return_code != 0: - raise exceptions.GitCommandError(c.err) - - -def merge_branch(branch: str): - c = cmd.run(f"git merge {branch}") - if c.return_code != 0: - raise exceptions.GitCommandError(c.err) - - -def create_tag(tag: str, message: str | None = None) -> None: - c = git.tag(tag, annotated=(message is not None), msg=message) - if c.return_code != 0: - raise exceptions.CommitError(c.err) - - @dataclass class UtilFixture: """ @@ -160,6 +117,11 @@ def tick(self) -> None: self.freezer.tick() self.patch_env() + def mock_cmd(self, out: str = "", err: str = "", return_code: int = 0) -> Mock: + """Mock cmd.run command.""" + return_value = Command(out, err, b"", b"", return_code) + return self.mocker.patch("commitizen.cmd.run", return_value=return_value) + @pytest.fixture def util(