summaryrefslogtreecommitdiffstats
path: root/qa/test_hooks.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2020-03-19 14:00:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2020-03-19 14:00:14 +0000
commitdf9615bac55ac6f1c3f516b66279ac0007175030 (patch)
tree84dd81d1c97835271cea7fbdd67c074742365e07 /qa/test_hooks.py
parentInitial commit. (diff)
downloadgitlint-upstream/0.13.1.tar.xz
gitlint-upstream/0.13.1.zip
Adding upstream version 0.13.1.upstream/0.13.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--qa/test_hooks.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/qa/test_hooks.py b/qa/test_hooks.py
new file mode 100644
index 0000000..a41580b
--- /dev/null
+++ b/qa/test_hooks.py
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+# pylint: disable=too-many-function-args,unexpected-keyword-arg
+import os
+from qa.shell import git, gitlint
+from qa.base import BaseTestCase
+
+
+class HookTests(BaseTestCase):
+ """ Integration tests for gitlint commitmsg hooks"""
+
+ VIOLATIONS = ['gitlint: checking commit message...\n',
+ u'1: T3 Title has trailing punctuation (.): "WIP: This ïs a title."\n',
+ u'1: T5 Title contains the word \'WIP\' (case-insensitive): "WIP: This ïs a title."\n',
+ u'2: B4 Second line is not empty: "Contënt on the second line"\n',
+ '3: B6 Body message is missing\n',
+ '-----------------------------------------------\n',
+ 'gitlint: \x1b[31mYour commit message contains the above violations.\x1b[0m\n']
+
+ def setUp(self):
+ self.responses = []
+ self.response_index = 0
+ self.githook_output = []
+
+ # The '--staged' flag used in the commit-msg hook fetches additional information from the underlying
+ # git repo which means there already needs to be a commit in the repo
+ # (as gitlint --staged doesn't work against empty repos)
+ self.create_simple_commit(u"Commït Title\n\nCommit Body explaining commit.")
+
+ # install git commit-msg hook and assert output
+ output_installed = gitlint("install-hook", _cwd=self.tmp_git_repo)
+ expected_installed = u"Successfully installed gitlint commit-msg hook in %s/.git/hooks/commit-msg\n" % \
+ self.tmp_git_repo
+ self.assertEqualStdout(output_installed, expected_installed)
+
+ def tearDown(self):
+ # uninstall git commit-msg hook and assert output
+ output_uninstalled = gitlint("uninstall-hook", _cwd=self.tmp_git_repo)
+ expected_uninstalled = u"Successfully uninstalled gitlint commit-msg hook from %s/.git/hooks/commit-msg\n" % \
+ self.tmp_git_repo
+ self.assertEqualStdout(output_uninstalled, expected_uninstalled)
+
+ def _violations(self):
+ # Make a copy of the violations array so that we don't inadvertently edit it in the test (like I did :D)
+ return list(self.VIOLATIONS)
+
+ # callback function that captures git commit-msg hook output
+
+ def _interact(self, line, stdin):
+ self.githook_output.append(line)
+ # Answer 'yes' to question to keep violating commit-msg
+ if "Your commit message contains the above violations" in line:
+ response = self.responses[self.response_index]
+ stdin.put("{0}\n".format(response))
+ self.response_index = (self.response_index + 1) % len(self.responses)
+
+ def test_commit_hook_continue(self):
+ self.responses = ["y"]
+ test_filename = self.create_simple_commit(u"WIP: This ïs a title.\nContënt on the second line",
+ out=self._interact, tty_in=True)
+
+ # Determine short commit-msg hash, needed to determine expected output
+ short_hash = self.get_last_commit_short_hash()
+
+ expected_output = self._violations()
+ expected_output += ["Continue with commit anyways (this keeps the current commit message)? " +
+ "[y(es)/n(no)/e(dit)] " +
+ u"[master %s] WIP: This ïs a title. Contënt on the second line\n"
+ % short_hash,
+ " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
+ u" create mode 100644 %s\n" % test_filename]
+
+ assert len(self.githook_output) == len(expected_output)
+ for output, expected in zip(self.githook_output, expected_output):
+ self.assertMultiLineEqual(
+ output.replace('\r', ''),
+ expected.replace('\r', ''))
+
+ def test_commit_hook_abort(self):
+ self.responses = ["n"]
+ test_filename = self.create_simple_commit(u"WIP: This ïs a title.\nContënt on the second line",
+ out=self._interact, ok_code=1, tty_in=True)
+ git("rm", "-f", test_filename, _cwd=self.tmp_git_repo)
+
+ # Determine short commit-msg hash, needed to determine expected output
+
+ expected_output = self._violations()
+ expected_output += ["Continue with commit anyways (this keeps the current commit message)? " +
+ "[y(es)/n(no)/e(dit)] " +
+ "Commit aborted.\n",
+ "Your commit message: \n",
+ "-----------------------------------------------\n",
+ u"WIP: This ïs a title.\n",
+ u"Contënt on the second line\n",
+ "-----------------------------------------------\n"]
+
+ self.assertListEqual(expected_output, self.githook_output)
+
+ def test_commit_hook_edit(self):
+ self.responses = ["e", "y"]
+ env = {"EDITOR": ":"}
+ test_filename = self.create_simple_commit(u"WIP: This ïs a title.\nContënt on the second line",
+ out=self._interact, env=env, tty_in=True)
+ git("rm", "-f", test_filename, _cwd=self.tmp_git_repo)
+
+ short_hash = git("rev-parse", "--short", "HEAD", _cwd=self.tmp_git_repo, _tty_in=True).replace("\n", "")
+
+ # Determine short commit-msg hash, needed to determine expected output
+
+ expected_output = self._violations()
+ expected_output += ['Continue with commit anyways (this keeps the current commit message)? ' +
+ '[y(es)/n(no)/e(dit)] ' + self._violations()[0]]
+ expected_output += self._violations()[1:]
+ expected_output += ['Continue with commit anyways (this keeps the current commit message)? ' +
+ "[y(es)/n(no)/e(dit)] " +
+ u"[master %s] WIP: This ïs a title. Contënt on the second line\n" % short_hash,
+ " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
+ u" create mode 100644 %s\n" % test_filename]
+
+ assert len(self.githook_output) == len(expected_output)
+ for output, expected in zip(self.githook_output, expected_output):
+ self.assertMultiLineEqual(
+ output.replace('\r', ''),
+ expected.replace('\r', ''))
+
+ def test_commit_hook_worktree(self):
+ """ Tests that hook installation and un-installation also work in git worktrees.
+ Test steps:
+ ```sh
+ git init <tmpdir>
+ cd <tmpdir>
+ git worktree add <worktree-tempdir>
+ cd <worktree-tempdir>
+ gitlint install-hook
+ gitlint uninstall-hook
+ ```
+ """
+ tmp_git_repo = self.create_tmp_git_repo()
+ self.create_simple_commit(u"Simple title\n\nContënt in the body", git_repo=tmp_git_repo)
+
+ worktree_dir = self.generate_temp_path()
+ self.tmp_git_repos.append(worktree_dir) # make sure we clean up the worktree afterwards
+
+ git("worktree", "add", worktree_dir, _cwd=tmp_git_repo, _tty_in=True)
+
+ output_installed = gitlint("install-hook", _cwd=worktree_dir)
+ expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks", "commit-msg")
+ expected_msg = "Successfully installed gitlint commit-msg hook in {0}\n".format(expected_hook_path)
+ self.assertEqual(output_installed, expected_msg)
+
+ output_uninstalled = gitlint("uninstall-hook", _cwd=worktree_dir)
+ expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks", "commit-msg")
+ expected_msg = "Successfully uninstalled gitlint commit-msg hook from {0}\n".format(expected_hook_path)
+ self.assertEqual(output_uninstalled, expected_msg)