From 63fad53303381388673073de580a32088a4ef0fe Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 24 Mar 2020 22:59:15 +0100 Subject: Adding upstream version 2.2.0. Signed-off-by: Daniel Baumann --- tests/languages/__init__.py | 0 tests/languages/docker_test.py | 23 ++++++++++++ tests/languages/golang_test.py | 20 ++++++++++ tests/languages/helpers_test.py | 82 +++++++++++++++++++++++++++++++++++++++++ tests/languages/pygrep_test.py | 65 ++++++++++++++++++++++++++++++++ tests/languages/python_test.py | 75 +++++++++++++++++++++++++++++++++++++ tests/languages/ruby_test.py | 28 ++++++++++++++ 7 files changed, 293 insertions(+) create mode 100644 tests/languages/__init__.py create mode 100644 tests/languages/docker_test.py create mode 100644 tests/languages/golang_test.py create mode 100644 tests/languages/helpers_test.py create mode 100644 tests/languages/pygrep_test.py create mode 100644 tests/languages/python_test.py create mode 100644 tests/languages/ruby_test.py (limited to 'tests/languages') diff --git a/tests/languages/__init__.py b/tests/languages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/languages/docker_test.py b/tests/languages/docker_test.py new file mode 100644 index 0000000..171a3f7 --- /dev/null +++ b/tests/languages/docker_test.py @@ -0,0 +1,23 @@ +from unittest import mock + +from pre_commit.languages import docker +from pre_commit.util import CalledProcessError + + +def test_docker_is_running_process_error(): + with mock.patch( + 'pre_commit.languages.docker.cmd_output_b', + side_effect=CalledProcessError(1, (), 0, b'', None), + ): + assert docker.docker_is_running() is False + + +def test_docker_fallback_user(): + def invalid_attribute(): + raise AttributeError + with mock.patch.multiple( + 'os', create=True, + getuid=invalid_attribute, + getgid=invalid_attribute, + ): + assert docker.get_docker_user() == '1000:1000' diff --git a/tests/languages/golang_test.py b/tests/languages/golang_test.py new file mode 100644 index 0000000..9a64ed1 --- /dev/null +++ b/tests/languages/golang_test.py @@ -0,0 +1,20 @@ +import pytest + +from pre_commit.languages.golang import guess_go_dir + + +@pytest.mark.parametrize( + ('url', 'expected'), + ( + ('/im/a/path/on/disk', 'unknown_src_dir'), + ('file:///im/a/path/on/disk', 'unknown_src_dir'), + ('git@github.com:golang/lint', 'github.com/golang/lint'), + ('git://github.com/golang/lint', 'github.com/golang/lint'), + ('http://github.com/golang/lint', 'github.com/golang/lint'), + ('https://github.com/golang/lint', 'github.com/golang/lint'), + ('ssh://git@github.com/golang/lint', 'github.com/golang/lint'), + ('git@github.com:golang/lint.git', 'github.com/golang/lint'), + ), +) +def test_guess_go_dir(url, expected): + assert guess_go_dir(url) == expected diff --git a/tests/languages/helpers_test.py b/tests/languages/helpers_test.py new file mode 100644 index 0000000..c52e947 --- /dev/null +++ b/tests/languages/helpers_test.py @@ -0,0 +1,82 @@ +import multiprocessing +import os +import sys +from unittest import mock + +import pytest + +import pre_commit.constants as C +from pre_commit.languages import helpers +from pre_commit.prefix import Prefix +from pre_commit.util import CalledProcessError +from testing.auto_namedtuple import auto_namedtuple + + +def test_basic_get_default_version(): + assert helpers.basic_get_default_version() == C.DEFAULT + + +def test_basic_healthy(): + assert helpers.basic_healthy(Prefix('.'), 'default') is True + + +def test_failed_setup_command_does_not_unicode_error(): + script = ( + 'import sys\n' + "getattr(sys.stderr, 'buffer', sys.stderr).write(b'\\x81\\xfe')\n" + 'exit(1)\n' + ) + + # an assertion that this does not raise `UnicodeError` + with pytest.raises(CalledProcessError): + helpers.run_setup_cmd(Prefix('.'), (sys.executable, '-c', script)) + + +def test_assert_no_additional_deps(): + with pytest.raises(AssertionError) as excinfo: + helpers.assert_no_additional_deps('lang', ['hmmm']) + msg, = excinfo.value.args + assert msg == ( + 'For now, pre-commit does not support additional_dependencies for lang' + ) + + +SERIAL_FALSE = auto_namedtuple(require_serial=False) +SERIAL_TRUE = auto_namedtuple(require_serial=True) + + +def test_target_concurrency_normal(): + with mock.patch.object(multiprocessing, 'cpu_count', return_value=123): + with mock.patch.dict(os.environ, {}, clear=True): + assert helpers.target_concurrency(SERIAL_FALSE) == 123 + + +def test_target_concurrency_cpu_count_require_serial_true(): + with mock.patch.dict(os.environ, {}, clear=True): + assert helpers.target_concurrency(SERIAL_TRUE) == 1 + + +def test_target_concurrency_testing_env_var(): + with mock.patch.dict( + os.environ, {'PRE_COMMIT_NO_CONCURRENCY': '1'}, clear=True, + ): + assert helpers.target_concurrency(SERIAL_FALSE) == 1 + + +def test_target_concurrency_on_travis(): + with mock.patch.dict(os.environ, {'TRAVIS': '1'}, clear=True): + assert helpers.target_concurrency(SERIAL_FALSE) == 2 + + +def test_target_concurrency_cpu_count_not_implemented(): + with mock.patch.object( + multiprocessing, 'cpu_count', side_effect=NotImplementedError, + ): + with mock.patch.dict(os.environ, {}, clear=True): + assert helpers.target_concurrency(SERIAL_FALSE) == 1 + + +def test_shuffled_is_deterministic(): + seq = [str(i) for i in range(10)] + expected = ['3', '7', '8', '2', '4', '6', '5', '1', '0', '9'] + assert helpers._shuffled(seq) == expected diff --git a/tests/languages/pygrep_test.py b/tests/languages/pygrep_test.py new file mode 100644 index 0000000..cabea22 --- /dev/null +++ b/tests/languages/pygrep_test.py @@ -0,0 +1,65 @@ +import pytest + +from pre_commit.languages import pygrep + + +@pytest.fixture +def some_files(tmpdir): + tmpdir.join('f1').write_binary(b'foo\nbar\n') + tmpdir.join('f2').write_binary(b'[INFO] hi\n') + tmpdir.join('f3').write_binary(b"with'quotes\n") + with tmpdir.as_cwd(): + yield + + +@pytest.mark.usefixtures('some_files') +@pytest.mark.parametrize( + ('pattern', 'expected_retcode', 'expected_out'), + ( + ('baz', 0, ''), + ('foo', 1, 'f1:1:foo\n'), + ('bar', 1, 'f1:2:bar\n'), + (r'(?i)\[info\]', 1, 'f2:1:[INFO] hi\n'), + ("h'q", 1, "f3:1:with'quotes\n"), + ), +) +def test_main(some_files, cap_out, pattern, expected_retcode, expected_out): + ret = pygrep.main((pattern, 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == expected_retcode + assert out == expected_out + + +def test_ignore_case(some_files, cap_out): + ret = pygrep.main(('--ignore-case', 'info', 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == 1 + assert out == 'f2:1:[INFO] hi\n' + + +def test_multiline(some_files, cap_out): + ret = pygrep.main(('--multiline', r'foo\nbar', 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == 1 + assert out == 'f1:1:foo\nbar\n' + + +def test_multiline_line_number(some_files, cap_out): + ret = pygrep.main(('--multiline', r'ar', 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == 1 + assert out == 'f1:2:bar\n' + + +def test_multiline_dotall_flag_is_enabled(some_files, cap_out): + ret = pygrep.main(('--multiline', r'o.*bar', 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == 1 + assert out == 'f1:1:foo\nbar\n' + + +def test_multiline_multiline_flag_is_enabled(some_files, cap_out): + ret = pygrep.main(('--multiline', r'foo$.*bar', 'f1', 'f2', 'f3')) + out = cap_out.get() + assert ret == 1 + assert out == 'f1:1:foo\nbar\n' diff --git a/tests/languages/python_test.py b/tests/languages/python_test.py new file mode 100644 index 0000000..34c6c7f --- /dev/null +++ b/tests/languages/python_test.py @@ -0,0 +1,75 @@ +import os.path +import sys +from unittest import mock + +import pytest + +import pre_commit.constants as C +from pre_commit.languages import python +from pre_commit.prefix import Prefix + + +def test_norm_version_expanduser(): + home = os.path.expanduser('~') + if os.name == 'nt': # pragma: nt cover + path = r'~\python343' + expected_path = fr'{home}\python343' + else: # pragma: nt no cover + path = '~/.pyenv/versions/3.4.3/bin/python' + expected_path = f'{home}/.pyenv/versions/3.4.3/bin/python' + result = python.norm_version(path) + assert result == expected_path + + +@pytest.mark.parametrize('v', ('python3.6', 'python3', 'python')) +def test_sys_executable_matches(v): + with mock.patch.object(sys, 'version_info', (3, 6, 7)): + assert python._sys_executable_matches(v) + + +@pytest.mark.parametrize('v', ('notpython', 'python3.x')) +def test_sys_executable_matches_does_not_match(v): + with mock.patch.object(sys, 'version_info', (3, 6, 7)): + assert not python._sys_executable_matches(v) + + +@pytest.mark.parametrize( + ('exe', 'realpath', 'expected'), ( + ('/usr/bin/python3', '/usr/bin/python3.7', 'python3'), + ('/usr/bin/python', '/usr/bin/python3.7', 'python3.7'), + ('/usr/bin/python', '/usr/bin/python', None), + ('/usr/bin/python3.6m', '/usr/bin/python3.6m', 'python3.6m'), + ('v/bin/python', 'v/bin/pypy', 'pypy'), + ), +) +def test_find_by_sys_executable(exe, realpath, expected): + with mock.patch.object(sys, 'executable', exe): + with mock.patch.object(os.path, 'realpath', return_value=realpath): + with mock.patch.object(python, 'find_executable', lambda x: x): + assert python._find_by_sys_executable() == expected + + +def test_healthy_types_py_in_cwd(tmpdir): + with tmpdir.as_cwd(): + prefix = tmpdir.join('prefix').ensure_dir() + prefix.join('setup.py').write('import setuptools; setuptools.setup()') + prefix = Prefix(str(prefix)) + python.install_environment(prefix, C.DEFAULT, ()) + + # even if a `types.py` file exists, should still be healthy + tmpdir.join('types.py').ensure() + assert python.healthy(prefix, C.DEFAULT) is True + + +def test_healthy_python_goes_missing(tmpdir): + with tmpdir.as_cwd(): + prefix = tmpdir.join('prefix').ensure_dir() + prefix.join('setup.py').write('import setuptools; setuptools.setup()') + prefix = Prefix(str(prefix)) + python.install_environment(prefix, C.DEFAULT, ()) + + exe_name = 'python' if sys.platform != 'win32' else 'python.exe' + py_exe = prefix.path(python.bin_dir('py_env-default'), exe_name) + os.remove(py_exe) + + assert python.healthy(prefix, C.DEFAULT) is False diff --git a/tests/languages/ruby_test.py b/tests/languages/ruby_test.py new file mode 100644 index 0000000..36a029d --- /dev/null +++ b/tests/languages/ruby_test.py @@ -0,0 +1,28 @@ +import os.path + +from pre_commit.languages import ruby +from pre_commit.prefix import Prefix +from pre_commit.util import cmd_output +from testing.util import xfailif_windows_no_ruby + + +@xfailif_windows_no_ruby +def test_install_rbenv(tempdir_factory): + prefix = Prefix(tempdir_factory.get()) + ruby._install_rbenv(prefix) + # Should have created rbenv directory + assert os.path.exists(prefix.path('rbenv-default')) + + # Should be able to activate using our script and access rbenv + with ruby.in_env(prefix, 'default'): + cmd_output('rbenv', '--help') + + +@xfailif_windows_no_ruby +def test_install_rbenv_with_version(tempdir_factory): + prefix = Prefix(tempdir_factory.get()) + ruby._install_rbenv(prefix, version='1.9.3p547') + + # Should be able to activate and use rbenv install + with ruby.in_env(prefix, '1.9.3p547'): + cmd_output('rbenv', 'install', '--help') -- cgit v1.2.3