From 39e32d43295ace6d5c9802f88a58ddad84acff8b Mon Sep 17 00:00:00 2001 From: Loic Teixeira Date: Fri, 23 Feb 2018 16:10:55 +1100 Subject: [PATCH] Test for all supported versions (#21) * Add tox * Add coverage configuration * Linting * Define supported versions * Fix travis notification token --- .coveragerc | 29 +++++++++++++++++++++++++ .travis.yml | 28 ++++++++++++++++++++---- Makefile | 18 ++++++++++++++++ docs/README.md | 21 ++++++++++++++++++ setup.cfg | 6 ++++-- setup.py | 16 +++++++------- tests/test_blocks.py | 4 +--- tests/test_widget.py | 4 ++-- tests/testapp/core/fixtures/.gitkeep | 0 tox.ini | 32 ++++++++++++++++++++++++++++ wagtailmodelchoosers/views.py | 12 ++++++----- wagtailmodelchoosers/widgets.py | 3 ++- 12 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 .coveragerc create mode 100644 docs/README.md create mode 100644 tests/testapp/core/fixtures/.gitkeep create mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..9aeb401 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,29 @@ +# .coveragerc to control coverage.py +[run] +branch = True + +source = ./wagtailmodelchoosers + +[report] +# Regexes for lines to exclude from consideration +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + # Don't complain about missing debug-only code: + def __repr__ + if self\.debug + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + return NotImplemented + + # Don't complain if non-runnable code isn't run: + if 0: + if __name__ == .__main__.: + +ignore_errors = True + +[html] +directory = coverage_html_report diff --git a/.travis.yml b/.travis.yml index ab24a7f..f3ea52e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,14 +5,34 @@ cache: directories: - node_modules - ".tox" +matrix: + # See `Which version combinations to include in Travis test matrix?` in `/docs/README.md`. + include: + - env: TOXENV=py34-dj111-wt113 + python: 3.4 + - env: TOXENV=py35-dj111-wt113 + python: 3.5 + - env: TOXENV=py36-dj111-wt112 + python: 3.6 + - env: TOXENV=py36-dj111-wt113 + python: 3.6 + # - env: TOXENV=py36-dj111-wt2b + # python: 3.6 + # - env: TOXENV=py36-dj2-wt2b + # python: 3.6 install: - nvm install - npm install +- pip install tox coveralls +- gem install coveralls-lcov script: -- npm run lint -- make dist +- make test-ci +after_success: +# This is ran on all build, but the coverage is only fully calculated in one. +# Convert JS LCOV report to Coveralls JSON, merge and send. +- coveralls-lcov -v -n coverage/lcov.info > js_coverage.json +- coveralls --merge=js_coverage.json notifications: email: false slack: - rooms: - secure: ECApgbjlDLJYxMSMKo40PJj8nG5BesJXa5GsreQ5h6ursJ5elTs8RugJa3IvPw7fc71RJUH1Hv/g0KMpanlGT7o+jc/V18Ts4rDbIcAlbtlYRFLfcVeisIWoGMIyuerraPTKIRmDpiBGc2ZkuF2JWDSExMQZ3q+cQ2wpUZB8eCOF6erSUhxEqk7QUremmzMy5kSTlyfsIgmRuz1aIIed3Aa6dbsudgHvbIkvmWvE22vvfD1TTy+cDHsLtkJ9N59HIlxg6Z5G8jlP+aKeiUxiSU1TvofleNcsgyZhZZwVhTop4iuYA/i4fKof3fWbR1v98xKfgoigZtNmFvTyegK1SXuawiavgUkOxo0ovW7qPi2Q1wCdTPmyemIymzA0KpkyzYjw5T+Xzb56KNzj2Pi+vKBrMiBqQDX/+h8RGoosF+9KpV3tuL85/y+RhuYrFVGPUR3xN+gs7Y0NnjEKfotdAEhsPXYhXus3Jk7cxUBecHDIY0+OQ5Bmc2DVr7amMrfHZyPnyPflxWPketF05+eSstH5NX8phmgwtMO1YDrIOuJJn7lq6XrlNOc86otJeTp4YFqDAAriq/ZC59rcOhTYeM+U6AS1NfjhNaNz8SwR1tmbPvyL9BEjNkrh5zB2Gl4JoM8tazkX+EltzMQ7T1x0nUtdvRrXeoL+08l+VrvoMo4= + secure: pxW/lXkUqypBnahEyx7RTTtA8NLS/OG3M7f3ZRsWij7g6z55eIAwIwOMXh+iRYF4Ez0J7OK21Fy31WyUNslTaXXj9HVBq3cjeqHLYo1K3VwyPVpgo+JB7OQrzKbJ3abBxdU41bjN7sJKoKCxGDYv6BjuOIWMAgjpJDgvq3XCNi0pGb2Tph1AgOzVM+QabXEIn4cNhJrpSyKcWoUEpV0cxNxqsU5X1n2XS+Hd+6sUGjrVVPrZsIK4InSx28N6i0xFdN4vnsk2Zy1VJYymJbDd3REsj/VsUPp/SJRP3bsJ9S8Xy1LGkwjiotlICQu51/sUz9wVBG67y/aK8e4qskcOnfaZsNBBJbeHHTx6REsl2XmuQO1Lg/unTzT+PQgjpNWscaOSNgVKhCP9v65E6z6VZNuEEfZECo6OAvzQXqwVWIQt+ATGrvJv8SCx0cM5U247Dwd2MSyOtmteDgXy38XoAta/1uEE09U9QogopntnvuLPiJEHAssGatEgejcP7KmDpE6uv6J9xAU35gBdVubDhkwkssfwzNR/hntNrjmiOmvJs1UIU4KQo7GacB5oHyMPR4WZ+SoOCLNNO+2MvvkQ0lDTkwUsfaXoGpo6FkGzYoLAddrfzd8+tJKGOMkyYfAZtwBNi1H52Bg0D/4BGSzg2qhLpHOor1Bni+iLKjDX6QM= diff --git a/Makefile b/Makefile index 6b8f2ca..f64eb69 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,11 @@ help: ## See what commands are available. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36mmake %-15s\033[0m # %s\n", $$1, $$2}' +init: clean-pyc ## Install dependencies and initialise for development. + pip install -e .[testing,docs] -U + python ./tests/testapp/manage.py migrate --noinput + # python ./tests/testapp/manage.py loaddata test_data + clean-pyc: ## Remove Python file artifacts. find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + @@ -12,9 +17,22 @@ clean-pyc: ## Remove Python file artifacts. start: ## Starts the development server. python ./tests/testapp/manage.py runserver +lint: ## Lint the project. + flake8 wagtailmodelchoosers tests setup.py + isort --check-only --diff --recursive wagtailmodelchoosers tests setup.py + test: ## Test the project. python ./runtests.py +test-coverage: ## Run the tests while generating test coverage data. + coverage run ./runtests.py && coverage report && coverage html + +test-ci: ## Continuous integration test suite. + tox + +update-test-fixture: ## Update test fixture from the db. + python ./tests/testapp/manage.py dumpdata --indent=4 -e contenttypes -e auth.permission -e auth.group -e sessions -e wagtailcore.site -e wagtailcore.pagerevision -e wagtailcore.grouppagepermission -e wagtailimages.rendition -e wagtailcore.collection -e wagtailcore.groupcollectionpermission > tests/testapp/core/fixtures/test_data.json + dist: ## Compile the JS and CSS for release. npm run dist diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..f95bff9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,21 @@ +# Documentation + +## Browser support + +We align our browser support targets with that of Wagtail. Have a look at the [official documentation](http://docs.wagtail.io/en/latest/contributing/developing.html). + +## Python/Django/Wagtail support + +Python versions as defined in `setup.py` classifiers. + +Wagtail versions as [supported](http://docs.wagtail.io/en/latest/releases/upgrading.html) by Wagtail (LTS, current and current-1). + +Django/Wagtail combinations as [supported](http://docs.wagtail.io/en/latest/releases/upgrading.html#compatible-django-python-versions) by Wagtail (for the Wagtail versions as defined above). + +### Which version combinations to include in Travis test matrix? + +In order to keep for CI build time from growing out of control, not all Python/Django/Wagtail combinations will be tested. + +Test as follow: +- All supported Django/Wagtail combinations with the latest supported Python version of the `3.x` series. +- The latest supported Django/Wagtail combination for the remaining Python versions. diff --git a/setup.cfg b/setup.cfg index 7c972e6..63902b4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,5 +6,7 @@ exclude = [isort] line_length=100 -multi_line_output=4 -# add_imports=from __future__ import absolute_import,from __future__ import unicode_literals +multi_line_output=3 +include_trailing_comma=True +skip= + migrations, diff --git a/setup.py b/setup.py index c71b517..e179e31 100644 --- a/setup.py +++ b/setup.py @@ -19,12 +19,13 @@ # Testing dependencies testing_extras = [ # Required for running the tests - 'tox>=2.3.1', + 'tox>=2.3.1,<2.4', # For coverage and PEP8 linting - 'coverage>=4.1.0', - 'flake8>=3.2.0', - 'isort>=4.2.5', + 'coverage>=4.1.0,<4.2', + 'flake8>=3.2.0,<3.3', + 'flake8-colors>=0.1.6,<1', + 'isort==4.2.5', ] # Documentation dependencies @@ -52,11 +53,10 @@ 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', - # 'Programming Language :: Python :: 2', - # 'Programming Language :: Python :: 2.7', - # 'Programming Language :: Python :: 3', - # 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: Site Management', diff --git a/tests/test_blocks.py b/tests/test_blocks.py index fe73bca..164e943 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -1,12 +1,10 @@ from __future__ import absolute_import, unicode_literals from django.test import TestCase, override_settings - from wagtail.wagtailcore.models import Page -from wagtailmodelchoosers import blocks -from wagtailmodelchoosers import widgets from core.models import SimplePage +from wagtailmodelchoosers import blocks, widgets TEST_MODEL_CHOOSERS_OPTIONS = { 'core_page': { diff --git a/tests/test_widget.py b/tests/test_widget.py index 2aaa239..6e614bb 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -1,12 +1,12 @@ from __future__ import absolute_import, unicode_literals import uuid -from django.test import TestCase +from django.test import TestCase from wagtail.wagtailcore.models import Page -from wagtailmodelchoosers import widgets from core.models import SimplePage +from wagtailmodelchoosers import widgets class TestModelChooserWidget(TestCase): diff --git a/tests/testapp/core/fixtures/.gitkeep b/tests/testapp/core/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..7f43c46 --- /dev/null +++ b/tox.ini @@ -0,0 +1,32 @@ +# Tox (http://tox.testrun.org/) is a tool for running tests +# in multiple virtualenvs. This configuration file will run the +# test suite on all supported python versions. To use it, "pip install tox" +# and then run "tox" from this directory. + +[tox] +skipsdist = True +usedevelop = True +envlist = + py{34,35,36}-dj{111}-wt{112,113} + # py{34,35,36}-dj{111,2}-wt{2b} + +[testenv] +install_command = pip install -e ".[testing]" -U {opts} {packages} +whitelist_externals = + make + +basepython = + py34: python3.4 + py35: python3.5 + py36: python3.6 + +deps = + dj111: Django>=1.11,<2.0 + # dj2: Django>=2.0,<2.1 + wt112: wagtail>=1.12,<1.13 + wt113: wagtail>=1.13,<1.14 + # wt2b: wagtail==2.0b1 + +commands = + make lint + make test-coverage diff --git a/wagtailmodelchoosers/views.py b/wagtailmodelchoosers/views.py index f94e65b..8eb5337 100644 --- a/wagtailmodelchoosers/views.py +++ b/wagtailmodelchoosers/views.py @@ -1,8 +1,6 @@ -from django.apps import apps -from django.db.models import Q, CharField - import requests - +from django.apps import apps +from django.db.models import CharField, Q from rest_framework import filters, serializers from rest_framework.authentication import BasicAuthentication, SessionAuthentication from rest_framework.mixins import ListModelMixin @@ -11,7 +9,11 @@ from rest_framework.viewsets import GenericViewSet, ViewSet from wagtailmodelchoosers.paginators import GenericModelPaginator -from wagtailmodelchoosers.utils import get_chooser_options, get_query_keys_map, get_response_keys_map +from wagtailmodelchoosers.utils import ( + get_chooser_options, + get_query_keys_map, + get_response_keys_map, +) class ModelView(ListModelMixin, GenericViewSet): diff --git a/wagtailmodelchoosers/widgets.py b/wagtailmodelchoosers/widgets.py index 2535777..03fccf1 100644 --- a/wagtailmodelchoosers/widgets.py +++ b/wagtailmodelchoosers/widgets.py @@ -187,7 +187,8 @@ def get_js_init_data(self, id_, name, value): def render_js_init(self, id_, name, value): data = self.get_js_init_data(id_, name, value) - return 'wagtailModelChoosers.initRemoteModelChooser({id_}, {data})'.format(id_=json.dumps(id_), data=json.dumps(data)) + return 'wagtailModelChoosers.initRemoteModelChooser({id_}, {data})'.format( + id_=json.dumps(id_), data=json.dumps(data)) def render_html(self, name, value, attrs): context = {