Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip tests instead of fail'ing if VCS <foo> command not installed #42

Merged
merged 7 commits into from
Jan 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
language: python
sudo: false
python:
- 2.6
- 2.7
- 3.2
- 3.3
- 3.4
- pypy
env:
- FORCE_TEST_VCS=bzr
- FORCE_TEST_VCS=git
- FORCE_TEST_VCS=hg
- FORCE_TEST_VCS=svn
install:
- pip install coverage coveralls mock
script:
- coverage run --source=check_manifest setup.py test -q
- SKIP_NO_TESTS=1 coverage run --source=check_manifest setup.py test -q
- coverage run --source=check_manifest --append check_manifest.py
after_script:
- coveralls
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ all:
test:
detox
check:
tox
SKIP_NO_TESTS=1 tox

.PHONY: coverage
coverage:
Expand Down
2 changes: 1 addition & 1 deletion check_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class Mercurial(VCS):
@staticmethod
def get_versioned_files():
"""List all files under Mercurial control in the current directory."""
output = run(['hg', 'status', '-ncam', '.'])
output = run(['hg', 'status', '-ncamd', '.'])
return add_directories(output.splitlines())


Expand Down
94 changes: 81 additions & 13 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import mock


CAN_SKIP_TESTS = os.getenv('SKIP_NO_TESTS', '') == ''


def rmtree(path):
"""A version of rmtree that can remove read-only files on Windows.

Expand Down Expand Up @@ -715,6 +718,18 @@ def test_zest_releaser_check_failure_user_plods_on(self, check_manifest,

class VCSHelper(object):

command = None # override in subclasses

def is_installed(self):
try:
p = subprocess.Popen([self.command, '--version'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = p.communicate()
rc = p.wait()
return (rc == 0)
except OSError:
return False

def _run(self, *command):
# Windows doesn't like Unicode arguments to subprocess.Popen(), on Py2:
# https://github.com/mgedmin/check-manifest/issues/23#issuecomment-33933031
Expand All @@ -733,6 +748,8 @@ def _run(self, *command):
class VCSMixin(object):

def setUp(self):
if not self.vcs.is_installed() and CAN_SKIP_TESTS:
self.skipTest("%s is not installed" % self.vcs.command)
self.tmpdir = tempfile.mkdtemp(prefix='test-', suffix='-check-manifest')
self.olddir = os.getcwd()
os.chdir(self.tmpdir)
Expand Down Expand Up @@ -786,6 +803,17 @@ def test_get_vcs_files_added_but_uncommitted(self):
['a.txt', 'b', j('b', 'b.txt'), j('b', 'c'),
j('b', 'c', 'd.txt')])

def test_get_vcs_files_deleted_but_not_removed(self):
if self.vcs.command == 'bzr':
self.skipTest("this cosmetic feature is not supported with bzr")
# see the longer explanation in test_missing_source_files
from check_manifest import get_vcs_files
self._init_vcs()
self._create_and_add_to_vcs(['a.txt'])
self._commit()
os.unlink('a.txt')
self.assertEqual(get_vcs_files(), ['a.txt'])

def test_get_vcs_files_in_a_subdir(self):
from check_manifest import get_vcs_files
self._init_vcs()
Expand All @@ -809,6 +837,8 @@ def test_get_vcs_files_nonascii_filenames(self):

class GitHelper(VCSHelper):

command = 'git'

def _init_vcs(self):
self._run('git', 'init')
self._run('git', 'config', 'user.name', 'Unit Test')
Expand All @@ -827,6 +857,8 @@ class TestGit(VCSMixin, unittest.TestCase):

class BzrHelper(VCSHelper):

command = 'bzr'

def _init_vcs(self):
self._run('bzr', 'init')
self._run('bzr', 'whoami', '--branch', 'Unit Test <test@example.com>')
Expand All @@ -844,6 +876,8 @@ class TestBzr(VCSMixin, unittest.TestCase):

class HgHelper(VCSHelper):

command = 'hg'

def _init_vcs(self):
self._run('hg', 'init')
with open('.hg/hgrc', 'a') as f:
Expand All @@ -862,6 +896,8 @@ class TestHg(VCSMixin, unittest.TestCase):

class SvnHelper(VCSHelper):

command = 'svn'

def _init_vcs(self):
self._run('svnadmin', 'create', 'repo')
self._run('svn', 'co', 'file:///' + os.path.abspath('repo').replace(os.path.sep, '/'), 'checkout')
Expand Down Expand Up @@ -993,11 +1029,29 @@ def test_error_verbose(self):
"Forgot to turn the gas off!\n")


def pick_installed_vcs():
preferred_order = [GitHelper, HgHelper, BzrHelper, SvnHelper]
force = os.getenv('FORCE_TEST_VCS')
if force:
for cls in preferred_order:
if force == cls.command:
return cls()
raise ValueError('Unsupported FORCE_TEST_VCS=%s (supported: %s)'
% (force, '/'.join(cls.command for cls in preferred_order)))
for cls in preferred_order:
vcs = cls()
if vcs.is_installed():
return vcs
return None


class TestCheckManifest(unittest.TestCase):

_vcs = GitHelper()
_vcs = pick_installed_vcs()

def setUp(self):
if self._vcs is None:
self.fail('at least one version control system should be installed')
self.oldpwd = os.getcwd()
self.tmpdir = tempfile.mkdtemp(prefix='test-', suffix='-check-manifest')
os.chdir(self.tmpdir)
Expand All @@ -1021,6 +1075,16 @@ def _create_repo_with_code(self):
f.write("# wow. such code. so amaze\n")
self._vcs._add_to_vcs(['setup.py', 'sample.py'])

def _create_repo_with_code_in_subdir(self):
os.mkdir('subdir')
os.chdir('subdir')
self._create_repo_with_code()
# NB: when self._vcs is SvnHelper, we're actually in
# ./subdir/checout rather than in ./subdir
subdir = os.path.basename(os.getcwd())
os.chdir(os.pardir)
return subdir

def _add_to_vcs(self, filename, content=''):
if os.path.sep in filename and not os.path.isdir(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
Expand All @@ -1042,20 +1106,14 @@ def test_all_is_well(self):

def test_relative_pathname(self):
from check_manifest import check_manifest
os.mkdir('subdir')
os.chdir('subdir')
self._create_repo_with_code()
os.chdir(os.pardir)
self.assertTrue(check_manifest('subdir'))
subdir = self._create_repo_with_code_in_subdir()
self.assertTrue(check_manifest(subdir))

def test_relative_python(self):
from check_manifest import check_manifest
os.mkdir('subdir')
os.chdir('subdir')
self._create_repo_with_code()
os.chdir(os.pardir)
subdir = self._create_repo_with_code_in_subdir()
python = os.path.relpath(sys.executable)
self.assertTrue(check_manifest('subdir', python=python))
self.assertTrue(check_manifest(subdir, python=python))

def test_suggestions(self):
from check_manifest import check_manifest
Expand Down Expand Up @@ -1145,13 +1203,23 @@ def test_bad_ideas(self):
sys.stderr.getvalue())

def test_missing_source_files(self):
# https://github.com/mgedmin/check-manifest/issues/32
from check_manifest import check_manifest
self._create_repo_with_code()
self._add_to_vcs('missing.py')
os.unlink('missing.py')
check_manifest()
self.assertIn("some files listed as being under source control are missing:\n missing.py",
sys.stderr.getvalue())
if self._vcs.command != 'bzr':
# 'bzr ls' doesn't list files that were deleted but not
# marked for deletion. 'bzr st' does, but it doesn't list
# unmodified files. Importing bzrlib and using the API to
# get the file list we need is (a) complicated, (b) opens
# the optional dependency can of worms, and (c) not viable
# under Python 3 unless we fork off a Python 2 subprocess.
# Manually combining 'bzr ls' and 'bzr st' outputs just to
# produce a cosmetic warning message seems like overkill.
self.assertIn("some files listed as being under source control are missing:\n missing.py",
sys.stderr.getvalue())


def test_suite():
Expand Down