summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/admin_validation/tests.py80
-rw-r--r--tests/base/models.py4
-rw-r--r--tests/cache/tests.py36
-rw-r--r--tests/csrf_tests/tests.py51
-rw-r--r--tests/defaultfilters/tests.py68
-rw-r--r--tests/fixtures/tests.py23
-rw-r--r--tests/fixtures_model_package/tests.py6
-rw-r--r--tests/fixtures_regress/tests.py16
-rw-r--r--tests/forms_tests/tests/test_extra.py8
-rw-r--r--tests/forms_tests/tests/test_fields.py9
-rw-r--r--tests/generic_views/test_base.py33
-rw-r--r--tests/generic_views/views.py16
-rw-r--r--tests/i18n/__init__.py17
-rw-r--r--tests/i18n/contenttypes/tests.py4
-rw-r--r--tests/i18n/tests.py97
-rw-r--r--tests/invalid_models/invalid_models/models.py4
-rw-r--r--tests/middleware/tests.py4
-rw-r--r--tests/model_forms_regress/tests.py35
-rw-r--r--tests/model_formsets_regress/tests.py7
-rw-r--r--tests/model_validation/__init__.py (renamed from tests/special_headers/__init__.py)0
-rw-r--r--tests/model_validation/models.py27
-rw-r--r--tests/model_validation/tests.py13
-rw-r--r--tests/modeladmin/tests.py239
-rw-r--r--tests/requests/tests.py14
-rw-r--r--tests/special_headers/fixtures/data.xml20
-rw-r--r--tests/special_headers/models.py5
-rw-r--r--tests/special_headers/templates/special_headers/article_detail.html1
-rw-r--r--tests/special_headers/tests.py62
-rw-r--r--tests/special_headers/urls.py13
-rw-r--r--tests/special_headers/views.py21
-rw-r--r--tests/template_tests/filters.py59
-rw-r--r--tests/transactions/tests.py14
-rw-r--r--tests/transactions_regress/tests.py4
-rw-r--r--tests/utils_tests/test_timesince.py71
-rw-r--r--tests/view_tests/tests/test_debug.py21
35 files changed, 626 insertions, 476 deletions
diff --git a/tests/admin_validation/tests.py b/tests/admin_validation/tests.py
index 16f73c6390..5eee3e7105 100644
--- a/tests/admin_validation/tests.py
+++ b/tests/admin_validation/tests.py
@@ -2,7 +2,6 @@ from __future__ import absolute_import
from django import forms
from django.contrib import admin
-from django.contrib.admin.validation import validate, validate_inline
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
@@ -38,13 +37,13 @@ class ValidationTestCase(TestCase):
"fields": ["title", "original_release"],
}),
]
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_custom_modelforms_with_fields_fieldsets(self):
"""
# Regression test for #8027: custom ModelForms with fields/fieldsets
"""
- validate(ValidFields, Song)
+ ValidFields.validate(Song)
def test_custom_get_form_with_fieldsets(self):
"""
@@ -52,7 +51,7 @@ class ValidationTestCase(TestCase):
is overridden.
Refs #19445.
"""
- validate(ValidFormFieldsets, Song)
+ ValidFormFieldsets.validate(Song)
def test_exclude_values(self):
"""
@@ -62,16 +61,16 @@ class ValidationTestCase(TestCase):
exclude = ('foo')
self.assertRaisesMessage(ImproperlyConfigured,
"'ExcludedFields1.exclude' must be a list or tuple.",
- validate,
- ExcludedFields1, Book)
+ ExcludedFields1.validate,
+ Book)
def test_exclude_duplicate_values(self):
class ExcludedFields2(admin.ModelAdmin):
exclude = ('name', 'name')
self.assertRaisesMessage(ImproperlyConfigured,
"There are duplicate field(s) in ExcludedFields2.exclude",
- validate,
- ExcludedFields2, Book)
+ ExcludedFields2.validate,
+ Book)
def test_exclude_in_inline(self):
class ExcludedFieldsInline(admin.TabularInline):
@@ -84,8 +83,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"'ExcludedFieldsInline.exclude' must be a list or tuple.",
- validate,
- ExcludedFieldsAlbumAdmin, Album)
+ ExcludedFieldsAlbumAdmin.validate,
+ Album)
def test_exclude_inline_model_admin(self):
"""
@@ -102,8 +101,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"SongInline cannot exclude the field 'album' - this is the foreign key to the parent model admin_validation.Album.",
- validate,
- AlbumAdmin, Album)
+ AlbumAdmin.validate,
+ Album)
def test_app_label_in_admin_validation(self):
"""
@@ -114,8 +113,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"'RawIdNonexistingAdmin.raw_id_fields' refers to field 'nonexisting' that is missing from model 'admin_validation.Album'.",
- validate,
- RawIdNonexistingAdmin, Album)
+ RawIdNonexistingAdmin.validate,
+ Album)
def test_fk_exclusion(self):
"""
@@ -127,28 +126,35 @@ class ValidationTestCase(TestCase):
model = TwoAlbumFKAndAnE
exclude = ("e",)
fk_name = "album1"
- validate_inline(TwoAlbumFKAndAnEInline, None, Album)
+ class MyAdmin(admin.ModelAdmin):
+ inlines = [TwoAlbumFKAndAnEInline]
+ MyAdmin.validate(Album)
+
def test_inline_self_validation(self):
class TwoAlbumFKAndAnEInline(admin.TabularInline):
model = TwoAlbumFKAndAnE
+ class MyAdmin(admin.ModelAdmin):
+ inlines = [TwoAlbumFKAndAnEInline]
self.assertRaisesMessage(Exception,
"<class 'admin_validation.models.TwoAlbumFKAndAnE'> has more than 1 ForeignKey to <class 'admin_validation.models.Album'>",
- validate_inline,
- TwoAlbumFKAndAnEInline, None, Album)
+ MyAdmin.validate, Album)
def test_inline_with_specified(self):
class TwoAlbumFKAndAnEInline(admin.TabularInline):
model = TwoAlbumFKAndAnE
fk_name = "album1"
- validate_inline(TwoAlbumFKAndAnEInline, None, Album)
+
+ class MyAdmin(admin.ModelAdmin):
+ inlines = [TwoAlbumFKAndAnEInline]
+ MyAdmin.validate(Album)
def test_readonly(self):
class SongAdmin(admin.ModelAdmin):
readonly_fields = ("title",)
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_readonly_on_method(self):
def my_function(obj):
@@ -157,7 +163,7 @@ class ValidationTestCase(TestCase):
class SongAdmin(admin.ModelAdmin):
readonly_fields = (my_function,)
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_readonly_on_modeladmin(self):
class SongAdmin(admin.ModelAdmin):
@@ -166,13 +172,13 @@ class ValidationTestCase(TestCase):
def readonly_method_on_modeladmin(self, obj):
pass
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_readonly_method_on_model(self):
class SongAdmin(admin.ModelAdmin):
readonly_fields = ("readonly_method_on_model",)
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_nonexistant_field(self):
class SongAdmin(admin.ModelAdmin):
@@ -180,8 +186,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"SongAdmin.readonly_fields[1], 'nonexistant' is not a callable or an attribute of 'SongAdmin' or found in the model 'Song'.",
- validate,
- SongAdmin, Song)
+ SongAdmin.validate,
+ Song)
def test_nonexistant_field_on_inline(self):
class CityInline(admin.TabularInline):
@@ -190,8 +196,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"CityInline.readonly_fields[0], 'i_dont_exist' is not a callable or an attribute of 'CityInline' or found in the model 'City'.",
- validate_inline,
- CityInline, None, State)
+ CityInline.validate,
+ City)
def test_extra(self):
class SongAdmin(admin.ModelAdmin):
@@ -199,13 +205,13 @@ class ValidationTestCase(TestCase):
if instance.title == "Born to Run":
return "Best Ever!"
return "Status unknown."
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_readonly_lambda(self):
class SongAdmin(admin.ModelAdmin):
readonly_fields = (lambda obj: "test",)
- validate(SongAdmin, Song)
+ SongAdmin.validate(Song)
def test_graceful_m2m_fail(self):
"""
@@ -219,8 +225,8 @@ class ValidationTestCase(TestCase):
self.assertRaisesMessage(ImproperlyConfigured,
"'BookAdmin.fields' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.",
- validate,
- BookAdmin, Book)
+ BookAdmin.validate,
+ Book)
def test_cannot_include_through(self):
class FieldsetBookAdmin(admin.ModelAdmin):
@@ -230,20 +236,20 @@ class ValidationTestCase(TestCase):
)
self.assertRaisesMessage(ImproperlyConfigured,
"'FieldsetBookAdmin.fieldsets[1][1]['fields']' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.",
- validate,
- FieldsetBookAdmin, Book)
+ FieldsetBookAdmin.validate,
+ Book)
def test_nested_fields(self):
class NestedFieldsAdmin(admin.ModelAdmin):
fields = ('price', ('name', 'subtitle'))
- validate(NestedFieldsAdmin, Book)
+ NestedFieldsAdmin.validate(Book)
def test_nested_fieldsets(self):
class NestedFieldsetAdmin(admin.ModelAdmin):
fieldsets = (
('Main', {'fields': ('price', ('name', 'subtitle'))}),
)
- validate(NestedFieldsetAdmin, Book)
+ NestedFieldsetAdmin.validate(Book)
def test_explicit_through_override(self):
"""
@@ -260,7 +266,7 @@ class ValidationTestCase(TestCase):
# If the through model is still a string (and hasn't been resolved to a model)
# the validation will fail.
- validate(BookAdmin, Book)
+ BookAdmin.validate(Book)
def test_non_model_fields(self):
"""
@@ -274,7 +280,7 @@ class ValidationTestCase(TestCase):
form = SongForm
fields = ['title', 'extra_data']
- validate(FieldsOnFormOnlyAdmin, Song)
+ FieldsOnFormOnlyAdmin.validate(Song)
def test_non_model_first_field(self):
"""
@@ -292,4 +298,4 @@ class ValidationTestCase(TestCase):
form = SongForm
fields = ['extra_data', 'title']
- validate(FieldsOnFormOnlyAdmin, Song)
+ FieldsOnFormOnlyAdmin.validate(Song)
diff --git a/tests/base/models.py b/tests/base/models.py
index bddb406820..d47ddcfd66 100644
--- a/tests/base/models.py
+++ b/tests/base/models.py
@@ -14,8 +14,10 @@ class CustomBaseModel(models.base.ModelBase):
class MyModel(six.with_metaclass(CustomBaseModel, models.Model)):
- """Model subclass with a custom base using six.with_metaclass."""
+ """Model subclass with a custom base using six.with_metaclass."""
+# This is done to ensure that for Python2 only, defining metaclasses
+# still does not fail to create the model.
if not six.PY3:
class MyModel(models.Model):
diff --git a/tests/cache/tests.py b/tests/cache/tests.py
index 00c51638b7..231a3bfb50 100644
--- a/tests/cache/tests.py
+++ b/tests/cache/tests.py
@@ -28,8 +28,8 @@ from django.middleware.cache import (FetchFromCacheMiddleware,
from django.template import Template
from django.template.response import TemplateResponse
from django.test import TestCase, TransactionTestCase, RequestFactory
-from django.test.utils import override_settings, six
-from django.utils import timezone, translation, unittest
+from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
+from django.utils import six, timezone, translation, unittest
from django.utils.cache import (patch_vary_headers, get_cache_key,
learn_cache_key, patch_cache_control, patch_response_headers)
from django.utils.encoding import force_text
@@ -441,6 +441,34 @@ class BaseCacheTests(object):
self.assertEqual(self.cache.get('key3'), 'sausage')
self.assertEqual(self.cache.get('key4'), 'lobster bisque')
+ def test_forever_timeout(self):
+ '''
+ Passing in None into timeout results in a value that is cached forever
+ '''
+ self.cache.set('key1', 'eggs', None)
+ self.assertEqual(self.cache.get('key1'), 'eggs')
+
+ self.cache.add('key2', 'ham', None)
+ self.assertEqual(self.cache.get('key2'), 'ham')
+
+ self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, None)
+ self.assertEqual(self.cache.get('key3'), 'sausage')
+ self.assertEqual(self.cache.get('key4'), 'lobster bisque')
+
+ def test_zero_timeout(self):
+ '''
+ Passing in None into timeout results in a value that is cached forever
+ '''
+ self.cache.set('key1', 'eggs', 0)
+ self.assertEqual(self.cache.get('key1'), None)
+
+ self.cache.add('key2', 'ham', 0)
+ self.assertEqual(self.cache.get('key2'), None)
+
+ self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 0)
+ self.assertEqual(self.cache.get('key3'), None)
+ self.assertEqual(self.cache.get('key4'), None)
+
def test_float_timeout(self):
# Make sure a timeout given as a float doesn't crash anything.
self.cache.set("key1", "spam", 100.2)
@@ -1564,9 +1592,10 @@ def hello_world_view(request, value):
},
},
)
-class CacheMiddlewareTest(TestCase):
+class CacheMiddlewareTest(IgnorePendingDeprecationWarningsMixin, TestCase):
def setUp(self):
+ super(CacheMiddlewareTest, self).setUp()
self.factory = RequestFactory()
self.default_cache = get_cache('default')
self.other_cache = get_cache('other')
@@ -1574,6 +1603,7 @@ class CacheMiddlewareTest(TestCase):
def tearDown(self):
self.default_cache.clear()
self.other_cache.clear()
+ super(CacheMiddlewareTest, self).tearDown()
def test_constructor(self):
"""
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
index b9e8cb5f75..841b24bb42 100644
--- a/tests/csrf_tests/tests.py
+++ b/tests/csrf_tests/tests.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+import logging
from django.conf import settings
from django.core.context_processors import csrf
@@ -78,18 +79,18 @@ class CsrfViewMiddlewareTest(TestCase):
def _check_token_present(self, response, csrf_id=None):
self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id))
- def test_process_view_token_too_long(self):
- """
- Check that if the token is longer than expected, it is ignored and
- a new token is created.
- """
- req = self._get_GET_no_csrf_cookie_request()
- req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 10000000
- CsrfViewMiddleware().process_view(req, token_view, (), {})
- resp = token_view(req)
- resp2 = CsrfViewMiddleware().process_response(req, resp)
- csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
- self.assertEqual(len(csrf_cookie.value), CSRF_KEY_LENGTH)
+ def test_process_view_token_too_long(self):
+ """
+ Check that if the token is longer than expected, it is ignored and
+ a new token is created.
+ """
+ req = self._get_GET_no_csrf_cookie_request()
+ req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 10000000
+ CsrfViewMiddleware().process_view(req, token_view, (), {})
+ resp = token_view(req)
+ resp2 = CsrfViewMiddleware().process_response(req, resp)
+ csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
+ self.assertEqual(len(csrf_cookie.value), CSRF_KEY_LENGTH)
def test_process_response_get_token_used(self):
"""
@@ -353,3 +354,29 @@ class CsrfViewMiddlewareTest(TestCase):
resp2 = CsrfViewMiddleware().process_response(req, resp)
self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False))
self.assertTrue('Cookie' in resp2.get('Vary',''))
+
+ def test_ensures_csrf_cookie_no_logging(self):
+ """
+ Tests that ensure_csrf_cookie doesn't log warnings. See #19436.
+ """
+ @ensure_csrf_cookie
+ def view(request):
+ # Doesn't insert a token or anything
+ return HttpResponse(content="")
+
+ class TestHandler(logging.Handler):
+ def emit(self, record):
+ raise Exception("This shouldn't have happened!")
+
+ logger = logging.getLogger('django.request')
+ test_handler = TestHandler()
+ old_log_level = logger.level
+ try:
+ logger.addHandler(test_handler)
+ logger.setLevel(logging.WARNING)
+
+ req = self._get_GET_no_csrf_cookie_request()
+ resp = view(req)
+ finally:
+ logger.removeHandler(test_handler)
+ logger.setLevel(old_log_level)
diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py
index 21734faf95..be16719c8e 100644
--- a/tests/defaultfilters/tests.py
+++ b/tests/defaultfilters/tests.py
@@ -527,24 +527,26 @@ class DefaultFiltersTests(TestCase):
def test_timesince(self):
# real testing is done in timesince.py, where we can provide our own 'now'
+ # NOTE: \xa0 avoids wrapping between value and unit
self.assertEqual(
timesince_filter(datetime.datetime.now() - datetime.timedelta(1)),
- '1 day')
+ '1\xa0day')
self.assertEqual(
timesince_filter(datetime.datetime(2005, 12, 29),
datetime.datetime(2005, 12, 30)),
- '1 day')
+ '1\xa0day')
def test_timeuntil(self):
+ # NOTE: \xa0 avoids wrapping between value and unit
self.assertEqual(
timeuntil_filter(datetime.datetime.now() + datetime.timedelta(1, 1)),
- '1 day')
+ '1\xa0day')
self.assertEqual(
timeuntil_filter(datetime.datetime(2005, 12, 30),
datetime.datetime(2005, 12, 29)),
- '1 day')
+ '1\xa0day')
def test_default(self):
self.assertEqual(default("val", "default"), 'val')
@@ -574,43 +576,45 @@ class DefaultFiltersTests(TestCase):
'get out of town')
def test_filesizeformat(self):
- self.assertEqual(filesizeformat(1023), '1023 bytes')
- self.assertEqual(filesizeformat(1024), '1.0 KB')
- self.assertEqual(filesizeformat(10*1024), '10.0 KB')
- self.assertEqual(filesizeformat(1024*1024-1), '1024.0 KB')
- self.assertEqual(filesizeformat(1024*1024), '1.0 MB')
- self.assertEqual(filesizeformat(1024*1024*50), '50.0 MB')
- self.assertEqual(filesizeformat(1024*1024*1024-1), '1024.0 MB')
- self.assertEqual(filesizeformat(1024*1024*1024), '1.0 GB')
- self.assertEqual(filesizeformat(1024*1024*1024*1024), '1.0 TB')
- self.assertEqual(filesizeformat(1024*1024*1024*1024*1024), '1.0 PB')
+ # NOTE: \xa0 avoids wrapping between value and unit
+ self.assertEqual(filesizeformat(1023), '1023\xa0bytes')
+ self.assertEqual(filesizeformat(1024), '1.0\xa0KB')
+ self.assertEqual(filesizeformat(10*1024), '10.0\xa0KB')
+ self.assertEqual(filesizeformat(1024*1024-1), '1024.0\xa0KB')
+ self.assertEqual(filesizeformat(1024*1024), '1.0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*50), '50.0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*1024-1), '1024.0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*1024), '1.0\xa0GB')
+ self.assertEqual(filesizeformat(1024*1024*1024*1024), '1.0\xa0TB')
+ self.assertEqual(filesizeformat(1024*1024*1024*1024*1024), '1.0\xa0PB')
self.assertEqual(filesizeformat(1024*1024*1024*1024*1024*2000),
- '2000.0 PB')
- self.assertEqual(filesizeformat(complex(1,-1)), '0 bytes')
- self.assertEqual(filesizeformat(""), '0 bytes')
+ '2000.0\xa0PB')
+ self.assertEqual(filesizeformat(complex(1,-1)), '0\xa0bytes')
+ self.assertEqual(filesizeformat(""), '0\xa0bytes')
self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"),
- '0 bytes')
+ '0\xa0bytes')
def test_localized_filesizeformat(self):
+ # NOTE: \xa0 avoids wrapping between value and unit
with self.settings(USE_L10N=True):
with translation.override('de', deactivate=True):
- self.assertEqual(filesizeformat(1023), '1023 Bytes')
- self.assertEqual(filesizeformat(1024), '1,0 KB')
- self.assertEqual(filesizeformat(10*1024), '10,0 KB')
- self.assertEqual(filesizeformat(1024*1024-1), '1024,0 KB')
- self.assertEqual(filesizeformat(1024*1024), '1,0 MB')
- self.assertEqual(filesizeformat(1024*1024*50), '50,0 MB')
- self.assertEqual(filesizeformat(1024*1024*1024-1), '1024,0 MB')
- self.assertEqual(filesizeformat(1024*1024*1024), '1,0 GB')
- self.assertEqual(filesizeformat(1024*1024*1024*1024), '1,0 TB')
+ self.assertEqual(filesizeformat(1023), '1023\xa0Bytes')
+ self.assertEqual(filesizeformat(1024), '1,0\xa0KB')
+ self.assertEqual(filesizeformat(10*1024), '10,0\xa0KB')
+ self.assertEqual(filesizeformat(1024*1024-1), '1024,0\xa0KB')
+ self.assertEqual(filesizeformat(1024*1024), '1,0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*50), '50,0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*1024-1), '1024,0\xa0MB')
+ self.assertEqual(filesizeformat(1024*1024*1024), '1,0\xa0GB')
+ self.assertEqual(filesizeformat(1024*1024*1024*1024), '1,0\xa0TB')
self.assertEqual(filesizeformat(1024*1024*1024*1024*1024),
- '1,0 PB')
+ '1,0\xa0PB')
self.assertEqual(filesizeformat(1024*1024*1024*1024*1024*2000),
- '2000,0 PB')
- self.assertEqual(filesizeformat(complex(1,-1)), '0 Bytes')
- self.assertEqual(filesizeformat(""), '0 Bytes')
+ '2000,0\xa0PB')
+ self.assertEqual(filesizeformat(complex(1,-1)), '0\xa0Bytes')
+ self.assertEqual(filesizeformat(""), '0\xa0Bytes')
self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"),
- '0 Bytes')
+ '0\xa0Bytes')
def test_pluralize(self):
self.assertEqual(pluralize(1), '')
diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py
index 103612198e..f954933046 100644
--- a/tests/fixtures/tests.py
+++ b/tests/fixtures/tests.py
@@ -1,5 +1,7 @@
from __future__ import absolute_import
+import warnings
+
from django.contrib.sites.models import Site
from django.core import management
from django.db import connection, IntegrityError
@@ -137,8 +139,18 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
'<Book: Music for all ages by Artist formerly known as "Prince" and Django Reinhardt>'
])
- # Load a fixture that doesn't exist
- management.call_command('loaddata', 'unknown.json', verbosity=0, commit=False)
+ # Loading a fixture that doesn't exist emits a warning
+ with warnings.catch_warnings(record=True) as w:
+ management.call_command('loaddata', 'unknown.json', verbosity=0,
+ commit=False)
+ self.assertEqual(len(w), 1)
+ self.assertTrue(w[0].message, "No fixture named 'unknown' found.")
+
+ # An attempt to load a nonexistent 'initial_data' fixture isn't an error
+ with warnings.catch_warnings(record=True) as w:
+ management.call_command('loaddata', 'initial_data.json', verbosity=0,
+ commit=False)
+ self.assertEqual(len(w), 0)
# object list is unaffected
self.assertQuerysetEqual(Article.objects.all(), [
@@ -273,10 +285,11 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_unmatched_identifier_loading(self):
# Try to load db fixture 3. This won't load because the database identifier doesn't match
- management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False)
- self.assertQuerysetEqual(Article.objects.all(), [])
+ with warnings.catch_warnings(record=True):
+ management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False)
- management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False)
+ with warnings.catch_warnings(record=True):
+ management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False)
self.assertQuerysetEqual(Article.objects.all(), [])
def test_output_formats(self):
diff --git a/tests/fixtures_model_package/tests.py b/tests/fixtures_model_package/tests.py
index c250f647ce..fbd0271336 100644
--- a/tests/fixtures_model_package/tests.py
+++ b/tests/fixtures_model_package/tests.py
@@ -1,5 +1,7 @@
from __future__ import unicode_literals
+import warnings
+
from django.core import management
from django.db import transaction
from django.test import TestCase, TransactionTestCase
@@ -100,7 +102,9 @@ class FixtureTestCase(TestCase):
)
# Load a fixture that doesn't exist
- management.call_command("loaddata", "unknown.json", verbosity=0, commit=False)
+ with warnings.catch_warnings(record=True):
+ management.call_command("loaddata", "unknown.json", verbosity=0, commit=False)
+
self.assertQuerysetEqual(
Article.objects.all(), [
"Django conquers world!",
diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py
index 02e923e386..5114302267 100644
--- a/tests/fixtures_regress/tests.py
+++ b/tests/fixtures_regress/tests.py
@@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals
import os
import re
+import warnings
from django.core.serializers.base import DeserializationError
from django.core import management
@@ -441,13 +442,14 @@ class TestFixtures(TestCase):
def test_loaddata_not_existant_fixture_file(self):
stdout_output = StringIO()
- management.call_command(
- 'loaddata',
- 'this_fixture_doesnt_exist',
- verbosity=2,
- commit=False,
- stdout=stdout_output,
- )
+ with warnings.catch_warnings(record=True):
+ management.call_command(
+ 'loaddata',
+ 'this_fixture_doesnt_exist',
+ verbosity=2,
+ commit=False,
+ stdout=stdout_output,
+ )
self.assertTrue("No xml fixture 'this_fixture_doesnt_exist' in" in
force_text(stdout_output.getvalue()))
diff --git a/tests/forms_tests/tests/test_extra.py b/tests/forms_tests/tests/test_extra.py
index a83cdfc05f..ea0f063c30 100644
--- a/tests/forms_tests/tests/test_extra.py
+++ b/tests/forms_tests/tests/test_extra.py
@@ -569,6 +569,14 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
f = GenericIPAddressField(unpack_ipv4=True)
self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10')
+ def test_slugfield_normalization(self):
+ f = SlugField()
+ self.assertEqual(f.clean(' aa-bb-cc '), 'aa-bb-cc')
+
+ def test_urlfield_normalization(self):
+ f = URLField()
+ self.assertEqual(f.clean('http://example.com/ '), 'http://example.com/')
+
def test_smart_text(self):
class Test:
if six.PY3:
diff --git a/tests/forms_tests/tests/test_fields.py b/tests/forms_tests/tests/test_fields.py
index 7516de29b4..47c637befa 100644
--- a/tests/forms_tests/tests/test_fields.py
+++ b/tests/forms_tests/tests/test_fields.py
@@ -125,6 +125,15 @@ class FieldsTests(SimpleTestCase):
self.assertEqual(f.max_length, None)
self.assertEqual(f.min_length, 10)
+ def test_charfield_length_not_int(self):
+ """
+ Ensure that setting min_length or max_length to something that is not a
+ number returns an exception.
+ """
+ self.assertRaises(ValueError, CharField, min_length='a')
+ self.assertRaises(ValueError, CharField, max_length='a')
+ self.assertRaises(ValueError, CharField, 'a')
+
def test_charfield_widget_attrs(self):
"""
Ensure that CharField.widget_attrs() always returns a dictionary.
diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py
index 0e84e17132..ffdad4b69f 100644
--- a/tests/generic_views/test_base.py
+++ b/tests/generic_views/test_base.py
@@ -411,3 +411,36 @@ class GetContextDataTest(unittest.TestCase):
# test that kwarg overrides values assigned higher up
context = test_view.get_context_data(test_name='test_value')
self.assertEqual(context['test_name'], 'test_value')
+
+ def test_object_at_custom_name_in_context_data(self):
+ # Checks 'pony' key presence in dict returned by get_context_date
+ test_view = views.CustomSingleObjectView()
+ test_view.context_object_name = 'pony'
+ context = test_view.get_context_data()
+ self.assertEqual(context['pony'], test_view.object)
+
+ def test_object_in_get_context_data(self):
+ # Checks 'object' key presence in dict returned by get_context_date #20234
+ test_view = views.CustomSingleObjectView()
+ context = test_view.get_context_data()
+ self.assertEqual(context['object'], test_view.object)
+
+
+class UseMultipleObjectMixinTest(unittest.TestCase):
+ rf = RequestFactory()
+
+ def test_use_queryset_from_view(self):
+ test_view = views.CustomMultipleObjectMixinView()
+ test_view.get(self.rf.get('/'))
+ # Don't pass queryset as argument
+ context = test_view.get_context_data()
+ self.assertEqual(context['object_list'], test_view.queryset)
+
+ def test_overwrite_queryset(self):
+ test_view = views.CustomMultipleObjectMixinView()
+ test_view.get(self.rf.get('/'))
+ queryset = [{'name': 'Lennon'}, {'name': 'Ono'}]
+ self.assertNotEqual(test_view.queryset, queryset)
+ # Overwrite the view's queryset with queryset from kwarg
+ context = test_view.get_context_data(object_list=queryset)
+ self.assertEqual(context['object_list'], queryset)
diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py
index aa8777e8c6..fd331f14b7 100644
--- a/tests/generic_views/views.py
+++ b/tests/generic_views/views.py
@@ -1,7 +1,6 @@
from __future__ import absolute_import
from django.contrib.auth.decorators import login_required
-from django.contrib.messages.views import SuccessMessageMixin
from django.core.paginator import Paginator
from django.core.urlresolvers import reverse, reverse_lazy
from django.utils.decorators import method_decorator
@@ -201,6 +200,17 @@ class BookDetailGetObjectCustomQueryset(BookDetail):
return super(BookDetailGetObjectCustomQueryset,self).get_object(
queryset=Book.objects.filter(pk=2))
+
+class CustomMultipleObjectMixinView(generic.list.MultipleObjectMixin, generic.View):
+ queryset = [
+ {'name': 'John'},
+ {'name': 'Yoko'},
+ ]
+
+ def get(self, request):
+ self.object_list = self.get_queryset()
+
+
class CustomContextView(generic.detail.SingleObjectMixin, generic.View):
model = Book
object = Book(name='dummy')
@@ -216,6 +226,10 @@ class CustomContextView(generic.detail.SingleObjectMixin, generic.View):
def get_context_object_name(self, obj):
return "test_name"
+class CustomSingleObjectView(generic.detail.SingleObjectMixin, generic.View):
+ model = Book
+ object = Book(name="dummy")
+
class BookSigningConfig(object):
model = BookSigning
date_field = 'event_date'
diff --git a/tests/i18n/__init__.py b/tests/i18n/__init__.py
index e69de29bb2..a3e9ce7053 100644
--- a/tests/i18n/__init__.py
+++ b/tests/i18n/__init__.py
@@ -0,0 +1,17 @@
+from threading import local
+
+
+class TransRealMixin(object):
+ """This is the only way to reset the translation machinery. Otherwise
+ the test suite occasionally fails because of global state pollution
+ between tests."""
+ def flush_caches(self):
+ from django.utils.translation import trans_real
+ trans_real._translations = {}
+ trans_real._active = local()
+ trans_real._default = None
+ trans_real._accepted = {}
+
+ def tearDown(self):
+ self.flush_caches()
+ super(TransRealMixin, self).tearDown()
diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py
index 5e8a9823e1..cbac9ec5da 100644
--- a/tests/i18n/contenttypes/tests.py
+++ b/tests/i18n/contenttypes/tests.py
@@ -10,6 +10,8 @@ from django.utils._os import upath
from django.utils import six
from django.utils import translation
+from i18n import TransRealMixin
+
@override_settings(
USE_I18N=True,
@@ -22,7 +24,7 @@ from django.utils import translation
('fr', 'French'),
),
)
-class ContentTypeTests(TestCase):
+class ContentTypeTests(TransRealMixin, TestCase):
def test_verbose_name(self):
company_type = ContentType.objects.get(app_label='i18n', model='company')
with translation.override('en'):
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index 1022c8d2f1..137270f830 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -30,7 +30,8 @@ from django.utils.translation import (activate, deactivate,
ngettext, ngettext_lazy,
ungettext, ungettext_lazy,
pgettext, pgettext_lazy,
- npgettext, npgettext_lazy)
+ npgettext, npgettext_lazy,
+ check_for_language)
from .commands.tests import can_run_extraction_tests, can_run_compilation_tests
if can_run_extraction_tests:
@@ -43,6 +44,7 @@ if can_run_compilation_tests:
from .commands.compilation import (PoFileTests, PoFileContentsTests,
PercentRenderingTests, MultipleLocaleCompilationTests,
CompilationErrorHandling)
+from . import TransRealMixin
from .forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm
from .models import Company, TestModel
@@ -52,7 +54,8 @@ extended_locale_paths = settings.LOCALE_PATHS + (
os.path.join(here, 'other', 'locale'),
)
-class TranslationTests(TestCase):
+
+class TranslationTests(TransRealMixin, TestCase):
def test_override(self):
activate('de')
@@ -333,10 +336,43 @@ class TranslationTests(TestCase):
self.assertEqual(rendered, 'My other name is James.')
+class TranslationThreadSafetyTests(TestCase):
+ """Specifically not using TransRealMixin here to test threading."""
+
+ def setUp(self):
+ self._old_language = get_language()
+ self._translations = trans_real._translations
+
+ # here we rely on .split() being called inside the _fetch()
+ # in trans_real.translation()
+ class sideeffect_str(str):
+ def split(self, *args, **kwargs):
+ res = str.split(self, *args, **kwargs)
+ trans_real._translations['en-YY'] = None
+ return res
+
+ trans_real._translations = {sideeffect_str('en-XX'): None}
+
+ def tearDown(self):
+ trans_real._translations = self._translations
+ activate(self._old_language)
+
+ def test_bug14894_translation_activate_thread_safety(self):
+ translation_count = len(trans_real._translations)
+ try:
+ translation.activate('pl')
+ except RuntimeError:
+ self.fail('translation.activate() is not thread-safe')
+
+ # make sure sideeffect_str actually added a new translation
+ self.assertLess(translation_count, len(trans_real._translations))
+
+
@override_settings(USE_L10N=True)
-class FormattingTests(TestCase):
+class FormattingTests(TransRealMixin, TestCase):
def setUp(self):
+ super(FormattingTests, self).setUp()
self.n = decimal.Decimal('66666.666')
self.f = 99999.999
self.d = datetime.date(2009, 12, 31)
@@ -738,9 +774,10 @@ class FormattingTests(TestCase):
self.assertEqual(template2.render(context), output2)
self.assertEqual(template3.render(context), output3)
-class MiscTests(TestCase):
+class MiscTests(TransRealMixin, TestCase):
def setUp(self):
+ super(MiscTests, self).setUp()
self.rf = RequestFactory()
def test_parse_spec_http_header(self):
@@ -884,17 +921,15 @@ class MiscTests(TestCase):
self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 4})), '%(percent)s% represents 4 objects')
-class ResolutionOrderI18NTests(TestCase):
+class ResolutionOrderI18NTests(TransRealMixin, TestCase):
def setUp(self):
- # Okay, this is brutal, but we have no other choice to fully reset
- # the translation framework
- trans_real._active = local()
- trans_real._translations = {}
+ super(ResolutionOrderI18NTests, self).setUp()
activate('de')
def tearDown(self):
deactivate()
+ super(ResolutionOrderI18NTests, self).tearDown()
def assertUgettext(self, msgid, msgstr):
result = ugettext(msgid)
@@ -967,15 +1002,17 @@ class TestLanguageInfo(TestCase):
six.assertRaisesRegex(self, KeyError, r"Unknown language code xx-xx and xx\.", get_language_info, 'xx-xx')
-class MultipleLocaleActivationTests(TestCase):
+class MultipleLocaleActivationTests(TransRealMixin, TestCase):
"""
Tests for template rendering behavior when multiple locales are activated
during the lifetime of the same process.
"""
def setUp(self):
+ super(MultipleLocaleActivationTests, self).setUp()
self._old_language = get_language()
def tearDown(self):
+ super(MultipleLocaleActivationTests, self).tearDown()
activate(self._old_language)
def test_single_locale_activation(self):
@@ -1104,7 +1141,7 @@ class MultipleLocaleActivationTests(TestCase):
'django.middleware.common.CommonMiddleware',
),
)
-class LocaleMiddlewareTests(TestCase):
+class LocaleMiddlewareTests(TransRealMixin, TestCase):
urls = 'i18n.urls'
@@ -1114,3 +1151,41 @@ class LocaleMiddlewareTests(TestCase):
self.assertContains(response, "Oui/Non")
response = self.client.get('/en/streaming/')
self.assertContains(response, "Yes/No")
+
+@override_settings(
+ USE_I18N=True,
+ LANGUAGES=(
+ ('bg', 'Bulgarian'),
+ ('en-us', 'English'),
+ ),
+ MIDDLEWARE_CLASSES=(
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ ),
+)
+class CountrySpecificLanguageTests(TransRealMixin, TestCase):
+
+ urls = 'i18n.urls'
+
+ def setUp(self):
+ super(CountrySpecificLanguageTests, self).setUp()
+ self.rf = RequestFactory()
+
+ def test_check_for_language(self):
+ self.assertTrue(check_for_language('en'))
+ self.assertTrue(check_for_language('en-us'))
+ self.assertTrue(check_for_language('en-US'))
+
+
+ def test_get_language_from_request(self):
+ # issue 19919
+ r = self.rf.get('/')
+ r.COOKIES = {}
+ r.META = {'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8,bg;q=0.6,ru;q=0.4'}
+ lang = get_language_from_request(r)
+ self.assertEqual('en-us', lang)
+ r = self.rf.get('/')
+ r.COOKIES = {}
+ r.META = {'HTTP_ACCEPT_LANGUAGE': 'bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4'}
+ lang = get_language_from_request(r)
+ self.assertEqual('bg', lang)
diff --git a/tests/invalid_models/invalid_models/models.py b/tests/invalid_models/invalid_models/models.py
index 3c21e1ddb8..6ba3f04e5e 100644
--- a/tests/invalid_models/invalid_models/models.py
+++ b/tests/invalid_models/invalid_models/models.py
@@ -375,8 +375,8 @@ invalid_models.fielderrors: "decimalfield3": DecimalFields require a "max_digits
invalid_models.fielderrors: "decimalfield4": DecimalFields require a "max_digits" attribute value that is greater than or equal to the value of the "decimal_places" attribute.
invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list).
-invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples.
-invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples.
+invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-item iterables (e.g. list of 2 item tuples).
+invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-item iterables (e.g. list of 2 item tuples).
invalid_models.fielderrors: "index": "db_index" should be either None, True or False.
invalid_models.fielderrors: "field_": Field names cannot end with underscores, because this would lead to ambiguous queryset filters.
invalid_models.fielderrors: "nullbool": BooleanFields do not accept null values. Use a NullBooleanField instead.
diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py
index e526da4772..1ff8390f31 100644
--- a/tests/middleware/tests.py
+++ b/tests/middleware/tests.py
@@ -18,14 +18,12 @@ from django.middleware.http import ConditionalGetMiddleware
from django.middleware.gzip import GZipMiddleware
from django.middleware.transaction import TransactionMiddleware
from django.test import TransactionTestCase, TestCase, RequestFactory
-from django.test.utils import override_settings
+from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
from django.utils import six
from django.utils.encoding import force_str
from django.utils.six.moves import xrange
from django.utils.unittest import expectedFailure, skipIf
-from transactions.tests import IgnorePendingDeprecationWarningsMixin
-
from .models import Band
diff --git a/tests/model_forms_regress/tests.py b/tests/model_forms_regress/tests.py
index 0e033e033f..80900a59e0 100644
--- a/tests/model_forms_regress/tests.py
+++ b/tests/model_forms_regress/tests.py
@@ -92,6 +92,41 @@ class OverrideCleanTests(TestCase):
self.assertEqual(form.instance.left, 1)
+
+class PartiallyLocalizedTripleForm(forms.ModelForm):
+ class Meta:
+ model = Triple
+ localized_fields = ('left', 'right',)
+
+
+class FullyLocalizedTripleForm(forms.ModelForm):
+ class Meta:
+ model = Triple
+ localized_fields = "__all__"
+
+class LocalizedModelFormTest(TestCase):
+ def test_model_form_applies_localize_to_some_fields(self):
+ f = PartiallyLocalizedTripleForm({'left': 10, 'middle': 10, 'right': 10})
+ self.assertTrue(f.is_valid())
+ self.assertTrue(f.fields['left'].localize)
+ self.assertFalse(f.fields['middle'].localize)
+ self.assertTrue(f.fields['right'].localize)
+
+ def test_model_form_applies_localize_to_all_fields(self):
+ f = FullyLocalizedTripleForm({'left': 10, 'middle': 10, 'right': 10})
+ self.assertTrue(f.is_valid())
+ self.assertTrue(f.fields['left'].localize)
+ self.assertTrue(f.fields['middle'].localize)
+ self.assertTrue(f.fields['right'].localize)
+
+ def test_model_form_refuses_arbitrary_string(self):
+ with self.assertRaises(TypeError):
+ class BrokenLocalizedTripleForm(forms.ModelForm):
+ class Meta:
+ model = Triple
+ localized_fields = "foo"
+
+
# Regression test for #12960.
# Make sure the cleaned_data returned from ModelForm.clean() is applied to the
# model instance.
diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py
index 38ebd9d24b..c8fb1e76c1 100644
--- a/tests/model_formsets_regress/tests.py
+++ b/tests/model_formsets_regress/tests.py
@@ -273,6 +273,7 @@ class UserSiteForm(forms.ModelForm):
'id': CustomWidget,
'data': CustomWidget,
}
+ localized_fields = ('data',)
class Callback(object):
@@ -297,19 +298,23 @@ class FormfieldCallbackTests(TestCase):
form = Formset().forms[0]
self.assertTrue(isinstance(form['id'].field.widget, CustomWidget))
self.assertTrue(isinstance(form['data'].field.widget, CustomWidget))
+ self.assertFalse(form.fields['id'].localize)
+ self.assertTrue(form.fields['data'].localize)
def test_modelformset_factory_default(self):
Formset = modelformset_factory(UserSite, form=UserSiteForm)
form = Formset().forms[0]
self.assertTrue(isinstance(form['id'].field.widget, CustomWidget))
self.assertTrue(isinstance(form['data'].field.widget, CustomWidget))
+ self.assertFalse(form.fields['id'].localize)
+ self.assertTrue(form.fields['data'].localize)
def assertCallbackCalled(self, callback):
id_field, user_field, data_field = UserSite._meta.fields
expected_log = [
(id_field, {'widget': CustomWidget}),
(user_field, {}),
- (data_field, {'widget': CustomWidget}),
+ (data_field, {'widget': CustomWidget, 'localize': True}),
]
self.assertEqual(callback.log, expected_log)
diff --git a/tests/special_headers/__init__.py b/tests/model_validation/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/special_headers/__init__.py
+++ b/tests/model_validation/__init__.py
diff --git a/tests/model_validation/models.py b/tests/model_validation/models.py
new file mode 100644
index 0000000000..9a2a5f7cd0
--- /dev/null
+++ b/tests/model_validation/models.py
@@ -0,0 +1,27 @@
+from django.db import models
+
+
+class ThingItem(object):
+
+ def __init__(self, value, display):
+ self.value = value
+ self.display = display
+
+ def __iter__(self):
+ return (x for x in [self.value, self.display])
+
+ def __len__(self):
+ return 2
+
+
+class Things(object):
+
+ def __iter__(self):
+ return (x for x in [ThingItem(1, 2), ThingItem(3, 4)])
+
+
+class ThingWithIterableChoices(models.Model):
+
+ # Testing choices= Iterable of Iterables
+ # See: https://code.djangoproject.com/ticket/20430
+ thing = models.CharField(max_length=100, blank=True, choices=Things())
diff --git a/tests/model_validation/tests.py b/tests/model_validation/tests.py
new file mode 100644
index 0000000000..ffd0d89412
--- /dev/null
+++ b/tests/model_validation/tests.py
@@ -0,0 +1,13 @@
+from django.core import management
+from django.test import TestCase
+from django.utils import six
+
+
+class ModelValidationTest(TestCase):
+
+ def test_models_validate(self):
+ # All our models should validate properly
+ # Validation Tests:
+ # * choices= Iterable of Iterables
+ # See: https://code.djangoproject.com/ticket/20430
+ management.call_command("validate", stdout=six.StringIO())
diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py
index 0d933bc1f9..f89f1c20ec 100644
--- a/tests/modeladmin/tests.py
+++ b/tests/modeladmin/tests.py
@@ -7,7 +7,6 @@ from django.conf import settings
from django.contrib.admin.options import (ModelAdmin, TabularInline,
HORIZONTAL, VERTICAL)
from django.contrib.admin.sites import AdminSite
-from django.contrib.admin.validation import validate
from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect
from django.contrib.admin import (SimpleListFilter,
BooleanFieldListFilter)
@@ -523,8 +522,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -534,8 +532,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.raw_id_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -545,15 +542,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.raw_id_fields\[0\]', 'name' must be either a ForeignKey or ManyToManyField.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
raw_id_fields = ('users',)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_fieldsets_validation(self):
@@ -563,8 +559,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.fieldsets' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -574,8 +569,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.fieldsets\[0\]' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -585,8 +579,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.fieldsets\[0\]' does not have exactly two elements.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -596,8 +589,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.fieldsets\[0\]\[1\]' must be a dictionary.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -607,15 +599,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'fields' key is required in ValidationTestModelAdmin.fieldsets\[0\]\[1\] field options dict.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
fieldsets = (("General", {"fields": ("name",)}),)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
class ValidationTestModelAdmin(ModelAdmin):
fieldsets = (("General", {"fields": ("name",)}),)
@@ -624,8 +615,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"Both fieldsets and fields are specified in ValidationTestModelAdmin.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -635,8 +625,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"There are duplicate field\(s\) in ValidationTestModelAdmin.fieldsets",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -646,8 +635,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"There are duplicate field\(s\) in ValidationTestModelAdmin.fields",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -662,8 +650,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"ValidationTestModelAdmin.form does not inherit from BaseModelForm.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -676,7 +663,7 @@ class ValidationTests(unittest.TestCase):
}),
)
- validate(BandAdmin, Band)
+ BandAdmin.validate(Band)
class AdminBandForm(forms.ModelForm):
delete = forms.BooleanField()
@@ -690,7 +677,7 @@ class ValidationTests(unittest.TestCase):
}),
)
- validate(BandAdmin, Band)
+ BandAdmin.validate(Band)
def test_filter_vertical_validation(self):
@@ -700,8 +687,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_vertical' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -711,8 +697,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_vertical' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -722,15 +707,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_vertical\[0\]' must be a ManyToManyField.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
filter_vertical = ("users",)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_filter_horizontal_validation(self):
@@ -740,8 +724,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_horizontal' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -751,8 +734,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_horizontal' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -762,15 +744,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.filter_horizontal\[0\]' must be a ManyToManyField.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
filter_horizontal = ("users",)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_radio_fields_validation(self):
@@ -780,8 +761,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.radio_fields' must be a dictionary.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -791,8 +771,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.radio_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -802,8 +781,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.radio_fields\['name'\]' is neither an instance of ForeignKey nor does have choices set.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -813,15 +791,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.radio_fields\['state'\]' is neither admin.HORIZONTAL nor admin.VERTICAL.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
radio_fields = {"state": VERTICAL}
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_prepopulated_fields_validation(self):
@@ -831,8 +808,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.prepopulated_fields' must be a dictionary.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -842,8 +818,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.prepopulated_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -853,8 +828,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.prepopulated_fields\['slug'\]\[0\]' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -864,15 +838,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.prepopulated_fields\['users'\]' is either a DateTimeField, ForeignKey or ManyToManyField. This isn't allowed.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
prepopulated_fields = {"slug": ("name",)}
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_list_display_validation(self):
@@ -882,8 +855,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_display' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -893,8 +865,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
str_prefix("ValidationTestModelAdmin.list_display\[0\], %(_)s'non_existent_field' is not a callable or an attribute of 'ValidationTestModelAdmin' or found in the model 'ValidationTestModel'."),
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -904,8 +875,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_display\[0\]', 'users' is a ManyToManyField which is not supported.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -917,7 +887,7 @@ class ValidationTests(unittest.TestCase):
pass
list_display = ('name', 'decade_published_in', 'a_method', a_callable)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_list_display_links_validation(self):
@@ -927,8 +897,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_display_links' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -938,8 +907,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_display_links\[0\]' refers to 'non_existent_field' which is not defined in 'list_display'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -949,8 +917,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_display_links\[0\]' refers to 'name' which is not defined in 'list_display'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -963,7 +930,7 @@ class ValidationTests(unittest.TestCase):
list_display = ('name', 'decade_published_in', 'a_method', a_callable)
list_display_links = ('name', 'decade_published_in', 'a_method', a_callable)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_list_filter_validation(self):
@@ -973,8 +940,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -984,8 +950,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter\[0\]' refers to 'non_existent_field' which does not refer to a Field.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -998,8 +963,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter\[0\]' is 'RandomClass' which is not a descendant of ListFilter.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1009,8 +973,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'RandomClass' which is not of type FieldListFilter.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1028,8 +991,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'AwesomeFilter' which is not of type FieldListFilter.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1039,8 +1001,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.list_filter\[0\]' is 'BooleanFieldListFilter' which is of type FieldListFilter but is not associated with a field name.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1049,7 +1010,7 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter), 'no')
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_list_per_page_validation(self):
@@ -1058,16 +1019,15 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestModelAdmin.list_per_page' should be a integer.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestModelAdmin.list_per_page' should be a int.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
list_per_page = 100
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_max_show_all_allowed_validation(self):
@@ -1076,16 +1036,15 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestModelAdmin.list_max_show_all' should be an integer.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestModelAdmin.list_max_show_all' should be a int.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
list_max_show_all = 200
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_search_fields_validation(self):
@@ -1095,8 +1054,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.search_fields' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1108,8 +1066,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.date_hierarchy' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1119,15 +1076,14 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.date_hierarchy is neither an instance of DateField nor DateTimeField.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
date_hierarchy = 'pub_date'
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_ordering_validation(self):
@@ -1137,8 +1093,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.ordering' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1148,8 +1103,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.ordering\[0\]' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1159,25 +1113,24 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.ordering' has the random ordering marker '\?', but contains other fields as well. Please either remove '\?' or the other fields.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
ordering = ('?',)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
class ValidationTestModelAdmin(ModelAdmin):
ordering = ('band__name',)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
class ValidationTestModelAdmin(ModelAdmin):
ordering = ('name',)
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_list_select_related_validation(self):
@@ -1186,16 +1139,15 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestModelAdmin.list_select_related' should be a boolean.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestModelAdmin.list_select_related' should be a bool.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
list_select_related = False
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_save_as_validation(self):
@@ -1204,16 +1156,15 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestModelAdmin.save_as' should be a boolean.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestModelAdmin.save_as' should be a bool.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
save_as = True
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_save_on_top_validation(self):
@@ -1222,16 +1173,15 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestModelAdmin.save_on_top' should be a boolean.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestModelAdmin.save_on_top' should be a bool.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
class ValidationTestModelAdmin(ModelAdmin):
save_on_top = True
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_inlines_validation(self):
@@ -1241,8 +1191,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.inlines' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1255,8 +1204,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.inlines\[0\]' does not inherit from BaseModelAdmin.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1269,8 +1217,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'model' is a required attribute of 'ValidationTestModelAdmin.inlines\[0\]'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1286,8 +1233,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestModelAdmin.inlines\[0\].model' does not inherit from models.Model.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1297,7 +1243,7 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
inlines = [ValidationTestInline]
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_fields_validation(self):
@@ -1311,8 +1257,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestInline.fields' must be a list or tuple.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1328,8 +1273,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestInline.fk_name' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestInlineModel'.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1340,7 +1284,7 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
inlines = [ValidationTestInline]
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_extra_validation(self):
@@ -1353,9 +1297,8 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestInline.extra' should be a integer.",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestInline.extra' should be a int.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1366,7 +1309,7 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
inlines = [ValidationTestInline]
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_max_num_validation(self):
@@ -1379,9 +1322,8 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
- "'ValidationTestInline.max_num' should be an integer or None \(default\).",
- validate,
- ValidationTestModelAdmin,
+ "'ValidationTestInline.max_num' should be a int.",
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1392,7 +1334,7 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
inlines = [ValidationTestInline]
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
def test_formset_validation(self):
@@ -1409,8 +1351,7 @@ class ValidationTests(unittest.TestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
"'ValidationTestInline.formset' does not inherit from BaseModelFormSet.",
- validate,
- ValidationTestModelAdmin,
+ ValidationTestModelAdmin.validate,
ValidationTestModel,
)
@@ -1424,4 +1365,4 @@ class ValidationTests(unittest.TestCase):
class ValidationTestModelAdmin(ModelAdmin):
inlines = [ValidationTestInline]
- validate(ValidationTestModelAdmin, ValidationTestModel)
+ ValidationTestModelAdmin.validate(ValidationTestModel)
diff --git a/tests/requests/tests.py b/tests/requests/tests.py
index 56d58c4c75..676cd05679 100644
--- a/tests/requests/tests.py
+++ b/tests/requests/tests.py
@@ -532,13 +532,13 @@ class RequestsTests(SimpleTestCase):
# There are cases in which the multipart data is related instead of
# being a binary upload, in which case it should still be accessible
# via body.
- payload_data = "\r\n".join([
- '--boundary',
- 'Content-ID: id; name="name"',
- '',
- 'value',
- '--boundary--'
- ''])
+ payload_data = b"\r\n".join([
+ b'--boundary',
+ b'Content-ID: id; name="name"',
+ b'',
+ b'value',
+ b'--boundary--'
+ b''])
payload = FakePayload(payload_data)
request = WSGIRequest({'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'multipart/related; boundary=boundary',
diff --git a/tests/special_headers/fixtures/data.xml b/tests/special_headers/fixtures/data.xml
deleted file mode 100644
index 7e60d45199..0000000000
--- a/tests/special_headers/fixtures/data.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<django-objects version="1.0">
- <object pk="100" model="auth.user">
- <field type="CharField" name="username">super</field>
- <field type="CharField" name="first_name">Super</field>
- <field type="CharField" name="last_name">User</field>
- <field type="CharField" name="email">super@example.com</field>
- <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field>
- <field type="BooleanField" name="is_staff">True</field>
- <field type="BooleanField" name="is_active">True</field>
- <field type="BooleanField" name="is_superuser">True</field>
- <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field>
- <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field>
- <field to="auth.group" name="groups" rel="ManyToManyRel"></field>
- <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field>
- </object>
- <object pk="1" model="special_headers.article">
- <field type="TextField" name="text">text</field>
- </object>
-</django-objects>
diff --git a/tests/special_headers/models.py b/tests/special_headers/models.py
deleted file mode 100644
index e05c5a6920..0000000000
--- a/tests/special_headers/models.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from django.db import models
-
-
-class Article(models.Model):
- text = models.TextField()
diff --git a/tests/special_headers/templates/special_headers/article_detail.html b/tests/special_headers/templates/special_headers/article_detail.html
deleted file mode 100644
index 3cbd38cb7e..0000000000
--- a/tests/special_headers/templates/special_headers/article_detail.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ object }}
diff --git a/tests/special_headers/tests.py b/tests/special_headers/tests.py
deleted file mode 100644
index b4b704ae21..0000000000
--- a/tests/special_headers/tests.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from django.contrib.auth.models import User
-from django.test import TestCase
-from django.test.utils import override_settings
-
-
-@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
-class SpecialHeadersTest(TestCase):
- fixtures = ['data.xml']
- urls = 'special_headers.urls'
-
- def test_xheaders(self):
- user = User.objects.get(username='super')
- response = self.client.get('/special_headers/article/1/')
- self.assertFalse('X-Object-Type' in response)
- self.client.login(username='super', password='secret')
- response = self.client.get('/special_headers/article/1/')
- self.assertTrue('X-Object-Type' in response)
- user.is_staff = False
- user.save()
- response = self.client.get('/special_headers/article/1/')
- self.assertFalse('X-Object-Type' in response)
- user.is_staff = True
- user.is_active = False
- user.save()
- response = self.client.get('/special_headers/article/1/')
- self.assertFalse('X-Object-Type' in response)
-
- def test_xview_func(self):
- user = User.objects.get(username='super')
- response = self.client.head('/special_headers/xview/func/')
- self.assertFalse('X-View' in response)
- self.client.login(username='super', password='secret')
- response = self.client.head('/special_headers/xview/func/')
- self.assertTrue('X-View' in response)
- self.assertEqual(response['X-View'], 'special_headers.views.xview')
- user.is_staff = False
- user.save()
- response = self.client.head('/special_headers/xview/func/')
- self.assertFalse('X-View' in response)
- user.is_staff = True
- user.is_active = False
- user.save()
- response = self.client.head('/special_headers/xview/func/')
- self.assertFalse('X-View' in response)
-
- def test_xview_class(self):
- user = User.objects.get(username='super')
- response = self.client.head('/special_headers/xview/class/')
- self.assertFalse('X-View' in response)
- self.client.login(username='super', password='secret')
- response = self.client.head('/special_headers/xview/class/')
- self.assertTrue('X-View' in response)
- self.assertEqual(response['X-View'], 'special_headers.views.XViewClass')
- user.is_staff = False
- user.save()
- response = self.client.head('/special_headers/xview/class/')
- self.assertFalse('X-View' in response)
- user.is_staff = True
- user.is_active = False
- user.save()
- response = self.client.head('/special_headers/xview/class/')
- self.assertFalse('X-View' in response)
diff --git a/tests/special_headers/urls.py b/tests/special_headers/urls.py
deleted file mode 100644
index f7ba141207..0000000000
--- a/tests/special_headers/urls.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# coding: utf-8
-from __future__ import absolute_import
-
-from django.conf.urls import patterns
-
-from . import views
-from .models import Article
-
-urlpatterns = patterns('',
- (r'^special_headers/article/(?P<object_id>\d+)/$', views.xview_xheaders),
- (r'^special_headers/xview/func/$', views.xview_dec(views.xview)),
- (r'^special_headers/xview/class/$', views.xview_dec(views.XViewClass.as_view())),
-)
diff --git a/tests/special_headers/views.py b/tests/special_headers/views.py
deleted file mode 100644
index a8bbd6542e..0000000000
--- a/tests/special_headers/views.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from django.core.xheaders import populate_xheaders
-from django.http import HttpResponse
-from django.utils.decorators import decorator_from_middleware
-from django.views.generic import View
-from django.middleware.doc import XViewMiddleware
-
-from .models import Article
-
-xview_dec = decorator_from_middleware(XViewMiddleware)
-
-def xview(request):
- return HttpResponse()
-
-def xview_xheaders(request, object_id):
- response = HttpResponse()
- populate_xheaders(request, response, Article, 1)
- return response
-
-class XViewClass(View):
- def get(self, request):
- return HttpResponse()
diff --git a/tests/template_tests/filters.py b/tests/template_tests/filters.py
index 7ba1681fd5..68ef15d827 100644
--- a/tests/template_tests/filters.py
+++ b/tests/template_tests/filters.py
@@ -35,59 +35,60 @@ def get_filter_tests():
now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone
today = date.today()
+ # NOTE: \xa0 avoids wrapping between value and unit
return {
# Default compare with datetime.now()
- 'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1 minute'),
- 'filter-timesince02' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(days=1, minutes = 1)}, '1 day'),
- 'filter-timesince03' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(hours=1, minutes=25, seconds = 10)}, '1 hour, 25 minutes'),
+ 'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1\xa0minute'),
+ 'filter-timesince02' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(days=1, minutes = 1)}, '1\xa0day'),
+ 'filter-timesince03' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(hours=1, minutes=25, seconds = 10)}, '1\xa0hour, 25\xa0minutes'),
# Compare to a given parameter
- 'filter-timesince04' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=1)}, '1 day'),
- 'filter-timesince05' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2, minutes=1), 'b':now - timedelta(days=2)}, '1 minute'),
+ 'filter-timesince04' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=1)}, '1\xa0day'),
+ 'filter-timesince05' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2, minutes=1), 'b':now - timedelta(days=2)}, '1\xa0minute'),
# Check that timezone is respected
- 'filter-timesince06' : ('{{ a|timesince:b }}', {'a':now_tz - timedelta(hours=8), 'b':now_tz}, '8 hours'),
+ 'filter-timesince06' : ('{{ a|timesince:b }}', {'a':now_tz - timedelta(hours=8), 'b':now_tz}, '8\xa0hours'),
# Regression for #7443
- 'filter-timesince07': ('{{ earlier|timesince }}', { 'earlier': now - timedelta(days=7) }, '1 week'),
- 'filter-timesince08': ('{{ earlier|timesince:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '1 week'),
- 'filter-timesince09': ('{{ later|timesince }}', { 'later': now + timedelta(days=7) }, '0 minutes'),
- 'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0 minutes'),
+ 'filter-timesince07': ('{{ earlier|timesince }}', { 'earlier': now - timedelta(days=7) }, '1\xa0week'),
+ 'filter-timesince08': ('{{ earlier|timesince:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '1\xa0week'),
+ 'filter-timesince09': ('{{ later|timesince }}', { 'later': now + timedelta(days=7) }, '0\xa0minutes'),
+ 'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0\xa0minutes'),
# Ensures that differing timezones are calculated correctly
- 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0 minutes'),
- 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0 minutes'),
- 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0 minutes'),
- 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0 minutes'),
+ 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0\xa0minutes'),
+ 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0\xa0minutes'),
+ 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0\xa0minutes'),
+ 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0\xa0minutes'),
'filter-timesince15' : ('{{ a|timesince:b }}', {'a': now, 'b': now_tz_i}, ''),
'filter-timesince16' : ('{{ a|timesince:b }}', {'a': now_tz_i, 'b': now}, ''),
# Regression for #9065 (two date objects).
- 'filter-timesince17' : ('{{ a|timesince:b }}', {'a': today, 'b': today}, '0 minutes'),
- 'filter-timesince18' : ('{{ a|timesince:b }}', {'a': today, 'b': today + timedelta(hours=24)}, '1 day'),
+ 'filter-timesince17' : ('{{ a|timesince:b }}', {'a': today, 'b': today}, '0\xa0minutes'),
+ 'filter-timesince18' : ('{{ a|timesince:b }}', {'a': today, 'b': today + timedelta(hours=24)}, '1\xa0day'),
# Default compare with datetime.now()
- 'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'),
- 'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1 day'),
- 'filter-timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8 hours, 10 minutes'),
+ 'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2\xa0minutes'),
+ 'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1\xa0day'),
+ 'filter-timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8\xa0hours, 10\xa0minutes'),
# Compare to a given parameter
- 'filter-timeuntil04' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=1), 'b':now - timedelta(days=2)}, '1 day'),
- 'filter-timeuntil05' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=2, minutes=1)}, '1 minute'),
+ 'filter-timeuntil04' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=1), 'b':now - timedelta(days=2)}, '1\xa0day'),
+ 'filter-timeuntil05' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=2, minutes=1)}, '1\xa0minute'),
# Regression for #7443
- 'filter-timeuntil06': ('{{ earlier|timeuntil }}', { 'earlier': now - timedelta(days=7) }, '0 minutes'),
- 'filter-timeuntil07': ('{{ earlier|timeuntil:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '0 minutes'),
- 'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now + timedelta(days=7, hours=1) }, '1 week'),
- 'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1 week'),
+ 'filter-timeuntil06': ('{{ earlier|timeuntil }}', { 'earlier': now - timedelta(days=7) }, '0\xa0minutes'),
+ 'filter-timeuntil07': ('{{ earlier|timeuntil:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '0\xa0minutes'),
+ 'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now + timedelta(days=7, hours=1) }, '1\xa0week'),
+ 'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1\xa0week'),
# Ensures that differing timezones are calculated correctly
- 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0 minutes'),
- 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0 minutes'),
+ 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0\xa0minutes'),
+ 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0\xa0minutes'),
# Regression for #9065 (two date objects).
- 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0 minutes'),
- 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1 day'),
+ 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0\xa0minutes'),
+ 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1\xa0day'),
'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{ b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"<a>\' <a>\'"),
'filter-addslash02': ("{{ a|addslashes }} {{ b|addslashes }}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"&lt;a&gt;\&#39; <a>\'"),
diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py
index aeb9bc3d2c..0f16a9c805 100644
--- a/tests/transactions/tests.py
+++ b/tests/transactions/tests.py
@@ -5,6 +5,7 @@ import warnings
from django.db import connection, transaction, IntegrityError
from django.test import TransactionTestCase, skipUnlessDBFeature
+from django.test.utils import IgnorePendingDeprecationWarningsMixin
from django.utils import six
from django.utils.unittest import skipIf, skipUnless
@@ -319,19 +320,6 @@ class AtomicMiscTests(TransactionTestCase):
transaction.atomic(Callable())
-class IgnorePendingDeprecationWarningsMixin(object):
-
- def setUp(self):
- super(IgnorePendingDeprecationWarningsMixin, self).setUp()
- self.catch_warnings = warnings.catch_warnings()
- self.catch_warnings.__enter__()
- warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
-
- def tearDown(self):
- self.catch_warnings.__exit__(*sys.exc_info())
- super(IgnorePendingDeprecationWarningsMixin, self).tearDown()
-
-
class TransactionTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
def create_a_reporter_then_fail(self, first, last):
diff --git a/tests/transactions_regress/tests.py b/tests/transactions_regress/tests.py
index fb3f257dab..5339b4a8ea 100644
--- a/tests/transactions_regress/tests.py
+++ b/tests/transactions_regress/tests.py
@@ -4,11 +4,9 @@ from django.db import (connection, connections, transaction, DEFAULT_DB_ALIAS, D
IntegrityError)
from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError
from django.test import TransactionTestCase, skipUnlessDBFeature
-from django.test.utils import override_settings
+from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
from django.utils.unittest import skipIf, skipUnless
-from transactions.tests import IgnorePendingDeprecationWarningsMixin
-
from .models import Mod, M2mA, M2mB, SubMod
class ModelInheritanceTests(TransactionTestCase):
diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py
index 5e641a42c4..cdb95e6877 100644
--- a/tests/utils_tests/test_timesince.py
+++ b/tests/utils_tests/test_timesince.py
@@ -21,32 +21,33 @@ class TimesinceTests(unittest.TestCase):
def test_equal_datetimes(self):
""" equal datetimes. """
- self.assertEqual(timesince(self.t, self.t), '0 minutes')
+ # NOTE: \xa0 avoids wrapping between value and unit
+ self.assertEqual(timesince(self.t, self.t), '0\xa0minutes')
def test_ignore_microseconds_and_seconds(self):
""" Microseconds and seconds are ignored. """
self.assertEqual(timesince(self.t, self.t+self.onemicrosecond),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t+self.onesecond),
- '0 minutes')
+ '0\xa0minutes')
def test_other_units(self):
""" Test other units. """
self.assertEqual(timesince(self.t, self.t+self.oneminute),
- '1 minute')
- self.assertEqual(timesince(self.t, self.t+self.onehour), '1 hour')
- self.assertEqual(timesince(self.t, self.t+self.oneday), '1 day')
- self.assertEqual(timesince(self.t, self.t+self.oneweek), '1 week')
+ '1\xa0minute')
+ self.assertEqual(timesince(self.t, self.t+self.onehour), '1\xa0hour')
+ self.assertEqual(timesince(self.t, self.t+self.oneday), '1\xa0day')
+ self.assertEqual(timesince(self.t, self.t+self.oneweek), '1\xa0week')
self.assertEqual(timesince(self.t, self.t+self.onemonth),
- '1 month')
- self.assertEqual(timesince(self.t, self.t+self.oneyear), '1 year')
+ '1\xa0month')
+ self.assertEqual(timesince(self.t, self.t+self.oneyear), '1\xa0year')
def test_multiple_units(self):
""" Test multiple units. """
self.assertEqual(timesince(self.t,
- self.t+2*self.oneday+6*self.onehour), '2 days, 6 hours')
+ self.t+2*self.oneday+6*self.onehour), '2\xa0days, 6\xa0hours')
self.assertEqual(timesince(self.t,
- self.t+2*self.oneweek+2*self.oneday), '2 weeks, 2 days')
+ self.t+2*self.oneweek+2*self.oneday), '2\xa0weeks, 2\xa0days')
def test_display_first_unit(self):
"""
@@ -55,10 +56,10 @@ class TimesinceTests(unittest.TestCase):
"""
self.assertEqual(timesince(self.t,
self.t+2*self.oneweek+3*self.onehour+4*self.oneminute),
- '2 weeks')
+ '2\xa0weeks')
self.assertEqual(timesince(self.t,
- self.t+4*self.oneday+5*self.oneminute), '4 days')
+ self.t+4*self.oneday+5*self.oneminute), '4\xa0days')
def test_display_second_before_first(self):
"""
@@ -66,30 +67,30 @@ class TimesinceTests(unittest.TestCase):
get 0 minutes.
"""
self.assertEqual(timesince(self.t, self.t-self.onemicrosecond),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.onesecond),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.oneminute),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.onehour),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.oneday),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.oneweek),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.onemonth),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t, self.t-self.oneyear),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t,
- self.t-2*self.oneday-6*self.onehour), '0 minutes')
+ self.t-2*self.oneday-6*self.onehour), '0\xa0minutes')
self.assertEqual(timesince(self.t,
- self.t-2*self.oneweek-2*self.oneday), '0 minutes')
+ self.t-2*self.oneweek-2*self.oneday), '0\xa0minutes')
self.assertEqual(timesince(self.t,
self.t-2*self.oneweek-3*self.onehour-4*self.oneminute),
- '0 minutes')
+ '0\xa0minutes')
self.assertEqual(timesince(self.t,
- self.t-4*self.oneday-5*self.oneminute), '0 minutes')
+ self.t-4*self.oneday-5*self.oneminute), '0\xa0minutes')
def test_different_timezones(self):
""" When using two different timezones. """
@@ -97,28 +98,28 @@ class TimesinceTests(unittest.TestCase):
now_tz = datetime.datetime.now(LocalTimezone(now))
now_tz_i = datetime.datetime.now(FixedOffset((3 * 60) + 15))
- self.assertEqual(timesince(now), '0 minutes')
- self.assertEqual(timesince(now_tz), '0 minutes')
- self.assertEqual(timeuntil(now_tz, now_tz_i), '0 minutes')
+ self.assertEqual(timesince(now), '0\xa0minutes')
+ self.assertEqual(timesince(now_tz), '0\xa0minutes')
+ self.assertEqual(timeuntil(now_tz, now_tz_i), '0\xa0minutes')
def test_date_objects(self):
""" Both timesince and timeuntil should work on date objects (#17937). """
today = datetime.date.today()
- self.assertEqual(timesince(today + self.oneday), '0 minutes')
- self.assertEqual(timeuntil(today - self.oneday), '0 minutes')
+ self.assertEqual(timesince(today + self.oneday), '0\xa0minutes')
+ self.assertEqual(timeuntil(today - self.oneday), '0\xa0minutes')
def test_both_date_objects(self):
""" Timesince should work with both date objects (#9672) """
today = datetime.date.today()
- self.assertEqual(timeuntil(today + self.oneday, today), '1 day')
- self.assertEqual(timeuntil(today - self.oneday, today), '0 minutes')
- self.assertEqual(timeuntil(today + self.oneweek, today), '1 week')
+ self.assertEqual(timeuntil(today + self.oneday, today), '1\xa0day')
+ self.assertEqual(timeuntil(today - self.oneday, today), '0\xa0minutes')
+ self.assertEqual(timeuntil(today + self.oneweek, today), '1\xa0week')
def test_naive_datetime_with_tzinfo_attribute(self):
class naive(datetime.tzinfo):
def utcoffset(self, dt):
return None
future = datetime.datetime(2080, 1, 1, tzinfo=naive())
- self.assertEqual(timesince(future), '0 minutes')
+ self.assertEqual(timesince(future), '0\xa0minutes')
past = datetime.datetime(1980, 1, 1, tzinfo=naive())
- self.assertEqual(timeuntil(past), '0 minutes')
+ self.assertEqual(timeuntil(past), '0\xa0minutes')
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index b44cd88abe..a84b41959c 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -6,6 +6,7 @@ from __future__ import absolute_import, unicode_literals
import inspect
import os
import sys
+import tempfile
from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -13,7 +14,7 @@ from django.core.urlresolvers import reverse
from django.test import TestCase, RequestFactory
from django.test.utils import (override_settings, setup_test_template_loader,
restore_template_loaders)
-from django.utils.encoding import force_text
+from django.utils.encoding import force_text, force_bytes
from django.views.debug import ExceptionReporter
from .. import BrokenException, except_args
@@ -122,6 +123,24 @@ class ExceptionReporterTests(TestCase):
self.assertIn('<h2>Request information</h2>', html)
self.assertIn('<p>Request data not supplied</p>', html)
+ def test_eol_support(self):
+ """Test that the ExceptionReporter supports Unix, Windows and Macintosh EOL markers"""
+ LINES = list('print %d' % i for i in range(1, 6))
+ reporter = ExceptionReporter(None, None, None, None)
+
+ for newline in ['\n','\r\n','\r']:
+ fd,filename = tempfile.mkstemp(text = False)
+ os.write(fd, force_bytes(newline.join(LINES)+newline))
+ os.close(fd)
+
+ try:
+ self.assertEqual(
+ reporter._get_lines_from_file(filename, 3, 2),
+ (1, LINES[1:3], LINES[3], LINES[4:])
+ )
+ finally:
+ os.unlink(filename)
+
def test_no_exception(self):
"An exception report can be generated for just a request"
request = self.rf.get('/test_view/')