summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpbregener <pbregener@users.noreply.github.com>2018-11-07 11:46:43 +0100
committerJoris Roovers <jroovers@cisco.com>2019-03-13 10:35:43 +0100
commit87993c9f75264ba09e1602ff619731c410aad5da (patch)
tree9b67736be15b8ab71edc42ddc16322b7bee1daa4
parentc9db6a0b49004f514254c79fa5048dbd5a760e3d (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--.pylintrc2
-rw-r--r--.travis.yml36
-rw-r--r--gitlint/cli.py5
-rw-r--r--gitlint/git.py4
-rw-r--r--gitlint/lint.py1
-rw-r--r--gitlint/rules.py3
-rw-r--r--gitlint/user_rules.py6
-rw-r--r--gitlint/utils.py2
-rw-r--r--qa/base.py30
-rw-r--r--qa/requirements.txt9
-rw-r--r--qa/test_commits.py12
-rw-r--r--qa/test_config.py20
-rw-r--r--qa/test_gitlint.py30
-rw-r--r--qa/test_hooks.py20
-rw-r--r--qa/test_stdin.py7
-rw-r--r--qa/test_user_defined.py10
-rw-r--r--requirements.txt7
-rwxr-xr-xrun_tests.sh33
-rw-r--r--setup.py5
-rw-r--r--test-requirements.txt18
20 files changed, 130 insertions, 130 deletions
diff --git a/.pylintrc b/.pylintrc
index f4adf04..d3aee01 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -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
diff --git a/qa/base.py b/qa/base.py
index acab657..c939ede 100644
--- a/qa/base.py
+++ b/qa/base.py
@@ -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