diff options
Diffstat (limited to 'gitlint-core/gitlint/tests')
36 files changed, 357 insertions, 234 deletions
diff --git a/gitlint-core/gitlint/tests/base.py b/gitlint-core/gitlint/tests/base.py index 710efe2..3899a5f 100644 --- a/gitlint-core/gitlint/tests/base.py +++ b/gitlint-core/gitlint/tests/base.py @@ -5,15 +5,15 @@ import os import re import shutil import tempfile - import unittest - +from pathlib import Path from unittest.mock import patch from gitlint.config import LintConfig -from gitlint.deprecation import Deprecation, LOG as DEPRECATION_LOG -from gitlint.git import GitContext, GitChangedFileStats -from gitlint.utils import LOG_FORMAT, DEFAULT_ENCODING +from gitlint.deprecation import LOG as DEPRECATION_LOG +from gitlint.deprecation import Deprecation +from gitlint.git import GitChangedFileStats, GitContext +from gitlint.utils import FILE_ENCODING, LOG_FORMAT EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING = ( "WARNING: gitlint.deprecated.regex_style_search {0} - {1}: gitlint will be switching from using " @@ -30,10 +30,28 @@ class BaseTestCase(unittest.TestCase): # In case of assert failures, print the full error message maxDiff = None + # Working directory in which tests in this class are executed + working_dir = None + # Originally working dir when the test was started + original_working_dir = None + SAMPLES_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "samples") EXPECTED_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "expected") GITLINT_USE_SH_LIB = os.environ.get("GITLINT_USE_SH_LIB", "[NOT SET]") + @classmethod + def setUpClass(cls): + # Run tests a temporary directory to shield them from any local git config + cls.original_working_dir = os.getcwd() + cls.working_dir = tempfile.mkdtemp() + os.chdir(cls.working_dir) + + @classmethod + def tearDownClass(cls): + # Go back to original working dir and remove our temp working dir + os.chdir(cls.original_working_dir) + shutil.rmtree(cls.working_dir) + def setUp(self): self.logcapture = LogCapture() self.logcapture.setFormatter(logging.Formatter(LOG_FORMAT)) @@ -77,9 +95,7 @@ class BaseTestCase(unittest.TestCase): def get_sample(filename=""): """Read and return the contents of a file in gitlint/tests/samples""" sample_path = BaseTestCase.get_sample_path(filename) - with open(sample_path, encoding=DEFAULT_ENCODING) as content: - sample = content.read() - return sample + return Path(sample_path).read_text(encoding=FILE_ENCODING) @staticmethod def patch_input(side_effect): @@ -93,8 +109,7 @@ class BaseTestCase(unittest.TestCase): """Utility method to read an expected file from gitlint/tests/expected and return it as a string. Optionally replace template variables specified by variable_dict.""" expected_path = os.path.join(BaseTestCase.EXPECTED_DIR, filename) - with open(expected_path, encoding=DEFAULT_ENCODING) as content: - expected = content.read() + expected = Path(expected_path).read_text(encoding=FILE_ENCODING) if variable_dict: expected = expected.format(**variable_dict) @@ -150,22 +165,24 @@ class BaseTestCase(unittest.TestCase): self.logcapture.clear() @contextlib.contextmanager - def assertRaisesMessage(self, expected_exception, expected_msg): # pylint: disable=invalid-name + def assertRaisesMessage(self, expected_exception, expected_msg): """Asserts an exception has occurred with a given error message""" try: yield except expected_exception as exc: exception_msg = str(exc) - if exception_msg != expected_msg: + if exception_msg != expected_msg: # pragma: nocover error = f"Right exception, wrong message:\n got: {exception_msg}\n expected: {expected_msg}" - raise self.fail(error) + raise self.fail(error) from exc # else: everything is fine, just return return - except Exception as exc: - raise self.fail(f"Expected '{expected_exception.__name__}' got '{exc.__class__.__name__}'") + except Exception as exc: # pragma: nocover + raise self.fail(f"Expected '{expected_exception.__name__}' got '{exc.__class__.__name__}'") from exc # No exception raised while we expected one - raise self.fail(f"Expected to raise {expected_exception.__name__}, didn't get an exception at all") + raise self.fail( + f"Expected to raise {expected_exception.__name__}, didn't get an exception at all" + ) # pragma: nocover def object_equality_test(self, obj, attr_list, ctor_kwargs=None): """Helper function to easily implement object equality tests. diff --git a/gitlint-core/gitlint/tests/cli/test_cli.py b/gitlint-core/gitlint/tests/cli/test_cli.py index d18efe9..c006375 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli.py +++ b/gitlint-core/gitlint/tests/cli/test_cli.py @@ -1,22 +1,15 @@ -import io import os -import sys import platform - -import arrow - +import sys from io import StringIO - -from click.testing import CliRunner - from unittest.mock import patch +import arrow +from click.testing import CliRunner +from gitlint import __version__, cli from gitlint.shell import CommandNotFound - from gitlint.tests.base import BaseTestCase -from gitlint import cli -from gitlint import __version__ -from gitlint.utils import DEFAULT_ENCODING +from gitlint.utils import FILE_ENCODING, TERMINAL_ENCODING class CLITests(BaseTestCase): @@ -46,7 +39,8 @@ class CLITests(BaseTestCase): "gitlint_version": __version__, "GITLINT_USE_SH_LIB": BaseTestCase.GITLINT_USE_SH_LIB, "target": os.path.realpath(os.getcwd()), - "DEFAULT_ENCODING": DEFAULT_ENCODING, + "TERMINAL_ENCODING": TERMINAL_ENCODING, + "FILE_ENCODING": FILE_ENCODING, } def test_version(self): @@ -107,6 +101,40 @@ class CLITests(BaseTestCase): @patch("gitlint.cli.get_stdin_data", return_value=False) @patch("gitlint.git.sh") + def test_lint_multiple_commits_csv(self, sh, _): + """Test for --commits option""" + + # fmt: off + sh.git.side_effect = [ + "6f29bf81a8322a04071bb794666e48c443a90360\n", # git rev-list <SHA> + "25053ccec5e28e1bb8f7551fdbb5ab213ada2401\n", + "4da2656b0dadc76c7ee3fd0243a96cb64007f125\n", + # git log --pretty <FORMAT> <SHA> + "test åuthor1\x00test-email1@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" + "commït-title1\n\ncommït-body1", + "#", # git config --get core.commentchar + "3\t5\tcommit-1/file-1\n1\t4\tcommit-1/file-2\n", # git diff-tree + "commit-1-branch-1\ncommit-1-branch-2\n", # git branch --contains <sha> + # git log --pretty <FORMAT> <SHA> + "test åuthor2\x00test-email3@föo.com\x002016-12-04 15:28:15 +0100\x00åbc\n" + "commït-title2\n\ncommït-body2", + "8\t3\tcommit-2/file-1\n1\t5\tcommit-2/file-2\n", # git diff-tree + "commit-2-branch-1\ncommit-2-branch-2\n", # git branch --contains <sha> + # git log --pretty <FORMAT> <SHA> + "test åuthor3\x00test-email3@föo.com\x002016-12-05 15:28:15 +0100\x00åbc\n" + "commït-title3\n\ncommït-body3", + "7\t2\tcommit-3/file-1\n1\t7\tcommit-3/file-2\n", # git diff-tree + "commit-3-branch-1\ncommit-3-branch-2\n", # git branch --contains <sha> + ] + # fmt: on + + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--commits", "6f29bf81,25053cce,4da2656b"]) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_multiple_commits_csv_1")) + self.assertEqual(result.exit_code, 3) + + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_multiple_commits_config(self, sh, _): """Test for --commits option where some of the commits have gitlint config in the commit message""" @@ -225,8 +253,7 @@ class CLITests(BaseTestCase): self.assertEqual(result.exit_code, 2) @patch("gitlint.cli.get_stdin_data", return_value=False) - @patch("gitlint.git.sh") - def test_lint_commit_negative(self, sh, _): + def test_lint_commit_negative(self, _): """Negative test for --commit option""" # Try using --commit and --commits at the same time (not allowed) @@ -298,6 +325,11 @@ class CLITests(BaseTestCase): self.assertEqual(result.output, "") expected_kwargs = self.get_system_info_dict() + changed_files_stats = ( + f" {os.path.join('commit-1', 'file-1')}: 1 additions, 5 deletions\n" + f" {os.path.join('commit-1', 'file-2')}: 8 additions, 9 deletions" + ) + expected_kwargs.update({"changed_files_stats": changed_files_stats}) expected_logs = self.get_expected("cli/test_cli/test_lint_staged_stdin_2", expected_kwargs) self.assert_logged(expected_logs) @@ -318,7 +350,7 @@ class CLITests(BaseTestCase): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "msg") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: f.write("WIP: msg-filename tïtle\n") with patch("gitlint.display.stderr", new=StringIO()) as stderr: @@ -328,6 +360,11 @@ class CLITests(BaseTestCase): self.assertEqual(result.output, "") expected_kwargs = self.get_system_info_dict() + changed_files_stats = ( + f" {os.path.join('commit-1', 'file-1')}: 3 additions, 4 deletions\n" + f" {os.path.join('commit-1', 'file-2')}: 4 additions, 7 deletions" + ) + expected_kwargs.update({"changed_files_stats": changed_files_stats}) expected_logs = self.get_expected("cli/test_cli/test_lint_staged_msg_filename_2", expected_kwargs) self.assert_logged(expected_logs) @@ -368,7 +405,7 @@ class CLITests(BaseTestCase): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "msg") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: f.write("Commït title\n") with patch("gitlint.display.stderr", new=StringIO()) as stderr: @@ -458,6 +495,25 @@ class CLITests(BaseTestCase): self.assertEqual(result.exit_code, 6) expected_kwargs = self.get_system_info_dict() + changed_files_stats1 = ( + f" {os.path.join('commit-1', 'file-1')}: 5 additions, 8 deletions\n" + f" {os.path.join('commit-1', 'file-2')}: 2 additions, 9 deletions" + ) + changed_files_stats2 = ( + f" {os.path.join('commit-2', 'file-1')}: 5 additions, 8 deletions\n" + f" {os.path.join('commit-2', 'file-2')}: 7 additions, 9 deletions" + ) + changed_files_stats3 = ( + f" {os.path.join('commit-3', 'file-1')}: 1 additions, 4 deletions\n" + f" {os.path.join('commit-3', 'file-2')}: 3 additions, 4 deletions" + ) + expected_kwargs.update( + { + "changed_files_stats1": changed_files_stats1, + "changed_files_stats2": changed_files_stats2, + "changed_files_stats3": changed_files_stats3, + } + ) expected_kwargs.update({"config_path": config_path}) expected_logs = self.get_expected("cli/test_cli/test_debug_1", expected_kwargs) self.assert_logged(expected_logs) @@ -548,7 +604,7 @@ class CLITests(BaseTestCase): # Non existing file config_path = self.get_sample_path("föo") result = self.cli.invoke(cli.cli, ["--config", config_path]) - expected_string = f"Error: Invalid value for '-C' / '--config': File '{config_path}' does not exist." + expected_string = f"Error: Invalid value for '-C' / '--config': File {config_path!r} does not exist." self.assertEqual(result.output.split("\n")[3], expected_string) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) @@ -569,7 +625,7 @@ class CLITests(BaseTestCase): # Non existing file config_path = self.get_sample_path("föo") result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) - expected_string = f"Error: Invalid value for '-C' / '--config': File '{config_path}' does not exist." + expected_string = f"Error: Invalid value for '-C' / '--config': File {config_path!r} does not exist." self.assertEqual(result.output.split("\n")[3], expected_string) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) @@ -578,6 +634,11 @@ class CLITests(BaseTestCase): result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) self.assertEqual(result.exit_code, self.CONFIG_ERROR_CODE) + def test_config_error(self): + result = self.cli.invoke(cli.cli, ["-c", "foo.bar=hur"]) + self.assertEqual(result.output, "Config Error: No such rule 'foo'\n") + self.assertEqual(result.exit_code, self.CONFIG_ERROR_CODE) + @patch("gitlint.cli.get_stdin_data", return_value=False) def test_target(self, _): """Test for the --target option""" @@ -602,7 +663,7 @@ class CLITests(BaseTestCase): target_path = self.get_sample_path(os.path.join("config", "gitlintconfig")) result = self.cli.invoke(cli.cli, ["--target", target_path]) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - expected_msg = f"Error: Invalid value for '--target': Directory '{target_path}' is a file." + expected_msg = f"Error: Invalid value for '--target': Directory {target_path!r} is a file." self.assertEqual(result.output.split("\n")[3], expected_msg) @patch("gitlint.config.LintConfigGenerator.generate_config") diff --git a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py index d4311c6..c9e4eba 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py +++ b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py @@ -1,18 +1,12 @@ -import io -from io import StringIO import os - -from click.testing import CliRunner - +from io import StringIO from unittest.mock import patch -from gitlint.tests.base import BaseTestCase -from gitlint import cli -from gitlint import hooks -from gitlint import config +from click.testing import CliRunner +from gitlint import cli, config, hooks from gitlint.shell import ErrorReturnCode - -from gitlint.utils import DEFAULT_ENCODING +from gitlint.tests.base import BaseTestCase +from gitlint.utils import FILE_ENCODING class CLIHookTests(BaseTestCase): @@ -108,7 +102,7 @@ class CLIHookTests(BaseTestCase): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "hür") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: f.write("WIP: tïtle\n") with patch("gitlint.display.stderr", new=StringIO()) as stderr: @@ -134,68 +128,65 @@ class CLIHookTests(BaseTestCase): # When set_editors[i] == None, ensure we don't fallback to EDITOR set in shell invocating the tests os.environ.pop("EDITOR", None) - with self.patch_input(["e", "e", "n"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.realpath(os.path.join(tmpdir, "hür")) - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write(commit_messages[i] + "\n") - - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual( - result.output, - self.get_expected( - "cli/test_cli_hooks/test_hook_edit_1_stdout", {"commit_msg": commit_messages[i]} - ), - ) - expected = self.get_expected( - "cli/test_cli_hooks/test_hook_edit_1_stderr", {"commit_msg": commit_messages[i]} - ) - self.assertEqual(stderr.getvalue(), expected) - - # exit code = number of violations - self.assertEqual(result.exit_code, 2) - - shell.assert_called_with(expected_editors[i] + " " + msg_filename) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: editing commit message") - self.assert_log_contains(f"DEBUG: gitlint.cli run-hook: {expected_editors[i]} {msg_filename}") + with self.patch_input(["e", "e", "n"]), self.tempdir() as tmpdir: + msg_filename = os.path.realpath(os.path.join(tmpdir, "hür")) + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: + f.write(commit_messages[i] + "\n") + + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual( + result.output, + self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stdout", {"commit_msg": commit_messages[i]} + ), + ) + expected = self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stderr", {"commit_msg": commit_messages[i]} + ) + self.assertEqual(stderr.getvalue(), expected) + + # exit code = number of violations + self.assertEqual(result.exit_code, 2) + + shell.assert_called_with(expected_editors[i] + " " + msg_filename) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: editing commit message") + self.assert_log_contains(f"DEBUG: gitlint.cli run-hook: {expected_editors[i]} {msg_filename}") def test_run_hook_no(self): """Test for run-hook subcommand, answering 'n(o)' after commit-hook""" - with self.patch_input(["n"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.join(tmpdir, "hür") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write("WIP: höok no\n") + with self.patch_input(["n"]), self.tempdir() as tmpdir: + msg_filename = os.path.join(tmpdir, "hür") + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: + f.write("WIP: höok no\n") - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_1_stdout")) - self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_1_stderr")) + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_1_stdout")) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_1_stderr")) - # We decided not to keep the commit message: hook returns number of violations (>0) - # This will cause git to abort the commit - self.assertEqual(result.exit_code, 2) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message declined") + # We decided not to keep the commit message: hook returns number of violations (>0) + # This will cause git to abort the commit + self.assertEqual(result.exit_code, 2) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message declined") def test_run_hook_yes(self): """Test for run-hook subcommand, answering 'y(es)' after commit-hook""" - with self.patch_input(["y"]): - with self.tempdir() as tmpdir: - msg_filename = os.path.join(tmpdir, "hür") - with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: - f.write("WIP: höok yes\n") + with self.patch_input(["y"]), self.tempdir() as tmpdir: + msg_filename = os.path.join(tmpdir, "hür") + with open(msg_filename, "w", encoding=FILE_ENCODING) as f: + f.write("WIP: höok yes\n") - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stdout")) - self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stderr")) + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stdout")) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stderr")) - # Exit code is 0 because we decide to keep the commit message - # This will cause git to keep the commit - self.assertEqual(result.exit_code, 0) - self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message accepted") + # Exit code is 0 because we decide to keep the commit message + # This will cause git to keep the commit + self.assertEqual(result.exit_code, 0) + self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message accepted") @patch("gitlint.cli.get_stdin_data", return_value=False) @patch("gitlint.git.sh") @@ -207,7 +198,8 @@ class CLIHookTests(BaseTestCase): error_msg = b"fatal: not a git repository (or any of the parent directories): .git" sh.git.side_effect = ErrorReturnCode("full command", b"stdout", error_msg) result = self.cli.invoke(cli.cli, ["run-hook"]) - expected = self.get_expected("cli/test_cli_hooks/test_run_hook_negative_1", {"git_repo": os.getcwd()}) + expected_kwargs = {"git_repo": os.path.realpath(os.getcwd())} + expected = self.get_expected("cli/test_cli_hooks/test_run_hook_negative_1", expected_kwargs) self.assertEqual(result.output, expected) self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) @@ -276,11 +268,10 @@ class CLIHookTests(BaseTestCase): "commit-1-branch-1\ncommit-1-branch-2\n", ] - with self.patch_input(["e"]): - with patch("gitlint.display.stderr", new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["run-hook"]) - expected = self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stderr") - self.assertEqual(stderr.getvalue(), expected) - self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stdout")) - # If we can't edit the message, run-hook follows regular gitlint behavior and exit code = # violations - self.assertEqual(result.exit_code, 2) + with self.patch_input(["e"]), patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["run-hook"]) + expected = self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stderr") + self.assertEqual(stderr.getvalue(), expected) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stdout")) + # If we can't edit the message, run-hook follows regular gitlint behavior and exit code = # violations + self.assertEqual(result.exit_code, 2) diff --git a/gitlint-core/gitlint/tests/config/test_config.py b/gitlint-core/gitlint/tests/config/test_config.py index 852bf75..439fd93 100644 --- a/gitlint-core/gitlint/tests/config/test_config.py +++ b/gitlint-core/gitlint/tests/config/test_config.py @@ -1,8 +1,12 @@ from unittest.mock import patch -from gitlint import rules -from gitlint.config import LintConfig, LintConfigError, LintConfigGenerator, GITLINT_CONFIG_TEMPLATE_SRC_PATH -from gitlint import options +from gitlint import options, rules +from gitlint.config import ( + GITLINT_CONFIG_TEMPLATE_SRC_PATH, + LintConfig, + LintConfigError, + LintConfigGenerator, +) from gitlint.tests.base import BaseTestCase @@ -166,7 +170,7 @@ class LintConfigTests(BaseTestCase): # UserRuleError, RuleOptionError should be re-raised as LintConfigErrors side_effects = [rules.UserRuleError("üser-rule"), options.RuleOptionError("rüle-option")] for side_effect in side_effects: - with patch("gitlint.config.rule_finder.find_rule_classes", side_effect=side_effect): + with patch("gitlint.config.rule_finder.find_rule_classes", side_effect=side_effect): # noqa: SIM117 with self.assertRaisesMessage(LintConfigError, str(side_effect)): config.contrib = "contrib-title-conventional-commits" diff --git a/gitlint-core/gitlint/tests/config/test_config_builder.py b/gitlint-core/gitlint/tests/config/test_config_builder.py index dfb77cd..ac2a896 100644 --- a/gitlint-core/gitlint/tests/config/test_config_builder.py +++ b/gitlint-core/gitlint/tests/config/test_config_builder.py @@ -1,10 +1,8 @@ import copy -from gitlint.tests.base import BaseTestCase - -from gitlint.config import LintConfig, LintConfigBuilder, LintConfigError - from gitlint import rules +from gitlint.config import LintConfig, LintConfigBuilder, LintConfigError +from gitlint.tests.base import BaseTestCase class LintConfigBuilderTests(BaseTestCase): @@ -256,8 +254,7 @@ class LintConfigBuilderTests(BaseTestCase): my_rule.options["regex"].set("wrong") def test_named_rules_negative(self): - # T7 = title-match-regex - # Invalid rule name + # Invalid rule name (T7 = title-match-regex) for invalid_name in ["", " ", " ", "\t", "\n", "å b", "å:b", "åb:", ":åb"]: config_builder = LintConfigBuilder() config_builder.set_option(f"T7:{invalid_name}", "regex", "tëst") diff --git a/gitlint-core/gitlint/tests/config/test_config_precedence.py b/gitlint-core/gitlint/tests/config/test_config_precedence.py index 22197e8..a7f94cf 100644 --- a/gitlint-core/gitlint/tests/config/test_config_precedence.py +++ b/gitlint-core/gitlint/tests/config/test_config_precedence.py @@ -1,12 +1,10 @@ from io import StringIO - -from click.testing import CliRunner - from unittest.mock import patch -from gitlint.tests.base import BaseTestCase +from click.testing import CliRunner from gitlint import cli from gitlint.config import LintConfigBuilder +from gitlint.tests.base import BaseTestCase class LintConfigPrecedenceTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/config/test_rule_collection.py b/gitlint-core/gitlint/tests/config/test_rule_collection.py index ea7039f..2cb0e5c 100644 --- a/gitlint-core/gitlint/tests/config/test_rule_collection.py +++ b/gitlint-core/gitlint/tests/config/test_rule_collection.py @@ -1,4 +1,5 @@ from collections import OrderedDict + from gitlint import rules from gitlint.config import RuleCollection from gitlint.tests.base import BaseTestCase diff --git a/gitlint-core/gitlint/tests/contrib/rules/test_authors_commit.py b/gitlint-core/gitlint/tests/contrib/rules/test_authors_commit.py index 5ea9d8f..2bad2ed 100644 --- a/gitlint-core/gitlint/tests/contrib/rules/test_authors_commit.py +++ b/gitlint-core/gitlint/tests/contrib/rules/test_authors_commit.py @@ -1,10 +1,10 @@ from collections import namedtuple from unittest.mock import patch -from gitlint.tests.base import BaseTestCase -from gitlint.rules import RuleViolation -from gitlint.config import LintConfig +from gitlint.config import LintConfig from gitlint.contrib.rules.authors_commit import AllowedAuthors +from gitlint.rules import RuleViolation +from gitlint.tests.base import BaseTestCase class ContribAuthorsCommitTests(BaseTestCase): @@ -101,6 +101,5 @@ class ContribAuthorsCommitTests(BaseTestCase): return_value=False, ) def test_read_authors_file_missing_file(self, _mock_iterdir): - with self.assertRaises(FileNotFoundError) as err: + with self.assertRaisesMessage(FileNotFoundError, "No AUTHORS file found!"): AllowedAuthors._read_authors_from_file(self.gitcontext) - self.assertEqual(err.exception.args[0], "AUTHORS file not found") diff --git a/gitlint-core/gitlint/tests/contrib/rules/test_conventional_commit.py b/gitlint-core/gitlint/tests/contrib/rules/test_conventional_commit.py index 7ce9c89..cbab684 100644 --- a/gitlint-core/gitlint/tests/contrib/rules/test_conventional_commit.py +++ b/gitlint-core/gitlint/tests/contrib/rules/test_conventional_commit.py @@ -1,7 +1,7 @@ -from gitlint.tests.base import BaseTestCase -from gitlint.rules import RuleViolation -from gitlint.contrib.rules.conventional_commit import ConventionalCommit from gitlint.config import LintConfig +from gitlint.contrib.rules.conventional_commit import ConventionalCommit +from gitlint.rules import RuleViolation +from gitlint.tests.base import BaseTestCase class ContribConventionalCommitTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/contrib/rules/test_disallow_cleanup_commits.py b/gitlint-core/gitlint/tests/contrib/rules/test_disallow_cleanup_commits.py index 841640a..1983367 100644 --- a/gitlint-core/gitlint/tests/contrib/rules/test_disallow_cleanup_commits.py +++ b/gitlint-core/gitlint/tests/contrib/rules/test_disallow_cleanup_commits.py @@ -1,8 +1,7 @@ -from gitlint.tests.base import BaseTestCase -from gitlint.rules import RuleViolation -from gitlint.contrib.rules.disallow_cleanup_commits import DisallowCleanupCommits - from gitlint.config import LintConfig +from gitlint.contrib.rules.disallow_cleanup_commits import DisallowCleanupCommits +from gitlint.rules import RuleViolation +from gitlint.tests.base import BaseTestCase class ContribDisallowCleanupCommitsTest(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/contrib/rules/test_signedoff_by.py b/gitlint-core/gitlint/tests/contrib/rules/test_signedoff_by.py index 88ff1db..bf526a0 100644 --- a/gitlint-core/gitlint/tests/contrib/rules/test_signedoff_by.py +++ b/gitlint-core/gitlint/tests/contrib/rules/test_signedoff_by.py @@ -1,8 +1,7 @@ -from gitlint.tests.base import BaseTestCase -from gitlint.rules import RuleViolation -from gitlint.contrib.rules.signedoff_by import SignedOffBy - from gitlint.config import LintConfig +from gitlint.contrib.rules.signedoff_by import SignedOffBy +from gitlint.rules import RuleViolation +from gitlint.tests.base import BaseTestCase class ContribSignedOffByTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/contrib/test_contrib_rules.py b/gitlint-core/gitlint/tests/contrib/test_contrib_rules.py index bd098c6..b0372d8 100644 --- a/gitlint-core/gitlint/tests/contrib/test_contrib_rules.py +++ b/gitlint-core/gitlint/tests/contrib/test_contrib_rules.py @@ -1,9 +1,9 @@ import os -from gitlint.tests.base import BaseTestCase +from gitlint import rule_finder, rules from gitlint.contrib import rules as contrib_rules +from gitlint.tests.base import BaseTestCase from gitlint.tests.contrib import rules as contrib_tests -from gitlint import rule_finder, rules class ContribRuleTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_debug_1 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_debug_1 index 4bd3b7d..046294c 100644 --- a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_debug_1 +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_debug_1 @@ -4,7 +4,8 @@ DEBUG: gitlint.cli Python version: {python_version} DEBUG: gitlint.cli Git version: git version 1.2.3 DEBUG: gitlint.cli Gitlint version: {gitlint_version} DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} -DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli TERMINAL_ENCODING: {TERMINAL_ENCODING} +DEBUG: gitlint.cli FILE_ENCODING: {FILE_ENCODING} DEBUG: gitlint.cli Configuration config-path: {config_path} [GENERAL] @@ -88,8 +89,7 @@ Parents: ['a123'] Branches: ['commit-1-branch-1', 'commit-1-branch-2'] Changed Files: ['commit-1/file-1', 'commit-1/file-2'] Changed Files Stats: - commit-1/file-1: 5 additions, 8 deletions - commit-1/file-2: 2 additions, 9 deletions +{changed_files_stats1} ----------------------- DEBUG: gitlint.git ('log', '25053ccec5e28e1bb8f7551fdbb5ab213ada2401', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B') DEBUG: gitlint.lint Linting commit 25053ccec5e28e1bb8f7551fdbb5ab213ada2401 @@ -112,8 +112,7 @@ Parents: ['b123'] Branches: ['commit-2-branch-1', 'commit-2-branch-2'] Changed Files: ['commit-2/file-1', 'commit-2/file-2'] Changed Files Stats: - commit-2/file-1: 5 additions, 8 deletions - commit-2/file-2: 7 additions, 9 deletions +{changed_files_stats2} ----------------------- DEBUG: gitlint.git ('log', '4da2656b0dadc76c7ee3fd0243a96cb64007f125', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B') DEBUG: gitlint.lint Linting commit 4da2656b0dadc76c7ee3fd0243a96cb64007f125 @@ -135,7 +134,6 @@ Parents: ['c123'] Branches: ['commit-3-branch-1', 'commit-3-branch-2'] Changed Files: ['commit-3/file-1', 'commit-3/file-2'] Changed Files Stats: - commit-3/file-1: 1 additions, 4 deletions - commit-3/file-2: 3 additions, 4 deletions +{changed_files_stats3} ----------------------- DEBUG: gitlint.cli Exit Code = 6
\ No newline at end of file diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_input_stream_debug_2 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_input_stream_debug_2 index 6d6da43..46a8adf 100644 --- a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_input_stream_debug_2 +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_input_stream_debug_2 @@ -4,7 +4,8 @@ DEBUG: gitlint.cli Python version: {python_version} DEBUG: gitlint.cli Git version: git version 1.2.3 DEBUG: gitlint.cli Gitlint version: {gitlint_version} DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} -DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli TERMINAL_ENCODING: {TERMINAL_ENCODING} +DEBUG: gitlint.cli FILE_ENCODING: {FILE_ENCODING} DEBUG: gitlint.cli Configuration config-path: None [GENERAL] diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_multiple_commits_csv_1 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_multiple_commits_csv_1 new file mode 100644 index 0000000..be3288b --- /dev/null +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_multiple_commits_csv_1 @@ -0,0 +1,8 @@ +Commit 6f29bf81a8: +3: B5 Body message is too short (12<20): "commït-body1" + +Commit 25053ccec5: +3: B5 Body message is too short (12<20): "commït-body2" + +Commit 4da2656b0d: +3: B5 Body message is too short (12<20): "commït-body3" diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_msg_filename_2 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_msg_filename_2 index 59b2414..6b96a45 100644 --- a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_msg_filename_2 +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_msg_filename_2 @@ -4,7 +4,8 @@ DEBUG: gitlint.cli Python version: {python_version} DEBUG: gitlint.cli Git version: git version 1.2.3 DEBUG: gitlint.cli Gitlint version: {gitlint_version} DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} -DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli TERMINAL_ENCODING: {TERMINAL_ENCODING} +DEBUG: gitlint.cli FILE_ENCODING: {FILE_ENCODING} DEBUG: gitlint.cli Configuration config-path: None [GENERAL] @@ -87,7 +88,6 @@ Parents: [] Branches: ['my-branch'] Changed Files: ['commit-1/file-1', 'commit-1/file-2'] Changed Files Stats: - commit-1/file-1: 3 additions, 4 deletions - commit-1/file-2: 4 additions, 7 deletions +{changed_files_stats} ----------------------- DEBUG: gitlint.cli Exit Code = 2
\ No newline at end of file diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_stdin_2 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_stdin_2 index 23df7b2..45d94e2 100644 --- a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_stdin_2 +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_lint_staged_stdin_2 @@ -4,7 +4,8 @@ DEBUG: gitlint.cli Python version: {python_version} DEBUG: gitlint.cli Git version: git version 1.2.3 DEBUG: gitlint.cli Gitlint version: {gitlint_version} DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} -DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli TERMINAL_ENCODING: {TERMINAL_ENCODING} +DEBUG: gitlint.cli FILE_ENCODING: {FILE_ENCODING} DEBUG: gitlint.cli Configuration config-path: None [GENERAL] @@ -89,7 +90,6 @@ Parents: [] Branches: ['my-branch'] Changed Files: ['commit-1/file-1', 'commit-1/file-2'] Changed Files Stats: - commit-1/file-1: 1 additions, 5 deletions - commit-1/file-2: 8 additions, 9 deletions +{changed_files_stats} ----------------------- DEBUG: gitlint.cli Exit Code = 3
\ No newline at end of file diff --git a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_named_rules_2 b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_named_rules_2 index c4491f1..f4df46e 100644 --- a/gitlint-core/gitlint/tests/expected/cli/test_cli/test_named_rules_2 +++ b/gitlint-core/gitlint/tests/expected/cli/test_cli/test_named_rules_2 @@ -4,7 +4,8 @@ DEBUG: gitlint.cli Python version: {python_version} DEBUG: gitlint.cli Git version: git version 1.2.3 DEBUG: gitlint.cli Gitlint version: {gitlint_version} DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} -DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli TERMINAL_ENCODING: {TERMINAL_ENCODING} +DEBUG: gitlint.cli FILE_ENCODING: {FILE_ENCODING} DEBUG: gitlint.cli Configuration config-path: {config_path} [GENERAL] diff --git a/gitlint-core/gitlint/tests/git/test_git.py b/gitlint-core/gitlint/tests/git/test_git.py index 9c73bd9..b6a146a 100644 --- a/gitlint-core/gitlint/tests/git/test_git.py +++ b/gitlint-core/gitlint/tests/git/test_git.py @@ -1,11 +1,15 @@ import os - -from unittest.mock import patch, call - -from gitlint.shell import ErrorReturnCode, CommandNotFound - +from unittest.mock import call, patch + +from gitlint.git import ( + GitContext, + GitContextError, + GitNotInstalledError, + git_commentchar, + git_hooks_dir, +) +from gitlint.shell import CommandNotFound, ErrorReturnCode from gitlint.tests.base import BaseTestCase -from gitlint.git import GitContext, GitContextError, GitNotInstalledError, git_commentchar, git_hooks_dir class GitTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/git/test_git_commit.py b/gitlint-core/gitlint/tests/git/test_git_commit.py index b27deaf..e6b0b2c 100644 --- a/gitlint-core/gitlint/tests/git/test_git_commit.py +++ b/gitlint-core/gitlint/tests/git/test_git_commit.py @@ -1,25 +1,21 @@ import copy import datetime from pathlib import Path - -import dateutil +from unittest.mock import call, patch import arrow - -from unittest.mock import patch, call - -from gitlint.tests.base import BaseTestCase +import dateutil from gitlint.git import ( GitChangedFileStats, - GitContext, GitCommit, + GitCommitMessage, + GitContext, GitContextError, LocalGitCommit, StagedLocalGitCommit, - GitCommitMessage, - GitChangedFileStats, ) from gitlint.shell import ErrorReturnCode +from gitlint.tests.base import BaseTestCase class GitCommitTests(BaseTestCase): @@ -383,7 +379,7 @@ class GitCommitTests(BaseTestCase): @patch("gitlint.git.sh") def test_get_latest_commit_fixup_squash_commit(self, sh): commit_prefixes = {"fixup": "is_fixup_commit", "squash": "is_squash_commit", "amend": "is_fixup_amend_commit"} - for commit_type in commit_prefixes.keys(): + for commit_type in commit_prefixes: sample_sha = "d8ac47e9f2923c7f22d8668e3a1ed04eb4cdbca9" sh.git.side_effect = [ @@ -616,7 +612,7 @@ class GitCommitTests(BaseTestCase): # mapping between cleanup commit prefixes and the commit object attribute commit_prefixes = {"fixup": "is_fixup_commit", "squash": "is_squash_commit", "amend": "is_fixup_amend_commit"} - for commit_type in commit_prefixes.keys(): + for commit_type in commit_prefixes: commit_msg = f"{commit_type}! Test message" gitcontext = GitContext.from_commit_msg(commit_msg) commit = gitcontext.commits[-1] @@ -642,7 +638,7 @@ class GitCommitTests(BaseTestCase): @patch("gitlint.git.sh") @patch("arrow.now") def test_staged_commit(self, now, sh): - # StagedLocalGitCommit() + """Test for StagedLocalGitCommit()""" sh.git.side_effect = [ "#", # git config --get core.commentchar @@ -744,7 +740,7 @@ class GitCommitTests(BaseTestCase): git.return_value = "foöbar" # Test simple equality case - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.timezone.utc) context1 = GitContext() commit_message1 = GitCommitMessage(context1, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit1 = GitCommit( diff --git a/gitlint-core/gitlint/tests/git/test_git_context.py b/gitlint-core/gitlint/tests/git/test_git_context.py index 3dcbe4a..751136c 100644 --- a/gitlint-core/gitlint/tests/git/test_git_context.py +++ b/gitlint-core/gitlint/tests/git/test_git_context.py @@ -1,7 +1,7 @@ -from unittest.mock import patch, call +from unittest.mock import call, patch -from gitlint.tests.base import BaseTestCase from gitlint.git import GitContext +from gitlint.tests.base import BaseTestCase class GitContextTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/rules/test_body_rules.py b/gitlint-core/gitlint/tests/rules/test_body_rules.py index 94b1edf..c142e6e 100644 --- a/gitlint-core/gitlint/tests/rules/test_body_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_body_rules.py @@ -1,5 +1,5 @@ -from gitlint.tests.base import BaseTestCase from gitlint import rules +from gitlint.tests.base import BaseTestCase class BodyRuleTests(BaseTestCase): @@ -100,13 +100,13 @@ class BodyRuleTests(BaseTestCase): expected_violation = rules.RuleViolation("B5", "Body message is too short (21<120)", "å" * 21, 3) rule = rules.BodyMinLength({"min-length": 120}) - commit = self.gitcommit("Title\n\n{}\n".format("å" * 21)) # pylint: disable=consider-using-f-string + commit = self.gitcommit("Title\n\n{}\n".format("å" * 21)) violations = rule.validate(commit) self.assertListEqual(violations, [expected_violation]) # Make sure we don't get the error if the body-length is exactly the min-length rule = rules.BodyMinLength({"min-length": 8}) - commit = self.gitcommit("Tïtle\n\n{}\n".format("å" * 8)) # pylint: disable=consider-using-f-string + commit = self.gitcommit("Tïtle\n\n{}\n".format("å" * 8)) violations = rule.validate(commit) self.assertIsNone(violations) diff --git a/gitlint-core/gitlint/tests/rules/test_configuration_rules.py b/gitlint-core/gitlint/tests/rules/test_configuration_rules.py index 9e3b07c..5935a4a 100644 --- a/gitlint-core/gitlint/tests/rules/test_configuration_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_configuration_rules.py @@ -1,6 +1,9 @@ -from gitlint.tests.base import BaseTestCase, EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING from gitlint import rules from gitlint.config import LintConfig +from gitlint.tests.base import ( + EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING, + BaseTestCase, +) class ConfigurationRuleTests(BaseTestCase): @@ -89,6 +92,25 @@ class ConfigurationRuleTests(BaseTestCase): self.assertEqual(config, LintConfig()) self.assert_logged([]) # nothing logged -> nothing ignored + # No author available -> rule is skipped and warning logged + staged_commit = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line") + rule = rules.IgnoreByAuthorName({"regex": "foo"}) + config = LintConfig() + rule.apply(config, staged_commit) + self.assertEqual(config, LintConfig()) + expected_log_messages = [ + "WARNING: gitlint.rules ignore-by-author-name - I4: skipping - commit.author_name unknown. " + "Suggested fix: Use the --staged flag (or set general.staged=True in .gitlint). " + "More details: https://jorisroovers.com/gitlint/configuration/#staged" + ] + self.assert_logged(expected_log_messages) + + # Non-Matching regex -> expect config to stay the same + rule = rules.IgnoreByAuthorName({"regex": "foo"}) + expected_config = LintConfig() + rule.apply(config, commit) + self.assertEqual(config, LintConfig()) + # Matching regex -> expect config to ignore all rules rule = rules.IgnoreByAuthorName({"regex": "(.*)ëst(.*)"}) expected_config = LintConfig() @@ -96,7 +118,7 @@ class ConfigurationRuleTests(BaseTestCase): rule.apply(config, commit) self.assertEqual(config, expected_config) - expected_log_messages = [ + expected_log_messages += [ EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING.format("I4", "ignore-by-author-name"), "DEBUG: gitlint.rules Ignoring commit because of rule 'I4': " "Commit Author Name 'Tëst nåme' matches the regex '(.*)ëst(.*)'," diff --git a/gitlint-core/gitlint/tests/rules/test_meta_rules.py b/gitlint-core/gitlint/tests/rules/test_meta_rules.py index 0b8a10a..a574aa3 100644 --- a/gitlint-core/gitlint/tests/rules/test_meta_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_meta_rules.py @@ -1,5 +1,8 @@ -from gitlint.tests.base import BaseTestCase, EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING from gitlint.rules import AuthorValidEmail, RuleViolation +from gitlint.tests.base import ( + EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING, + BaseTestCase, +) class MetaRuleTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/rules/test_rules.py b/gitlint-core/gitlint/tests/rules/test_rules.py index 199cc7e..b401372 100644 --- a/gitlint-core/gitlint/tests/rules/test_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_rules.py @@ -1,8 +1,12 @@ -from gitlint.tests.base import BaseTestCase from gitlint.rules import Rule, RuleViolation +from gitlint.tests.base import BaseTestCase class RuleTests(BaseTestCase): + def test_ruleviolation__str__(self): + expected = '57: rule-ïd Tēst message: "Tēst content"' + self.assertEqual(str(RuleViolation("rule-ïd", "Tēst message", "Tēst content", 57)), expected) + def test_rule_equality(self): self.assertEqual(Rule(), Rule()) # Ensure rules are not equal if they differ on their attributes @@ -13,9 +17,16 @@ class RuleTests(BaseTestCase): def test_rule_log(self): rule = Rule() + self.assertIsNone(rule._log) rule.log.debug("Tēst message") self.assert_log_contains("DEBUG: gitlint.rules Tēst message") + # Assert the same logger is reused when logging multiple messages + log = rule._log + rule.log.debug("Anöther message") + self.assertEqual(log, rule._log) + self.assert_log_contains("DEBUG: gitlint.rules Anöther message") + def test_rule_violation_equality(self): violation1 = RuleViolation("ïd1", "My messåge", "My cöntent", 1) self.object_equality_test(violation1, ["rule_id", "message", "content", "line_nr"]) diff --git a/gitlint-core/gitlint/tests/rules/test_title_rules.py b/gitlint-core/gitlint/tests/rules/test_title_rules.py index 4796e54..cba3851 100644 --- a/gitlint-core/gitlint/tests/rules/test_title_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_title_rules.py @@ -1,15 +1,15 @@ -from gitlint.tests.base import BaseTestCase from gitlint.rules import ( - TitleMaxLength, - TitleTrailingWhitespace, + RuleViolation, TitleHardTab, - TitleMustNotContainWord, - TitleTrailingPunctuation, TitleLeadingWhitespace, - TitleRegexMatches, - RuleViolation, + TitleMaxLength, TitleMinLength, + TitleMustNotContainWord, + TitleRegexMatches, + TitleTrailingPunctuation, + TitleTrailingWhitespace, ) +from gitlint.tests.base import BaseTestCase class TitleRuleTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/rules/test_user_rules.py b/gitlint-core/gitlint/tests/rules/test_user_rules.py index fc8d423..8086bea 100644 --- a/gitlint-core/gitlint/tests/rules/test_user_rules.py +++ b/gitlint-core/gitlint/tests/rules/test_user_rules.py @@ -1,11 +1,10 @@ import os import sys -from gitlint.tests.base import BaseTestCase -from gitlint.rule_finder import find_rule_classes, assert_valid_rule_class -from gitlint.rules import UserRuleError - from gitlint import options, rules +from gitlint.rule_finder import assert_valid_rule_class, find_rule_classes +from gitlint.rules import UserRuleError +from gitlint.tests.base import BaseTestCase class UserRuleTests(BaseTestCase): @@ -104,21 +103,21 @@ class UserRuleTests(BaseTestCase): target = rules.CommitMessageTitle def validate(self): - pass + pass # pragma: nocover class MyCommitRuleClass(rules.CommitRule): id = "UC2" name = "my-cömmit-rule" def validate(self): - pass + pass # pragma: nocover class MyConfigurationRuleClass(rules.ConfigurationRule): id = "UC3" name = "my-cönfiguration-rule" def apply(self): - pass + pass # pragma: nocover # Just assert that no error is raised self.assertIsNone(assert_valid_rule_class(MyLineRuleClass)) @@ -203,7 +202,7 @@ class UserRuleTests(BaseTestCase): assert_valid_rule_class(MyRuleClass) # option_spec is a list, but not of gitlint options - MyRuleClass.options_spec = ["föo", 123] # pylint: disable=bad-option-value,redefined-variable-type + MyRuleClass.options_spec = ["föo", 123] with self.assertRaisesMessage(UserRuleError, expected_msg): assert_valid_rule_class(MyRuleClass) @@ -236,8 +235,8 @@ class UserRuleTests(BaseTestCase): with self.assertRaisesMessage(UserRuleError, expected_msg): assert_valid_rule_class(MyRuleClass) - # validate attribute - not a method - MyRuleClass.validate = "föo" + # apply attribute - not a method + MyRuleClass.apply = "föo" with self.assertRaisesMessage(UserRuleError, expected_msg): assert_valid_rule_class(MyRuleClass) @@ -247,7 +246,7 @@ class UserRuleTests(BaseTestCase): name = "my-rüle-class" def validate(self): - pass + pass # pragma: nocover # no target expected_msg = ( @@ -263,5 +262,5 @@ class UserRuleTests(BaseTestCase): assert_valid_rule_class(MyRuleClass) # valid target, no exception should be raised - MyRuleClass.target = rules.CommitMessageTitle # pylint: disable=bad-option-value,redefined-variable-type + MyRuleClass.target = rules.CommitMessageTitle self.assertIsNone(assert_valid_rule_class(MyRuleClass)) diff --git a/gitlint-core/gitlint/tests/samples/user_rules/my_commit_rules.py b/gitlint-core/gitlint/tests/samples/user_rules/my_commit_rules.py index 02c922d..c947250 100644 --- a/gitlint-core/gitlint/tests/samples/user_rules/my_commit_rules.py +++ b/gitlint-core/gitlint/tests/samples/user_rules/my_commit_rules.py @@ -1,5 +1,5 @@ -from gitlint.rules import CommitRule, RuleViolation from gitlint.options import IntOption +from gitlint.rules import CommitRule, RuleViolation class MyUserCommitRule(CommitRule): @@ -19,7 +19,7 @@ class MyUserCommitRule(CommitRule): def func_should_be_ignored(): - pass + pass # pragma: nocover global_variable_should_be_ignored = True diff --git a/gitlint-core/gitlint/tests/samples/user_rules/parent_package/__init__.py b/gitlint-core/gitlint/tests/samples/user_rules/parent_package/__init__.py index 22c3f65..c2863fe 100644 --- a/gitlint-core/gitlint/tests/samples/user_rules/parent_package/__init__.py +++ b/gitlint-core/gitlint/tests/samples/user_rules/parent_package/__init__.py @@ -9,4 +9,4 @@ class InitFileRule(CommitRule): options_spec = [] def validate(self, _commit): - return [] + return [] # pragma: nocover diff --git a/gitlint-core/gitlint/tests/test_cache.py b/gitlint-core/gitlint/tests/test_cache.py index 9c327dc..08b821e 100644 --- a/gitlint-core/gitlint/tests/test_cache.py +++ b/gitlint-core/gitlint/tests/test_cache.py @@ -1,5 +1,5 @@ -from gitlint.tests.base import BaseTestCase from gitlint.cache import PropertyCache, cache +from gitlint.tests.base import BaseTestCase class CacheTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/test_deprecation.py b/gitlint-core/gitlint/tests/test_deprecation.py index d85593a..bfe5934 100644 --- a/gitlint-core/gitlint/tests/test_deprecation.py +++ b/gitlint-core/gitlint/tests/test_deprecation.py @@ -1,7 +1,10 @@ from gitlint.config import LintConfig from gitlint.deprecation import Deprecation from gitlint.rules import IgnoreByTitle -from gitlint.tests.base import EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING, BaseTestCase +from gitlint.tests.base import ( + EXPECTED_REGEX_STYLE_SEARCH_DEPRECATION_WARNING, + BaseTestCase, +) class DeprecationTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/test_display.py b/gitlint-core/gitlint/tests/test_display.py index 1f759d2..e669cdb 100644 --- a/gitlint-core/gitlint/tests/test_display.py +++ b/gitlint-core/gitlint/tests/test_display.py @@ -1,9 +1,8 @@ from io import StringIO +from unittest.mock import patch -from unittest.mock import patch # pylint: disable=no-name-in-module, import-error - -from gitlint.display import Display from gitlint.config import LintConfig +from gitlint.display import Display from gitlint.tests.base import BaseTestCase diff --git a/gitlint-core/gitlint/tests/test_hooks.py b/gitlint-core/gitlint/tests/test_hooks.py index f92b148..7390f14 100644 --- a/gitlint-core/gitlint/tests/test_hooks.py +++ b/gitlint-core/gitlint/tests/test_hooks.py @@ -1,16 +1,15 @@ import os +from unittest.mock import ANY, mock_open, patch -from unittest.mock import patch, ANY, mock_open - -from gitlint.tests.base import BaseTestCase from gitlint.config import LintConfig from gitlint.hooks import ( - GitHookInstaller, - GitHookInstallerError, - COMMIT_MSG_HOOK_SRC_PATH, COMMIT_MSG_HOOK_DST_PATH, + COMMIT_MSG_HOOK_SRC_PATH, GITLINT_HOOK_IDENTIFIER, + GitHookInstaller, + GitHookInstallerError, ) +from gitlint.tests.base import BaseTestCase class HookTests(BaseTestCase): @@ -58,9 +57,10 @@ class HookTests(BaseTestCase): expected_msg = f"{lint_config.target} is not a git repository." with self.assertRaisesMessage(GitHookInstallerError, expected_msg): GitHookInstaller.install_commit_msg_hook(lint_config) - isdir.assert_called_with(git_hooks_dir.return_value) - path_exists.assert_not_called() - copy.assert_not_called() + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_not_called() + copy.assert_not_called() # mock that there is already a commit hook present isdir.return_value = True @@ -106,9 +106,10 @@ class HookTests(BaseTestCase): expected_msg = f"{lint_config.target} is not a git repository." with self.assertRaisesMessage(GitHookInstallerError, expected_msg): GitHookInstaller.uninstall_commit_msg_hook(lint_config) - isdir.assert_called_with(git_hooks_dir.return_value) - path_exists.assert_not_called() - remove.assert_not_called() + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_not_called() + remove.assert_not_called() # mock that there is no commit hook present isdir.return_value = True @@ -117,9 +118,10 @@ class HookTests(BaseTestCase): expected_msg = f"There is no commit-msg hook present in {expected_dst}." with self.assertRaisesMessage(GitHookInstallerError, expected_msg): GitHookInstaller.uninstall_commit_msg_hook(lint_config) - isdir.assert_called_with(git_hooks_dir.return_value) - path_exists.assert_called_once_with(expected_dst) - remove.assert_not_called() + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_called_once_with(expected_dst) + remove.assert_not_called() # mock that there is a different (=not gitlint) commit hook isdir.return_value = True diff --git a/gitlint-core/gitlint/tests/test_lint.py b/gitlint-core/gitlint/tests/test_lint.py index 2af4615..1cf3772 100644 --- a/gitlint-core/gitlint/tests/test_lint.py +++ b/gitlint-core/gitlint/tests/test_lint.py @@ -1,11 +1,10 @@ from io import StringIO +from unittest.mock import patch -from unittest.mock import patch # pylint: disable=no-name-in-module, import-error - -from gitlint.tests.base import BaseTestCase +from gitlint.config import LintConfig, LintConfigBuilder from gitlint.lint import GitLinter from gitlint.rules import RuleViolation, TitleMustNotContainWord -from gitlint.config import LintConfig, LintConfigBuilder +from gitlint.tests.base import BaseTestCase class LintTests(BaseTestCase): diff --git a/gitlint-core/gitlint/tests/test_options.py b/gitlint-core/gitlint/tests/test_options.py index 7b146e7..deff723 100644 --- a/gitlint-core/gitlint/tests/test_options.py +++ b/gitlint-core/gitlint/tests/test_options.py @@ -1,12 +1,23 @@ import os import re +from gitlint.options import ( + BoolOption, + IntOption, + ListOption, + PathOption, + RegexOption, + RuleOptionError, + StrOption, +) from gitlint.tests.base import BaseTestCase -from gitlint.options import IntOption, BoolOption, StrOption, ListOption, PathOption, RegexOption, RuleOptionError - class RuleOptionTests(BaseTestCase): + def test_option__str__(self): + option = StrOption("tëst-option", "åbc", "Test Dëscription") + self.assertEqual(str(option), "(tëst-option: åbc (Test Dëscription))") + def test_option_equality(self): options = { IntOption: 123, @@ -158,7 +169,7 @@ class RuleOptionTests(BaseTestCase): option = PathOption("tëst-directory", ".", "Tëst Description", type="dir") self.assertEqual(option.name, "tëst-directory") self.assertEqual(option.description, "Tëst Description") - self.assertEqual(option.value, os.getcwd()) + self.assertEqual(option.value, os.path.realpath(".")) self.assertEqual(option.type, "dir") # re-set value diff --git a/gitlint-core/gitlint/tests/test_utils.py b/gitlint-core/gitlint/tests/test_utils.py index 27036d3..d21ec3f 100644 --- a/gitlint-core/gitlint/tests/test_utils.py +++ b/gitlint-core/gitlint/tests/test_utils.py @@ -27,7 +27,7 @@ class UtilsTests(BaseTestCase): self.assertEqual(utils.use_sh_library(), False) @patch("gitlint.utils.locale") - def test_default_encoding_non_windows(self, mocked_locale): + def test_terminal_encoding_non_windows(self, mocked_locale): utils.PLATFORM_IS_WINDOWS = False mocked_locale.getpreferredencoding.return_value = "foöbar" self.assertEqual(utils.getpreferredencoding(), "foöbar") @@ -37,7 +37,7 @@ class UtilsTests(BaseTestCase): self.assertEqual(utils.getpreferredencoding(), "UTF-8") @patch("os.environ") - def test_default_encoding_windows(self, patched_env): + def test_terminal_encoding_windows(self, patched_env): utils.PLATFORM_IS_WINDOWS = True # Mock out os.environ mock_env = {} |