Merge pull request #117 from pre-commit/refactor_tests

Refactor tests
This commit is contained in:
Anthony Sottile 2014-06-15 19:03:50 -07:00
commit 332e8b480b
48 changed files with 490 additions and 436 deletions

View file

@ -1,4 +1,5 @@
from __future__ import print_function from __future__ import print_function
from __future__ import unicode_literals
import argparse import argparse
import jsonschema import jsonschema

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys import sys
from pre_commit.clientlib.validate_base import get_run_function from pre_commit.clientlib.validate_base import get_run_function

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys import sys
from pre_commit.clientlib.validate_base import get_run_function from pre_commit.clientlib.validate_base import get_run_function

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys import sys
RED = '\033[41m' RED = '\033[41m'

View file

@ -30,8 +30,8 @@ def _update_repository(repo_config, runner):
repo = Repository.create(repo_config, runner.store) repo = Repository.create(repo_config, runner.store)
with local.cwd(repo.repo_path_getter.repo_path): with local.cwd(repo.repo_path_getter.repo_path):
local['git']['fetch']() local['git']('fetch')
head_sha = local['git']['rev-parse', 'origin/master']().strip() head_sha = local['git']('rev-parse', 'origin/master').strip()
# Don't bother trying to update if our sha is the same # Don't bother trying to update if our sha is the same
if head_sha == repo_config['sha']: if head_sha == repo_config['sha']:

View file

@ -1,8 +1,13 @@
from __future__ import unicode_literals
CONFIG_FILE = '.pre-commit-config.yaml' CONFIG_FILE = '.pre-commit-config.yaml'
MANIFEST_FILE = 'hooks.yaml' MANIFEST_FILE = 'hooks.yaml'
YAML_DUMP_KWARGS = { YAML_DUMP_KWARGS = {
'default_flow_style': False, 'default_flow_style': False,
# Use unicode
'encoding': None,
'indent': 4, 'indent': 4,
} }

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
"""five: six, redux""" """five: six, redux"""
# pylint:disable=invalid-name # pylint:disable=invalid-name
PY2 = (str is bytes) PY2 = (str is bytes)

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import functools import functools
import logging import logging
import os import os
@ -49,21 +51,21 @@ def get_conflicted_files():
# This will get the rest of the changes made after the merge. # This will get the rest of the changes made after the merge.
# If they resolved the merge conflict by choosing a mesh of both sides # If they resolved the merge conflict by choosing a mesh of both sides
# this will also include the conflicted files # this will also include the conflicted files
tree_hash = local['git']['write-tree']().strip() tree_hash = local['git']('write-tree').strip()
merge_diff_filenames = local['git'][ merge_diff_filenames = local['git'](
'diff', '-m', tree_hash, 'HEAD', 'MERGE_HEAD', '--name-only', 'diff', '-m', tree_hash, 'HEAD', 'MERGE_HEAD', '--name-only',
]().splitlines() ).splitlines()
return set(merge_conflict_filenames) | set(merge_diff_filenames) return set(merge_conflict_filenames) | set(merge_diff_filenames)
@memoize_by_cwd @memoize_by_cwd
def get_staged_files(): def get_staged_files():
return local['git']['diff', '--staged', '--name-only']().splitlines() return local['git']('diff', '--staged', '--name-only').splitlines()
@memoize_by_cwd @memoize_by_cwd
def get_all_files(): def get_all_files():
return local['git']['ls-files']().splitlines() return local['git']('ls-files').splitlines()
def get_files_matching(all_file_list_strategy): def get_files_matching(all_file_list_strategy):

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import copy import copy
import jsonschema import jsonschema
import jsonschema.validators import jsonschema.validators

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
from pre_commit.languages import node from pre_commit.languages import node
from pre_commit.languages import python from pre_commit.languages import python
from pre_commit.languages import ruby from pre_commit.languages import ruby

View file

@ -1,3 +1,4 @@
from __future__ import unicode_literals
def run_hook(env, hook, file_args): def run_hook(env, hook, file_args):

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import contextlib import contextlib
from pre_commit.languages import helpers from pre_commit.languages import helpers

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import contextlib import contextlib
from pre_commit.languages import helpers from pre_commit.languages import helpers

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
ENVIRONMENT_DIR = None ENVIRONMENT_DIR = None

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import shlex import shlex

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import logging import logging
import sys import sys

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os.path import os.path
from asottile.cached_property import cached_property from asottile.cached_property import cached_property

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import subprocess import subprocess
from pre_commit import color from pre_commit import color

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os import os
import os.path import os.path
import subprocess import subprocess

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
from asottile.cached_property import cached_property from asottile.cached_property import cached_property
from asottile.ordereddict import OrderedDict from asottile.ordereddict import OrderedDict

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os import os
import os.path import os.path
from asottile.cached_property import cached_property from asottile.cached_property import cached_property

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import contextlib import contextlib
import io import io
import logging import logging

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import contextlib import contextlib
import functools import functools
import os import os

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import collections import collections

69
testing/fixtures.py Normal file
View file

@ -0,0 +1,69 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import io
import os.path
from asottile.ordereddict import OrderedDict
from asottile.yaml import ordered_dump
from plumbum import local
import pre_commit.constants as C
from pre_commit.clientlib.validate_manifest import load_manifest
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
from pre_commit.clientlib.validate_config import validate_config_extra
from pre_commit.jsonschema_extensions import apply_defaults
from testing.util import copy_tree_to_path
from testing.util import get_head_sha
from testing.util import get_resource_path
git = local['git']
def git_dir(tmpdir_factory):
path = tmpdir_factory.get()
with local.cwd(path):
git('init')
return path
def make_repo(tmpdir_factory, repo_source):
path = git_dir(tmpdir_factory)
copy_tree_to_path(get_resource_path(repo_source), path)
with local.cwd(path):
git('add', '.')
git('commit', '-m', 'Add hooks')
return path
def make_config_from_repo(repo_path, sha=None, hooks=None, check=True):
manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
config = OrderedDict((
('repo', repo_path),
('sha', sha or get_head_sha(repo_path)),
(
'hooks',
hooks or [OrderedDict((('id', hook['id']),)) for hook in manifest],
),
))
if check:
wrapped_config = apply_defaults([config], CONFIG_JSON_SCHEMA)
validate_config_extra(wrapped_config)
return wrapped_config[0]
else:
return config
def write_config(directory, config):
assert type(config) is OrderedDict
with io.open(os.path.join(directory, C.CONFIG_FILE), 'w') as config_file:
config_file.write(ordered_dump([config], **C.YAML_DUMP_KWARGS))
def make_consuming_repo(tmpdir_factory, repo_source):
path = make_repo(tmpdir_factory, repo_source)
config = make_config_from_repo(path)
git_path = git_dir(tmpdir_factory)
write_config(git_path, config)
return git_path

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import jsonschema import jsonschema
import os import os
import os.path import os.path
@ -33,7 +35,7 @@ def copy_tree_to_path(src_dir, dest_dir):
def get_head_sha(dir): def get_head_sha(dir):
with local.cwd(dir): with local.cwd(dir):
return local['git']['rev-parse', 'HEAD']().strip() return local['git']('rev-parse', 'HEAD').strip()
def is_valid_according_to_schema(obj, schema): def is_valid_according_to_schema(obj, schema):

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import pytest import pytest
from asottile.ordereddict import OrderedDict from asottile.ordereddict import OrderedDict
from asottile.yaml import ordered_load from asottile.yaml import ordered_load

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import pytest import pytest
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import pytest import pytest
from pre_commit.clientlib.validate_manifest import additional_manifest_check from pre_commit.clientlib.validate_manifest import additional_manifest_check

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import mock import mock
import pytest import pytest
import sys import sys

View file

@ -1,64 +1,45 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os
import os.path
import pytest import pytest
import shutil import shutil
from asottile.ordereddict import OrderedDict from asottile.ordereddict import OrderedDict
from asottile.yaml import ordered_dump
from plumbum import local from plumbum import local
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
from pre_commit.clientlib.validate_config import validate_config_extra
from pre_commit.commands.autoupdate import _update_repository from pre_commit.commands.autoupdate import _update_repository
from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.autoupdate import autoupdate
from pre_commit.commands.autoupdate import RepositoryCannotBeUpdatedError from pre_commit.commands.autoupdate import RepositoryCannotBeUpdatedError
from pre_commit.jsonschema_extensions import apply_defaults
from pre_commit.jsonschema_extensions import remove_defaults
from pre_commit.runner import Runner from pre_commit.runner import Runner
from testing.auto_namedtuple import auto_namedtuple from testing.auto_namedtuple import auto_namedtuple
from testing.fixtures import make_config_from_repo
from testing.fixtures import make_repo
from testing.fixtures import write_config
from testing.util import get_head_sha from testing.util import get_head_sha
from testing.util import get_resource_path from testing.util import get_resource_path
@pytest.yield_fixture @pytest.yield_fixture
def up_to_date_repo(python_hooks_repo): def up_to_date_repo(tmpdir_factory):
config = OrderedDict(( yield make_repo(tmpdir_factory, 'python_hooks_repo')
('repo', python_hooks_repo),
('sha', get_head_sha(python_hooks_repo)),
('hooks', [OrderedDict((('id', 'foo'),))]),
))
wrapped_config = apply_defaults([config], CONFIG_JSON_SCHEMA)
validate_config_extra(wrapped_config)
config = wrapped_config[0]
with open(os.path.join(python_hooks_repo, C.CONFIG_FILE), 'w') as file_obj:
file_obj.write(
ordered_dump(
remove_defaults([config], CONFIG_JSON_SCHEMA),
**C.YAML_DUMP_KWARGS
)
)
yield auto_namedtuple(
repo_config=config,
python_hooks_repo=python_hooks_repo,
)
def test_up_to_date_repo(up_to_date_repo, runner_with_mocked_store): def test_up_to_date_repo(up_to_date_repo, runner_with_mocked_store):
input_sha = up_to_date_repo.repo_config['sha'] config = make_config_from_repo(up_to_date_repo)
ret = _update_repository( input_sha = config['sha']
up_to_date_repo.repo_config, runner_with_mocked_store, ret = _update_repository(config, runner_with_mocked_store)
)
assert ret['sha'] == input_sha assert ret['sha'] == input_sha
def test_autoupdate_up_to_date_repo(up_to_date_repo, mock_out_store_directory): def test_autoupdate_up_to_date_repo(
up_to_date_repo, in_tmpdir, mock_out_store_directory,
):
# Write out the config
config = make_config_from_repo(up_to_date_repo, check=False)
write_config('.', config)
before = open(C.CONFIG_FILE).read() before = open(C.CONFIG_FILE).read()
assert '^$' not in before assert '^$' not in before
runner = Runner(up_to_date_repo.python_hooks_repo) runner = Runner('.')
ret = autoupdate(runner) ret = autoupdate(runner)
after = open(C.CONFIG_FILE).read() after = open(C.CONFIG_FILE).read()
assert ret == 0 assert ret == 0
@ -66,42 +47,40 @@ def test_autoupdate_up_to_date_repo(up_to_date_repo, mock_out_store_directory):
@pytest.yield_fixture @pytest.yield_fixture
def out_of_date_repo(python_hooks_repo): def out_of_date_repo(tmpdir_factory):
config = OrderedDict(( path = make_repo(tmpdir_factory, 'python_hooks_repo')
('repo', python_hooks_repo), original_sha = get_head_sha(path)
('sha', get_head_sha(python_hooks_repo)),
('hooks', [OrderedDict((('id', 'foo'), ('files', '')))]),
))
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
validate_config_extra(config_wrapped)
config = config_wrapped[0]
local['git']['commit', '--allow-empty', '-m', 'foo']()
head_sha = get_head_sha(python_hooks_repo)
with open(os.path.join(python_hooks_repo, C.CONFIG_FILE), 'w') as file_obj: # Make a commit
file_obj.write( with local.cwd(path):
ordered_dump([config], **C.YAML_DUMP_KWARGS) local['git']['commit', '--allow-empty', '-m', 'foo']()
) head_sha = get_head_sha(path)
yield auto_namedtuple( yield auto_namedtuple(
repo_config=config, path=path, original_sha=original_sha, head_sha=head_sha,
head_sha=head_sha,
python_hooks_repo=python_hooks_repo,
) )
def test_out_of_date_repo(out_of_date_repo, runner_with_mocked_store): def test_out_of_date_repo(out_of_date_repo, runner_with_mocked_store):
ret = _update_repository( config = make_config_from_repo(
out_of_date_repo.repo_config, runner_with_mocked_store, out_of_date_repo.path, sha=out_of_date_repo.original_sha,
) )
ret = _update_repository(config, runner_with_mocked_store)
assert ret['sha'] != out_of_date_repo.original_sha
assert ret['sha'] == out_of_date_repo.head_sha assert ret['sha'] == out_of_date_repo.head_sha
def test_autoupdate_out_of_date_repo( def test_autoupdate_out_of_date_repo(
out_of_date_repo, mock_out_store_directory out_of_date_repo, in_tmpdir, mock_out_store_directory
): ):
# Write out the config
config = make_config_from_repo(
out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False,
)
write_config('.', config)
before = open(C.CONFIG_FILE).read() before = open(C.CONFIG_FILE).read()
runner = Runner(out_of_date_repo.python_hooks_repo) runner = Runner('.')
ret = autoupdate(runner) ret = autoupdate(runner)
after = open(C.CONFIG_FILE).read() after = open(C.CONFIG_FILE).read()
assert ret == 0 assert ret == 0
@ -112,47 +91,46 @@ def test_autoupdate_out_of_date_repo(
@pytest.yield_fixture @pytest.yield_fixture
def hook_disappearing_repo(python_hooks_repo): def hook_disappearing_repo(tmpdir_factory):
config = OrderedDict(( path = make_repo(tmpdir_factory, 'python_hooks_repo')
('repo', python_hooks_repo), original_sha = get_head_sha(path)
('sha', get_head_sha(python_hooks_repo)),
('hooks', [OrderedDict((('id', 'foo'),))]), with local.cwd(path):
))
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
validate_config_extra(config_wrapped)
config = config_wrapped[0]
shutil.copy( shutil.copy(
get_resource_path('manifest_without_foo.yaml'), get_resource_path('manifest_without_foo.yaml'),
C.MANIFEST_FILE, C.MANIFEST_FILE,
) )
local['git']['add', '.']() local['git']('add', '.')
local['git']['commit', '-m', 'Remove foo']() local['git']('commit', '-m', 'Remove foo')
with open(os.path.join(python_hooks_repo, C.CONFIG_FILE), 'w') as file_obj: yield auto_namedtuple(path=path, original_sha=original_sha)
file_obj.write(
ordered_dump([config], **C.YAML_DUMP_KWARGS)
)
yield auto_namedtuple(
repo_config=config,
python_hooks_repo=python_hooks_repo,
)
def test_hook_disppearing_repo_raises( def test_hook_disppearing_repo_raises(
hook_disappearing_repo, runner_with_mocked_store hook_disappearing_repo, runner_with_mocked_store
): ):
with pytest.raises(RepositoryCannotBeUpdatedError): config = make_config_from_repo(
_update_repository( hook_disappearing_repo.path,
hook_disappearing_repo.repo_config, runner_with_mocked_store, sha=hook_disappearing_repo.original_sha,
hooks=[OrderedDict((('id', 'foo'),))],
) )
with pytest.raises(RepositoryCannotBeUpdatedError):
_update_repository(config, runner_with_mocked_store)
def test_autoupdate_hook_disappearing_repo( def test_autoupdate_hook_disappearing_repo(
hook_disappearing_repo, mock_out_store_directory hook_disappearing_repo, in_tmpdir, mock_out_store_directory
): ):
config = make_config_from_repo(
hook_disappearing_repo.path,
sha=hook_disappearing_repo.original_sha,
hooks=[OrderedDict((('id', 'foo'),))],
check=False,
)
write_config('.', config)
before = open(C.CONFIG_FILE).read() before = open(C.CONFIG_FILE).read()
runner = Runner(hook_disappearing_repo.python_hooks_repo) runner = Runner('.')
ret = autoupdate(runner) ret = autoupdate(runner)
after = open(C.CONFIG_FILE).read() after = open(C.CONFIG_FILE).read()
assert ret == 1 assert ret == 1

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import io import io
@ -8,10 +9,12 @@ import stat
from pre_commit.commands.install import install from pre_commit.commands.install import install
from pre_commit.runner import Runner from pre_commit.runner import Runner
from testing.fixtures import git_dir
def test_install_pre_commit(empty_git_dir): def test_install_pre_commit(tmpdir_factory):
runner = Runner(empty_git_dir) path = git_dir(tmpdir_factory)
runner = Runner(path)
ret = install(runner) ret = install(runner)
assert ret == 0 assert ret == 0
assert os.path.exists(runner.pre_commit_path) assert os.path.exists(runner.pre_commit_path)

View file

@ -11,11 +11,26 @@ from pre_commit.commands.run import _has_unmerged_paths
from pre_commit.commands.run import run from pre_commit.commands.run import run
from pre_commit.runner import Runner from pre_commit.runner import Runner
from testing.auto_namedtuple import auto_namedtuple from testing.auto_namedtuple import auto_namedtuple
from testing.fixtures import make_consuming_repo
@pytest.yield_fixture
def repo_with_passing_hook(tmpdir_factory):
git_path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
with local.cwd(git_path):
yield git_path
@pytest.yield_fixture
def repo_with_failing_hook(tmpdir_factory):
git_path = make_consuming_repo(tmpdir_factory, 'failing_hook_repo')
with local.cwd(git_path):
yield git_path
def stage_a_file(): def stage_a_file():
local['touch']['foo.py']() local['touch']('foo.py')
local['git']['add', 'foo.py']() local['git']('add', 'foo.py')
def get_write_mock_output(write_mock): def get_write_mock_output(write_mock):
@ -75,11 +90,9 @@ def test_run_all_hooks_failing(
({'verbose': True}, ('foo.py\nHello World',), 0, True), ({'verbose': True}, ('foo.py\nHello World',), 0, True),
({'hook': 'bash_hook'}, ('Bash hook', 'Passed'), 0, True), ({'hook': 'bash_hook'}, ('Bash hook', 'Passed'), 0, True),
({'hook': 'nope'}, ('No hook with id `nope`',), 1, True), ({'hook': 'nope'}, ('No hook with id `nope`',), 1, True),
# All the files in the repo.
# This seems kind of weird but it is beacuse py.test reuses fixtures
( (
{'all_files': True, 'verbose': True}, {'all_files': True, 'verbose': True},
('hooks.yaml', 'bin/hook.sh', 'foo.py', 'dummy'), ('foo.py'),
0, 0,
True, True,
), ),
@ -153,7 +166,7 @@ def test_merge_conflict_modified(in_merge_conflict, mock_out_store_directory):
def test_merge_conflict_resolved(in_merge_conflict, mock_out_store_directory): def test_merge_conflict_resolved(in_merge_conflict, mock_out_store_directory):
local['git']['add', '.']() local['git']('add', '.')
ret, printed = _do_run(in_merge_conflict, _get_opts()) ret, printed = _do_run(in_merge_conflict, _get_opts())
for msg in ('Checking merge-conflict files only.', 'Bash hook', 'Passed'): for msg in ('Checking merge-conflict files only.', 'Bash hook', 'Passed'):
assert msg in printed assert msg in printed

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import os.path import os.path
@ -5,16 +6,19 @@ import os.path
from pre_commit.runner import Runner from pre_commit.runner import Runner
from pre_commit.commands.install import install from pre_commit.commands.install import install
from pre_commit.commands.uninstall import uninstall from pre_commit.commands.uninstall import uninstall
from testing.fixtures import git_dir
def test_uninstall_pre_commit_does_not_blow_up_when_not_there(empty_git_dir): def test_uninstall_does_not_blow_up_when_not_there(tmpdir_factory):
runner = Runner(empty_git_dir) path = git_dir(tmpdir_factory)
runner = Runner(path)
ret = uninstall(runner) ret = uninstall(runner)
assert ret == 0 assert ret == 0
def test_uninstall(empty_git_dir): def test_uninstall(tmpdir_factory):
runner = Runner(empty_git_dir) path = git_dir(tmpdir_factory)
runner = Runner(path)
assert not os.path.exists(runner.pre_commit_path) assert not os.path.exists(runner.pre_commit_path)
install(runner) install(runner)
assert os.path.exists(runner.pre_commit_path) assert os.path.exists(runner.pre_commit_path)

View file

@ -1,24 +1,22 @@
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import unicode_literals
import io
import mock import mock
import os import os
import os.path import os.path
import pytest import pytest
import time
import yaml
from plumbum import local from plumbum import local
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit import five from pre_commit import five
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
from pre_commit.clientlib.validate_config import validate_config_extra
from pre_commit.jsonschema_extensions import apply_defaults
from pre_commit.prefixed_command_runner import PrefixedCommandRunner from pre_commit.prefixed_command_runner import PrefixedCommandRunner
from pre_commit.runner import Runner from pre_commit.runner import Runner
from pre_commit.store import Store from pre_commit.store import Store
from testing.util import copy_tree_to_path from testing.fixtures import make_consuming_repo
from testing.util import get_head_sha
from testing.util import get_resource_path
git = local['git']
@pytest.yield_fixture @pytest.yield_fixture
@ -44,189 +42,35 @@ def in_tmpdir(tmpdir_factory):
@pytest.yield_fixture @pytest.yield_fixture
def empty_git_dir(in_tmpdir): def in_merge_conflict(tmpdir_factory):
local['git']['init']() path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
yield in_tmpdir with local.cwd(path):
local['touch']('dummy')
git('add', 'dummy')
git('add', C.CONFIG_FILE)
git('commit', '-m', 'Add config.')
conflict_path = tmpdir_factory.get()
def add_and_commit(): git('clone', path, conflict_path)
local['git']['add', '.']() with local.cwd(conflict_path):
local['git']['commit', '-m', 'random commit {0}'.format(time.time())]() git('checkout', 'origin/master', '-b', 'foo')
with io.open('conflict_file', 'w') as conflict_file:
@pytest.yield_fixture
def dummy_git_repo(empty_git_dir):
# This is needed otherwise there is no `HEAD`
local['touch']['dummy']()
add_and_commit()
yield empty_git_dir
def _make_repo(repo_path, repo_source):
copy_tree_to_path(get_resource_path(repo_source), repo_path)
add_and_commit()
return repo_path
@pytest.yield_fixture
def python_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'python_hooks_repo')
@pytest.yield_fixture
def python3_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'python3_hooks_repo')
@pytest.yield_fixture
def node_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'node_hooks_repo')
@pytest.yield_fixture
def node_0_11_8_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'node_0_11_8_hooks_repo')
@pytest.yield_fixture
def ruby_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'ruby_hooks_repo')
@pytest.yield_fixture
def ruby_1_9_3_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'ruby_1_9_3_hooks_repo')
@pytest.yield_fixture
def consumer_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'consumer_repo')
@pytest.yield_fixture
def prints_cwd_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'prints_cwd_repo')
@pytest.yield_fixture
def script_hooks_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'script_hooks_repo')
@pytest.yield_fixture
def failing_hook_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'failing_hook_repo')
@pytest.yield_fixture
def system_hook_with_spaces_repo(dummy_git_repo):
yield _make_repo(dummy_git_repo, 'system_hook_with_spaces_repo')
def _make_config(path, hook_id):
config = {
'repo': path,
'sha': get_head_sha(path),
'hooks': [{'id': hook_id}],
}
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
validate_config_extra(config_wrapped)
return config_wrapped[0]
@pytest.yield_fixture
def config_for_node_hooks_repo(node_hooks_repo):
yield _make_config(node_hooks_repo, 'foo')
@pytest.yield_fixture
def config_for_node_0_11_8_hooks_repo(node_0_11_8_hooks_repo):
yield _make_config(node_0_11_8_hooks_repo, 'node-11-8-hook')
@pytest.yield_fixture
def config_for_ruby_hooks_repo(ruby_hooks_repo):
yield _make_config(ruby_hooks_repo, 'ruby_hook')
@pytest.yield_fixture
def config_for_ruby_1_9_3_hooks_repo(ruby_1_9_3_hooks_repo):
yield _make_config(ruby_1_9_3_hooks_repo, 'ruby_hook')
@pytest.yield_fixture
def config_for_python_hooks_repo(python_hooks_repo):
yield _make_config(python_hooks_repo, 'foo')
@pytest.yield_fixture
def config_for_python3_hooks_repo(python3_hooks_repo):
yield _make_config(python3_hooks_repo, 'python3-hook')
@pytest.yield_fixture
def config_for_prints_cwd_repo(prints_cwd_repo):
yield _make_config(prints_cwd_repo, 'prints_cwd')
@pytest.yield_fixture
def config_for_script_hooks_repo(script_hooks_repo):
yield _make_config(script_hooks_repo, 'bash_hook')
@pytest.yield_fixture
def config_for_system_hook_with_spaces(system_hook_with_spaces_repo):
yield _make_config(
system_hook_with_spaces_repo, 'system-hook-with-spaces',
)
def _make_repo_from_configs(*configs):
with open(C.CONFIG_FILE, 'w') as config_file:
yaml.dump(
configs,
stream=config_file,
Dumper=yaml.SafeDumper,
**C.YAML_DUMP_KWARGS
)
@pytest.yield_fixture
def repo_with_passing_hook(config_for_script_hooks_repo, empty_git_dir):
_make_repo_from_configs(config_for_script_hooks_repo)
yield empty_git_dir
@pytest.yield_fixture
def repo_with_failing_hook(failing_hook_repo, empty_git_dir):
_make_repo_from_configs(_make_config(failing_hook_repo, 'failing_hook'))
yield empty_git_dir
@pytest.yield_fixture
def in_merge_conflict(repo_with_passing_hook):
local['git']['add', C.CONFIG_FILE]()
local['git']['commit', '-m' 'add hooks file']()
local['git']['clone', '.', 'foo']()
with local.cwd('foo'):
local['git']['checkout', 'origin/master', '-b', 'foo']()
with open('conflict_file', 'w') as conflict_file:
conflict_file.write('herp\nderp\n') conflict_file.write('herp\nderp\n')
local['git']['add', 'conflict_file']() git('add', 'conflict_file')
with open('foo_only_file', 'w') as foo_only_file: with io.open('foo_only_file', 'w') as foo_only_file:
foo_only_file.write('foo') foo_only_file.write('foo')
local['git']['add', 'foo_only_file']() git('add', 'foo_only_file')
local['git']['commit', '-m', 'conflict_file']() git('commit', '-m', 'conflict_file')
local['git']['checkout', 'origin/master', '-b', 'bar']() git('checkout', 'origin/master', '-b', 'bar')
with open('conflict_file', 'w') as conflict_file: with io.open('conflict_file', 'w') as conflict_file:
conflict_file.write('harp\nddrp\n') conflict_file.write('harp\nddrp\n')
local['git']['add', 'conflict_file']() git('add', 'conflict_file')
with open('bar_only_file', 'w') as bar_only_file: with io.open('bar_only_file', 'w') as bar_only_file:
bar_only_file.write('bar') bar_only_file.write('bar')
local['git']['add', 'bar_only_file']() git('add', 'bar_only_file')
local['git']['commit', '-m', 'conflict_file']() git('commit', '-m', 'conflict_file')
local['git']['merge', 'foo'](retcode=None) git('merge', 'foo', retcode=None)
yield os.path.join(repo_with_passing_hook, 'foo') yield os.path.join(conflict_path)
@pytest.yield_fixture(scope='session', autouse=True) @pytest.yield_fixture(scope='session', autouse=True)

View file

@ -1,20 +1,32 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import os.path
import pytest import pytest
from plumbum import local from plumbum import local
from pre_commit import git from pre_commit import git
from testing.fixtures import git_dir
def test_get_root(empty_git_dir): def test_get_root_at_root(tmpdir_factory):
assert git.get_root() == empty_git_dir path = git_dir(tmpdir_factory)
with local.cwd(path):
foo = local.path('foo') assert git.get_root() == path
foo.mkdir()
with local.cwd(foo):
assert git.get_root() == empty_git_dir
def test_is_not_in_merge_conflict(empty_git_dir): def test_get_root_deeper(tmpdir_factory):
path = git_dir(tmpdir_factory)
foo_path = os.path.join(path, 'foo')
os.mkdir(foo_path)
with local.cwd(foo_path):
assert git.get_root() == path
def test_is_not_in_merge_conflict(tmpdir_factory):
path = git_dir(tmpdir_factory)
with local.cwd(path):
assert git.is_in_merge_conflict() is False assert git.is_in_merge_conflict() is False
@ -77,14 +89,14 @@ def test_exclude_removes_files(get_files_matching_func):
def resolve_conflict(): def resolve_conflict():
with open('conflict_file', 'w') as conflicted_file: with open('conflict_file', 'w') as conflicted_file:
conflicted_file.write('herp\nderp\n') conflicted_file.write('herp\nderp\n')
local['git']['add', 'conflict_file']() local['git']('add', 'conflict_file')
def test_get_conflicted_files(in_merge_conflict): def test_get_conflicted_files(in_merge_conflict):
resolve_conflict() resolve_conflict()
with open('other_file', 'w') as other_file: with open('other_file', 'w') as other_file:
other_file.write('oh hai') other_file.write('oh hai')
local['git']['add', 'other_file']() local['git']('add', 'other_file')
ret = set(git.get_conflicted_files()) ret = set(git.get_conflicted_files())
assert ret == set(('conflict_file', 'other_file')) assert ret == set(('conflict_file', 'other_file'))

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import jsonschema.exceptions import jsonschema.exceptions
import pytest import pytest

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import pytest import pytest
from pre_commit.languages.all import all_languages from pre_commit.languages.all import all_languages

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os.path import os.path
from pre_commit.languages.ruby import _install_rbenv from pre_commit.languages.ruby import _install_rbenv

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import mock import mock
from pre_commit import color from pre_commit import color

View file

@ -1,13 +1,18 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import pytest import pytest
from pre_commit.manifest import Manifest from pre_commit.manifest import Manifest
from testing.fixtures import make_repo
from testing.util import get_head_sha from testing.util import get_head_sha
@pytest.yield_fixture @pytest.yield_fixture
def manifest(store, script_hooks_repo): def manifest(store, tmpdir_factory):
head_sha = get_head_sha(script_hooks_repo) path = make_repo(tmpdir_factory, 'script_hooks_repo')
repo_path_getter = store.get_repo_path_getter(script_hooks_repo, head_sha) head_sha = get_head_sha(path)
repo_path_getter = store.get_repo_path_getter(path, head_sha)
yield Manifest(repo_path_getter) yield Manifest(repo_path_getter)

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import pytest import pytest
from pre_commit import color from pre_commit import color

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os import os
import mock import mock
import pytest import pytest
@ -9,7 +11,9 @@ from pre_commit.prefixed_command_runner import PrefixedCommandRunner
def test_CalledProcessError_str(): def test_CalledProcessError_str():
error = CalledProcessError(1, ['git', 'status'], 0, ('stdout', 'stderr')) error = CalledProcessError(
1, [str('git'), str('status')], 0, (str('stdout'), str('stderr'))
)
assert str(error) == ( assert str(error) == (
"Command: ['git', 'status']\n" "Command: ['git', 'status']\n"
"Return code: 1\n" "Return code: 1\n"

View file

@ -1,3 +1,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import mock
import os.path import os.path
import pytest import pytest
from plumbum import local from plumbum import local
@ -6,101 +10,115 @@ from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
from pre_commit.clientlib.validate_config import validate_config_extra from pre_commit.clientlib.validate_config import validate_config_extra
from pre_commit.jsonschema_extensions import apply_defaults from pre_commit.jsonschema_extensions import apply_defaults
from pre_commit.repository import Repository from pre_commit.repository import Repository
from testing.fixtures import git_dir
from testing.fixtures import make_config_from_repo
from testing.fixtures import make_repo
from testing.util import skipif_slowtests_false from testing.util import skipif_slowtests_false
@pytest.mark.integration @pytest.mark.integration
def test_install_python_repo_in_env(config_for_python_hooks_repo, store): def test_install_python_repo_in_env(tmpdir_factory, store):
repo = Repository.create(config_for_python_hooks_repo, store) path = make_repo(tmpdir_factory, 'python_hooks_repo')
config = make_config_from_repo(path)
repo = Repository.create(config, store)
repo.install() repo.install()
assert os.path.exists(os.path.join(store.directory, repo.sha, 'py_env')) assert os.path.exists(os.path.join(store.directory, repo.sha, 'py_env'))
@pytest.mark.integration def _test_hook_repo(tmpdir_factory, store, repo_path, hook_id, args, expected):
def test_run_a_python_hook(config_for_python_hooks_repo, store): path = make_repo(tmpdir_factory, repo_path)
repo = Repository.create(config_for_python_hooks_repo, store) config = make_config_from_repo(path)
ret = repo.run_hook('foo', ['/dev/null']) repo = Repository.create(config, store)
ret = repo.run_hook(hook_id, args)
assert ret[0] == 0 assert ret[0] == 0
assert ret[1] == "['/dev/null']\nHello World\n" assert ret[1] == expected
@pytest.mark.integration @pytest.mark.integration
def test_run_versioned_hook(config_for_python3_hooks_repo, store): def test_python_hook(tmpdir_factory, store):
repo = Repository.create(config_for_python3_hooks_repo, store) _test_hook_repo(
ret = repo.run_hook('python3-hook', ['/dev/null']) tmpdir_factory, store, 'python_hooks_repo',
assert ret[0] == 0 'foo', ['/dev/null'], "['/dev/null']\nHello World\n",
assert ret[1] == "3.3\n['/dev/null']\nHello World\n" )
@pytest.mark.integration
def test_versioned_python_hook(tmpdir_factory, store):
_test_hook_repo(
tmpdir_factory, store, 'python3_hooks_repo',
'python3-hook', ['/dev/null'], "3.3\n['/dev/null']\nHello World\n",
)
@skipif_slowtests_false @skipif_slowtests_false
@pytest.mark.integration @pytest.mark.integration
def test_run_versioned_node_hook(config_for_node_0_11_8_hooks_repo, store): def test_run_a_node_hook(tmpdir_factory, store):
repo = Repository.create(config_for_node_0_11_8_hooks_repo, store) _test_hook_repo(
ret = repo.run_hook('node-11-8-hook', ['/dev/null']) tmpdir_factory, store, 'node_hooks_repo',
assert ret[0] == 0 'foo', [], 'Hello World\n',
assert ret[1] == 'v0.11.8\nHello World\n' )
@pytest.mark.herpderp
@skipif_slowtests_false @skipif_slowtests_false
@pytest.mark.integration @pytest.mark.integration
def test_run_versioned_ruby_hook(config_for_ruby_1_9_3_hooks_repo, store): def test_run_versioned_node_hook(tmpdir_factory, store):
repo = Repository.create(config_for_ruby_1_9_3_hooks_repo, store) _test_hook_repo(
ret = repo.run_hook('ruby_hook', []) tmpdir_factory, store, 'node_0_11_8_hooks_repo',
assert ret[0] == 0 'node-11-8-hook', ['/dev/null'], 'v0.11.8\nHello World\n',
assert ret[1] == '1.9.3\n484\nHello world from a ruby hook\n' )
@skipif_slowtests_false
@pytest.mark.integration
def test_run_a_ruby_hook(tmpdir_factory, store):
_test_hook_repo(
tmpdir_factory, store, 'ruby_hooks_repo',
'ruby_hook', [], 'Hello world from a ruby hook\n',
)
@skipif_slowtests_false
@pytest.mark.integration
def test_run_versioned_ruby_hook(tmpdir_factory, store):
_test_hook_repo(
tmpdir_factory, store, 'ruby_1_9_3_hooks_repo',
'ruby_hook', [], '1.9.3\n484\nHello world from a ruby hook\n',
)
@pytest.mark.integration @pytest.mark.integration
def test_lots_of_files(config_for_python_hooks_repo, store): def test_system_hook_with_spaces(tmpdir_factory, store):
repo = Repository.create(config_for_python_hooks_repo, store) _test_hook_repo(
ret = repo.run_hook('foo', ['/dev/null'] * 15000) tmpdir_factory, store, 'system_hook_with_spaces_repo',
assert ret[0] == 0 'system-hook-with-spaces', [], 'Hello World\n',
)
@pytest.mark.integration @pytest.mark.integration
def test_cwd_of_hook(config_for_prints_cwd_repo, store): def test_run_a_script_hook(tmpdir_factory, store):
_test_hook_repo(
tmpdir_factory, store, 'script_hooks_repo',
'bash_hook', ['bar'], 'bar\nHello World\n',
)
@pytest.mark.integration
def test_cwd_of_hook(tmpdir_factory, store):
# Note: this doubles as a test for `system` hooks # Note: this doubles as a test for `system` hooks
repo = Repository.create(config_for_prints_cwd_repo, store) path = git_dir(tmpdir_factory)
ret = repo.run_hook('prints_cwd', []) with local.cwd(path):
assert ret[0] == 0 _test_hook_repo(
assert ret[1] == repo.repo_url + '\n' tmpdir_factory, store, 'prints_cwd_repo',
'prints_cwd', [], path + '\n',
)
@pytest.mark.integration @pytest.mark.integration
def test_system_hook_with_spaces(config_for_system_hook_with_spaces, store): def test_lots_of_files(tmpdir_factory, store):
repo = Repository.create(config_for_system_hook_with_spaces, store) _test_hook_repo(
ret = repo.run_hook('system-hook-with-spaces', []) tmpdir_factory, store, 'script_hooks_repo',
assert ret[0] == 0 'bash_hook', ['/dev/null'] * 15000, mock.ANY,
assert ret[1] == 'Hello World\n' )
@skipif_slowtests_false
@pytest.mark.integration
def test_run_a_node_hook(config_for_node_hooks_repo, store):
repo = Repository.create(config_for_node_hooks_repo, store)
ret = repo.run_hook('foo', [])
assert ret[0] == 0
assert ret[1] == 'Hello World\n'
@pytest.mark.herpderp
@skipif_slowtests_false
@pytest.mark.integration
def test_run_a_ruby_hook(config_for_ruby_hooks_repo, store):
repo = Repository.create(config_for_ruby_hooks_repo, store)
ret = repo.run_hook('ruby_hook', [])
assert ret[0] == 0
assert ret[1] == 'Hello world from a ruby hook\n'
@pytest.mark.integration
def test_run_a_script_hook(config_for_script_hooks_repo, store):
repo = Repository.create(config_for_script_hooks_repo, store)
ret = repo.run_hook('bash_hook', ['bar'])
assert ret[0] == 0
assert ret[1] == 'bar\nHello World\n'
@pytest.fixture @pytest.fixture
@ -129,37 +147,49 @@ def test_sha(mock_repo_config):
@pytest.mark.integration @pytest.mark.integration
def test_languages(config_for_python_hooks_repo, store): def test_languages(tmpdir_factory, store):
repo = Repository.create(config_for_python_hooks_repo, store) path = make_repo(tmpdir_factory, 'python_hooks_repo')
config = make_config_from_repo(path)
repo = Repository.create(config, store)
assert repo.languages == set([('python', 'default')]) assert repo.languages == set([('python', 'default')])
def test_reinstall(config_for_python_hooks_repo, store): def test_reinstall(tmpdir_factory, store):
repo = Repository.create(config_for_python_hooks_repo, store) path = make_repo(tmpdir_factory, 'python_hooks_repo')
config = make_config_from_repo(path)
repo = Repository.create(config, store)
repo.require_installed() repo.require_installed()
# Reinstall with same repo should not trigger another install # Reinstall with same repo should not trigger another install
# TODO: how to assert this? # TODO: how to assert this?
repo.require_installed() repo.require_installed()
# Reinstall on another run should not trigger another install # Reinstall on another run should not trigger another install
# TODO: how to assert this? # TODO: how to assert this?
repo = Repository.create(config_for_python_hooks_repo, store) repo = Repository.create(config, store)
repo.require_installed() repo.require_installed()
@pytest.mark.integration @pytest.mark.integration
def test_really_long_file_paths(config_for_python_hooks_repo, store): def test_really_long_file_paths(tmpdir_factory, store):
path = 'really_long' * 10 base_path = tmpdir_factory.get()
local['git']['init', path]() really_long_path = os.path.join(base_path, 'really_long' * 10)
with local.cwd(path): local['git']('init', really_long_path)
repo = Repository.create(config_for_python_hooks_repo, store)
path = make_repo(tmpdir_factory, 'python_hooks_repo')
config = make_config_from_repo(path)
with local.cwd(really_long_path):
repo = Repository.create(config, store)
repo.require_installed() repo.require_installed()
@pytest.mark.integration @pytest.mark.integration
def test_config_overrides_repo_specifics(config_for_script_hooks_repo, store): def test_config_overrides_repo_specifics(tmpdir_factory, store):
repo = Repository.create(config_for_script_hooks_repo, store) path = make_repo(tmpdir_factory, 'script_hooks_repo')
config = make_config_from_repo(path)
repo = Repository.create(config, store)
assert repo.hooks['bash_hook']['files'] == '' assert repo.hooks['bash_hook']['files'] == ''
# Set the file regex to something else # Set the file regex to something else
config_for_script_hooks_repo['hooks'][0]['files'] = '\\.sh$' config['hooks'][0]['files'] = '\\.sh$'
repo = Repository.create(config_for_script_hooks_repo, store) repo = Repository.create(config, store)
assert repo.hooks['bash_hook']['files'] == '\\.sh$' assert repo.hooks['bash_hook']['files'] == '\\.sh$'

View file

@ -1,9 +1,14 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import os import os
import os.path import os.path
import pytest from plumbum import local
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit.runner import Runner from pre_commit.runner import Runner
from testing.fixtures import git_dir
from testing.fixtures import make_repo
def test_init_has_no_side_effects(tmpdir): def test_init_has_no_side_effects(tmpdir):
@ -13,24 +18,26 @@ def test_init_has_no_side_effects(tmpdir):
assert os.getcwd() == current_wd assert os.getcwd() == current_wd
def test_create_sets_correct_directory(empty_git_dir): def test_create_sets_correct_directory(tmpdir_factory):
path = git_dir(tmpdir_factory)
with local.cwd(path):
runner = Runner.create() runner = Runner.create()
assert runner.git_root == empty_git_dir assert runner.git_root == path
assert os.getcwd() == empty_git_dir assert os.getcwd() == path
@pytest.yield_fixture def test_create_changes_to_git_root(tmpdir_factory):
def git_dir_with_directory(empty_git_dir): path = git_dir(tmpdir_factory)
os.mkdir('foo') with local.cwd(path):
yield empty_git_dir # Change into some directory, create should set to root
foo_path = os.path.join(path, 'foo')
os.mkdir(foo_path)
os.chdir(foo_path)
assert os.getcwd() != path
def test_changes_to_root_of_git_dir(git_dir_with_directory):
os.chdir('foo')
assert os.getcwd() != git_dir_with_directory
runner = Runner.create() runner = Runner.create()
assert runner.git_root == git_dir_with_directory assert runner.git_root == path
assert os.getcwd() == git_dir_with_directory assert os.getcwd() == path
def test_config_file_path(): def test_config_file_path():
@ -39,9 +46,10 @@ def test_config_file_path():
assert runner.config_file_path == expected_path assert runner.config_file_path == expected_path
def test_repositories(consumer_repo, mock_out_store_directory): def test_repositories(tmpdir_factory, mock_out_store_directory):
# TODO: make this not have external deps # TODO: make this not have external deps
runner = Runner(consumer_repo) path = make_repo(tmpdir_factory, 'consumer_repo')
runner = Runner(path)
assert len(runner.repositories) == 2 assert len(runner.repositories) == 2
assert [repo.repo_url for repo in runner.repositories] == [ assert [repo.repo_url for repo in runner.repositories] == [
'git@github.com:pre-commit/pre-commit-hooks', 'git@github.com:pre-commit/pre-commit-hooks',

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import io import io
@ -10,6 +11,7 @@ from plumbum import local
from pre_commit.staged_files_only import staged_files_only from pre_commit.staged_files_only import staged_files_only
from testing.auto_namedtuple import auto_namedtuple from testing.auto_namedtuple import auto_namedtuple
from testing.fixtures import git_dir
from testing.util import get_resource_path from testing.util import get_resource_path
@ -17,17 +19,19 @@ FOO_CONTENTS = '\n'.join(('1', '2', '3', '4', '5', '6', '7', '8', ''))
def get_short_git_status(): def get_short_git_status():
git_status = local['git']['status', '-s']() git_status = local['git']('status', '-s')
return dict(reversed(line.split()) for line in git_status.splitlines()) return dict(reversed(line.split()) for line in git_status.splitlines())
@pytest.yield_fixture @pytest.yield_fixture
def foo_staged(empty_git_dir): def foo_staged(tmpdir_factory):
path = git_dir(tmpdir_factory)
with local.cwd(path):
with io.open('foo', 'w') as foo_file: with io.open('foo', 'w') as foo_file:
foo_file.write(FOO_CONTENTS) foo_file.write(FOO_CONTENTS)
local['git']['add', 'foo']() local['git']('add', 'foo')
foo_filename = os.path.join(empty_git_dir, 'foo') foo_filename = os.path.join(path, 'foo')
yield auto_namedtuple(path=empty_git_dir, foo_filename=foo_filename) yield auto_namedtuple(path=path, foo_filename=foo_filename)
def _test_foo_state(path, foo_contents=FOO_CONTENTS, status='A'): def _test_foo_state(path, foo_contents=FOO_CONTENTS, status='A'):
@ -96,11 +100,13 @@ def test_foo_both_modify_conflicting(foo_staged, cmd_runner):
@pytest.yield_fixture @pytest.yield_fixture
def img_staged(empty_git_dir): def img_staged(tmpdir_factory):
img_filename = os.path.join(empty_git_dir, 'img.jpg') path = git_dir(tmpdir_factory)
with local.cwd(path):
img_filename = os.path.join(path, 'img.jpg')
shutil.copy(get_resource_path('img1.jpg'), img_filename) shutil.copy(get_resource_path('img1.jpg'), img_filename)
local['git']['add', 'img.jpg']() local['git']('add', 'img.jpg')
yield auto_namedtuple(path=empty_git_dir, img_filename=img_filename) yield auto_namedtuple(path=path, img_filename=img_filename)
def _test_img_state(path, expected_file='img1.jpg', status='A'): def _test_img_state(path, expected_file='img1.jpg', status='A'):
@ -149,27 +155,31 @@ def test_img_conflict(img_staged, cmd_runner):
@pytest.yield_fixture @pytest.yield_fixture
def submodule_with_commits(empty_git_dir): def submodule_with_commits(tmpdir_factory):
local['git']['commit', '--allow-empty', '-m', 'foo']() path = git_dir(tmpdir_factory)
sha1 = local['git']['rev-parse', 'HEAD']().strip() with local.cwd(path):
local['git']['commit', '--allow-empty', '-m', 'bar']() local['git']('commit', '--allow-empty', '-m', 'foo')
sha2 = local['git']['rev-parse', 'HEAD']().strip() sha1 = local['git']('rev-parse', 'HEAD').strip()
yield auto_namedtuple(path=empty_git_dir, sha1=sha1, sha2=sha2) local['git']('commit', '--allow-empty', '-m', 'bar')
sha2 = local['git']('rev-parse', 'HEAD').strip()
yield auto_namedtuple(path=path, sha1=sha1, sha2=sha2)
def checkout_submodule(sha): def checkout_submodule(sha):
with local.cwd('sub'): with local.cwd('sub'):
local['git']['checkout', sha]() local['git']('checkout', sha)
@pytest.yield_fixture @pytest.yield_fixture
def sub_staged(submodule_with_commits, empty_git_dir): def sub_staged(submodule_with_commits, tmpdir_factory):
local['git']['submodule', 'add', submodule_with_commits.path, 'sub']() path = git_dir(tmpdir_factory)
with local.cwd(path):
local['git']('submodule', 'add', submodule_with_commits.path, 'sub')
checkout_submodule(submodule_with_commits.sha1) checkout_submodule(submodule_with_commits.sha1)
local['git']['add', 'sub']() local['git']('add', 'sub')
yield auto_namedtuple( yield auto_namedtuple(
path=empty_git_dir, path=path,
sub_path=os.path.join(empty_git_dir, 'sub'), sub_path=os.path.join(path, 'sub'),
submodule=submodule_with_commits, submodule=submodule_with_commits,
) )
@ -177,7 +187,7 @@ def sub_staged(submodule_with_commits, empty_git_dir):
def _test_sub_state(path, sha='sha1', status='A'): def _test_sub_state(path, sha='sha1', status='A'):
assert os.path.exists(path.sub_path) assert os.path.exists(path.sub_path)
with local.cwd(path.sub_path): with local.cwd(path.sub_path):
actual_sha = local['git']['rev-parse', 'HEAD']().strip() actual_sha = local['git']('rev-parse', 'HEAD').strip()
assert actual_sha == getattr(path.submodule, sha) assert actual_sha == getattr(path.submodule, sha)
actual_status = get_short_git_status()['sub'] actual_status = get_short_git_status()['sub']
assert actual_status == status assert actual_status == status

View file

@ -1,3 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import io import io
import mock import mock
import os import os
@ -10,6 +13,7 @@ from pre_commit import five
from pre_commit.store import _get_default_directory from pre_commit.store import _get_default_directory
from pre_commit.store import logger from pre_commit.store import logger
from pre_commit.store import Store from pre_commit.store import Store
from testing.fixtures import git_dir
from testing.util import get_head_sha from testing.util import get_head_sha
@ -71,13 +75,14 @@ def log_info_mock():
yield info_mock yield info_mock
def test_clone(store, empty_git_dir, log_info_mock): def test_clone(store, tmpdir_factory, log_info_mock):
with local.cwd(empty_git_dir): path = git_dir(tmpdir_factory)
with local.cwd(path):
local['git']('commit', '--allow-empty', '-m', 'foo') local['git']('commit', '--allow-empty', '-m', 'foo')
sha = get_head_sha(empty_git_dir) sha = get_head_sha(path)
local['git']('commit', '--allow-empty', '-m', 'bar') local['git']('commit', '--allow-empty', '-m', 'bar')
ret = store.clone(empty_git_dir, sha) ret = store.clone(path, sha)
# Should have printed some stuff # Should have printed some stuff
log_info_mock.assert_called_with('This may take a few minutes...') log_info_mock.assert_called_with('This may take a few minutes...')

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
import mock import mock
import pytest import pytest
import os import os