diff options
Diffstat (limited to 'qa/test_commits.py')
-rw-r--r-- | qa/test_commits.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/qa/test_commits.py b/qa/test_commits.py new file mode 100644 index 0000000..f485856 --- /dev/null +++ b/qa/test_commits.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-function-args,unexpected-keyword-arg +import re + +import arrow + +from qa.shell import echo, git, gitlint +from qa.base import BaseTestCase +from qa.utils import sstr + + +class CommitsTests(BaseTestCase): + """ Integration tests for the --commits argument, i.e. linting multiple commits at once or linting specific commits + """ + + def test_successful(self): + """ Test linting multiple commits without violations """ + git("checkout", "-b", "test-branch-commits-base", _cwd=self.tmp_git_repo) + self.create_simple_commit(u"Sïmple title\n\nSimple bödy describing the commit") + git("checkout", "-b", "test-branch-commits", _cwd=self.tmp_git_repo) + self.create_simple_commit(u"Sïmple title2\n\nSimple bödy describing the commit2") + self.create_simple_commit(u"Sïmple title3\n\nSimple bödy describing the commit3") + output = gitlint("--commits", "test-branch-commits-base...test-branch-commits", + _cwd=self.tmp_git_repo, _tty_in=True) + self.assertEqualStdout(output, "") + + def test_violations(self): + """ Test linting multiple commits with violations """ + git("checkout", "-b", "test-branch-commits-violations-base", _cwd=self.tmp_git_repo) + self.create_simple_commit(u"Sïmple title.\n") + git("checkout", "-b", "test-branch-commits-violations", _cwd=self.tmp_git_repo) + + self.create_simple_commit(u"Sïmple title2.\n") + commit_sha1 = self.get_last_commit_hash()[:10] + self.create_simple_commit(u"Sïmple title3.\n") + commit_sha2 = self.get_last_commit_hash()[:10] + output = gitlint("--commits", "test-branch-commits-violations-base...test-branch-commits-violations", + _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[4]) + + self.assertEqual(output.exit_code, 4) + expected_kwargs = {'commit_sha1': commit_sha1, 'commit_sha2': commit_sha2} + self.assertEqualStdout(output, self.get_expected("test_commits/test_violations_1", expected_kwargs)) + + def test_lint_single_commit(self): + """ Tests `gitlint --commits <sha>` """ + self.create_simple_commit(u"Sïmple title.\n") + self.create_simple_commit(u"Sïmple title2.\n") + commit_sha = self.get_last_commit_hash() + refspec = "{0}^...{0}".format(commit_sha) + self.create_simple_commit(u"Sïmple title3.\n") + output = gitlint("--commits", refspec, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2]) + expected = (u"1: T3 Title has trailing punctuation (.): \"Sïmple title2.\"\n" + + u"3: B6 Body message is missing\n") + self.assertEqual(output.exit_code, 2) + self.assertEqualStdout(output, expected) + + def test_lint_staged_stdin(self): + """ Tests linting a staged commit. Gitint should lint the passed commit message andfetch additional meta-data + from the underlying repository. The easiest way to test this is by inspecting `--debug` output. + This is the equivalent of doing: + echo "WIP: Pïpe test." | gitlint --staged --debug + """ + # Create a commit first, before we stage changes. This ensures the repo is properly initialized. + self.create_simple_commit(u"Sïmple title.\n") + + # Add some files, stage them: they should show up in the debug output as changed file + filename1 = self.create_file(self.tmp_git_repo) + git("add", filename1, _cwd=self.tmp_git_repo) + filename2 = self.create_file(self.tmp_git_repo) + git("add", filename2, _cwd=self.tmp_git_repo) + + output = gitlint(echo(u"WIP: Pïpe test."), "--staged", "--debug", + _cwd=self.tmp_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3]) + + # Determine variable parts of expected output + expected_kwargs = self.get_debug_vars_last_commit() + expected_kwargs.update({'changed_files': sstr(sorted([filename1, filename2]))}) + + # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date + # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the + # gitlint output using a regex, parse the date to ensure the format is correct, and then pass that as an + # expected variable. + matches = re.search(r'^Date:\s+(.*)', str(output), re.MULTILINE) + if matches: + expected_date = arrow.get(str(matches.group(1)), "YYYY-MM-DD HH:mm:ss Z").format("YYYY-MM-DD HH:mm:ss Z") + expected_kwargs['staged_date'] = expected_date + + self.assertEqualStdout(output, self.get_expected("test_commits/test_lint_staged_stdin_1", expected_kwargs)) + self.assertEqual(output.exit_code, 3) + + def test_lint_staged_msg_filename(self): + """ Tests linting a staged commit. Gitint should lint the passed commit message andfetch additional meta-data + from the underlying repository. The easiest way to test this is by inspecting `--debug` output. + This is the equivalent of doing: + gitlint --msg-filename /tmp/my-commit-msg --staged --debug + """ + # Create a commit first, before we stage changes. This ensures the repo is properly initialized. + self.create_simple_commit(u"Sïmple title.\n") + + # Add some files, stage them: they should show up in the debug output as changed file + filename1 = self.create_file(self.tmp_git_repo) + git("add", filename1, _cwd=self.tmp_git_repo) + filename2 = self.create_file(self.tmp_git_repo) + git("add", filename2, _cwd=self.tmp_git_repo) + + tmp_commit_msg_file = self.create_tmpfile(u"WIP: from fïle test.") + + output = gitlint("--msg-filename", tmp_commit_msg_file, "--staged", "--debug", + _cwd=self.tmp_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3]) + + # Determine variable parts of expected output + expected_kwargs = self.get_debug_vars_last_commit() + expected_kwargs.update({'changed_files': sstr(sorted([filename1, filename2]))}) + + # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date + # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the + # gitlint output using a regex, parse the date to ensure the format is correct, and then pass that as an + # expected variable. + matches = re.search(r'^Date:\s+(.*)', str(output), re.MULTILINE) + if matches: + expected_date = arrow.get(str(matches.group(1)), "YYYY-MM-DD HH:mm:ss Z").format("YYYY-MM-DD HH:mm:ss Z") + expected_kwargs['staged_date'] = expected_date + + expected = self.get_expected("test_commits/test_lint_staged_msg_filename_1", expected_kwargs) + self.assertEqualStdout(output, expected) + self.assertEqual(output.exit_code, 3) + + def test_lint_head(self): + """ Testing whether we can also recognize special refs like 'HEAD' """ + tmp_git_repo = self.create_tmp_git_repo() + self.create_simple_commit(u"Sïmple title.\n\nSimple bödy describing the commit", git_repo=tmp_git_repo) + self.create_simple_commit(u"Sïmple title", git_repo=tmp_git_repo) + self.create_simple_commit(u"WIP: Sïmple title\n\nSimple bödy describing the commit", git_repo=tmp_git_repo) + output = gitlint("--commits", "HEAD", _cwd=tmp_git_repo, _tty_in=True, _ok_code=[3]) + revlist = git("rev-list", "HEAD", _tty_in=True, _cwd=tmp_git_repo).split() + + expected_kwargs = {"commit_sha0": revlist[0][:10], "commit_sha1": revlist[1][:10], + "commit_sha2": revlist[2][:10]} + + self.assertEqualStdout(output, self.get_expected("test_commits/test_lint_head_1", expected_kwargs)) + + def test_ignore_commits(self): + """ Tests multiple commits of which some rules get igonored because of ignore-* rules """ + # Create repo and some commits + tmp_git_repo = self.create_tmp_git_repo() + self.create_simple_commit(u"Sïmple title.\n\nSimple bödy describing the commit", git_repo=tmp_git_repo) + # Normally, this commit will give T3 (trailing-punctuation), T5 (WIP) and B5 (bod-too-short) violations + # But in this case only B5 because T3 and T5 are being ignored because of config + self.create_simple_commit(u"Release: WIP tïtle.\n\nShort", git_repo=tmp_git_repo) + # In the following 2 commits, the T3 violations are as normal + self.create_simple_commit( + u"Sïmple WIP title3.\n\nThis is \ta relëase commit\nMore info", git_repo=tmp_git_repo) + self.create_simple_commit(u"Sïmple title4.\n\nSimple bödy describing the commit4", git_repo=tmp_git_repo) + revlist = git("rev-list", "HEAD", _tty_in=True, _cwd=tmp_git_repo).split() + + config_path = self.get_sample_path("config/ignore-release-commits") + output = gitlint("--commits", "HEAD", "--config", config_path, _cwd=tmp_git_repo, _tty_in=True, _ok_code=[4]) + + expected_kwargs = {"commit_sha0": revlist[0][:10], "commit_sha1": revlist[1][:10], + "commit_sha2": revlist[2][:10], "commit_sha3": revlist[3][:10]} + self.assertEqualStdout(output, self.get_expected("test_commits/test_ignore_commits_1", expected_kwargs)) |