diff options
Diffstat (limited to 'qa/test_gitlint.py')
-rw-r--r-- | qa/test_gitlint.py | 165 |
1 files changed, 120 insertions, 45 deletions
diff --git a/qa/test_gitlint.py b/qa/test_gitlint.py index 0200d76..6c45196 100644 --- a/qa/test_gitlint.py +++ b/qa/test_gitlint.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # pylint: disable=too-many-function-args,unexpected-keyword-arg -import io import os from qa.shell import echo, git, gitlint from qa.base import BaseTestCase @@ -8,7 +6,7 @@ from qa.utils import DEFAULT_ENCODING class IntegrationTests(BaseTestCase): - """ Simple set of integration tests for gitlint """ + """Simple set of integration tests for gitlint""" def test_successful(self): # Test for STDIN with and without a TTY attached @@ -17,8 +15,8 @@ class IntegrationTests(BaseTestCase): self.assertEqualStdout(output, "") def test_successful_gitconfig(self): - """ Test gitlint when the underlying repo has specific git config set. - In the past, we've had issues with gitlint failing on some of these, so this acts as a regression test. """ + """Test gitlint when the underlying repo has specific git config set. + In the past, we've had issues with gitlint failing on some of these, so this acts as a regression test.""" # Different commentchar (Note: tried setting this to a special unicode char, but git doesn't like that) git("config", "--add", "core.commentchar", "$", _cwd=self.tmp_git_repo) @@ -27,8 +25,8 @@ class IntegrationTests(BaseTestCase): self.assertEqualStdout(output, "") def test_successful_merge_commit(self): - # Create branch on master - self.create_simple_commit("Cömmit on master\n\nSimple bödy") + # Create branch on main + self.create_simple_commit("Cömmit on main\n\nSimple bödy") # Create test branch, add a commit and determine the commit hash git("checkout", "-b", "test-branch", _cwd=self.tmp_git_repo) @@ -37,10 +35,10 @@ class IntegrationTests(BaseTestCase): self.create_simple_commit(f"{commit_title}\n\nSïmple body") hash = self.get_last_commit_hash() - # Checkout master and merge the commit + # Checkout main and merge the commit # We explicitly set the title of the merge commit to the title of the previous commit as this or similar # behavior is what many tools do that handle merges (like github, gerrit, etc). - git("checkout", "master", _cwd=self.tmp_git_repo) + git("checkout", "main", _cwd=self.tmp_git_repo) git("merge", "--no-ff", "-m", f"Merge '{commit_title}'", hash, _cwd=self.tmp_git_repo) # Run gitlint and assert output is empty @@ -54,18 +52,14 @@ class IntegrationTests(BaseTestCase): def test_fixup_commit(self): # Create a normal commit and assert that it has a violation - test_filename = self.create_simple_commit("Cömmit on WIP master\n\nSimple bödy that is long enough") + test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough") output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) - expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n" + expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n" self.assertEqualStdout(output, expected) # Make a small modification to the commit and commit it using fixup commit - with io.open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh: - # Wanted to write a unicode string, but that's obnoxious if you want to do it across Python 2 and 3. - # https://stackoverflow.com/questions/22392377/ - # error-writing-a-file-with-file-write-in-python-unicodeencodeerror - # So just keeping it simple - ASCII will here - fh.write("Appending some stuff\n") + with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh: + fh.write("Appending söme stuff\n") git("add", test_filename, _cwd=self.tmp_git_repo) @@ -78,13 +72,44 @@ class IntegrationTests(BaseTestCase): # Make sure that if we set the ignore-fixup-commits option to false that we do still see the violations output = gitlint("-c", "general.ignore-fixup-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2]) - expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"fixup! Cömmit on WIP master\"\n" + \ + expected = ( + "1: T5 Title contains the word 'WIP' (case-insensitive): \"fixup! Cömmit on WIP main\"\n" "3: B6 Body message is missing\n" + ) + + self.assertEqualStdout(output, expected) + + def test_fixup_amend_commit(self): + # Create a normal commit and assert that it has a violation + test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough") + output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) + expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n" + self.assertEqualStdout(output, expected) + + # Make a small modification to the commit and commit it using fixup=amend commit + with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh: + fh.write("Appending söme stuff\n") + + git("add", test_filename, _cwd=self.tmp_git_repo) + + # We have to use --no-edit to avoid git starting $EDITOR to modify the commit message that is being amended + git("commit", "--no-edit", f"--fixup=amend:{self.get_last_commit_hash()}", _cwd=self.tmp_git_repo) + + # Assert that gitlint does not show an error for the fixup commit + output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True) + # No need to check exit code, the command above throws an exception on > 0 exit codes + self.assertEqualStdout(output, "") + + # Make sure that if we set the ignore-fixup-commits option to false that we do still see the violations + output = gitlint( + "-c", "general.ignore-fixup-amend-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1] + ) + expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"amend! Cömmit on WIP main\"\n" self.assertEqualStdout(output, expected) def test_revert_commit(self): - self.create_simple_commit("WIP: Cömmit on master.\n\nSimple bödy") + self.create_simple_commit("WIP: Cömmit on main.\n\nSimple bödy") hash = self.get_last_commit_hash() git("revert", hash, _cwd=self.tmp_git_repo) @@ -93,21 +118,22 @@ class IntegrationTests(BaseTestCase): self.assertEqualStdout(output, "") # Assert that we do see the error if we disable the ignore-revert-commits option - output = gitlint("-c", "general.ignore-revert-commits=false", - _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) + output = gitlint( + "-c", "general.ignore-revert-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1] + ) self.assertEqual(output.exit_code, 1) - expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Revert \"WIP: Cömmit on master.\"\"\n" + expected = '1: T5 Title contains the word \'WIP\' (case-insensitive): "Revert "WIP: Cömmit on main.""\n' self.assertEqualStdout(output, expected) def test_squash_commit(self): # Create a normal commit and assert that it has a violation - test_filename = self.create_simple_commit("Cömmit on WIP master\n\nSimple bödy that is long enough") + test_filename = self.create_simple_commit("Cömmit on WIP main\n\nSimple bödy that is long enough") output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) - expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n" + expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP main\"\n" self.assertEqualStdout(output, expected) # Make a small modification to the commit and commit it using squash commit - with io.open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh: + with open(os.path.join(self.tmp_git_repo, test_filename), "a", encoding=DEFAULT_ENCODING) as fh: # Wanted to write a unicode string, but that's obnoxious if you want to do it across Python 2 and 3. # https://stackoverflow.com/questions/22392377/ # error-writing-a-file-with-file-write-in-python-unicodeencodeerror @@ -124,10 +150,13 @@ class IntegrationTests(BaseTestCase): self.assertEqualStdout(output, "") # Make sure that if we set the ignore-squash-commits option to false that we do still see the violations - output = gitlint("-c", "general.ignore-squash-commits=false", - _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2]) - expected = "1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP master\"\n" + \ - "3: B5 Body message is too short (14<20): \"Töo short body\"\n" + output = gitlint( + "-c", "general.ignore-squash-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2] + ) + expected = ( + "1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP main\"\n" + '3: B5 Body message is too short (14<20): "Töo short body"\n' + ) self.assertEqualStdout(output, expected) @@ -139,11 +168,11 @@ class IntegrationTests(BaseTestCase): def test_msg_filename(self): tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename test.") - output = gitlint("--msg-filename", tmp_commit_msg_file, _tty_in=True, _ok_code=[3]) + output = gitlint("--msg-filename", tmp_commit_msg_file, _tty_in=True, _cwd=self.tmp_git_repo, _ok_code=[3]) self.assertEqualStdout(output, self.get_expected("test_gitlint/test_msg_filename_1")) def test_msg_filename_no_tty(self): - """ Make sure --msg-filename option also works with no TTY attached """ + """Make sure --msg-filename option also works with no TTY attached""" tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO TTY test.") # We need to set _err_to_out explicitly for sh to merge stdout and stderr output in case there's @@ -151,34 +180,51 @@ class IntegrationTests(BaseTestCase): # http://amoffat.github.io/sh/sections/special_arguments.html?highlight=_tty_in#err-to-out # We need to pass some whitespace to _in as sh will otherwise hang, see # https://github.com/amoffat/sh/issues/427 - output = gitlint("--msg-filename", tmp_commit_msg_file, _in=" ", - _tty_in=False, _err_to_out=True, _ok_code=[3]) + output = gitlint( + "--msg-filename", + tmp_commit_msg_file, + _cwd=self.tmp_git_repo, + _in=" ", + _tty_in=False, + _err_to_out=True, + _ok_code=[3], + ) self.assertEqualStdout(output, self.get_expected("test_gitlint/test_msg_filename_no_tty_1")) def test_no_git_name_set(self): - """ Ensure we print out a helpful message if user.name is not set """ + """Ensure we print out a helpful message if user.name is not set""" tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO name test.") # Name is checked before email so this isn't strictly # necessary but seems good for consistency. env = self.create_tmp_git_config("[user]\n email = test-emåil@foo.com\n") - output = gitlint("--staged", "--msg-filename", tmp_commit_msg_file, - _ok_code=[self.GIT_CONTEXT_ERROR_CODE], - _env=env) + output = gitlint( + "--staged", + "--msg-filename", + tmp_commit_msg_file, + _ok_code=[self.GIT_CONTEXT_ERROR_CODE], + _env=env, + _cwd=self.tmp_git_repo, + ) expected = "Missing git configuration: please set user.name\n" self.assertEqualStdout(output, expected) def test_no_git_email_set(self): - """ Ensure we print out a helpful message if user.email is not set """ + """Ensure we print out a helpful message if user.email is not set""" tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO email test.") env = self.create_tmp_git_config("[user]\n name = test åuthor\n") - output = gitlint("--staged", "--msg-filename", tmp_commit_msg_file, - _ok_code=[self.GIT_CONTEXT_ERROR_CODE], - _env=env) + output = gitlint( + "--staged", + "--msg-filename", + tmp_commit_msg_file, + _ok_code=[self.GIT_CONTEXT_ERROR_CODE], + _env=env, + _cwd=self.tmp_git_repo, + ) expected = "Missing git configuration: please set user.email\n" self.assertEqualStdout(output, expected) - def test_git_errors(self): + def test_git_empty_repo(self): # Repo has no commits: caused by `git log` empty_git_repo = self.create_tmp_git_repo() output = gitlint(_cwd=empty_git_repo, _tty_in=True, _ok_code=[self.GIT_CONTEXT_ERROR_CODE]) @@ -186,7 +232,36 @@ class IntegrationTests(BaseTestCase): expected = "Current branch has no commits. Gitlint requires at least one commit to function.\n" self.assertEqualStdout(output, expected) - # Repo has no commits: caused by `git rev-parse` - output = gitlint(echo("WIP: Pïpe test."), "--staged", _cwd=empty_git_repo, _tty_in=False, - _err_to_out=True, _ok_code=[self.GIT_CONTEXT_ERROR_CODE]) + def test_git_empty_repo_staged(self): + """When repo is empty, we can still use gitlint when using --staged flag and piping a message into it""" + empty_git_repo = self.create_tmp_git_repo() + expected = ( + '1: T3 Title has trailing punctuation (.): "WIP: Pïpe test."\n' + "1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: Pïpe test.\"\n" + "3: B6 Body message is missing\n" + ) + + output = gitlint( + echo("WIP: Pïpe test."), "--staged", _cwd=empty_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3] + ) + self.assertEqualStdout(output, expected) + + def test_commit_binary_file(self): + """When committing a binary file, git shows somewhat different output in diff commands, + this test ensures gitlint deals with that correctly""" + binary_filename = self.create_simple_commit("Sïmple commit", file_contents=bytes([0x48, 0x00, 0x49, 0x00])) + output = gitlint( + "--debug", + _ok_code=1, + _cwd=self.tmp_git_repo, + ) + + expected_kwargs = self.get_debug_vars_last_commit() + expected_kwargs.update( + { + "changed_files": [binary_filename], + "changed_files_stats": (f"{binary_filename}: None additions, None deletions"), + } + ) + expected = self.get_expected("test_gitlint/test_commit_binary_file_1", expected_kwargs) self.assertEqualStdout(output, expected) |