# -*- coding: utf-8 -*- import copy import datetime import dateutil import arrow from unittest.mock import patch, call from gitlint.tests.base import BaseTestCase from gitlint.git import GitContext, GitCommit, GitContextError, LocalGitCommit, StagedLocalGitCommit, GitCommitMessage from gitlint.shell import ErrorReturnCode class GitCommitTests(BaseTestCase): # Expected special_args passed to 'sh' expected_sh_special_args = { '_tty_out': False, '_cwd': "fåke/path" } @patch('gitlint.git.sh') def test_get_latest_commit(self, sh): sample_sha = "d8ac47e9f2923c7f22d8668e3a1ed04eb4cdbca9" sh.git.side_effect = [ sample_sha, "test åuthor\x00test-emåil@foo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" "cömmit-title\n\ncömmit-body", "#", # git config --get core.commentchar "file1.txt\npåth/to/file2.txt\n", "foöbar\n* hürdur\n" ] context = GitContext.from_local_repository("fåke/path") # assert that commit info was read using git command expected_calls = [ call("log", "-1", "--pretty=%H", **self.expected_sh_special_args), call("log", sample_sha, "-1", "--pretty=%aN%x00%aE%x00%ai%x00%P%n%B", **self.expected_sh_special_args), call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', sample_sha, **self.expected_sh_special_args), call('branch', '--contains', sample_sha, **self.expected_sh_special_args) ] # Only first 'git log' call should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:1]) last_commit = context.commits[-1] self.assertIsInstance(last_commit, LocalGitCommit) self.assertEqual(last_commit.sha, sample_sha) self.assertEqual(last_commit.message.title, "cömmit-title") self.assertEqual(last_commit.message.body, ["", "cömmit-body"]) self.assertEqual(last_commit.author_name, "test åuthor") self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["åbc"]) self.assertFalse(last_commit.is_merge_commit) self.assertFalse(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) # First 2 'git log' calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:3]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) # 'git diff-tree' should have happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:4]) self.assertListEqual(last_commit.branches, ["foöbar", "hürdur"]) # All expected calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls) @patch('gitlint.git.sh') def test_from_local_repository_specific_refspec(self, sh): sample_refspec = "åbc123..def456" sample_sha = "åbc123" sh.git.side_effect = [ sample_sha, # git rev-list "test åuthor\x00test-emåil@foo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" "cömmit-title\n\ncömmit-body", "#", # git config --get core.commentchar "file1.txt\npåth/to/file2.txt\n", "foöbar\n* hürdur\n" ] context = GitContext.from_local_repository("fåke/path", refspec=sample_refspec) # assert that commit info was read using git command expected_calls = [ call("rev-list", sample_refspec, **self.expected_sh_special_args), call("log", sample_sha, "-1", "--pretty=%aN%x00%aE%x00%ai%x00%P%n%B", **self.expected_sh_special_args), call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', sample_sha, **self.expected_sh_special_args), call('branch', '--contains', sample_sha, **self.expected_sh_special_args) ] # Only first 'git log' call should've happened at this point self.assertEqual(sh.git.mock_calls, expected_calls[:1]) last_commit = context.commits[-1] self.assertIsInstance(last_commit, LocalGitCommit) self.assertEqual(last_commit.sha, sample_sha) self.assertEqual(last_commit.message.title, "cömmit-title") self.assertEqual(last_commit.message.body, ["", "cömmit-body"]) self.assertEqual(last_commit.author_name, "test åuthor") self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["åbc"]) self.assertFalse(last_commit.is_merge_commit) self.assertFalse(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) # First 2 'git log' calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:3]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) # 'git diff-tree' should have happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:4]) self.assertListEqual(last_commit.branches, ["foöbar", "hürdur"]) # All expected calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls) @patch('gitlint.git.sh') def test_from_local_repository_specific_commit_hash(self, sh): sample_hash = "åbc123" sh.git.side_effect = [ sample_hash, # git log -1 "test åuthor\x00test-emåil@foo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" "cömmit-title\n\ncömmit-body", "#", # git config --get core.commentchar "file1.txt\npåth/to/file2.txt\n", "foöbar\n* hürdur\n" ] context = GitContext.from_local_repository("fåke/path", commit_hash=sample_hash) # assert that commit info was read using git command expected_calls = [ call("log", "-1", sample_hash, "--pretty=%H", **self.expected_sh_special_args), call("log", sample_hash, "-1", "--pretty=%aN%x00%aE%x00%ai%x00%P%n%B", **self.expected_sh_special_args), call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', sample_hash, **self.expected_sh_special_args), call('branch', '--contains', sample_hash, **self.expected_sh_special_args) ] # Only first 'git log' call should've happened at this point self.assertEqual(sh.git.mock_calls, expected_calls[:1]) last_commit = context.commits[-1] self.assertIsInstance(last_commit, LocalGitCommit) self.assertEqual(last_commit.sha, sample_hash) self.assertEqual(last_commit.message.title, "cömmit-title") self.assertEqual(last_commit.message.body, ["", "cömmit-body"]) self.assertEqual(last_commit.author_name, "test åuthor") self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["åbc"]) self.assertFalse(last_commit.is_merge_commit) self.assertFalse(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) # First 2 'git log' calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:3]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) # 'git diff-tree' should have happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:4]) self.assertListEqual(last_commit.branches, ["foöbar", "hürdur"]) # All expected calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls) @patch('gitlint.git.sh') def test_get_latest_commit_merge_commit(self, sh): sample_sha = "d8ac47e9f2923c7f22d8668e3a1ed04eb4cdbca9" sh.git.side_effect = [ sample_sha, "test åuthor\x00test-emåil@foo.com\x002016-12-03 15:28:15 +0100\x00åbc def\n" "Merge \"foo bår commit\"", "#", # git config --get core.commentchar "file1.txt\npåth/to/file2.txt\n", "foöbar\n* hürdur\n" ] context = GitContext.from_local_repository("fåke/path") # assert that commit info was read using git command expected_calls = [ call("log", "-1", "--pretty=%H", **self.expected_sh_special_args), call("log", sample_sha, "-1", "--pretty=%aN%x00%aE%x00%ai%x00%P%n%B", **self.expected_sh_special_args), call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', sample_sha, **self.expected_sh_special_args), call('branch', '--contains', sample_sha, **self.expected_sh_special_args) ] # Only first 'git log' call should've happened at this point self.assertEqual(sh.git.mock_calls, expected_calls[:1]) last_commit = context.commits[-1] self.assertIsInstance(last_commit, LocalGitCommit) self.assertEqual(last_commit.sha, sample_sha) self.assertEqual(last_commit.message.title, "Merge \"foo bår commit\"") self.assertEqual(last_commit.message.body, []) self.assertEqual(last_commit.author_name, "test åuthor") self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["åbc", "def"]) self.assertTrue(last_commit.is_merge_commit) self.assertFalse(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) # First 2 'git log' calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:3]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) # 'git diff-tree' should have happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:4]) self.assertListEqual(last_commit.branches, ["foöbar", "hürdur"]) # All expected calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls) @patch('gitlint.git.sh') def test_get_latest_commit_fixup_squash_commit(self, sh): commit_types = ["fixup", "squash"] for commit_type in commit_types: sample_sha = "d8ac47e9f2923c7f22d8668e3a1ed04eb4cdbca9" sh.git.side_effect = [ sample_sha, "test åuthor\x00test-emåil@foo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" f"{commit_type}! \"foo bår commit\"", "#", # git config --get core.commentchar "file1.txt\npåth/to/file2.txt\n", "foöbar\n* hürdur\n" ] context = GitContext.from_local_repository("fåke/path") # assert that commit info was read using git command expected_calls = [ call("log", "-1", "--pretty=%H", **self.expected_sh_special_args), call("log", sample_sha, "-1", "--pretty=%aN%x00%aE%x00%ai%x00%P%n%B", **self.expected_sh_special_args), call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', sample_sha, **self.expected_sh_special_args), call('branch', '--contains', sample_sha, **self.expected_sh_special_args) ] # Only first 'git log' call should've happened at this point self.assertEqual(sh.git.mock_calls, expected_calls[:-4]) last_commit = context.commits[-1] self.assertIsInstance(last_commit, LocalGitCommit) self.assertEqual(last_commit.sha, sample_sha) self.assertEqual(last_commit.message.title, f"{commit_type}! \"foo bår commit\"") self.assertEqual(last_commit.message.body, []) self.assertEqual(last_commit.author_name, "test åuthor") self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertEqual(last_commit.date, datetime.datetime(2016, 12, 3, 15, 28, 15, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) self.assertListEqual(last_commit.parents, ["åbc"]) # First 2 'git log' calls should've happened at this point self.assertEqual(sh.git.mock_calls, expected_calls[:3]) # Asserting that squash and fixup are correct for type in commit_types: attr = "is_" + type + "_commit" self.assertEqual(getattr(last_commit, attr), commit_type == type) self.assertFalse(last_commit.is_merge_commit) self.assertFalse(last_commit.is_revert_commit) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) # 'git diff-tree' should have happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls[:4]) self.assertListEqual(last_commit.branches, ["foöbar", "hürdur"]) # All expected calls should've happened at this point self.assertListEqual(sh.git.mock_calls, expected_calls) sh.git.reset_mock() @patch("gitlint.git.git_commentchar") def test_from_commit_msg_full(self, commentchar): commentchar.return_value = "#" gitcontext = GitContext.from_commit_msg(self.get_sample("commit_message/sample1")) expected_title = "Commit title contåining 'WIP', as well as trailing punctuation." expected_body = ["This line should be empty", "This is the first line of the commit message body and it is meant to test a " + "line that exceeds the maximum line length of 80 characters.", "This line has a tråiling space. ", "This line has a trailing tab.\t"] expected_full = expected_title + "\n" + "\n".join(expected_body) expected_original = expected_full + ( "\n# This is a cömmented line\n" "# ------------------------ >8 ------------------------\n" "# Anything after this line should be cleaned up\n" "# this line appears on `git commit -v` command\n" "diff --git a/gitlint/tests/samples/commit_message/sample1 " "b/gitlint/tests/samples/commit_message/sample1\n" "index 82dbe7f..ae71a14 100644\n" "--- a/gitlint/tests/samples/commit_message/sample1\n" "+++ b/gitlint/tests/samples/commit_message/sample1\n" "@@ -1 +1 @@\n" ) commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, expected_title) self.assertEqual(commit.message.body, expected_body) self.assertEqual(commit.message.full, expected_full) self.assertEqual(commit.message.original, expected_original) self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertFalse(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) def test_from_commit_msg_just_title(self): gitcontext = GitContext.from_commit_msg(self.get_sample("commit_message/sample2")) commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, "Just a title contåining WIP") self.assertEqual(commit.message.body, []) self.assertEqual(commit.message.full, "Just a title contåining WIP") self.assertEqual(commit.message.original, "Just a title contåining WIP") self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertFalse(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) def test_from_commit_msg_empty(self): gitcontext = GitContext.from_commit_msg("") commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, "") self.assertEqual(commit.message.body, []) self.assertEqual(commit.message.full, "") self.assertEqual(commit.message.original, "") self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertFalse(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) @patch("gitlint.git.git_commentchar") def test_from_commit_msg_comment(self, commentchar): commentchar.return_value = "#" gitcontext = GitContext.from_commit_msg("Tïtle\n\nBödy 1\n#Cömment\nBody 2") commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, "Tïtle") self.assertEqual(commit.message.body, ["", "Bödy 1", "Body 2"]) self.assertEqual(commit.message.full, "Tïtle\n\nBödy 1\nBody 2") self.assertEqual(commit.message.original, "Tïtle\n\nBödy 1\n#Cömment\nBody 2") self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertFalse(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) def test_from_commit_msg_merge_commit(self): commit_msg = "Merge f919b8f34898d9b48048bcd703bc47139f4ff621 into 8b0409a26da6ba8a47c1fd2e746872a8dab15401" gitcontext = GitContext.from_commit_msg(commit_msg) commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, commit_msg) self.assertEqual(commit.message.body, []) self.assertEqual(commit.message.full, commit_msg) self.assertEqual(commit.message.original, commit_msg) self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertTrue(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertFalse(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) def test_from_commit_msg_revert_commit(self): commit_msg = "Revert \"Prev commit message\"\n\nThis reverts commit a8ad67e04164a537198dea94a4fde81c5592ae9c." gitcontext = GitContext.from_commit_msg(commit_msg) commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, "Revert \"Prev commit message\"") self.assertEqual(commit.message.body, ["", "This reverts commit a8ad67e04164a537198dea94a4fde81c5592ae9c."]) self.assertEqual(commit.message.full, commit_msg) self.assertEqual(commit.message.original, commit_msg) self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_fixup_commit) self.assertFalse(commit.is_squash_commit) self.assertTrue(commit.is_revert_commit) self.assertEqual(len(gitcontext.commits), 1) def test_from_commit_msg_fixup_squash_commit(self): commit_types = ["fixup", "squash"] for commit_type in commit_types: commit_msg = f"{commit_type}! Test message" gitcontext = GitContext.from_commit_msg(commit_msg) commit = gitcontext.commits[-1] self.assertIsInstance(commit, GitCommit) self.assertFalse(isinstance(commit, LocalGitCommit)) self.assertEqual(commit.message.title, commit_msg) self.assertEqual(commit.message.body, []) self.assertEqual(commit.message.full, commit_msg) self.assertEqual(commit.message.original, commit_msg) self.assertEqual(commit.author_name, None) self.assertEqual(commit.author_email, None) self.assertEqual(commit.date, None) self.assertListEqual(commit.parents, []) self.assertListEqual(commit.branches, []) self.assertEqual(len(gitcontext.commits), 1) self.assertFalse(commit.is_merge_commit) self.assertFalse(commit.is_revert_commit) # Asserting that squash and fixup are correct for type in commit_types: attr = "is_" + type + "_commit" self.assertEqual(getattr(commit, attr), commit_type == type) @patch('gitlint.git.sh') @patch('arrow.now') def test_staged_commit(self, now, sh): # StagedLocalGitCommit() sh.git.side_effect = [ "#", # git config --get core.commentchar "test åuthor\n", # git config --get user.name "test-emåil@foo.com\n", # git config --get user.email "my-brånch\n", # git rev-parse --abbrev-ref HEAD "file1.txt\npåth/to/file2.txt\n", ] now.side_effect = [arrow.get("2020-02-19T12:18:46.675182+01:00")] # We use a fixup commit, just to test a non-default path context = GitContext.from_staged_commit("fixup! Foōbar 123\n\ncömmit-body\n", "fåke/path") # git calls we're expexting expected_calls = [ call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('config', '--get', 'user.name', **self.expected_sh_special_args), call('config', '--get', 'user.email', **self.expected_sh_special_args), call("rev-parse", "--abbrev-ref", "HEAD", **self.expected_sh_special_args), call("diff", "--staged", "--name-only", "-r", **self.expected_sh_special_args) ] last_commit = context.commits[-1] self.assertIsInstance(last_commit, StagedLocalGitCommit) self.assertIsNone(last_commit.sha, None) self.assertEqual(last_commit.message.title, "fixup! Foōbar 123") self.assertEqual(last_commit.message.body, ["", "cömmit-body"]) # Only `git config --get core.commentchar` should've happened up until this point self.assertListEqual(sh.git.mock_calls, expected_calls[0:1]) self.assertEqual(last_commit.author_name, "test åuthor") self.assertListEqual(sh.git.mock_calls, expected_calls[0:2]) self.assertEqual(last_commit.author_email, "test-emåil@foo.com") self.assertListEqual(sh.git.mock_calls, expected_calls[0:3]) self.assertEqual(last_commit.date, datetime.datetime(2020, 2, 19, 12, 18, 46, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) now.assert_called_once() self.assertListEqual(last_commit.parents, []) self.assertFalse(last_commit.is_merge_commit) self.assertTrue(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) self.assertListEqual(last_commit.branches, ["my-brånch"]) self.assertListEqual(sh.git.mock_calls, expected_calls[0:4]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) self.assertListEqual(sh.git.mock_calls, expected_calls[0:5]) @patch('gitlint.git.sh') def test_staged_commit_with_missing_username(self, sh): # StagedLocalGitCommit() sh.git.side_effect = [ "#", # git config --get core.commentchar ErrorReturnCode('git config --get user.name', b"", b""), ] expected_msg = "Missing git configuration: please set user.name" with self.assertRaisesMessage(GitContextError, expected_msg): ctx = GitContext.from_staged_commit("Foōbar 123\n\ncömmit-body\n", "fåke/path") [str(commit) for commit in ctx.commits] @patch('gitlint.git.sh') def test_staged_commit_with_missing_email(self, sh): # StagedLocalGitCommit() sh.git.side_effect = [ "#", # git config --get core.commentchar "test åuthor\n", # git config --get user.name ErrorReturnCode('git config --get user.name', b"", b""), ] expected_msg = "Missing git configuration: please set user.email" with self.assertRaisesMessage(GitContextError, expected_msg): ctx = GitContext.from_staged_commit("Foōbar 123\n\ncömmit-body\n", "fåke/path") [str(commit) for commit in ctx.commits] def test_gitcommitmessage_equality(self): commit_message1 = GitCommitMessage(GitContext(), "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) attrs = ['original', 'full', 'title', 'body'] self.object_equality_test(commit_message1, attrs, {"context": commit_message1.context}) @patch("gitlint.git._git") def test_gitcommit_equality(self, git): # git will be called to setup the context (commentchar and current_branch), just return the same value # This only matters to test gitcontext equality, not gitcommit equality git.return_value = "foöbar" # Test simple equality case now = datetime.datetime.utcnow() context1 = GitContext() commit_message1 = GitCommitMessage(context1, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit1 = GitCommit(context1, commit_message1, "shä", now, "Jöhn Smith", "jöhn.smith@test.com", None, ["föo/bar"], ["brånch1", "brånch2"]) context1.commits = [commit1] context2 = GitContext() commit_message2 = GitCommitMessage(context2, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit2 = GitCommit(context2, commit_message1, "shä", now, "Jöhn Smith", "jöhn.smith@test.com", None, ["föo/bar"], ["brånch1", "brånch2"]) context2.commits = [commit2] self.assertEqual(context1, context2) self.assertEqual(commit_message1, commit_message2) self.assertEqual(commit1, commit2) # Check that objects are unequal when changing a single attribute kwargs = {'message': commit1.message, 'sha': commit1.sha, 'date': commit1.date, 'author_name': commit1.author_name, 'author_email': commit1.author_email, 'parents': commit1.parents, 'changed_files': commit1.changed_files, 'branches': commit1.branches} self.object_equality_test(commit1, kwargs.keys(), {"context": commit1.context}) # Check that the is_* attributes that are affected by the commit message affect equality special_messages = {'is_merge_commit': "Merge: foöbar", 'is_fixup_commit': "fixup! foöbar", 'is_squash_commit': "squash! foöbar", 'is_revert_commit': "Revert: foöbar"} for key in special_messages: kwargs_copy = copy.deepcopy(kwargs) clone1 = GitCommit(context=commit1.context, **kwargs_copy) clone1.message = GitCommitMessage.from_full_message(context1, special_messages[key]) self.assertTrue(getattr(clone1, key)) clone2 = GitCommit(context=commit1.context, **kwargs_copy) clone2.message = GitCommitMessage.from_full_message(context1, "foöbar") self.assertNotEqual(clone1, clone2) @patch("gitlint.git.git_commentchar") def test_commit_msg_custom_commentchar(self, patched): patched.return_value = "ä" context = GitContext() message = GitCommitMessage.from_full_message(context, "Tïtle\n\nBödy 1\näCömment\nBody 2") self.assertEqual(message.title, "Tïtle") self.assertEqual(message.body, ["", "Bödy 1", "Body 2"]) self.assertEqual(message.full, "Tïtle\n\nBödy 1\nBody 2") self.assertEqual(message.original, "Tïtle\n\nBödy 1\näCömment\nBody 2")