diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-11-19 14:52:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-11-19 14:53:01 +0000 |
commit | f3b6c222fb11c96e2f8bbaa0622f46c8ec486874 (patch) | |
tree | 0f38497775e27d3e16b20573b36dd22aa5b24f3e /gitlint-core/gitlint/tests/cli | |
parent | Releasing debian version 0.17.0-1. (diff) | |
download | gitlint-f3b6c222fb11c96e2f8bbaa0622f46c8ec486874.tar.xz gitlint-f3b6c222fb11c96e2f8bbaa0622f46c8ec486874.zip |
Merging upstream version 0.18.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gitlint-core/gitlint/tests/cli')
-rw-r--r-- | gitlint-core/gitlint/tests/cli/test_cli.py | 444 | ||||
-rw-r--r-- | gitlint-core/gitlint/tests/cli/test_cli_hooks.py | 157 |
2 files changed, 344 insertions, 257 deletions
diff --git a/gitlint-core/gitlint/tests/cli/test_cli.py b/gitlint-core/gitlint/tests/cli/test_cli.py index 59ec7af..d18efe9 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli.py +++ b/gitlint-core/gitlint/tests/cli/test_cli.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- - - import io import os import sys @@ -29,11 +26,11 @@ class CLITests(BaseTestCase): GITLINT_SUCCESS_CODE = 0 def setUp(self): - super(CLITests, self).setUp() + super().setUp() self.cli = CliRunner() # Patch gitlint.cli.git_version() so that we don't have to patch it separately in every test - self.git_version_path = patch('gitlint.cli.git_version') + self.git_version_path = patch("gitlint.cli.git_version") cli.git_version = self.git_version_path.start() cli.git_version.return_value = "git version 1.2.3" @@ -42,39 +39,44 @@ class CLITests(BaseTestCase): @staticmethod def get_system_info_dict(): - """ Returns a dict with items related to system values logged by `gitlint --debug` """ - return {'platform': platform.platform(), "python_version": sys.version, 'gitlint_version': __version__, - 'GITLINT_USE_SH_LIB': BaseTestCase.GITLINT_USE_SH_LIB, 'target': os.path.realpath(os.getcwd()), - 'DEFAULT_ENCODING': DEFAULT_ENCODING} + """Returns a dict with items related to system values logged by `gitlint --debug`""" + return { + "platform": platform.platform(), + "python_version": sys.version, + "gitlint_version": __version__, + "GITLINT_USE_SH_LIB": BaseTestCase.GITLINT_USE_SH_LIB, + "target": os.path.realpath(os.getcwd()), + "DEFAULT_ENCODING": DEFAULT_ENCODING, + } def test_version(self): - """ Test for --version option """ + """Test for --version option""" result = self.cli.invoke(cli.cli, ["--version"]) self.assertEqual(result.output.split("\n")[0], f"cli, version {__version__}") - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint(self, sh, _): - """ Test for basic simple linting functionality """ + """Test for basic simple linting functionality""" sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360", - "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" - "commït-title\n\ncommït-body", + "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\ncommït-title\n\ncommït-body", "#", # git config --get core.commentchar + "1\t4\tfile1.txt\n3\t5\tpåth/to/file2.txt\n", "commit-1-branch-1\ncommit-1-branch-2\n", - "file1.txt\npåth/to/file2.txt\n" ] - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli) - self.assertEqual(stderr.getvalue(), u'3: B5 Body message is too short (11<20): "commït-body"\n') + self.assertEqual(stderr.getvalue(), '3: B5 Body message is too short (11<20): "commït-body"\n') self.assertEqual(result.exit_code, 1) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_multiple_commits(self, sh, _): - """ Test for --commits option """ + """Test for --commits option""" + # fmt: off sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360\n" + # git rev-list <SHA> "25053ccec5e28e1bb8f7551fdbb5ab213ada2401\n" + @@ -83,30 +85,32 @@ class CLITests(BaseTestCase): "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> - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree # 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> - "commit-2/file-1\ncommit-2/file-2\n", # git diff-tree # 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> - "commit-3/file-1\ncommit-3/file-2\n", # git diff-tree ] + # fmt: on - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--commits", "foo...bar"]) 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') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_multiple_commits_config(self, sh, _): - """ Test for --commits option where some of the commits have gitlint config in the commit message """ + """Test for --commits option where some of the commits have gitlint config in the commit message""" + # fmt: off # Note that the second commit title has a trailing period that is being ignored by gitlint-ignore: T3 sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360\n" + # git rev-list <SHA> @@ -116,32 +120,33 @@ class CLITests(BaseTestCase): "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 + "9\t4\tcommit-1/file-1\n0\t2\tcommit-1/file-2\n", # git diff-tree "commit-1-branch-1\ncommit-1-branch-2\n", # git branch --contains <sha> - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree # git log --pretty <FORMAT> <SHA> "test åuthor2\x00test-email2@föo.com\x002016-12-04 15:28:15 +0100\x00åbc\n" "commït-title2.\n\ncommït-body2\ngitlint-ignore: T3\n", + "3\t7\tcommit-2/file-1\n4\t6\tcommit-2/file-2\n", # git diff-tree "commit-2-branch-1\ncommit-2-branch-2\n", # git branch --contains <sha> - "commit-2/file-1\ncommit-2/file-2\n", # git diff-tree # 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", + "3\t8\tcommit-3/file-1\n1\t4\tcommit-3/file-2\n", # git diff-tree "commit-3-branch-1\ncommit-3-branch-2\n", # git branch --contains <sha> - "commit-3/file-1\ncommit-3/file-2\n", # git diff-tree ] + # fmt: on - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--commits", "foo...bar"]) # We expect that the second commit has no failures because of 'gitlint-ignore: T3' in its commit msg body self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_multiple_commits_config_1")) self.assertEqual(result.exit_code, 3) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_multiple_commits_configuration_rules(self, sh, _): - """ Test for --commits option where where we have configured gitlint to ignore certain rules for certain commits - """ + """Test for --commits option where where we have configured gitlint to ignore certain rules for certain commits""" + # fmt: off # Note that the second commit sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360\n" + # git rev-list <SHA> @@ -151,62 +156,78 @@ class CLITests(BaseTestCase): "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 + "5\t9\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> - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree # git log --pretty <FORMAT> <SHA> "test åuthor2\x00test-email3@föo.com\x002016-12-04 15:28:15 +0100\x00åbc\n" # Normally T3 violation (trailing punctuation), but this commit is ignored because of # config below "commït-title2.\n\ncommït-body2\n", + "4\t7\tcommit-2/file-1\n1\t4\tcommit-2/file-2\n", # git diff-tree "commit-2-branch-1\ncommit-2-branch-2\n", # git branch --contains <sha> - "commit-2/file-1\ncommit-2/file-2\n", # git diff-tree # git log --pretty <FORMAT> <SHA> "test åuthor3\x00test-email3@föo.com\x002016-12-05 15:28:15 +0100\x00åbc\n" # Normally T1 and B5 violations, now only T1 because we're ignoring B5 in config below "commït-title3.\n\ncommït-body3 foo", + "1\t9\tcommit-3/file-1\n3\t7\tcommit-3/file-2\n", # git diff-tree "commit-3-branch-1\ncommit-3-branch-2\n", # git branch --contains <sha> - "commit-3/file-1\ncommit-3/file-2\n", # git diff-tree ] - - with patch('gitlint.display.stderr', new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["--commits", "foo...bar", "-c", "I1.regex=^commït-title2(.*)", - "-c", "I2.regex=^commït-body3(.*)", "-c", "I2.ignore=B5"]) + # fmt: on + + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke( + cli.cli, + [ + "--commits", + "foo...bar", + "-c", + "I1.regex=^commït-title2(.*)", + "-c", + "I2.regex=^commït-body3(.*)", + "-c", + "I2.ignore=B5", + ], + ) # We expect that the second commit has no failures because of it matching against I1.regex # Because we do test for the 3th commit to return violations, this test also ensures that a unique # config object is passed to each commit lint call - expected = ("Commit 6f29bf81a8:\n" - u'3: B5 Body message is too short (12<20): "commït-body1"\n\n' - "Commit 4da2656b0d:\n" - u'1: T3 Title has trailing punctuation (.): "commït-title3."\n') + expected = ( + "Commit 6f29bf81a8:\n" + '3: B5 Body message is too short (12<20): "commït-body1"\n\n' + "Commit 4da2656b0d:\n" + '1: T3 Title has trailing punctuation (.): "commït-title3."\n' + ) self.assertEqual(stderr.getvalue(), expected) self.assertEqual(result.exit_code, 2) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_commit(self, sh, _): - """ Test for --commit option """ + """Test for --commit option""" + # fmt: off sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360\n", # git log -1 <SHA> --pretty=%H # git log --pretty <FORMAT> <SHA> "test åuthor1\x00test-email1@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" "WIP: commït-title1\n\ncommït-body1", "#", # git config --get core.commentchar + "4\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> - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree ] + # fmt: on - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--commit", "foo"]) self.assertEqual(result.output, "") self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_commit_1")) self.assertEqual(result.exit_code, 2) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_lint_commit_negative(self, sh, _): - """ Negative test for --commit option """ + """Negative test for --commit option""" # Try using --commit and --commits at the same time (not allowed) result = self.cli.invoke(cli.cli, ["--commit", "foo", "--commits", "foo...bar"]) @@ -214,275 +235,309 @@ class CLITests(BaseTestCase): self.assertEqual(result.output, expected_output) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - @patch('gitlint.cli.get_stdin_data', return_value=u'WIP: tïtle \n') + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tïtle \n") def test_input_stream(self, _): - """ Test for linting when a message is passed via stdin """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + """Test for linting when a message is passed via stdin""" + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_input_stream_1")) self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") - @patch('gitlint.cli.get_stdin_data', return_value=u'WIP: tïtle \n') + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tïtle \n") def test_input_stream_debug(self, _): - """ Test for linting when a message is passed via stdin, and debug is enabled. - This tests specifically that git commit meta is not fetched when not passing --staged """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + """Test for linting when a message is passed via stdin, and debug is enabled. + This tests specifically that git commit meta is not fetched when not passing --staged""" + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--debug"]) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_input_stream_debug_1")) self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") expected_kwargs = self.get_system_info_dict() - expected_logs = self.get_expected('cli/test_cli/test_input_stream_debug_2', expected_kwargs) + expected_logs = self.get_expected("cli/test_cli/test_input_stream_debug_2", expected_kwargs) self.assert_logged(expected_logs) - @patch('gitlint.cli.get_stdin_data', return_value="Should be ignored\n") - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value="Should be ignored\n") + @patch("gitlint.git.sh") def test_lint_ignore_stdin(self, sh, stdin_data): - """ Test for ignoring stdin when --ignore-stdin flag is enabled""" + """Test for ignoring stdin when --ignore-stdin flag is enabled""" sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360", - "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" - "commït-title\n\ncommït-body", - "#", # git config --get core.commentchar + "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\ncommït-title\n\ncommït-body", + "#", # git config --get core.commentchar + "3\t12\tfile1.txt\n8\t5\tpåth/to/file2.txt\n", # git diff-tree "commit-1-branch-1\ncommit-1-branch-2\n", # git branch --contains <sha> - "file1.txt\npåth/to/file2.txt\n" # git diff-tree ] - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--ignore-stdin"]) - self.assertEqual(stderr.getvalue(), u'3: B5 Body message is too short (11<20): "commït-body"\n') + self.assertEqual(stderr.getvalue(), '3: B5 Body message is too short (11<20): "commït-body"\n') self.assertEqual(result.exit_code, 1) # Assert that we didn't even try to get the stdin data self.assertEqual(stdin_data.call_count, 0) - @patch('gitlint.cli.get_stdin_data', return_value=u'WIP: tïtle \n') - @patch('arrow.now', return_value=arrow.get("2020-02-19T12:18:46.675182+01:00")) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tïtle \n") + @patch("arrow.now", return_value=arrow.get("2020-02-19T12:18:46.675182+01:00")) + @patch("gitlint.git.sh") def test_lint_staged_stdin(self, sh, _, __): - """ Test for ignoring stdin when --ignore-stdin flag is enabled""" + """Test for ignoring stdin when --ignore-stdin flag is enabled""" sh.git.side_effect = [ - "#", # git config --get core.commentchar - "föo user\n", # git config --get user.name - "föo@bar.com\n", # git config --get user.email - "my-branch\n", # git rev-parse --abbrev-ref HEAD (=current branch) - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree + "#", # git config --get core.commentchar + "1\t5\tcommit-1/file-1\n8\t9\tcommit-1/file-2\n", # git diff-tree + "föo user\n", # git config --get user.name + "föo@bar.com\n", # git config --get user.email + "my-branch\n", # git rev-parse --abbrev-ref HEAD (=current branch) ] - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--debug", "--staged"]) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_staged_stdin_1")) self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") expected_kwargs = self.get_system_info_dict() - expected_logs = self.get_expected('cli/test_cli/test_lint_staged_stdin_2', expected_kwargs) + expected_logs = self.get_expected("cli/test_cli/test_lint_staged_stdin_2", expected_kwargs) self.assert_logged(expected_logs) - @patch('arrow.now', return_value=arrow.get("2020-02-19T12:18:46.675182+01:00")) - @patch('gitlint.git.sh') + @patch("arrow.now", return_value=arrow.get("2020-02-19T12:18:46.675182+01:00")) + @patch("gitlint.git.sh") def test_lint_staged_msg_filename(self, sh, _): - """ Test for ignoring stdin when --ignore-stdin flag is enabled""" + """Test for ignoring stdin when --ignore-stdin flag is enabled""" + # fmt: off sh.git.side_effect = [ "#", # git config --get core.commentchar + "3\t4\tcommit-1/file-1\n4\t7\tcommit-1/file-2\n", # git diff-tree "föo user\n", # git config --get user.name "föo@bar.com\n", # git config --get user.email "my-branch\n", # git rev-parse --abbrev-ref HEAD (=current branch) - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree ] + # fmt: on with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "msg") - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write("WIP: msg-filename tïtle\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--debug", "--staged", "--msg-filename", msg_filename]) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli/test_lint_staged_msg_filename_1")) self.assertEqual(result.exit_code, 2) self.assertEqual(result.output, "") expected_kwargs = self.get_system_info_dict() - expected_logs = self.get_expected('cli/test_cli/test_lint_staged_msg_filename_2', expected_kwargs) + expected_logs = self.get_expected("cli/test_cli/test_lint_staged_msg_filename_2", expected_kwargs) self.assert_logged(expected_logs) - @patch('gitlint.cli.get_stdin_data', return_value=False) + @patch("gitlint.cli.get_stdin_data", return_value=False) def test_lint_staged_negative(self, _): result = self.cli.invoke(cli.cli, ["--staged"]) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - self.assertEqual(result.output, ("Error: The 'staged' option (--staged) can only be used when using " - "'--msg-filename' or when piping data to gitlint via stdin.\n")) - - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + self.assertEqual( + result.output, + "Error: The 'staged' option (--staged) can only be used when using " + "'--msg-filename' or when piping data to gitlint via stdin.\n", + ) + + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_fail_without_commits(self, sh, _): - """ Test for --debug option """ + """Test for --debug option""" - sh.git.side_effect = [ - "", # First invocation of git rev-list - "" # Second invocation of git rev-list - ] + sh.git.side_effect = ["", ""] # First invocation of git rev-list # Second invocation of git rev-list - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: # By default, gitlint should silently exit with code GITLINT_SUCCESS when there are no commits result = self.cli.invoke(cli.cli, ["--commits", "foo..bar"]) self.assertEqual(stderr.getvalue(), "") self.assertEqual(result.exit_code, cli.GITLINT_SUCCESS) - self.assert_log_contains("DEBUG: gitlint.cli No commits in range \"foo..bar\"") + self.assert_log_contains('DEBUG: gitlint.cli No commits in range "foo..bar"') # When --fail-without-commits is set, gitlint should hard fail with code USAGE_ERROR_CODE self.clearlog() result = self.cli.invoke(cli.cli, ["--commits", "foo..bar", "--fail-without-commits"]) self.assertEqual(result.output, 'Error: No commits in range "foo..bar"\n') self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - self.assert_log_contains("DEBUG: gitlint.cli No commits in range \"foo..bar\"") + self.assert_log_contains('DEBUG: gitlint.cli No commits in range "foo..bar"') - @patch('gitlint.cli.get_stdin_data', return_value=False) + @patch("gitlint.cli.get_stdin_data", return_value=False) def test_msg_filename(self, _): expected_output = "3: B6 Body message is missing\n" with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "msg") - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write("Commït title\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename]) self.assertEqual(stderr.getvalue(), expected_output) self.assertEqual(result.exit_code, 1) self.assertEqual(result.output, "") - @patch('gitlint.cli.get_stdin_data', return_value="WIP: tïtle \n") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tïtle \n") def test_silent_mode(self, _): - """ Test for --silent option """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + """Test for --silent option""" + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--silent"]) self.assertEqual(stderr.getvalue(), "") self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") - @patch('gitlint.cli.get_stdin_data', return_value="WIP: tïtle \n") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tïtle \n") def test_verbosity(self, _): - """ Test for --verbosity option """ + """Test for --verbosity option""" # We only test -v and -vv, more testing is really not required here # -v - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["-v"]) self.assertEqual(stderr.getvalue(), "1: T2\n1: T5\n3: B6\n") self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") # -vv - expected_output = "1: T2 Title has trailing whitespace\n" + \ - "1: T5 Title contains the word 'WIP' (case-insensitive)\n" + \ - "3: B6 Body message is missing\n" + expected_output = ( + "1: T2 Title has trailing whitespace\n" + + "1: T5 Title contains the word 'WIP' (case-insensitive)\n" + + "3: B6 Body message is missing\n" + ) - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["-vv"], input="WIP: tïtle \n") self.assertEqual(stderr.getvalue(), expected_output) self.assertEqual(result.exit_code, 3) self.assertEqual(result.output, "") # -vvvv: not supported -> should print a config error - with patch('gitlint.display.stderr', new=StringIO()) as stderr: - result = self.cli.invoke(cli.cli, ["-vvvv"], input=u'WIP: tïtle \n') + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + result = self.cli.invoke(cli.cli, ["-vvvv"], input="WIP: tïtle \n") self.assertEqual(stderr.getvalue(), "") self.assertEqual(result.exit_code, CLITests.CONFIG_ERROR_CODE) self.assertEqual(result.output, "Config Error: Option 'verbosity' must be set between 0 and 3\n") - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_debug(self, sh, _): - """ Test for --debug option """ + """Test for --debug 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\x00abc\n" + "test åuthor1\x00test-email1@föo.com\x002016-12-03 15:28:15 +0100\x00a123\n" "commït-title1\n\ncommït-body1", - "#", # git config --get core.commentchar - "commit-1-branch-1\ncommit-1-branch-2\n", # git branch --contains <sha> - "commit-1/file-1\ncommit-1/file-2\n", # git diff-tree - "test åuthor2\x00test-email2@föo.com\x002016-12-04 15:28:15 +0100\x00abc\n" + "#", # git config --get core.commentchar + "5\t8\tcommit-1/file-1\n2\t9\tcommit-1/file-2\n", # git diff-tree + "commit-1-branch-1\ncommit-1-branch-2\n", # git branch --contains <sha> + "test åuthor2\x00test-email2@föo.com\x002016-12-04 15:28:15 +0100\x00b123\n" "commït-title2.\n\ncommït-body2", - "commit-2-branch-1\ncommit-2-branch-2\n", # git branch --contains <sha> - "commit-2/file-1\ncommit-2/file-2\n", # git diff-tree - "test åuthor3\x00test-email3@föo.com\x002016-12-05 15:28:15 +0100\x00abc\n" + "5\t8\tcommit-2/file-1\n7\t9\tcommit-2/file-2\n", # git diff-tree + "commit-2-branch-1\ncommit-2-branch-2\n", # git branch --contains <sha> + "test åuthor3\x00test-email3@föo.com\x002016-12-05 15:28:15 +0100\x00c123\n" "föobar\nbar", - "commit-3-branch-1\ncommit-3-branch-2\n", # git branch --contains <sha> - "commit-3/file-1\ncommit-3/file-2\n", # git diff-tree + "1\t4\tcommit-3/file-1\n3\t4\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: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: config_path = self.get_sample_path(os.path.join("config", "gitlintconfig")) - result = self.cli.invoke(cli.cli, ["--config", config_path, "--debug", "--commits", - "foo...bar"]) + result = self.cli.invoke(cli.cli, ["--config", config_path, "--debug", "--commits", "foo...bar"]) - expected = "Commit 6f29bf81a8:\n3: B5\n\n" + \ - "Commit 25053ccec5:\n1: T3\n3: B5\n\n" + \ - "Commit 4da2656b0d:\n2: B4\n3: B5\n3: B6\n" + expected = ( + "Commit 6f29bf81a8:\n3: B5\n\n" + "Commit 25053ccec5:\n1: T3\n3: B5\n\n" + "Commit 4da2656b0d:\n2: B4\n3: B5\n3: B6\n" + ) self.assertEqual(stderr.getvalue(), expected) self.assertEqual(result.exit_code, 6) expected_kwargs = self.get_system_info_dict() - expected_kwargs.update({'config_path': config_path}) - expected_logs = self.get_expected('cli/test_cli/test_debug_1', expected_kwargs) + expected_kwargs.update({"config_path": config_path}) + expected_logs = self.get_expected("cli/test_cli/test_debug_1", expected_kwargs) self.assert_logged(expected_logs) - @patch('gitlint.cli.get_stdin_data', return_value="Test tïtle\n") + @patch("gitlint.cli.get_stdin_data", return_value="Test tïtle\n") def test_extra_path(self, _): - """ Test for --extra-path flag """ + """Test for --extra-path flag""" # Test extra-path pointing to a directory - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: extra_path = self.get_sample_path("user_rules") result = self.cli.invoke(cli.cli, ["--extra-path", extra_path]) - expected_output = "1: UC1 Commit violåtion 1: \"Contënt 1\"\n" + \ - "3: B6 Body message is missing\n" + expected_output = '1: UC1 Commit violåtion 1: "Contënt 1"\n' + "3: B6 Body message is missing\n" self.assertEqual(stderr.getvalue(), expected_output) self.assertEqual(result.exit_code, 2) # Test extra-path pointing to a file - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: extra_path = self.get_sample_path(os.path.join("user_rules", "my_commit_rules.py")) result = self.cli.invoke(cli.cli, ["--extra-path", extra_path]) - expected_output = "1: UC1 Commit violåtion 1: \"Contënt 1\"\n" + \ - "3: B6 Body message is missing\n" + expected_output = '1: UC1 Commit violåtion 1: "Contënt 1"\n' + "3: B6 Body message is missing\n" + self.assertEqual(stderr.getvalue(), expected_output) + self.assertEqual(result.exit_code, 2) + + @patch("gitlint.cli.get_stdin_data", return_value="Test tïtle\n") + def test_extra_path_environment(self, _): + """Test for GITLINT_EXTRA_PATH environment variable""" + # Test setting extra-path to a directory from an environment variable + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + extra_path = self.get_sample_path("user_rules") + result = self.cli.invoke(cli.cli, env={"GITLINT_EXTRA_PATH": extra_path}) + + expected_output = '1: UC1 Commit violåtion 1: "Contënt 1"\n' + "3: B6 Body message is missing\n" + self.assertEqual(stderr.getvalue(), expected_output) + self.assertEqual(result.exit_code, 2) + + # Test extra-path pointing to a file from an environment variable + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + extra_path = self.get_sample_path(os.path.join("user_rules", "my_commit_rules.py")) + result = self.cli.invoke(cli.cli, env={"GITLINT_EXTRA_PATH": extra_path}) + expected_output = '1: UC1 Commit violåtion 1: "Contënt 1"\n' + "3: B6 Body message is missing\n" self.assertEqual(stderr.getvalue(), expected_output) self.assertEqual(result.exit_code, 2) - @patch('gitlint.cli.get_stdin_data', return_value="Test tïtle\n\nMy body that is long enough") + @patch("gitlint.cli.get_stdin_data", return_value="Test tïtle\n\nMy body that is long enough") def test_contrib(self, _): # Test enabled contrib rules - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--contrib", "contrib-title-conventional-commits,CC1"]) - expected_output = self.get_expected('cli/test_cli/test_contrib_1') + expected_output = self.get_expected("cli/test_cli/test_contrib_1") self.assertEqual(stderr.getvalue(), expected_output) self.assertEqual(result.exit_code, 2) - @patch('gitlint.cli.get_stdin_data', return_value="Test tïtle\n") + @patch("gitlint.cli.get_stdin_data", return_value="Test tïtle\n") def test_contrib_negative(self, _): result = self.cli.invoke(cli.cli, ["--contrib", "föobar,CC1"]) self.assertEqual(result.output, "Config Error: No contrib rule with id or name 'föobar' found.\n") self.assertEqual(result.exit_code, self.CONFIG_ERROR_CODE) - @patch('gitlint.cli.get_stdin_data', return_value="WIP: tëst") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tëst") def test_config_file(self, _): - """ Test for --config option """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + """Test for --config option""" + with patch("gitlint.display.stderr", new=StringIO()) as stderr: config_path = self.get_sample_path(os.path.join("config", "gitlintconfig")) result = self.cli.invoke(cli.cli, ["--config", config_path]) self.assertEqual(result.output, "") self.assertEqual(stderr.getvalue(), "1: T5\n3: B6\n") self.assertEqual(result.exit_code, 2) + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tëst") + def test_config_file_environment(self, _): + """Test for GITLINT_CONFIG environment variable""" + with patch("gitlint.display.stderr", new=StringIO()) as stderr: + config_path = self.get_sample_path(os.path.join("config", "gitlintconfig")) + result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) + self.assertEqual(result.output, "") + self.assertEqual(stderr.getvalue(), "1: T5\n3: B6\n") + self.assertEqual(result.exit_code, 2) + def test_config_file_negative(self): - """ Negative test for --config option """ + """Negative test for --config option""" # Directory as config file config_path = self.get_sample_path("config") result = self.cli.invoke(cli.cli, ["--config", config_path]) @@ -502,9 +557,30 @@ class CLITests(BaseTestCase): result = self.cli.invoke(cli.cli, ["--config", config_path]) self.assertEqual(result.exit_code, self.CONFIG_ERROR_CODE) - @patch('gitlint.cli.get_stdin_data', return_value=False) + def test_config_file_negative_environment(self): + """Negative test for GITLINT_CONFIG environment variable""" + # Directory as config file + config_path = self.get_sample_path("config") + result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) + expected_string = f"Error: Invalid value for '-C' / '--config': File '{config_path}' is a directory." + self.assertEqual(result.output.split("\n")[3], expected_string) + self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) + + # Non existing file + config_path = self.get_sample_path("föo") + result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) + expected_string = f"Error: Invalid value for '-C' / '--config': File '{config_path}' does not exist." + self.assertEqual(result.output.split("\n")[3], expected_string) + self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) + + # Invalid config file + config_path = self.get_sample_path(os.path.join("config", "invalid-option-value")) + result = self.cli.invoke(cli.cli, env={"GITLINT_CONFIG": config_path}) + 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 """ + """Test for the --target option""" with self.tempdir() as tmpdir: tmpdir_path = os.path.realpath(tmpdir) os.environ["LANGUAGE"] = "C" # Force language to english so we can check for error message @@ -515,7 +591,7 @@ class CLITests(BaseTestCase): self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) def test_target_negative(self): - """ Negative test for the --target option """ + """Negative test for the --target option""" # try setting a non-existing target result = self.cli.invoke(cli.cli, ["--target", "/föo/bar"]) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) @@ -529,57 +605,63 @@ class CLITests(BaseTestCase): expected_msg = f"Error: Invalid value for '--target': Directory '{target_path}' is a file." self.assertEqual(result.output.split("\n")[3], expected_msg) - @patch('gitlint.config.LintConfigGenerator.generate_config') + @patch("gitlint.config.LintConfigGenerator.generate_config") def test_generate_config(self, generate_config): - """ Test for the generate-config subcommand """ + """Test for the generate-config subcommand""" result = self.cli.invoke(cli.cli, ["generate-config"], input="tëstfile\n") self.assertEqual(result.exit_code, self.GITLINT_SUCCESS_CODE) - expected_msg = "Please specify a location for the sample gitlint config file [.gitlint]: tëstfile\n" + \ - f"Successfully generated {os.path.realpath('tëstfile')}\n" + expected_msg = ( + "Please specify a location for the sample gitlint config file [.gitlint]: tëstfile\n" + + f"Successfully generated {os.path.realpath('tëstfile')}\n" + ) self.assertEqual(result.output, expected_msg) generate_config.assert_called_once_with(os.path.realpath("tëstfile")) def test_generate_config_negative(self): - """ Negative test for the generate-config subcommand """ + """Negative test for the generate-config subcommand""" # Non-existing directory fake_dir = os.path.abspath("/föo") fake_path = os.path.join(fake_dir, "bar") result = self.cli.invoke(cli.cli, ["generate-config"], input=fake_path) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - expected_msg = f"Please specify a location for the sample gitlint config file [.gitlint]: {fake_path}\n" + \ - f"Error: Directory '{fake_dir}' does not exist.\n" + expected_msg = ( + f"Please specify a location for the sample gitlint config file [.gitlint]: {fake_path}\n" + + f"Error: Directory '{fake_dir}' does not exist.\n" + ) self.assertEqual(result.output, expected_msg) # Existing file sample_path = self.get_sample_path(os.path.join("config", "gitlintconfig")) result = self.cli.invoke(cli.cli, ["generate-config"], input=sample_path) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) - expected_msg = "Please specify a location for the sample gitlint " + \ - f"config file [.gitlint]: {sample_path}\n" + \ - f"Error: File \"{sample_path}\" already exists.\n" + expected_msg = ( + "Please specify a location for the sample gitlint " + f"config file [.gitlint]: {sample_path}\n" + f'Error: File "{sample_path}" already exists.\n' + ) self.assertEqual(result.output, expected_msg) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_git_error(self, sh, _): - """ Tests that the cli handles git errors properly """ + """Tests that the cli handles git errors properly""" sh.git.side_effect = CommandNotFound("git") result = self.cli.invoke(cli.cli) self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_no_commits_in_range(self, sh, _): - """ Test for --commits with the specified range being empty. """ + """Test for --commits with the specified range being empty.""" sh.git.side_effect = lambda *_args, **_kwargs: "" - result = self.cli.invoke(cli.cli, ["--commits", "master...HEAD"]) + result = self.cli.invoke(cli.cli, ["--commits", "main...HEAD"]) - self.assert_log_contains("DEBUG: gitlint.cli No commits in range \"master...HEAD\"") + self.assert_log_contains('DEBUG: gitlint.cli No commits in range "main...HEAD"') self.assertEqual(result.exit_code, self.GITLINT_SUCCESS_CODE) - @patch('gitlint.cli.get_stdin_data', return_value="WIP: tëst tïtle") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: tëst tïtle") def test_named_rules(self, _): - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: config_path = self.get_sample_path(os.path.join("config", "named-rules")) result = self.cli.invoke(cli.cli, ["--config", config_path, "--debug"]) self.assertEqual(result.output, "") @@ -588,6 +670,6 @@ class CLITests(BaseTestCase): # Assert debug logs are correct expected_kwargs = self.get_system_info_dict() - expected_kwargs.update({'config_path': config_path}) - expected_logs = self.get_expected('cli/test_cli/test_named_rules_2', expected_kwargs) + expected_kwargs.update({"config_path": config_path}) + expected_logs = self.get_expected("cli/test_cli/test_named_rules_2", expected_kwargs) self.assert_logged(expected_logs) diff --git a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py index 825345f..d4311c6 100644 --- a/gitlint-core/gitlint/tests/cli/test_cli_hooks.py +++ b/gitlint-core/gitlint/tests/cli/test_cli_hooks.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import io from io import StringIO import os @@ -23,21 +21,21 @@ class CLIHookTests(BaseTestCase): CONFIG_ERROR_CODE = 255 def setUp(self): - super(CLIHookTests, self).setUp() + super().setUp() self.cli = CliRunner() # Patch gitlint.cli.git_version() so that we don't have to patch it separately in every test - self.git_version_path = patch('gitlint.cli.git_version') + self.git_version_path = patch("gitlint.cli.git_version") cli.git_version = self.git_version_path.start() cli.git_version.return_value = "git version 1.2.3" def tearDown(self): self.git_version_path.stop() - @patch('gitlint.hooks.GitHookInstaller.install_commit_msg_hook') - @patch('gitlint.hooks.git_hooks_dir', return_value=os.path.join("/hür", "dur")) + @patch("gitlint.hooks.GitHookInstaller.install_commit_msg_hook") + @patch("gitlint.hooks.git_hooks_dir", return_value=os.path.join("/hür", "dur")) def test_install_hook(self, _, install_hook): - """ Test for install-hook subcommand """ + """Test for install-hook subcommand""" result = self.cli.invoke(cli.cli, ["install-hook"]) expected_path = os.path.join("/hür", "dur", hooks.COMMIT_MSG_HOOK_DST_PATH) expected = f"Successfully installed gitlint commit-msg hook in {expected_path}\n" @@ -47,10 +45,10 @@ class CLIHookTests(BaseTestCase): expected_config.target = os.path.realpath(os.getcwd()) install_hook.assert_called_once_with(expected_config) - @patch('gitlint.hooks.GitHookInstaller.install_commit_msg_hook') - @patch('gitlint.hooks.git_hooks_dir', return_value=os.path.join("/hür", "dur")) + @patch("gitlint.hooks.GitHookInstaller.install_commit_msg_hook") + @patch("gitlint.hooks.git_hooks_dir", return_value=os.path.join("/hür", "dur")) def test_install_hook_target(self, _, install_hook): - """ Test for install-hook subcommand with a specific --target option specified """ + """Test for install-hook subcommand with a specific --target option specified""" # Specified target result = self.cli.invoke(cli.cli, ["--target", self.SAMPLES_DIR, "install-hook"]) expected_path = os.path.join("/hür", "dur", hooks.COMMIT_MSG_HOOK_DST_PATH) @@ -62,9 +60,9 @@ class CLIHookTests(BaseTestCase): expected_config.target = self.SAMPLES_DIR install_hook.assert_called_once_with(expected_config) - @patch('gitlint.hooks.GitHookInstaller.install_commit_msg_hook', side_effect=hooks.GitHookInstallerError("tëst")) + @patch("gitlint.hooks.GitHookInstaller.install_commit_msg_hook", side_effect=hooks.GitHookInstallerError("tëst")) def test_install_hook_negative(self, install_hook): - """ Negative test for install-hook subcommand """ + """Negative test for install-hook subcommand""" result = self.cli.invoke(cli.cli, ["install-hook"]) self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) self.assertEqual(result.output, "tëst\n") @@ -72,10 +70,10 @@ class CLIHookTests(BaseTestCase): expected_config.target = os.path.realpath(os.getcwd()) install_hook.assert_called_once_with(expected_config) - @patch('gitlint.hooks.GitHookInstaller.uninstall_commit_msg_hook') - @patch('gitlint.hooks.git_hooks_dir', return_value=os.path.join("/hür", "dur")) + @patch("gitlint.hooks.GitHookInstaller.uninstall_commit_msg_hook") + @patch("gitlint.hooks.git_hooks_dir", return_value=os.path.join("/hür", "dur")) def test_uninstall_hook(self, _, uninstall_hook): - """ Test for uninstall-hook subcommand """ + """Test for uninstall-hook subcommand""" result = self.cli.invoke(cli.cli, ["uninstall-hook"]) expected_path = os.path.join("/hür", "dur", hooks.COMMIT_MSG_HOOK_DST_PATH) expected = f"Successfully uninstalled gitlint commit-msg hook from {expected_path}\n" @@ -85,9 +83,9 @@ class CLIHookTests(BaseTestCase): expected_config.target = os.path.realpath(os.getcwd()) uninstall_hook.assert_called_once_with(expected_config) - @patch('gitlint.hooks.GitHookInstaller.uninstall_commit_msg_hook', side_effect=hooks.GitHookInstallerError("tëst")) + @patch("gitlint.hooks.GitHookInstaller.uninstall_commit_msg_hook", side_effect=hooks.GitHookInstallerError("tëst")) def test_uninstall_hook_negative(self, uninstall_hook): - """ Negative test for uninstall-hook subcommand """ + """Negative test for uninstall-hook subcommand""" result = self.cli.invoke(cli.cli, ["uninstall-hook"]) self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) self.assertEqual(result.output, "tëst\n") @@ -96,8 +94,8 @@ class CLIHookTests(BaseTestCase): uninstall_hook.assert_called_once_with(expected_config) def test_run_hook_no_tty(self): - """ Test for run-hook subcommand. - When no TTY is available (like is the case for this test), the hook will abort after the first check. + """Test for run-hook subcommand. + When no TTY is available (like is the case for this test), the hook will abort after the first check. """ # No need to patch git as we're passing a msg-filename to run-hook, so no git calls are made. @@ -110,20 +108,20 @@ class CLIHookTests(BaseTestCase): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "hür") - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write("WIP: tïtle\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_no_tty_1_stdout')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_tty_1_stdout")) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_tty_1_stderr")) # exit code is 1 because aborted (no stdin available) self.assertEqual(result.exit_code, 1) - @patch('gitlint.cli.shell') + @patch("gitlint.cli.shell") def test_run_hook_edit(self, shell): - """ Test for run-hook subcommand, answering 'e(dit)' after commit-hook """ + """Test for run-hook subcommand, answering 'e(dit)' after commit-hook""" set_editors = [None, "myeditor"] expected_editors = ["vim -n", "myeditor"] @@ -131,20 +129,28 @@ class CLIHookTests(BaseTestCase): for i in range(0, len(set_editors)): if set_editors[i]: - os.environ['EDITOR'] = set_editors[i] + os.environ["EDITOR"] = set_editors[i] + else: + # When set_editors[i] == None, ensure we don't fallback to EDITOR set in shell invocating the tests + os.environ.pop("EDITOR", None) - with self.patch_input(['e', 'e', 'n']): + with self.patch_input(["e", "e", "n"]): with self.tempdir() as tmpdir: msg_filename = os.path.realpath(os.path.join(tmpdir, "hür")) - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write(commit_messages[i] + "\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_edit_1_stdout', - {"commit_msg": commit_messages[i]})) - expected = self.get_expected("cli/test_cli_hooks/test_hook_edit_1_stderr", - {"commit_msg": commit_messages[i]}) + self.assertEqual( + result.output, + self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stdout", {"commit_msg": commit_messages[i]} + ), + ) + expected = self.get_expected( + "cli/test_cli_hooks/test_hook_edit_1_stderr", {"commit_msg": commit_messages[i]} + ) self.assertEqual(stderr.getvalue(), expected) # exit code = number of violations @@ -155,17 +161,17 @@ class CLIHookTests(BaseTestCase): self.assert_log_contains(f"DEBUG: gitlint.cli run-hook: {expected_editors[i]} {msg_filename}") def test_run_hook_no(self): - """ Test for run-hook subcommand, answering 'n(o)' after commit-hook """ + """Test for run-hook subcommand, answering 'n(o)' after commit-hook""" - with self.patch_input(['n']): + with self.patch_input(["n"]): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "hür") - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write("WIP: höok no\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_no_1_stdout')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_no_1_stdout")) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_no_1_stderr")) # We decided not to keep the commit message: hook returns number of violations (>0) @@ -174,16 +180,16 @@ class CLIHookTests(BaseTestCase): self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message declined") def test_run_hook_yes(self): - """ Test for run-hook subcommand, answering 'y(es)' after commit-hook """ - with self.patch_input(['y']): + """Test for run-hook subcommand, answering 'y(es)' after commit-hook""" + with self.patch_input(["y"]): with self.tempdir() as tmpdir: msg_filename = os.path.join(tmpdir, "hür") - with io.open(msg_filename, 'w', encoding=DEFAULT_ENCODING) as f: + with open(msg_filename, "w", encoding=DEFAULT_ENCODING) as f: f.write("WIP: höok yes\n") - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["--msg-filename", msg_filename, "run-hook"]) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_yes_1_stdout')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stdout")) self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_yes_1_stderr")) # Exit code is 0 because we decide to keep the commit message @@ -191,23 +197,23 @@ class CLIHookTests(BaseTestCase): self.assertEqual(result.exit_code, 0) self.assert_log_contains("DEBUG: gitlint.cli run-hook: commit message accepted") - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_run_hook_negative(self, sh, _): - """ Negative test for the run-hook subcommand: testing whether exceptions are correctly handled when + """Negative test for the run-hook subcommand: testing whether exceptions are correctly handled when running `gitlint run-hook`. """ # GIT_CONTEXT_ERROR_CODE: git error error_msg = b"fatal: not a git repository (or any of the parent directories): .git" sh.git.side_effect = ErrorReturnCode("full command", b"stdout", error_msg) result = self.cli.invoke(cli.cli, ["run-hook"]) - expected = self.get_expected('cli/test_cli_hooks/test_run_hook_negative_1', {'git_repo': os.getcwd()}) + expected = self.get_expected("cli/test_cli_hooks/test_run_hook_negative_1", {"git_repo": os.getcwd()}) self.assertEqual(result.output, expected) self.assertEqual(result.exit_code, self.GIT_CONTEXT_ERROR_CODE) # USAGE_ERROR_CODE: incorrect use of gitlint result = self.cli.invoke(cli.cli, ["--staged", "run-hook"]) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_run_hook_negative_2')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_run_hook_negative_2")) self.assertEqual(result.exit_code, self.USAGE_ERROR_CODE) # CONFIG_ERROR_CODE: incorrect config. Note that this is handled before the hook even runs @@ -215,67 +221,66 @@ class CLIHookTests(BaseTestCase): self.assertEqual(result.output, "Config Error: No such rule 'föo'\n") self.assertEqual(result.exit_code, self.CONFIG_ERROR_CODE) - @patch('gitlint.cli.get_stdin_data', return_value="WIP: Test hook stdin tïtle\n") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: Test hook stdin tïtle\n") def test_run_hook_stdin_violations(self, _): - """ Test for passing stdin data to run-hook, expecting some violations. Equivalent of: - $ echo "WIP: Test hook stdin tïtle" | gitlint run-hook + """Test for passing stdin data to run-hook, expecting some violations. Equivalent of: + $ echo "WIP: Test hook stdin tïtle" | gitlint run-hook """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["run-hook"]) - expected_stderr = self.get_expected('cli/test_cli_hooks/test_hook_stdin_violations_1_stderr') + expected_stderr = self.get_expected("cli/test_cli_hooks/test_hook_stdin_violations_1_stderr") self.assertEqual(stderr.getvalue(), expected_stderr) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_stdin_violations_1_stdout')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_stdin_violations_1_stdout")) # Hook will auto-abort because we're using stdin. Abort = exit code 1 self.assertEqual(result.exit_code, 1) - @patch('gitlint.cli.get_stdin_data', return_value="Test tïtle\n\nTest bödy that is long enough") + @patch("gitlint.cli.get_stdin_data", return_value="Test tïtle\n\nTest bödy that is long enough") def test_run_hook_stdin_no_violations(self, _): - """ Test for passing stdin data to run-hook, expecting *NO* violations, Equivalent of: - $ echo -e "Test tïtle\n\nTest bödy that is long enough" | gitlint run-hook + """Test for passing stdin data to run-hook, expecting *NO* violations, Equivalent of: + $ echo -e "Test tïtle\n\nTest bödy that is long enough" | gitlint run-hook """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["run-hook"]) self.assertEqual(stderr.getvalue(), "") # no errors = no stderr output - expected_stdout = self.get_expected('cli/test_cli_hooks/test_hook_stdin_no_violations_1_stdout') + expected_stdout = self.get_expected("cli/test_cli_hooks/test_hook_stdin_no_violations_1_stdout") self.assertEqual(result.output, expected_stdout) self.assertEqual(result.exit_code, 0) - @patch('gitlint.cli.get_stdin_data', return_value="WIP: Test hook config tïtle\n") + @patch("gitlint.cli.get_stdin_data", return_value="WIP: Test hook config tïtle\n") def test_run_hook_config(self, _): - """ Test that gitlint still respects config when running run-hook, equivalent of: - $ echo "WIP: Test hook config tïtle" | gitlint -c title-max-length.line-length=5 --ignore B6 run-hook + """Test that gitlint still respects config when running run-hook, equivalent of: + $ echo "WIP: Test hook config tïtle" | gitlint -c title-max-length.line-length=5 --ignore B6 run-hook """ - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["-c", "title-max-length.line-length=5", "--ignore", "B6", "run-hook"]) - self.assertEqual(stderr.getvalue(), self.get_expected('cli/test_cli_hooks/test_hook_config_1_stderr')) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_config_1_stdout')) + self.assertEqual(stderr.getvalue(), self.get_expected("cli/test_cli_hooks/test_hook_config_1_stderr")) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_config_1_stdout")) # Hook will auto-abort because we're using stdin. Abort = exit code 1 self.assertEqual(result.exit_code, 1) - @patch('gitlint.cli.get_stdin_data', return_value=False) - @patch('gitlint.git.sh') + @patch("gitlint.cli.get_stdin_data", return_value=False) + @patch("gitlint.git.sh") def test_run_hook_local_commit(self, sh, _): - """ Test running the hook on the last commit-msg from the local repo, equivalent of: - $ gitlint run-hook - and then choosing 'e' + """Test running the hook on the last commit-msg from the local repo, equivalent of: + $ gitlint run-hook + and then choosing 'e' """ sh.git.side_effect = [ "6f29bf81a8322a04071bb794666e48c443a90360", - "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\n" - "WIP: commït-title\n\ncommït-body", + "test åuthor\x00test-email@föo.com\x002016-12-03 15:28:15 +0100\x00åbc\nWIP: commït-title\n\ncommït-body", "#", # git config --get core.commentchar + "1\t5\tfile1.txt\n3\t4\tpåth/to/file2.txt\n", "commit-1-branch-1\ncommit-1-branch-2\n", - "file1.txt\npåth/to/file2.txt\n" ] - with self.patch_input(['e']): - with patch('gitlint.display.stderr', new=StringIO()) as stderr: + with self.patch_input(["e"]): + with patch("gitlint.display.stderr", new=StringIO()) as stderr: result = self.cli.invoke(cli.cli, ["run-hook"]) - expected = self.get_expected('cli/test_cli_hooks/test_hook_local_commit_1_stderr') + expected = self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stderr") self.assertEqual(stderr.getvalue(), expected) - self.assertEqual(result.output, self.get_expected('cli/test_cli_hooks/test_hook_local_commit_1_stdout')) + self.assertEqual(result.output, self.get_expected("cli/test_cli_hooks/test_hook_local_commit_1_stdout")) # If we can't edit the message, run-hook follows regular gitlint behavior and exit code = # violations self.assertEqual(result.exit_code, 2) |