A .coveragerc => .coveragerc +2 -0
@@ 0,0 1,2 @@
+[run]
+omit = */tests/*
M Makefile => Makefile +1 -1
@@ 27,7 27,7 @@ lint:
pep8 wiki
test:
- ./runtests.py
+ pytest
test-all:
tox
M pytest.ini => pytest.ini +1 -0
@@ 3,3 3,4 @@ django_find_project = false
python_files=test_*.py
testpaths=wiki
norecursedirs=testproject .svn _build tmp* dist *.egg-info
+DJANGO_SETTINGS_MODULE=wiki.tests.settings
M setup.py => setup.py +5 -45
@@ 3,8 3,6 @@
from __future__ import absolute_import, unicode_literals
import os
-from sys import version_info as PYTHON_VERSION
-
from setuptools import find_packages, setup
from wiki import __version__
@@ 14,8 12,6 @@ from wiki import __version__
# Used for the long_description. It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw
# string in below ...
-
-
def get_path(fname):
return os.path.join(os.path.dirname(__file__), fname)
@@ 25,52 21,16 @@ def read(fname):
requirements = [
- "Django>=1.5",
+ "Django>=1.8",
"Pillow",
"django-nyt>=0.9.7.2,<1.0",
"six",
+ "django-mptt>=0.8.6,<0.9",
+ "django-sekizai>=0.10",
+ "sorl-thumbnail>=12,<13",
+ "Markdown>=2.6,<2.7",
]
-
-# Requirements that depend on Django version: South and sorl-thumbnail
-try:
- from django import VERSION as DJANGO_VERSION
-except ImportError:
- # No Django so assuming that one will get installed, but we don't know which
- # one.
- # We will assume it's a very recent one and base the requirements on that...
- requirements.append("sorl-thumbnail>=12")
- # 0.6.1 broken: https://github.com/django-mptt/django-mptt/issues/316
- requirements.append("django-mptt>=0.8")
- requirements.append("django-sekizai>=0.9")
-else:
- if DJANGO_VERSION < (1, 7):
- requirements.append("South>=1.0.1")
- requirements.append("django-mptt>=0.7.1,<0.8")
- requirements.append("django-sekizai<0.9")
- elif DJANGO_VERSION < (1, 8):
- # Fixes
- # AttributeError: 'URLPath' object has no attribute 'get_deferred_fields'
- requirements.append("django-mptt>=0.7.1,<0.8")
- requirements.append("django-sekizai>=0.9")
- else:
- # Latest django-mptt only works for Django 1.8+
- requirements.append("django-mptt>=0.8.6,<0.9")
- requirements.append("django-sekizai>=0.9")
- if DJANGO_VERSION < (1, 5):
- # For Django 1.4, use sorl-thumbnail<11.12.1:
- # https://github.com/mariocesar/sorl-thumbnail/issues/255
- requirements.append("sorl-thumbnail<11.12.1")
- else:
- requirements.append("sorl-thumbnail>=12,<13")
-
-if PYTHON_VERSION < (2, 7):
- # For Python 2.6, use Markdown<2.5.0, see
- # https://github.com/waylan/Python-Markdown/issues/349
- requirements.append("Markdown>2.2.0,<2.5.0")
-else:
- requirements.append("Markdown>2.2.0,<2.7")
-
packages = find_packages()
M testproject/testproject/settings/base.py => testproject/testproject/settings/base.py +2 -8
@@ 13,7 13,6 @@ from __future__ import unicode_literals
import os
-from django import VERSION
from django.core.urlresolvers import reverse_lazy
@@ 32,9 31,6 @@ DEBUG = False
ALLOWED_HOSTS = []
-# Application definition
-
-
INSTALLED_APPS = [
'django.contrib.humanize',
'django.contrib.auth',
@@ 57,10 53,8 @@ INSTALLED_APPS = [
'wiki.plugins.notifications',
'mptt',
]
-if VERSION < (1, 7):
- INSTALLED_APPS.append('south')
-else:
- TEST_RUNNER = 'django.test.runner.DiscoverRunner'
+
+TEST_RUNNER = 'django.test.runner.DiscoverRunner'
MIDDLEWARE_CLASSES = [
M tox.ini => tox.ini +8 -5
@@ 5,24 5,27 @@ envlist = {py27,py34,py35}-django{18,19,110}
[testenv]
commands =
- {envbindir}/coverage run --source=wiki runtests.py
+ {envbindir}/pytest --cov=wiki --cov-config .coveragerc
+
+usedevelop = true
deps =
coverage
pytest
+ pytest-django
+ pytest-cov
Pillow==2.3.0
django-classy-tags==0.4
six>=1.9
mock>=2.0
- Markdown==2.6.5
+ Markdown==2.6.7
django_nyt==0.9.8
django18: Django==1.8.2
django19: Django==1.9
- django110: Django==1.10
+ django110: Django==1.10.2
django{18,19,110}: django-mptt==0.8.6
- django{18,19,110}: django-sekizai==0.9.0
+ django{18,19,110}: django-sekizai==0.10.0
django{18,19,110}: sorl-thumbnail==12.3
- django{18,19,110}: pytest-django>=3
basepython =
py27: python2.7
M wiki/models/__init__.py => wiki/models/__init__.py +19 -14
@@ 1,17 1,16 @@
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import unicode_literals
-# -*- coding: utf-8 -*-
-from django import VERSION
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured
-import warnings
-from six import string_types
+from six import string_types, text_type
# TODO: Don't use wildcards
from .article import * # noqa
from .pluginbase import * # noqa
from .urlpath import * # noqa
+from django.utils.functional import lazy
# TODO: Should the below stuff be executed a more logical place?
# Follow Django's default_settings.py / settings.py pattern and put these
@@ 64,16 63,6 @@ if 'django_notify' in django_settings.INSTALLED_APPS:
raise ImproperlyConfigured(
'django-wiki: You need to change from django_notify to django_nyt in INSTALLED_APPS and your urlconfig.')
-######################
-# Warnings
-######################
-
-
-if VERSION < (1, 7):
- if 'south' not in django_settings.INSTALLED_APPS:
- warnings.warn(
- "django-wiki: No south in your INSTALLED_APPS. This is highly discouraged.")
-
from django.core import urlresolvers # noqa
@@ 108,4 97,20 @@ def reverse(*args, **kwargs):
return url
# Now we redefine reverse method
+reverse_lazy = lazy(reverse, text_type)
urlresolvers.reverse = reverse
+urlresolvers.reverse_lazy = reverse_lazy
+
+# Patch up other locations of the reverse function
+try:
+ from django.urls import base
+ from django import urls
+ from django import shortcuts
+ base.reverse = reverse
+ base.reverse_lazy = reverse_lazy
+ urls.reverse = reverse
+ urls.reverse_lazy = reverse_lazy
+ shortcuts.reverse = reverse
+ urls.reverse_lazy = reverse_lazy
+except ImportError:
+ pass
M wiki/plugins/attachments/urls.py => wiki/plugins/attachments/urls.py +1 -5
@@ 1,7 1,6 @@
from __future__ import absolute_import, unicode_literals
-from django import VERSION as DJANGO_VERSION
-from django.conf.urls import patterns, url
+from django.conf.urls import url
from wiki.plugins.attachments import views
urlpatterns = [
@@ 33,6 32,3 @@ urlpatterns = [
views.AttachmentChangeRevisionView.as_view(),
name='attachments_revision_change'),
]
-
-if DJANGO_VERSION < (1, 8):
- urlpatterns = patterns('', *urlpatterns)
R runtests.py => wiki/tests/settings.py +57 -109
@@ 1,111 1,59 @@
-#!/usr/bin/env python
-from __future__ import absolute_import, unicode_literals
-
-import sys
-
-import django
-import pytest
-from django.conf import settings
-
-# Run py.tests
-# Compatibility testing patches on the py-moneyed
-
-settings_dict = dict(
- DEBUG=True,
- AUTH_USER_MODEL='testdata.CustomUser',
- WIKI_GROUP_MODEL='testdata.CustomGroup',
- DATABASES={
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- }
+# Database
+# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ }
+}
+
+DEBUG = True
+AUTH_USER_MODEL = 'testdata.CustomUser'
+WIKI_GROUP_MODEL = 'testdata.CustomGroup'
+SITE_ID = 1
+ROOT_URLCONF = 'wiki.tests.testdata.urls'
+INSTALLED_APPS = [
+ 'wiki.tests.testdata',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.admin',
+ 'django.contrib.humanize',
+ 'django.contrib.sites',
+ 'django_nyt',
+ 'mptt',
+ 'sekizai',
+ 'sorl.thumbnail',
+ 'wiki',
+ 'wiki.plugins.attachments',
+ 'wiki.plugins.notifications',
+ 'wiki.plugins.images',
+ 'wiki.plugins.macros',
+]
+MIDDLEWARE_CLASSES = [
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+]
+USE_TZ = True
+SECRET_KEY = 'b^fv_)t39h%9p40)fnkfblo##jkr!$0)lkp6bpy!fi*f$4*92!'
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ "django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media",
+ "django.template.context_processors.request",
+ "django.template.context_processors.static",
+ "django.template.context_processors.tz",
+ "django.contrib.messages.context_processors.messages",
+ "sekizai.context_processors.sekizai",
+ ]
+ },
},
- SITE_ID=1,
- ROOT_URLCONF='wiki.tests.testdata.urls',
- INSTALLED_APPS=[
- 'wiki.tests.testdata',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.admin',
- 'django.contrib.humanize',
- 'django.contrib.sites',
- 'django_nyt',
- 'mptt',
- 'sekizai',
- 'sorl.thumbnail',
- 'wiki',
- 'wiki.plugins.attachments',
- 'wiki.plugins.notifications',
- 'wiki.plugins.images',
- 'wiki.plugins.macros',
- ] + (['south'] if django.VERSION < (1, 7) else []),
- MIDDLEWARE_CLASSES=[
- 'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- ],
- USE_TZ=True,
- SOUTH_TESTS_MIGRATE=True,
- SECRET_KEY='b^fv_)t39h%9p40)fnkfblo##jkr!$0)lkp6bpy!fi*f$4*92!',
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = [
- "django.contrib.auth.context_processors.auth",
- "django.template.context_processors.debug",
- "django.template.context_processors.i18n",
- "django.template.context_processors.media",
- "django.template.context_processors.request",
- "django.template.context_processors.static",
- "django.template.context_processors.tz",
- "django.contrib.messages.context_processors.messages",
- "sekizai.context_processors.sekizai",
]
-
-if django.VERSION < (1, 8):
- settings_dict.update(dict(
- TEMPLATE_CONTEXT_PROCESSORS=[p.replace('django.template.context_processors',
- 'django.core.context_processors')
- for p in TEMPLATE_CONTEXT_PROCESSORS]
- ))
-else:
- settings_dict.update(dict(
- TEMPLATES=[
- {
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': TEMPLATE_CONTEXT_PROCESSORS
- },
- },
- ]
- ))
-
-settings.configure(**settings_dict)
-
-
-# If you use South for migrations, uncomment this to monkeypatch
-# syncdb to get migrations to run.
-if django.VERSION < (1, 7):
- from south.management.commands import patch_for_test_db_setup
- patch_for_test_db_setup()
-
-argv = [sys.argv[0], "test", "--traceback"]
-
-# python setup.py test calls script with just 'test'
-if len(sys.argv) == 1 or sys.argv[1] == 'test':
- # Nothing following 'runtests.py':
- if django.VERSION < (1, 6):
- argv.extend(["wiki", "attachments"])
- else:
- argv.extend(["wiki.tests", "wiki.plugins.attachments.tests"])
-else:
- # Allow tests to be specified:
- argv.extend(sys.argv[1:])
-
-
-failures = pytest.main()
-
-if failures:
- sys.exit(failures)
M wiki/tests/test_urls.py => wiki/tests/test_urls.py +1 -7
@@ 1,7 1,7 @@
from __future__ import absolute_import, unicode_literals
from django import VERSION as DJANGO_VERSION
-from django.conf.urls import patterns, url
+from django.conf.urls import url
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.test.testcases import TestCase
@@ 14,9 14,6 @@ from wiki.urls import WikiURLPatterns
User = get_user_model()
-
-
-
class WikiCustomUrlPatterns(WikiURLPatterns):
def get_article_urls(self):
@@ 41,9 38,6 @@ urlpatterns = [
url(r'', get_wiki_pattern(url_config_class=WikiCustomUrlPatterns))
]
-if DJANGO_VERSION < (1, 8):
- urlpatterns = patterns('', *urlpatterns)
-
@wiki_override_settings(WIKI_URL_CONFIG_CLASS='wiki.tests.test_models.WikiCustomUrlPatterns',
ROOT_URLCONF='wiki.tests.test_urls')
M wiki/tests/test_views.py => wiki/tests/test_views.py +1 -1
@@ 3,7 3,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import pprint
from django.contrib.auth import authenticate
-from django.core.urlresolvers import reverse
+from wiki.models import reverse
from .base import ArticleWebTestBase, WebTestBase
M wiki/tests/testdata/urls.py => wiki/tests/testdata/urls.py +1 -5
@@ 1,8 1,7 @@
from __future__ import absolute_import, unicode_literals
-from django import VERSION as DJANGO_VERSION
from django.conf import settings
-from django.conf.urls import include, patterns, url
+from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django_nyt.urls import get_pattern as get_notify_pattern
@@ 28,6 27,3 @@ urlpatterns += [
url(r'^notify/', get_notify_pattern()),
url(r'', get_wiki_pattern())
]
-
-if DJANGO_VERSION < (1, 8):
- urlpatterns = patterns('', *urlpatterns)
M wiki/urls.py => wiki/urls.py +39 -44
@@ 1,7 1,6 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
-from django import VERSION as DJANGO_VERSION
from django.conf.urls import include, url
from wiki.conf import settings
from wiki.core.plugins import registry
@@ 62,20 61,20 @@ class WikiURLPatterns(object):
def get_root_urls(self):
urlpatterns = [
- url('^$',
+ url(r'^$',
self.article_view_class.as_view(),
name='root',
kwargs={'path': ''}),
- url('^create-root/$',
+ url(r'^create-root/$',
article.CreateRootView.as_view(),
name='root_create'),
- url('^missing-root/$',
+ url(r'^missing-root/$',
article.MissingRootView.as_view(),
name='root_missing'),
- url('^_search/$',
+ url(r'^_search/$',
get_class_from_str(self.search_view_class).as_view(),
name='search'),
- url('^_revision/diff/(?P<revision_id>\d+)/$',
+ url(r'^_revision/diff/(?P<revision_id>\d+)/$',
self.article_diff_view,
name='diff'),
]
@@ 92,16 91,16 @@ class WikiURLPatterns(object):
def get_accounts_urls(self):
if settings.ACCOUNT_HANDLING:
urlpatterns = [
- url('^_accounts/sign-up/$',
+ url(r'^_accounts/sign-up/$',
self.signup_view_class.as_view(),
name='signup'),
- url('^_accounts/logout/$',
+ url(r'^_accounts/logout/$',
self.logout_view_class.as_view(),
name='logout'),
- url('^_accounts/login/$',
+ url(r'^_accounts/login/$',
self.login_view_class.as_view(),
name='login'),
- url('^_accounts/settings/$',
+ url(r'^_accounts/settings/$',
self.profile_update_view_class.as_view(),
name='profile_update'),
]
@@ 114,14 113,14 @@ class WikiURLPatterns(object):
# This one doesn't work because it don't know
# where to redirect after...
url(
- '^_revision/change/(?P<article_id>\d+)/(?P<revision_id>\d+)/$',
+ r'^_revision/change/(?P<article_id>\d+)/(?P<revision_id>\d+)/$',
self.revision_change_view_class.as_view(),
name='change_revision'),
- url('^_revision/preview/(?P<article_id>\d+)/$',
+ url(r'^_revision/preview/(?P<article_id>\d+)/$',
self.article_preview_view_class.as_view(),
name='preview_revision'),
url(
- '^_revision/merge/(?P<article_id>\d+)/(?P<revision_id>\d+)/preview/$',
+ r'^_revision/merge/(?P<article_id>\d+)/(?P<revision_id>\d+)/preview/$',
self.revision_merge_view,
name='merge_revision_preview',
kwargs={
@@ 132,39 131,39 @@ class WikiURLPatterns(object):
def get_article_urls(self):
urlpatterns = [
# Paths decided by article_ids
- url('^(?P<article_id>\d+)/$',
+ url(r'^(?P<article_id>\d+)/$',
self.article_view_class.as_view(),
name='get'),
- url('^(?P<article_id>\d+)/delete/$',
+ url(r'^(?P<article_id>\d+)/delete/$',
self.article_delete_view_class.as_view(),
name='delete'),
- url('^(?P<article_id>\d+)/deleted/$',
+ url(r'^(?P<article_id>\d+)/deleted/$',
self.article_deleted_view_class.as_view(),
name='deleted'),
- url('^(?P<article_id>\d+)/edit/$',
+ url(r'^(?P<article_id>\d+)/edit/$',
self.article_edit_view_class.as_view(),
name='edit'),
- url('^(?P<article_id>\d+)/preview/$',
+ url(r'^(?P<article_id>\d+)/preview/$',
self.article_preview_view_class.as_view(),
name='preview'),
- url('^(?P<article_id>\d+)/history/$',
+ url(r'^(?P<article_id>\d+)/history/$',
self.article_history_view_class.as_view(),
name='history'),
- url('^(?P<article_id>\d+)/settings/$',
+ url(r'^(?P<article_id>\d+)/settings/$',
self.article_settings_view_class.as_view(),
name='settings'),
- url('^(?P<article_id>\d+)/source/$',
+ url(r'^(?P<article_id>\d+)/source/$',
self.article_source_view_class.as_view(),
name='source'),
url(
- '^(?P<article_id>\d+)/revision/change/(?P<revision_id>\d+)/$',
+ r'^(?P<article_id>\d+)/revision/change/(?P<revision_id>\d+)/$',
self.revision_change_view_class.as_view(),
name='change_revision'),
url(
- '^(?P<article_id>\d+)/revision/merge/(?P<revision_id>\d+)/$',
+ r'^(?P<article_id>\d+)/revision/merge/(?P<revision_id>\d+)/$',
self.revision_merge_view,
name='merge_revision'),
- url('^(?P<article_id>\d+)/plugin/(?P<slug>\w+)/$',
+ url(r'^(?P<article_id>\d+)/plugin/(?P<slug>\w+)/$',
self.article_plugin_view_class.as_view(),
name='plugin'),
]
@@ 173,46 172,46 @@ class WikiURLPatterns(object):
def get_article_path_urls(self):
urlpatterns = [
# Paths decided by URLs
- url('^(?P<path>.+/|)_create/$',
+ url(r'^(?P<path>.+/|)_create/$',
self.article_create_view_class.as_view(),
name='create'),
- url('^(?P<path>.+/|)_delete/$',
+ url(r'^(?P<path>.+/|)_delete/$',
self.article_delete_view_class.as_view(),
name='delete'),
- url('^(?P<path>.+/|)_deleted/$',
+ url(r'^(?P<path>.+/|)_deleted/$',
self.article_deleted_view_class.as_view(),
name='deleted'),
- url('^(?P<path>.+/|)_edit/$',
+ url(r'^(?P<path>.+/|)_edit/$',
self.article_edit_view_class.as_view(),
name='edit'),
- url('^(?P<path>.+/|)_preview/$',
+ url(r'^(?P<path>.+/|)_preview/$',
self.article_preview_view_class.as_view(),
name='preview'),
- url('^(?P<path>.+/|)_history/$',
+ url(r'^(?P<path>.+/|)_history/$',
self.article_history_view_class.as_view(),
name='history'),
- url('^(?P<path>.+/|)_dir/$',
+ url(r'^(?P<path>.+/|)_dir/$',
self.article_dir_view_class.as_view(),
name='dir'),
- url('^(?P<path>.+/|)_settings/$',
+ url(r'^(?P<path>.+/|)_settings/$',
self.article_settings_view_class.as_view(),
name='settings'),
- url('^(?P<path>.+/|)_source/$',
+ url(r'^(?P<path>.+/|)_source/$',
self.article_source_view_class.as_view(),
name='source'),
url(
- '^(?P<path>.+/|)_revision/change/(?P<revision_id>\d+)/$',
+ r'^(?P<path>.+/|)_revision/change/(?P<revision_id>\d+)/$',
self.revision_change_view_class.as_view(),
name='change_revision'),
url(
- '^(?P<path>.+/|)_revision/merge/(?P<revision_id>\d+)/$',
+ r'^(?P<path>.+/|)_revision/merge/(?P<revision_id>\d+)/$',
self.revision_merge_view,
name='merge_revision'),
- url('^(?P<path>.+/|)_plugin/(?P<slug>\w+)/$',
+ url(r'^(?P<path>.+/|)_plugin/(?P<slug>\w+)/$',
self.article_plugin_view_class.as_view(),
name='plugin'),
# This should always go last!
- url('^(?P<path>.+/|)$',
+ url(r'^(?P<path>.+/|)$',
self.article_view_class.as_view(),
name='get'),
]
@@ 226,14 225,14 @@ class WikiURLPatterns(object):
if slug:
article_urlpatterns = plugin.urlpatterns.get('article', [])
urlpatterns += [
- url('^(?P<article_id>\d+)/plugin/' + slug + '/',
+ url(r'^(?P<article_id>\d+)/plugin/' + slug + '/',
include(article_urlpatterns)),
- url('^(?P<path>.+/|)_plugin/' + slug + '/',
+ url(r'^(?P<path>.+/|)_plugin/' + slug + '/',
include(article_urlpatterns)),
]
root_urlpatterns = plugin.urlpatterns.get('root', [])
urlpatterns += [
- url('^_plugin/' + slug + '/', include(root_urlpatterns)),
+ url(r'^_plugin/' + slug + '/', include(root_urlpatterns)),
]
return urlpatterns
@@ 252,10 251,6 @@ def get_pattern(app_name="wiki", namespace="wiki", url_config_class=None):
url_config_class = get_class_from_str(url_config_classname)
urlpatterns = url_config_class().get_urls()
- if DJANGO_VERSION < (1, 8):
- from django.conf.urls import patterns
- urlpatterns = patterns('', *urlpatterns)
-
return urlpatterns, app_name, namespace