diff options
author | pbregener <pbregener@users.noreply.github.com> | 2018-11-07 11:46:43 +0100 |
---|---|---|
committer | Joris Roovers <jroovers@cisco.com> | 2019-03-13 10:35:43 +0100 |
commit | 87993c9f75264ba09e1602ff619731c410aad5da (patch) | |
tree | 9b67736be15b8ab71edc42ddc16322b7bee1daa4 | |
parent | c9db6a0b49004f514254c79fa5048dbd5a760e3d (diff) |
Various test fixes, linting in CI, Python 3.7 compatibility (#76)
- Various text fixes all over
- Enable lint tests for Python 3.6
- Fix some pylint warnings
- Ignore pylint errors for bad options
- Use unittest2 only for Python 2
- Test Python 3.7 in Travis
- Integration Tests: Introduce assertEqualStdout
- Activate all integration tests in Travis
- Update dependencies in requirements.txt
-rw-r--r-- | .pylintrc | 2 | ||||
-rw-r--r-- | .travis.yml | 36 | ||||
-rw-r--r-- | gitlint/cli.py | 5 | ||||
-rw-r--r-- | gitlint/git.py | 4 | ||||
-rw-r--r-- | gitlint/lint.py | 1 | ||||
-rw-r--r-- | gitlint/rules.py | 3 | ||||
-rw-r--r-- | gitlint/user_rules.py | 6 | ||||
-rw-r--r-- | gitlint/utils.py | 2 | ||||
-rw-r--r-- | qa/base.py | 30 | ||||
-rw-r--r-- | qa/requirements.txt | 9 | ||||
-rw-r--r-- | qa/test_commits.py | 12 | ||||
-rw-r--r-- | qa/test_config.py | 20 | ||||
-rw-r--r-- | qa/test_gitlint.py | 30 | ||||
-rw-r--r-- | qa/test_hooks.py | 20 | ||||
-rw-r--r-- | qa/test_stdin.py | 7 | ||||
-rw-r--r-- | qa/test_user_defined.py | 10 | ||||
-rw-r--r-- | requirements.txt | 7 | ||||
-rwxr-xr-x | run_tests.sh | 33 | ||||
-rw-r--r-- | setup.py | 5 | ||||
-rw-r--r-- | test-requirements.txt | 18 |
20 files changed, 130 insertions, 130 deletions
@@ -11,7 +11,7 @@ # R0801: Similar lines in files # I0011: Informational: locally disabled pylint # I0013: Informational: Ignoring entire file -disable=C0111,W0511,W0142,W0622,W0223,W0212,R0901,R0801,I0011,I0013,anomalous-backslash-in-string +disable=bad-option-value,C0111,W0511,W0142,W0622,W0223,W0212,R0901,R0801,I0011,I0013,anomalous-backslash-in-string,useless-object-inheritance [Format] max-line-length=120 diff --git a/.travis.yml b/.travis.yml index c121329..261bda0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,43 +9,17 @@ matrix: os: linux - python: "3.3" os: linux - script: - # Skip integration tests in Travis for Python 3.3, need to look into this - # Error example: https://travis-ci.org/jorisroovers/gitlint/jobs/310861373 - - "./run_tests.sh" - - "./run_tests.sh --build" - - "./run_tests.sh --pep8" - - "./run_tests.sh --lint" - - "./run_tests.sh --git" - python: "3.4" os: linux - script: - # Skip integration tests in Travis for Python 3.4, need to look into this - # Error example: https://travis-ci.org/jorisroovers/gitlint/jobs/310861374 - - "./run_tests.sh" - - "./run_tests.sh --build" - - "./run_tests.sh --pep8" - - "./run_tests.sh --lint" - - "./run_tests.sh --git" - python: "3.5" os: linux - script: - # Skip integration tests in Travis for Python 3.5, need to look into this - # Error example: https://travis-ci.org/jorisroovers/gitlint/jobs/310861375 - - "./run_tests.sh" - - "./run_tests.sh --build" - - "./run_tests.sh --pep8" - - "./run_tests.sh --lint" - - "./run_tests.sh --git" - python: "3.6" os: linux - script: - # Skip lint tests for python 3.6 (see https://github.com/PyCQA/pylint/issues/1072) - - "./run_tests.sh" - - "./run_tests.sh --integration" - - "./run_tests.sh --build" - - "./run_tests.sh --pep8" - - "./run_tests.sh --git" + - python: "3.7" + os: linux + # See https://github.com/travis-ci/travis-ci/issues/9815 + dist: xenial + sudo: true - python: "pypy" os: linux install: diff --git a/gitlint/cli.py b/gitlint/cli.py index 1d22bf2..701a47f 100644 --- a/gitlint/cli.py +++ b/gitlint/cli.py @@ -120,7 +120,7 @@ def get_stdin_data(): input_data = sys.stdin.read() # Only return the input data if there's actually something passed # i.e. don't consider empty piped data - if len(input_data) != 0: + if input_data: return ustr(input_data) return False @@ -295,4 +295,5 @@ def generate_config(ctx): # Let's Party! setup_logging() if __name__ == "__main__": - cli() # pragma: no cover, # pylint: disable=no-value-for-parameter + # pylint: disable=no-value-for-parameter + cli() # pragma: no cover diff --git a/gitlint/git.py b/gitlint/git.py index 422bd9f..e7b114f 100644 --- a/gitlint/git.py +++ b/gitlint/git.py @@ -24,7 +24,7 @@ def _git(*command_parts, **kwargs): git_kwargs = {'_tty_out': False} git_kwargs.update(kwargs) try: - result = sh.git(*command_parts, **git_kwargs) + result = sh.git(*command_parts, **git_kwargs) # pylint: disable=unexpected-keyword-arg # If we reach this point and the result has an exit_code that is larger than 0, this means that we didn't # get an exception (which is the default sh behavior for non-zero exit codes) and so the user is expecting # a non-zero exit code -> just return the entire result @@ -82,7 +82,7 @@ class GitCommitMessage(object): cutline_index = None lines = [line for line in all_lines[:cutline_index] if not line.startswith(GitCommitMessage.COMMENT_CHAR)] full = "\n".join(lines) - title = lines[0] if len(lines) > 0 else "" + title = lines[0] if lines else "" body = lines[1:] if len(lines) > 1 else [] return GitCommitMessage(original=commit_msg_str, full=full, title=title, body=body) diff --git a/gitlint/lint.py b/gitlint/lint.py index 362d8ae..182a55a 100644 --- a/gitlint/lint.py +++ b/gitlint/lint.py @@ -1,3 +1,4 @@ +# pylint: disable=logging-not-lazy import logging from gitlint import rules as gitlint_rules from gitlint import display diff --git a/gitlint/rules.py b/gitlint/rules.py index a4a91e9..9a5acf7 100644 --- a/gitlint/rules.py +++ b/gitlint/rules.py @@ -1,3 +1,4 @@ +# pylint: disable=inconsistent-return-statements import copy import logging import re @@ -262,7 +263,7 @@ class BodyMinLength(CommitRule): min_length = self.options['min-length'].value body_message_no_newline = "".join([line for line in commit.message.body if line is not None]) actual_length = len(body_message_no_newline) - if actual_length > 0 and actual_length < min_length: + if 0 < actual_length < min_length: violation_message = "Body message is too short ({0}<{1})".format(actual_length, min_length) return [RuleViolation(self.id, violation_message, body_message_no_newline, 3)] diff --git a/gitlint/user_rules.py b/gitlint/user_rules.py index b061b24..3d80684 100644 --- a/gitlint/user_rules.py +++ b/gitlint/user_rules.py @@ -41,7 +41,7 @@ def find_rule_classes(extra_path): modules.append(os.path.splitext(filename)[0]) # No need to continue if there are no modules specified - if len(modules) == 0: + if not modules: return [] # Append the extra rules path to python path so that we can import them @@ -93,7 +93,7 @@ def assert_valid_rule_class(clazz): rules.LineRule.__name__, rules.CommitRule.__name__)) # Rules must have an id attribute - if not hasattr(clazz, 'id') or clazz.id is None or len(clazz.id) == 0: + if not hasattr(clazz, 'id') or clazz.id is None or not clazz.id: raise UserRuleError(u"User-defined rule class '{0}' must have an 'id' attribute".format(clazz.__name__)) # Rule id's cannot start with gitlint reserved letters @@ -102,7 +102,7 @@ def assert_valid_rule_class(clazz): raise UserRuleError(msg.format(clazz.__name__, clazz.id[0])) # Rules must have a name attribute - if not hasattr(clazz, 'name') or clazz.name is None or len(clazz.name) == 0: + if not hasattr(clazz, 'name') or clazz.name is None or not clazz.name: raise UserRuleError(u"User-defined rule class '{0}' must have a 'name' attribute".format(clazz.__name__)) # if set, options_spec must be a list of RuleOption diff --git a/gitlint/utils.py b/gitlint/utils.py index c0fdb4d..d1e67dc 100644 --- a/gitlint/utils.py +++ b/gitlint/utils.py @@ -1,4 +1,4 @@ -# pylint: disable=bad-option-value,unidiomatic-typecheck,undefined-variable +# pylint: disable=bad-option-value,unidiomatic-typecheck,undefined-variable,no-else-return import sys from locale import getpreferredencoding @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# pylint: disable=bad-option-value,unidiomatic-typecheck,undefined-variable +# pylint: disable=bad-option-value,unidiomatic-typecheck,undefined-variable,no-else-return, +# pylint: disable=too-many-function-args,unexpected-keyword-arg import os import sys @@ -7,8 +8,14 @@ import tempfile from datetime import datetime from uuid import uuid4 -from unittest2 import TestCase -from sh import git, rm, touch, DEFAULT_ENCODING # pylint: disable=no-name-in-module +try: + # python 2.x + from unittest2 import TestCase +except ImportError: + # python 3.x + from unittest import TestCase + +from sh import git, rm, touch, DEFAULT_ENCODING, RunningCommand # pylint: disable=no-name-in-module def ustr(obj): @@ -42,6 +49,12 @@ class BaseTestCase(TestCase): for tmpfile in self.tmpfiles: os.remove(tmpfile) + def assertEqualStdout(self, output, expected): # pylint: disable=invalid-name + self.assertIsInstance(output, RunningCommand) + output = output.stdout.decode(DEFAULT_ENCODING) + output = output.replace('\r\n', '\n') + self.assertMultiLineEqual(output, expected) + @classmethod def setUpClass(cls): """ Sets up the integration tests by creating a new temporary git repository """ @@ -57,7 +70,8 @@ class BaseTestCase(TestCase): @classmethod def create_tmp_git_repo(cls): """ Creates a temporary git repository and returns its directory path """ - tmp_git_repo = os.path.realpath("/tmp/gitlint-test-%s" % datetime.now().strftime("%Y%m%d-%H%M%S")) + tmp_git_repo = os.path.realpath("/tmp/gitlint-test-{0}".format( + datetime.now().strftime("%Y%m%d-%H%M%S-%f"))) git("init", tmp_git_repo) # configuring name and email is required in every git repot git("config", "user.name", "gitlint-test-user", _cwd=tmp_git_repo) @@ -138,11 +152,3 @@ class BaseTestCase(TestCase): if variable_dict: expected = expected.format(**variable_dict) return expected - - @staticmethod - def mock_stdin(): - """ Convenience method to create a Mock stdin object to deal with https://github.com/amoffat/sh/issues/427 """ - class MockInput(object): - def read(self, _size): # pylint: disable=no-self-use - return - return MockInput() diff --git a/qa/requirements.txt b/qa/requirements.txt index 853ce42..542358d 100644 --- a/qa/requirements.txt +++ b/qa/requirements.txt @@ -1,5 +1,6 @@ -unittest2==1.1.0 # support for python 2.6 -sh==1.11 -pytest==3.0.4 +unittest2==1.1.0; python_version <= '2.7' +sh==1.12.14 +pytest==3.2.5; python_version == '2.6' or python_version == '3.3' +pytest==3.10.0; python_version != '2.6' and python_version != '3.3' arrow==0.10.0 -gitlint # no version as you want to test the currently installed version
\ No newline at end of file +gitlint # no version as you want to test the currently installed version diff --git a/qa/test_commits.py b/qa/test_commits.py index 4620121..859d70a 100644 --- a/qa/test_commits.py +++ b/qa/test_commits.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +# pylint: disable=too-many-function-args,unexpected-keyword-arg from sh import git, gitlint # pylint: disable=no-name-in-module from qa.base import BaseTestCase @@ -17,7 +17,7 @@ class CommitsTests(BaseTestCase): 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.assertEqual(output, "") + self.assertEqualStdout(output, "") def test_violations(self): """ Test linting multiple commits with violations """ @@ -40,7 +40,7 @@ class CommitsTests(BaseTestCase): u"3: B6 Body message is missing\n") self.assertEqual(output.exit_code, 4) - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_lint_single_commit(self): self._create_simple_commit(u"Sïmple title.\n") @@ -52,7 +52,7 @@ class CommitsTests(BaseTestCase): 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.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_lint_head(self): """ Testing whether we can also recognize special refs like 'HEAD' """ @@ -72,7 +72,7 @@ class CommitsTests(BaseTestCase): u"1: T3 Title has trailing punctuation (.): \"Sïmple title.\"\n" ) - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_ignore_commits(self): """ Tests multiple commits of which some rules get igonored because of ignore-* rules """ @@ -102,4 +102,4 @@ class CommitsTests(BaseTestCase): u"1: T3 Title has trailing punctuation (.): \"Sïmple title.\"\n" ) - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) diff --git a/qa/test_config.py b/qa/test_config.py index b7cb733..318389d 100644 --- a/qa/test_config.py +++ b/qa/test_config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +# pylint: disable=too-many-function-args,unexpected-keyword-arg import platform import sys @@ -16,36 +16,36 @@ class ConfigTests(BaseTestCase): self._create_simple_commit(u"WIP: Thïs is a title.\nContënt on the second line") output = gitlint("--ignore", "T5,B4", _tty_in=True, _cwd=self.tmp_git_repo, _ok_code=[1]) expected = u"1: T3 Title has trailing punctuation (.): \"WIP: Thïs is a title.\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_ignore_by_name(self): self._create_simple_commit(u"WIP: Thïs is a title.\nContënt on the second line") output = gitlint("--ignore", "title-must-not-contain-word,body-first-line-empty", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) expected = u"1: T3 Title has trailing punctuation (.): \"WIP: Thïs is a title.\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_verbosity(self): self._create_simple_commit(u"WIP: Thïs is a title.\nContënt on the second line") output = gitlint("-v", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[3]) expected = u"1: T3\n1: T5\n2: B4\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) output = gitlint("-vv", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[3]) expected = u"1: T3 Title has trailing punctuation (.)\n" + \ u"1: T5 Title contains the word 'WIP' (case-insensitive)\n" + \ u"2: B4 Second line is not empty\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) output = gitlint("-vvv", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[3]) expected = u"1: T3 Title has trailing punctuation (.): \"WIP: Thïs is a title.\"\n" + \ u"1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: Thïs is a title.\"\n" + \ u"2: B4 Second line is not empty: \"Contënt on the second line\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) # test silent mode output = gitlint("--silent", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[3]) - self.assertEqual(output, "") + self.assertEqualStdout(output, "") def test_set_rule_option(self): self._create_simple_commit(u"This ïs a title.") @@ -53,7 +53,7 @@ class ConfigTests(BaseTestCase): expected = u"1: T1 Title exceeds max length (16>5): \"This ïs a title.\"\n" + \ u"1: T3 Title has trailing punctuation (.): \"This ïs a title.\"\n" + \ "3: B6 Body message is missing\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_config_from_file(self): commit_msg = u"WIP: Thïs is a title thåt is a bit longer.\nContent on the second line\n" + \ @@ -68,7 +68,7 @@ class ConfigTests(BaseTestCase): "2: B4 Second line is not empty\n" + \ "3: B1 Line exceeds max length (48>30)\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_config_from_file_debug(self): commit_msg = u"WIP: Thïs is a title thåt is a bit longer.\nContent on the second line\n" + \ @@ -89,4 +89,4 @@ class ConfigTests(BaseTestCase): 'config_path': config_path, 'target': self.tmp_git_repo, 'commit_sha': commit_sha, 'commit_date': expected_date}) - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) diff --git a/qa/test_gitlint.py b/qa/test_gitlint.py index f61b281..fa50e13 100644 --- a/qa/test_gitlint.py +++ b/qa/test_gitlint.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# pylint: disable=too-many-function-args,unexpected-keyword-arg import os from sh import git, gitlint # pylint: disable=no-name-in-module from qa.base import BaseTestCase @@ -11,7 +12,7 @@ class IntegrationTests(BaseTestCase): # Test for STDIN with and without a TTY attached self._create_simple_commit(u"Sïmple title\n\nSimple bödy describing the commit") output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _err_to_out=True) - self.assertEqual(output, "") + self.assertEqualStdout(output, "") def test_successful_merge_commit(self): # Create branch on master @@ -32,19 +33,20 @@ class IntegrationTests(BaseTestCase): # Run gitlint and assert output is empty output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True) - self.assertEqual(output, "") + self.assertEqualStdout(output, "") # Assert that we do see the error if we disable the ignore-merge-commits option output = gitlint("-c", "general.ignore-merge-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) self.assertEqual(output.exit_code, 1) - self.assertEqual(output, u"1: T1 Title exceeds max length (90>72): \"Merge '{0}'\"\n".format(commit_title)) + self.assertEqualStdout(output, + u"1: T1 Title exceeds max length (90>72): \"Merge '{0}'\"\n".format(commit_title)) def test_fixup_commit(self): # Create a normal commit and assert that it has a violation test_filename = self._create_simple_commit(u"Cömmit on WIP master\n\nSimple bödy that is long enough") output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) # Make a small modification to the commit and commit it using fixup commit with open(os.path.join(self.tmp_git_repo, test_filename), "a") as fh: @@ -61,21 +63,21 @@ class IntegrationTests(BaseTestCase): # 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.assertEqual(output, "") + 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-commits=false", _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[2]) expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"fixup! Cömmit on WIP master\"\n" + \ u"3: B6 Body message is missing\n" - self.assertEqual(output, expected) + 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(u"Cömmit on WIP master\n\nSimple bödy that is long enough") output = gitlint(_cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[1]) expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"Cömmit on WIP master\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) # Make a small modification to the commit and commit it using squash commit with open(os.path.join(self.tmp_git_repo, test_filename), "a") as fh: @@ -92,7 +94,7 @@ class IntegrationTests(BaseTestCase): # 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.assertEqual(output, "") + 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", @@ -100,7 +102,7 @@ class IntegrationTests(BaseTestCase): expected = u"1: T5 Title contains the word 'WIP' (case-insensitive): \"squash! Cömmit on WIP master\"\n" + \ u"3: B5 Body message is too short (14<20): \"Töo short body\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_violations(self): commit_msg = u"WIP: This ïs a title.\nContent on the sëcond line" @@ -110,7 +112,7 @@ class IntegrationTests(BaseTestCase): expected = 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: \"Content on the sëcond line\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_msg_filename(self): tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename test.") @@ -121,7 +123,7 @@ class IntegrationTests(BaseTestCase): u"1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: msg-fïlename test.\"\n" + \ u"3: B6 Body message is missing\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_msg_filename_no_tty(self): """ Make sure --msg-filename option also works with no TTY attached """ @@ -130,11 +132,13 @@ class IntegrationTests(BaseTestCase): # We need to set _err_to_out explicitly for sh to merge stdout and stderr output in case there's # no TTY attached to STDIN # http://amoffat.github.io/sh/sections/special_arguments.html?highlight=_tty_in#err-to-out - output = gitlint("--msg-filename", tmp_commit_msg_file, _in=self.mock_stdin(), + # 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]) expected = u"1: T3 Title has trailing punctuation (.): \"WIP: msg-fïlename NO TTY test.\"\n" + \ u"1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: msg-fïlename NO TTY test.\"\n" + \ u"3: B6 Body message is missing\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) diff --git a/qa/test_hooks.py b/qa/test_hooks.py index 8f8fb5a..b36cde6 100644 --- a/qa/test_hooks.py +++ b/qa/test_hooks.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +# pylint: disable=too-many-function-args,unexpected-keyword-arg from sh import git, gitlint # pylint: disable=no-name-in-module from qa.base import BaseTestCase @@ -24,14 +24,14 @@ class HookTests(BaseTestCase): 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.assertEqual(output_installed, expected_installed) + 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.assertEqual(output_uninstalled, expected_uninstalled) + 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) @@ -63,7 +63,11 @@ class HookTests(BaseTestCase): " 1 file changed, 0 insertions(+), 0 deletions(-)\n", u" create mode 100644 %s\n" % test_filename] - self.assertListEqual(expected_output, self.githook_output) + 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"] @@ -89,7 +93,7 @@ class HookTests(BaseTestCase): 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, ok_code=1, tty_in=True) + 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", "") @@ -106,4 +110,8 @@ class HookTests(BaseTestCase): " 1 file changed, 0 insertions(+), 0 deletions(-)\n", u" create mode 100644 %s\n" % test_filename] - self.assertListEqual(expected_output, self.githook_output) + 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', '')) diff --git a/qa/test_stdin.py b/qa/test_stdin.py index 317b53c..6a1d5da 100644 --- a/qa/test_stdin.py +++ b/qa/test_stdin.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# pylint: disable=too-many-function-args,unexpected-keyword-arg import subprocess from sh import gitlint, echo # pylint: disable=no-name-in-module from qa.base import BaseTestCase, ustr @@ -21,7 +22,7 @@ class StdInTests(BaseTestCase): u"1: T5 Title contains the word 'WIP' (case-insensitive): \"WIP: Pïpe test.\"\n" + \ u"3: B6 Body message is missing\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_stdin_pipe_empty(self): """ Test the scenario where no TTY is attached an nothing is piped into gitlint. This occurs in @@ -35,12 +36,12 @@ class StdInTests(BaseTestCase): # We need to set _err_to_out explicitly for sh to merge stdout and stderr output in case there's # no TTY attached to STDIN # http://amoffat.github.io/sh/sections/special_arguments.html?highlight=_tty_in#err-to-out - output = gitlint(_cwd=self.tmp_git_repo, _in=self.mock_stdin(), _tty_in=False, _err_to_out=True, _ok_code=[3]) + output = gitlint(echo("-n", ""), _cwd=self.tmp_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3]) expected = 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: \"Content on the sëcond line\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_stdin_file(self): """ Test the scenario where STDIN is a regular file (stat.S_ISREG = True) diff --git a/qa/test_user_defined.py b/qa/test_user_defined.py index a0b83df..f323c18 100644 --- a/qa/test_user_defined.py +++ b/qa/test_user_defined.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +# pylint: disable=too-many-function-args,unexpected-keyword-arg from sh import gitlint # pylint: disable=no-name-in-module from qa.base import BaseTestCase @@ -16,7 +16,7 @@ class UserDefinedRuleTests(BaseTestCase): "1: UC2 Body does not contain a 'Signed-Off-By' line\n" + \ u"1: UL1 Title contains the special character '$': \"WIP: Thi$ is å title\"\n" + \ "2: B4 Second line is not empty: \"Content on the second line\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_user_defined_rules_with_config(self): extra_path = self.get_example_path() @@ -30,11 +30,11 @@ class UserDefinedRuleTests(BaseTestCase): u"1: UL1 Title contains the special character '$': \"WIP: Thi$ is å title\"\n" + \ "2: B4 Second line is not empty: \"Content on the second line\"\n" - self.assertEqual(output, expected) + self.assertEqualStdout(output, expected) def test_invalid_user_defined_rules(self): extra_path = self.get_sample_path("user_rules/incorrect_linerule") self._create_simple_commit("WIP: test") output = gitlint("--extra-path", extra_path, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[255]) - self.assertEqual(output, - "Config Error: User-defined rule class 'MyUserLineRule' must have a 'validate' method\n") + self.assertEqualStdout(output, + "Config Error: User-defined rule class 'MyUserLineRule' must have a 'validate' method\n") diff --git a/requirements.txt b/requirements.txt index 5b4c6ab..3596958 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ setuptools -wheel==0.24.0 -Click==6.6 -sh==1.11; sys_platform != 'win32' # sh is not supported on windows +wheel==0.29.0; python_version == '2.6' or python_version == '3.3' +wheel==0.32.2; python_version != '2.6' and python_version != '3.3' +Click==6.7 +sh==1.12.14; sys_platform != 'win32' # sh is not supported on windows arrow==0.10.0 ordereddict==1.1; python_version < '2.7' importlib==1.0.3; python_version < '2.7' diff --git a/run_tests.sh b/run_tests.sh index 9e3d546..76a3fc1 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -54,12 +54,20 @@ assert_root(){ # Utility method that prints SUCCESS if a test was succesful, or FAIL together with the test output handle_test_result(){ - RESULT="$1" - if [ -z "$RESULT" ]; then - echo -e "${GREEN}SUCCESS${NO_COLOR}" + EXIT_CODE=$1 + RESULT="$2" + # Change color to red or green depending on SUCCESS + if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}SUCCESS" else - echo -e "${RED}FAIL\n${RESULT}${NO_COLOR}" + echo -e "${RED}FAIL" fi + # Print RESULT if not empty + if [ -n "$RESULT" ] ; then + echo -e "\n$RESULT" + fi + # Reset color + echo -e "${NO_COLOR}" } run_pep8_check(){ @@ -76,7 +84,7 @@ run_pep8_check(){ echo -ne "Running flake8..." RESULT=$(flake8 --ignore=$FLAKE8_IGNORE --max-line-length=120 --exclude=$FLAKE8_EXCLUDE gitlint qa examples) local exit_code=$? - handle_test_result "$RESULT" + handle_test_result $exit_code "$RESULT" return $exit_code } @@ -121,3 |