From 1968ada2d36e4508ef787e57f0e5f63214bcbad7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 Sep 2021 06:23:53 +0200 Subject: Merging upstream version 2.15.0. Signed-off-by: Daniel Baumann --- tests/clientlib_test.py | 11 +++++++ tests/commands/hook_impl_test.py | 9 ++++++ tests/commands/install_uninstall_test.py | 31 +++++++++++++++++- tests/commands/migrate_config_test.py | 13 -------- tests/commands/run_test.py | 9 ++++++ tests/git_test.py | 18 +++++++++++ tests/languages/python_test.py | 5 +-- tests/meta_hooks/check_useless_excludes_test.py | 22 +++++++++++++ tests/repository_test.py | 43 ++++++++++++++++++++++++- 9 files changed, 144 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/tests/clientlib_test.py b/tests/clientlib_test.py index 09bdb3e..da794e6 100644 --- a/tests/clientlib_test.py +++ b/tests/clientlib_test.py @@ -1,4 +1,5 @@ import logging +import re import cfgv import pytest @@ -10,6 +11,7 @@ from pre_commit.clientlib import CONFIG_REPO_DICT from pre_commit.clientlib import CONFIG_SCHEMA from pre_commit.clientlib import DEFAULT_LANGUAGE_VERSION from pre_commit.clientlib import MANIFEST_SCHEMA +from pre_commit.clientlib import META_HOOK_DICT from pre_commit.clientlib import MigrateShaToRev from pre_commit.clientlib import validate_config_main from pre_commit.clientlib import validate_manifest_main @@ -392,6 +394,15 @@ def test_meta_hook_invalid(config_repo): cfgv.validate(config_repo, CONFIG_REPO_DICT) +def test_meta_check_hooks_apply_only_at_top_level(): + cfg = {'id': 'check-hooks-apply'} + cfg = cfgv.apply_defaults(cfg, META_HOOK_DICT) + + files_re = re.compile(cfg['files']) + assert files_re.search('.pre-commit-config.yaml') + assert not files_re.search('foo/.pre-commit-config.yaml') + + @pytest.mark.parametrize( 'mapping', ( diff --git a/tests/commands/hook_impl_test.py b/tests/commands/hook_impl_test.py index c38b9ca..37b78bc 100644 --- a/tests/commands/hook_impl_test.py +++ b/tests/commands/hook_impl_test.py @@ -99,6 +99,7 @@ def test_run_legacy_recursive(tmpdir): ('post-commit', []), ('post-merge', ['1']), ('post-checkout', ['old_head', 'new_head', '1']), + ('post-rewrite', ['amend']), # multiple choices for commit-editmsg ('prepare-commit-msg', ['.git/COMMIT_EDITMSG']), ('prepare-commit-msg', ['.git/COMMIT_EDITMSG', 'message']), @@ -166,6 +167,14 @@ def test_run_ns_post_merge(): assert ns.is_squash_merge == '1' +def test_run_ns_post_rewrite(): + ns = hook_impl._run_ns('post-rewrite', True, ('amend',), b'') + assert ns is not None + assert ns.hook_stage == 'post-rewrite' + assert ns.color is True + assert ns.rewrite_command == 'amend' + + def test_run_ns_post_checkout(): ns = hook_impl._run_ns('post-checkout', True, ('a', 'b', 'c'), b'') assert ns is not None diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py index 314b8b9..3c07124 100644 --- a/tests/commands/install_uninstall_test.py +++ b/tests/commands/install_uninstall_test.py @@ -817,6 +817,35 @@ def test_post_merge_integration(tempdir_factory, store): assert os.path.exists('post-merge.tmp') +def test_post_rewrite_integration(tempdir_factory, store): + path = git_dir(tempdir_factory) + config = [ + { + 'repo': 'local', + 'hooks': [{ + 'id': 'post-rewrite', + 'name': 'Post rewrite', + 'entry': 'touch post-rewrite.tmp', + 'language': 'system', + 'always_run': True, + 'verbose': True, + 'stages': ['post-rewrite'], + }], + }, + ] + write_config(path, config) + with cwd(path): + open('init', 'a').close() + cmd_output('git', 'add', '.') + install(C.CONFIG_FILE, store, hook_types=['post-rewrite']) + git_commit() + + assert not os.path.exists('post-rewrite.tmp') + + git_commit('--amend', '-m', 'ammended message') + assert os.path.exists('post-rewrite.tmp') + + def test_post_checkout_integration(tempdir_factory, store): path = git_dir(tempdir_factory) config = [ @@ -948,7 +977,7 @@ def test_pre_merge_commit_integration(tempdir_factory, store): output_pattern = re_assert.Matches( r'^\[INFO\] Initializing environment for .+\n' r'Bash hook\.+Passed\n' - r"Merge made by the 'recursive' strategy.\n" + r"Merge made by the '(ort|recursive)' strategy.\n" r' foo \| 0\n' r' 1 file changed, 0 insertions\(\+\), 0 deletions\(-\)\n' r' create mode 100644 foo\n$', diff --git a/tests/commands/migrate_config_test.py b/tests/commands/migrate_config_test.py index f5c89d0..f5eddd3 100644 --- a/tests/commands/migrate_config_test.py +++ b/tests/commands/migrate_config_test.py @@ -1,7 +1,4 @@ -import pytest - import pre_commit.constants as C -from pre_commit.clientlib import InvalidConfigError from pre_commit.commands.migrate_config import migrate_config @@ -130,13 +127,3 @@ def test_migrate_config_sha_to_rev(tmpdir): ' rev: v1.2.0\n' ' hooks: []\n' ) - - -@pytest.mark.parametrize('contents', ('', '\n')) -def test_migrate_config_invalid_configuration(tmpdir, contents): - cfg = tmpdir.join(C.CONFIG_FILE) - cfg.write(contents) - with tmpdir.as_cwd(), pytest.raises(InvalidConfigError): - migrate_config(C.CONFIG_FILE) - # even though the config is invalid, this should be a noop - assert cfg.read() == contents diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index da7569e..8c15395 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -504,6 +504,15 @@ def test_is_squash_merge(cap_out, store, repo_with_passing_hook): assert environ['PRE_COMMIT_IS_SQUASH_MERGE'] == '1' +def test_rewrite_command(cap_out, store, repo_with_passing_hook): + args = run_opts(rewrite_command='amend') + environ: MutableMapping[str, str] = {} + ret, printed = _do_run( + cap_out, store, repo_with_passing_hook, args, environ, + ) + assert environ['PRE_COMMIT_REWRITE_COMMAND'] == 'amend' + + def test_checkout_type(cap_out, store, repo_with_passing_hook): args = run_opts(from_ref='', to_ref='', checkout_type='1') environ: MutableMapping[str, str] = {} diff --git a/tests/git_test.py b/tests/git_test.py index 51d5f8c..aa21880 100644 --- a/tests/git_test.py +++ b/tests/git_test.py @@ -139,6 +139,24 @@ def test_get_changed_files(in_git_dir): assert files == [] +def test_get_changed_files_disparate_histories(in_git_dir): + """in modern versions of git, `...` does not fall back to full diff""" + git_commit() + in_git_dir.join('a.txt').ensure() + cmd_output('git', 'add', '.') + git_commit() + cmd_output('git', 'branch', '-m', 'branch1') + + cmd_output('git', 'checkout', '--orphan', 'branch2') + cmd_output('git', 'rm', '-rf', '.') + in_git_dir.join('a.txt').ensure() + in_git_dir.join('b.txt').ensure() + cmd_output('git', 'add', '.') + git_commit() + + assert git.get_changed_files('branch1', 'branch2') == ['b.txt'] + + @pytest.mark.parametrize( ('s', 'expected'), ( diff --git a/tests/languages/python_test.py b/tests/languages/python_test.py index 90d1036..8324cac 100644 --- a/tests/languages/python_test.py +++ b/tests/languages/python_test.py @@ -9,6 +9,7 @@ from pre_commit.envcontext import envcontext from pre_commit.languages import python from pre_commit.prefix import Prefix from pre_commit.util import make_executable +from pre_commit.util import win_exe def test_read_pyvenv_cfg(tmpdir): @@ -112,7 +113,7 @@ def test_unhealthy_python_goes_missing(python_dir): python.install_environment(prefix, C.DEFAULT, ()) - exe_name = 'python' if sys.platform != 'win32' else 'python.exe' + exe_name = win_exe('python') py_exe = prefix.path(python.bin_dir('py_env-default'), exe_name) os.remove(py_exe) @@ -158,7 +159,7 @@ def test_unhealthy_then_replaced(python_dir): python.install_environment(prefix, C.DEFAULT, ()) # simulate an exe which returns an old version - exe_name = 'python.exe' if sys.platform == 'win32' else 'python' + exe_name = win_exe('python') py_exe = prefix.path(python.bin_dir('py_env-default'), exe_name) os.rename(py_exe, f'{py_exe}.tmp') diff --git a/tests/meta_hooks/check_useless_excludes_test.py b/tests/meta_hooks/check_useless_excludes_test.py index d261e81..703bd25 100644 --- a/tests/meta_hooks/check_useless_excludes_test.py +++ b/tests/meta_hooks/check_useless_excludes_test.py @@ -1,5 +1,10 @@ +from pre_commit import git from pre_commit.meta_hooks import check_useless_excludes +from pre_commit.util import cmd_output from testing.fixtures import add_config_to_repo +from testing.fixtures import make_config_from_repo +from testing.fixtures import make_repo +from testing.util import xfailif_windows def test_useless_exclude_global(capsys, in_git_dir): @@ -113,3 +118,20 @@ def test_valid_exclude(capsys, in_git_dir): out, _ = capsys.readouterr() assert out == '' + + +@xfailif_windows # pragma: win32 no cover +def test_useless_excludes_broken_symlink(capsys, in_git_dir, tempdir_factory): + path = make_repo(tempdir_factory, 'script_hooks_repo') + config = make_config_from_repo(path) + config['hooks'][0]['exclude'] = 'broken-symlink' + add_config_to_repo(in_git_dir.strpath, config) + + in_git_dir.join('broken-symlink').mksymlinkto('DNE') + cmd_output('git', 'add', 'broken-symlink') + git.commit() + + assert check_useless_excludes.main(('.pre-commit-config.yaml',)) == 0 + + out, _ = capsys.readouterr() + assert out == '' diff --git a/tests/repository_test.py b/tests/repository_test.py index af829c2..4121fed 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -1002,6 +1002,7 @@ def test_manifest_hooks(tempdir_factory, store): stages=( 'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'post-commit', 'manual', 'post-checkout', 'push', 'post-merge', + 'post-rewrite', ), types=['file'], types_or=[], @@ -1043,10 +1044,50 @@ def test_local_perl_additional_dependencies(store): def test_dotnet_hook(tempdir_factory, store, repo): _test_hook_repo( tempdir_factory, store, repo, - 'dotnet example hook', [], b'Hello from dotnet!\n', + 'dotnet-example-hook', [], b'Hello from dotnet!\n', ) +def test_dart_hook(tempdir_factory, store): + _test_hook_repo( + tempdir_factory, store, 'dart_repo', + 'hello-world-dart', [], b'hello hello world\n', + ) + + +def test_local_dart_additional_dependencies(store): + config = { + 'repo': 'local', + 'hooks': [{ + 'id': 'local-dart', + 'name': 'local-dart', + 'entry': 'hello-world-dart', + 'language': 'dart', + 'additional_dependencies': ['hello_world_dart'], + }], + } + hook = _get_hook(config, store, 'local-dart') + ret, out = _hook_run(hook, (), color=False) + assert (ret, _norm_out(out)) == (0, b'hello hello world\n') + + +def test_local_dart_additional_dependencies_versioned(store): + config = { + 'repo': 'local', + 'hooks': [{ + 'id': 'local-dart', + 'name': 'local-dart', + 'entry': 'secure-random -l 4 -b 16', + 'language': 'dart', + 'additional_dependencies': ['encrypt:5.0.0'], + }], + } + hook = _get_hook(config, store, 'local-dart') + ret, out = _hook_run(hook, (), color=False) + assert ret == 0 + re_assert.Matches('^[a-f0-9]{8}\r?\n$').assert_matches(out.decode()) + + def test_non_installable_hook_error_for_language_version(store, caplog): config = { 'repo': 'local', -- cgit v1.2.3