diff --git a/testing/util.py b/testing/util.py index d82612fa..dde0c4d0 100644 --- a/testing/util.py +++ b/testing/util.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import contextlib import os.path +import subprocess import sys import pytest @@ -24,9 +25,11 @@ def cmd_output_mocked_pre_commit_home(*args, **kwargs): # keyword-only argument tempdir_factory = kwargs.pop('tempdir_factory') pre_commit_home = kwargs.pop('pre_commit_home', tempdir_factory.get()) + kwargs.setdefault('stderr', subprocess.STDOUT) # Don't want to write to the home directory env = dict(kwargs.pop('env', os.environ), PRE_COMMIT_HOME=pre_commit_home) - return cmd_output(*args, env=env, **kwargs) + ret, out, _ = cmd_output(*args, env=env, **kwargs) + return ret, out.replace('\r\n', '\n'), None skipif_cant_run_docker = pytest.mark.skipif( @@ -137,8 +140,10 @@ def cwd(path): def git_commit(*args, **kwargs): fn = kwargs.pop('fn', cmd_output) msg = kwargs.pop('msg', 'commit!') + kwargs.setdefault('stderr', subprocess.STDOUT) cmd = ('git', 'commit', '--allow-empty', '--no-gpg-sign', '-a') + args if msg is not None: # allow skipping `-m` with `msg=None` cmd += ('-m', msg) - return fn(*cmd, **kwargs) + ret, out, _ = fn(*cmd, **kwargs) + return ret, out.replace('\r\n', '\n') diff --git a/tests/commands/init_templatedir_test.py b/tests/commands/init_templatedir_test.py index 1bb9695f..12c6696a 100644 --- a/tests/commands/init_templatedir_test.py +++ b/tests/commands/init_templatedir_test.py @@ -1,5 +1,4 @@ import os.path -import subprocess import mock @@ -30,11 +29,9 @@ def test_init_templatedir(tmpdir, tempdir_factory, store, cap_out): path = make_consuming_repo(tempdir_factory, 'script_hooks_repo') with cwd(path): - retcode, output, _ = git_commit( + retcode, output = git_commit( fn=cmd_output_mocked_pre_commit_home, tempdir_factory=tempdir_factory, - # git commit puts pre-commit to stderr - stderr=subprocess.STDOUT, ) assert retcode == 0 assert 'Bash hook....' in output diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py index 28bf66d1..ba626517 100644 --- a/tests/commands/install_uninstall_test.py +++ b/tests/commands/install_uninstall_test.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import io import os.path import re -import subprocess import sys import mock @@ -121,30 +120,28 @@ def _get_commit_output(tempdir_factory, touch_file='foo', **kwargs): cmd_output('git', 'add', touch_file) return git_commit( fn=cmd_output_mocked_pre_commit_home, - # git commit puts pre-commit to stderr - stderr=subprocess.STDOUT, retcode=None, tempdir_factory=tempdir_factory, **kwargs - )[:2] + ) # osx does this different :( FILES_CHANGED = ( r'(' - r' 1 file changed, 0 insertions\(\+\), 0 deletions\(-\)\r?\n' + r' 1 file changed, 0 insertions\(\+\), 0 deletions\(-\)\n' r'|' - r' 0 files changed\r?\n' + r' 0 files changed\n' r')' ) NORMAL_PRE_COMMIT_RUN = re.compile( - r'^\[INFO\] Initializing environment for .+\.\r?\n' - r'Bash hook\.+Passed\r?\n' - r'\[master [a-f0-9]{7}\] commit!\r?\n' + + r'^\[INFO\] Initializing environment for .+\.\n' + r'Bash hook\.+Passed\n' + r'\[master [a-f0-9]{7}\] commit!\n' + FILES_CHANGED + - r' create mode 100644 foo\r?\n$', + r' create mode 100644 foo\n$', ) @@ -265,7 +262,7 @@ def test_environment_not_sourced(tempdir_factory, store): # Use a specific homedir to ignore --user installs homedir = tempdir_factory.get() - ret, stdout, stderr = git_commit( + ret, out = git_commit( env={ 'HOME': homedir, 'PATH': _path_without_us(), @@ -278,22 +275,21 @@ def test_environment_not_sourced(tempdir_factory, store): retcode=None, ) assert ret == 1 - assert stdout == '' - assert stderr.replace('\r\n', '\n') == ( + assert out == ( '`pre-commit` not found. ' 'Did you forget to activate your virtualenv?\n' ) FAILING_PRE_COMMIT_RUN = re.compile( - r'^\[INFO\] Initializing environment for .+\.\r?\n' - r'Failing hook\.+Failed\r?\n' - r'- hook id: failing_hook\r?\n' - r'- exit code: 1\r?\n' - r'\r?\n' - r'Fail\r?\n' - r'foo\r?\n' - r'\r?\n$', + r'^\[INFO\] Initializing environment for .+\.\n' + r'Failing hook\.+Failed\n' + r'- hook id: failing_hook\n' + r'- exit code: 1\n' + r'\n' + r'Fail\n' + r'foo\n' + r'\n$', ) @@ -308,10 +304,10 @@ def test_failing_hooks_returns_nonzero(tempdir_factory, store): EXISTING_COMMIT_RUN = re.compile( - r'^legacy hook\r?\n' - r'\[master [a-f0-9]{7}\] commit!\r?\n' + + r'^legacy hook\n' + r'\[master [a-f0-9]{7}\] commit!\n' + FILES_CHANGED + - r' create mode 100644 baz\r?\n$', + r' create mode 100644 baz\n$', ) @@ -369,9 +365,9 @@ def test_install_existing_hook_no_overwrite_idempotent(tempdir_factory, store): FAIL_OLD_HOOK = re.compile( - r'fail!\r?\n' - r'\[INFO\] Initializing environment for .+\.\r?\n' - r'Bash hook\.+Passed\r?\n', + r'fail!\n' + r'\[INFO\] Initializing environment for .+\.\n' + r'Bash hook\.+Passed\n', ) @@ -465,10 +461,10 @@ def test_uninstall_doesnt_remove_not_our_hooks(in_git_dir): PRE_INSTALLED = re.compile( - r'Bash hook\.+Passed\r?\n' - r'\[master [a-f0-9]{7}\] commit!\r?\n' + + r'Bash hook\.+Passed\n' + r'\[master [a-f0-9]{7}\] commit!\n' + FILES_CHANGED + - r' create mode 100644 foo\r?\n$', + r' create mode 100644 foo\n$', ) @@ -527,8 +523,6 @@ def test_installed_from_venv(tempdir_factory, store): def _get_push_output(tempdir_factory, opts=()): return cmd_output_mocked_pre_commit_home( 'git', 'push', 'origin', 'HEAD:new_branch', *opts, - # git push puts pre-commit to stderr - stderr=subprocess.STDOUT, tempdir_factory=tempdir_factory, retcode=None )[:2] @@ -648,7 +642,7 @@ def test_commit_msg_integration_failing( install(C.CONFIG_FILE, store, hook_types=['commit-msg']) retc, out = _get_commit_output(tempdir_factory) assert retc == 1 - assert out.replace('\r', '') == '''\ + assert out == '''\ Must have "Signed off by:"...............................................Failed - hook id: must-have-signoff - exit code: 1 @@ -695,7 +689,7 @@ def test_prepare_commit_msg_integration_failing( install(C.CONFIG_FILE, store, hook_types=['prepare-commit-msg']) retc, out = _get_commit_output(tempdir_factory) assert retc == 1 - assert out.replace('\r', '') == '''\ + assert out == '''\ Add "Signed off by:".....................................................Failed - hook id: add-signoff - exit code: 1 diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index 4c75e62a..e56612e3 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -4,7 +4,6 @@ from __future__ import unicode_literals import io import os.path import pipes -import subprocess import sys import mock @@ -543,16 +542,14 @@ def test_stdout_write_bug_py26(repo_with_failing_hook, store, tempdir_factory): install(C.CONFIG_FILE, store, hook_types=['pre-commit']) # Have to use subprocess because pytest monkeypatches sys.stdout - _, stdout, _ = git_commit( + _, out = git_commit( fn=cmd_output_mocked_pre_commit_home, - # git commit puts pre-commit to stderr - stderr=subprocess.STDOUT, - retcode=None, tempdir_factory=tempdir_factory, + retcode=None, ) - assert 'UnicodeEncodeError' not in stdout + assert 'UnicodeEncodeError' not in out # Doesn't actually happen, but a reasonable assertion - assert 'UnicodeDecodeError' not in stdout + assert 'UnicodeDecodeError' not in out def test_lots_of_files(store, tempdir_factory): @@ -574,8 +571,6 @@ def test_lots_of_files(store, tempdir_factory): git_commit( fn=cmd_output_mocked_pre_commit_home, - # git commit puts pre-commit to stderr - stderr=subprocess.STDOUT, tempdir_factory=tempdir_factory, ) diff --git a/tests/commands/try_repo_test.py b/tests/commands/try_repo_test.py index 6e9db9db..ee010636 100644 --- a/tests/commands/try_repo_test.py +++ b/tests/commands/try_repo_test.py @@ -21,8 +21,7 @@ def try_repo_opts(repo, ref=None, **kwargs): def _get_out(cap_out): - out = cap_out.get().replace('\r\n', '\n') - out = re.sub(r'\[INFO\].+\n', '', out) + out = re.sub(r'\[INFO\].+\n', '', cap_out.get()) start, using_config, config, rest = out.split('=' * 79 + '\n') assert using_config == 'Using config:\n' return start, config, rest diff --git a/tests/conftest.py b/tests/conftest.py index 635ea39a..6e9fcf23 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -249,7 +249,7 @@ class Fixture(object): data = self._stream.data.getvalue() self._stream.data.seek(0) self._stream.data.truncate() - return data + return data.replace(b'\r\n', b'\n') def get(self): """Get the output assuming it was written as UTF-8 bytes""" diff --git a/tests/error_handler_test.py b/tests/error_handler_test.py index ff311a24..74ade618 100644 --- a/tests/error_handler_test.py +++ b/tests/error_handler_test.py @@ -144,7 +144,7 @@ def test_error_handler_non_ascii_exception(mock_store_dir): def test_error_handler_no_tty(tempdir_factory): pre_commit_home = tempdir_factory.get() - output = cmd_output_mocked_pre_commit_home( + ret, out, _ = cmd_output_mocked_pre_commit_home( sys.executable, '-c', 'from __future__ import unicode_literals\n' @@ -156,8 +156,6 @@ def test_error_handler_no_tty(tempdir_factory): pre_commit_home=pre_commit_home, ) log_file = os.path.join(pre_commit_home, 'pre-commit.log') - output_lines = output[1].replace('\r', '').splitlines() - assert ( - output_lines[-2] == 'An unexpected error has occurred: ValueError: ☃' - ) - assert output_lines[-1] == 'Check the log at {}'.format(log_file) + out_lines = out.splitlines() + assert out_lines[-2] == 'An unexpected error has occurred: ValueError: ☃' + assert out_lines[-1] == 'Check the log at {}'.format(log_file)