hookmeup

A Git hook to automate your Pipenv and Django workflow
git clone git://git.danielmoch.com/hookmeup.git
Log | Files | Refs | README | LICENSE

commit a7d6b2c92005726e6d9fe178e8a0c8473e138373
parent a1fa60be26d43d5130b0d0b8d5f0e9d4d2fe8dc8
Author: Daniel Moch <daniel@danielmoch.com>
Date:   Thu, 23 Aug 2018 18:22:35 -0400

Add Tox and update tests

Diffstat:
M.gitignore | 1+
MMakefile | 4++++
MPipfile | 1+
MPipfile.lock | 18+++++++++++++++++-
Mhookmeup/__init__.py | 4+++-
Mhookmeup/hookmeup.py | 3++-
Mpyproject.toml | 10+++++++++-
Mtests/pylintrc | 3++-
Mtests/test_hookmeup.py | 10+++++-----
Mtests/test_main.py | 2+-
Atox.ini | 24++++++++++++++++++++++++
11 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -2,3 +2,4 @@ dist/ .coverage .pytest_cache/ htmlcov/ +.tox/ diff --git a/Makefile b/Makefile @@ -50,6 +50,7 @@ clean-test: ## remove test and coverage artifacts rm -f .coverage rm -fr htmlcov/ rm -fr .pytest_cache + rm -fr .tox lint: ## check style with flake8 $(PIPENV) pylint --rcfile tests/pylintrc hookmeup tests @@ -57,6 +58,9 @@ lint: ## check style with flake8 test: ## run tests quickly with the default Python $(PIPENV) python -m pytest +test-all: ## run tests on every Python version with tox + $(PIPENV) tox + coverage: ## check code coverage quickly with the default Python $(PIPENV) python -m pytest $(PIPENV) coverage report -m diff --git a/Pipfile b/Pipfile @@ -12,6 +12,7 @@ pytest-cov = "*" pytest-pylint = "*" pytest-mock = "*" pudb = "*" +tox = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "fd5a5de24dc062a9d5c8bfdd4adde56e660fd0f62c616dac3732592b290123b2" + "sha256": "dbd531a84c2641232ac42cdd4450966f9a3af2034db26189b3b0b9a6bef8e79e" }, "pipfile-spec": 6, "requires": { @@ -276,12 +276,28 @@ ], "version": "==1.11.0" }, + "tox": { + "hashes": [ + "sha256:37cf240781b662fb790710c6998527e65ca6851eace84d1595ee71f7af4e85f7", + "sha256:eb61aa5bcce65325538686f09848f04ef679b5cd9b83cc491272099b28739600" + ], + "index": "pypi", + "version": "==3.2.1" + }, "urwid": { "hashes": [ "sha256:644d3e3900867161a2fc9287a9762753d66bd194754679adb26aede559bcccbc" ], "version": "==2.0.1" }, + "virtualenv": { + "hashes": [ + "sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669", + "sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752" + ], + "markers": "python_version != '3.2.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.1.*'", + "version": "==16.0.0" + }, "wrapt": { "hashes": [ "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6" diff --git a/hookmeup/__init__.py b/hookmeup/__init__.py @@ -17,7 +17,9 @@ def main(): version='%(prog)s {}'.format(__version__)) subparsers = parser.add_subparsers( title='subcommands', - description='Valid %(prog)s subcommands') + description='Valid %(prog)s subcommands. See more \ + information on a subcommand by typing hookmeup \ + {subcommand} {-h,--help}') install_parser = subparsers.add_parser( 'install', description='Run inside a repository to install the hook. \ diff --git a/hookmeup/hookmeup.py b/hookmeup/hookmeup.py @@ -26,7 +26,8 @@ def __init__(self, args): 'migrate'] deleted_migrations = {} stdout = call_checked_subprocess( - ['git', 'diff', '--name-status', args['old'], args['new']] + ['git', 'diff', '--name-status', args['old'], args['new']], + 'not in a Git repository' ) diff_lines = stdout.splitlines() for line in diff_lines: diff --git a/pyproject.toml b/pyproject.toml @@ -8,7 +8,15 @@ author = "Daniel Moch" author-email = "daniel@danielmoch.com" home-page = "https://github.com/djmoch/hookmeup" description-file = "README.md" -classifiers = ["License :: OSI Approved :: MIT License"] +classifiers = ["License :: OSI Approved :: MIT License", + "Environment :: Console", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Software Development :: Version Control :: Git"] +requires-python=">=3.5" [tool.flit.scripts] hookmeup = "hookmeup:main" diff --git a/tests/pylintrc b/tests/pylintrc @@ -241,7 +241,8 @@ generated-members=REQUEST, call_count, print, call_args_list, - assert_any_call + assert_any_call, + assert_not_called # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). diff --git a/tests/test_hookmeup.py b/tests/test_hookmeup.py @@ -73,7 +73,7 @@ def test_install_already_installed(mock_install, mocker): ) mocker.patch('hookmeup.hookmeup.print') hookmeup.hookmeup.install({}) - hookmeup.hookmeup.print.assert_called_once() + assert hookmeup.hookmeup.print.call_count == 1 def test_error(): """Test accessing error members""" @@ -97,7 +97,7 @@ def test_post_checkout(mocker): 'new': 'HEAD' }) assert subprocess.check_output.call_count == 3 - hookmeup.hookmeup.adjust_pipenv.assert_called_once() + assert hookmeup.hookmeup.adjust_pipenv.call_count == 1 def test_post_checkout_no_changes(mocker): """Test nominal post_checkout""" @@ -145,7 +145,7 @@ def test_migrate_up(mocker): ) migrator = DjangoMigrator({'old': 'test', 'new': 'test2'}) assert migrator.migrations_changed() is True - subprocess.check_output.assert_called_once() + assert subprocess.check_output.call_count == 1 mocker.resetall() migrator.migrate() subprocess.check_output.assert_called_once_with( @@ -163,7 +163,7 @@ def test_migrate_down(mocker): ) migrator = DjangoMigrator({'old': 'test', 'new': 'test2'}) assert migrator.migrations_changed() is True - subprocess.check_output.assert_called_once() + assert subprocess.check_output.call_count == 1 mocker.resetall() migrator.migrate() assert subprocess.check_output.call_count == 2 @@ -188,7 +188,7 @@ def test__migrate_to_zero(mocker): ) migrator = DjangoMigrator({'old': 'test', 'new': 'test2'}) assert migrator.migrations_changed() is True - subprocess.check_output.assert_called_once() + assert subprocess.check_output.call_count == 1 mocker.resetall() migrator.migrate() assert subprocess.check_output.call_count == 2 diff --git a/tests/test_main.py b/tests/test_main.py @@ -16,7 +16,7 @@ def test_main_install(mock_hookmeup, mocker): """Test the entrypoint with the install subcommand.""" mocker.patch.object(sys, 'argv', ['hookmeup', 'install']) hookmeup.main() - hookmeup.hookmeup.install.assert_called_once() + assert hookmeup.hookmeup.install.call_count == 1 assert hookmeup.hookmeup.post_checkout.call_count == 0 def test_install_too_many_args(mock_hookmeup, mocker): diff --git a/tox.ini b/tox.ini @@ -0,0 +1,24 @@ +[tox] +envlist = py35, py36, py37, pylint +skipsdist = True + +[travis] +python = + 3.7: py37 + 3.6: py36 + 3.5: py35 + +[testenv:pylint] +basepython = python +deps = pylint +commands = pylint --rcfile tests/pylintrc hookmeup + +[testenv] +setenv = + PYTHONPATH = {toxinidir} +deps = pytest<3.7.0 + pytest-cov + pytest-pylint + pytest-mock +commands = + py.test --basetemp={envtmpdir}