Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve unit test coverage #453

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gitlint-core/gitlint/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import sys

if sys.version_info >= (3, 8):
from importlib import metadata
from importlib import metadata # pragma: nocover
else:
import importlib_metadata as metadata
import importlib_metadata as metadata # pragma: nocover

__version__ = metadata.version("gitlint-core")
5 changes: 0 additions & 5 deletions gitlint-core/gitlint/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,6 @@ def __eq__(self, other):
def __str__(self) -> str:
return f"{self.filepath}: {self.additions} additions, {self.deletions} deletions"

def __repr__(self) -> str:
return (
f'GitChangedFileStats(filepath="{self.filepath}", additions={self.additions}, deletions={self.deletions})'
)


class GitCommit:
"""Class representing a git commit.
Expand Down
1 change: 1 addition & 0 deletions gitlint-core/gitlint/rule_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def assert_valid_rule_class(clazz, rule_type="User-defined"): # noqa: PLR0912 (
if issubclass(clazz, (rules.LineRule, rules.CommitRule)):
if not hasattr(clazz, "validate") or not inspect.isroutine(clazz.validate):
raise rules.UserRuleError(f"{rule_type} rule class '{clazz.__name__}' must have a 'validate' method")

# Configuration rules must have an `apply` method
elif issubclass(clazz, rules.ConfigurationRule): # noqa: SIM102
if not hasattr(clazz, "apply") or not inspect.isroutine(clazz.apply):
Expand Down
8 changes: 5 additions & 3 deletions gitlint-core/gitlint/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,18 @@ def assertRaisesMessage(self, expected_exception, expected_msg):
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) from exc
# else: everything is fine, just return
return
except Exception as exc:
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.
Expand Down
39 changes: 39 additions & 0 deletions gitlint-core/gitlint/tests/cli/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,40 @@ def test_lint_multiple_commits(self, sh, _):
self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_multiple_commits_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_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, _):
Expand Down Expand Up @@ -600,6 +634,11 @@ def test_config_file_negative_environment(self):
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"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,5 @@ def test_read_authors_file(self, _mock_read_text):
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")
Original file line number Diff line number Diff line change
@@ -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"
6 changes: 6 additions & 0 deletions gitlint-core/gitlint/tests/rules/test_configuration_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ def test_ignore_by_author_name(self):
]
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()
Expand Down
11 changes: 11 additions & 0 deletions gitlint-core/gitlint/tests/rules/test_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@


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
Expand All @@ -13,9 +17,16 @@ def test_rule_equality(self):

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"])
12 changes: 6 additions & 6 deletions gitlint-core/gitlint/tests/rules/test_user_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,21 @@ class MyLineRuleClass(rules.LineRule):
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))
Expand Down Expand Up @@ -235,8 +235,8 @@ class MyRuleClass(rules.ConfigurationRule):
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)

Expand All @@ -246,7 +246,7 @@ class MyRuleClass(rules.LineRule):
name = "my-rüle-class"

def validate(self):
pass
pass # pragma: nocover

# no target
expected_msg = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def validate(self, _commit):


def func_should_be_ignored():
pass
pass # pragma: nocover


global_variable_should_be_ignored = True
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ class InitFileRule(CommitRule):
options_spec = []

def validate(self, _commit):
return []
return [] # pragma: nocover
21 changes: 12 additions & 9 deletions gitlint-core/gitlint/tests/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ def test_install_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exist
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
Expand Down Expand Up @@ -105,9 +106,10 @@ def test_uninstall_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exi
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
Expand All @@ -116,9 +118,10 @@ def test_uninstall_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exi
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
Expand Down
4 changes: 4 additions & 0 deletions gitlint-core/gitlint/tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@


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,
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,4 @@ branch = true # measure branch coverage in addition to statement coverage

[tool.coverage.report]
fail_under = 97
show_missing = true