Used assertRaisesMessage() to test Django's error messages.
This commit is contained in:
parent
38988f289f
commit
a51c4de194
|
@ -30,7 +30,8 @@ class TestRegistration(SimpleTestCase):
|
||||||
|
|
||||||
def test_prevent_double_registration(self):
|
def test_prevent_double_registration(self):
|
||||||
self.site.register(Person)
|
self.site.register(Person)
|
||||||
with self.assertRaises(admin.sites.AlreadyRegistered):
|
msg = 'The model Person is already registered'
|
||||||
|
with self.assertRaisesMessage(admin.sites.AlreadyRegistered, msg):
|
||||||
self.site.register(Person)
|
self.site.register(Person)
|
||||||
|
|
||||||
def test_registration_with_star_star_options(self):
|
def test_registration_with_star_star_options(self):
|
||||||
|
@ -55,7 +56,8 @@ class TestRegistration(SimpleTestCase):
|
||||||
Exception is raised when trying to register an abstract model.
|
Exception is raised when trying to register an abstract model.
|
||||||
Refs #12004.
|
Refs #12004.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = 'The model Location is abstract, so it cannot be registered with admin.'
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.site.register(Location)
|
self.site.register(Location)
|
||||||
|
|
||||||
def test_is_registered_model(self):
|
def test_is_registered_model(self):
|
||||||
|
|
|
@ -222,7 +222,7 @@ class UtilsTests(SimpleTestCase):
|
||||||
"article"
|
"article"
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaisesMessage(AttributeError, "Unable to lookup 'unknown' on Article"):
|
||||||
label_for_field("unknown", Article)
|
label_for_field("unknown", Article)
|
||||||
|
|
||||||
def test_callable(obj):
|
def test_callable(obj):
|
||||||
|
|
|
@ -431,13 +431,23 @@ class AggregationTests(TestCase):
|
||||||
|
|
||||||
def test_field_error(self):
|
def test_field_error(self):
|
||||||
# Bad field requests in aggregates are caught and reported
|
# Bad field requests in aggregates are caught and reported
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'foo' into field. Choices are: authors, "
|
||||||
|
"contact, contact_id, hardbackbook, id, isbn, name, pages, price, "
|
||||||
|
"pubdate, publisher, publisher_id, rating, store, tags"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Book.objects.all().aggregate(num_authors=Count('foo'))
|
Book.objects.all().aggregate(num_authors=Count('foo'))
|
||||||
|
|
||||||
with self.assertRaises(FieldError):
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Book.objects.all().annotate(num_authors=Count('foo'))
|
Book.objects.all().annotate(num_authors=Count('foo'))
|
||||||
|
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'foo' into field. Choices are: authors, "
|
||||||
|
"contact, contact_id, hardbackbook, id, isbn, name, num_authors, "
|
||||||
|
"pages, price, pubdate, publisher, publisher_id, rating, store, tags"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo'))
|
Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo'))
|
||||||
|
|
||||||
def test_more(self):
|
def test_more(self):
|
||||||
|
@ -738,19 +748,25 @@ class AggregationTests(TestCase):
|
||||||
|
|
||||||
def test_duplicate_alias(self):
|
def test_duplicate_alias(self):
|
||||||
# Regression for #11256 - duplicating a default alias raises ValueError.
|
# Regression for #11256 - duplicating a default alias raises ValueError.
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
"The named annotation 'authors__age__avg' conflicts with "
|
||||||
|
"the default name for another annotation."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Book.objects.all().annotate(Avg('authors__age'), authors__age__avg=Avg('authors__age'))
|
Book.objects.all().annotate(Avg('authors__age'), authors__age__avg=Avg('authors__age'))
|
||||||
|
|
||||||
def test_field_name_conflict(self):
|
def test_field_name_conflict(self):
|
||||||
# Regression for #11256 - providing an aggregate name
|
# Regression for #11256 - providing an aggregate name
|
||||||
# that conflicts with a field name on the model raises ValueError
|
# that conflicts with a field name on the model raises ValueError
|
||||||
with self.assertRaises(ValueError):
|
msg = "The annotation 'age' conflicts with a field on the model."
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Author.objects.annotate(age=Avg('friends__age'))
|
Author.objects.annotate(age=Avg('friends__age'))
|
||||||
|
|
||||||
def test_m2m_name_conflict(self):
|
def test_m2m_name_conflict(self):
|
||||||
# Regression for #11256 - providing an aggregate name
|
# Regression for #11256 - providing an aggregate name
|
||||||
# that conflicts with an m2m name on the model raises ValueError
|
# that conflicts with an m2m name on the model raises ValueError
|
||||||
with self.assertRaises(ValueError):
|
msg = "The annotation 'friends' conflicts with a field on the model."
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Author.objects.annotate(friends=Count('friends'))
|
Author.objects.annotate(friends=Count('friends'))
|
||||||
|
|
||||||
def test_values_queryset_non_conflict(self):
|
def test_values_queryset_non_conflict(self):
|
||||||
|
@ -778,7 +794,8 @@ class AggregationTests(TestCase):
|
||||||
def test_reverse_relation_name_conflict(self):
|
def test_reverse_relation_name_conflict(self):
|
||||||
# Regression for #11256 - providing an aggregate name
|
# Regression for #11256 - providing an aggregate name
|
||||||
# that conflicts with a reverse-related name on the model raises ValueError
|
# that conflicts with a reverse-related name on the model raises ValueError
|
||||||
with self.assertRaises(ValueError):
|
msg = "The annotation 'book_contact_set' conflicts with a field on the model."
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Author.objects.annotate(book_contact_set=Avg('friends__age'))
|
Author.objects.annotate(book_contact_set=Avg('friends__age'))
|
||||||
|
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
|
@ -937,7 +954,8 @@ class AggregationTests(TestCase):
|
||||||
|
|
||||||
# Regression for #10766 - Shouldn't be able to reference an aggregate
|
# Regression for #10766 - Shouldn't be able to reference an aggregate
|
||||||
# fields in an aggregate() call.
|
# fields in an aggregate() call.
|
||||||
with self.assertRaises(FieldError):
|
msg = "Cannot compute Avg('mean_age'): 'mean_age' is an aggregate"
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age'))
|
Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age'))
|
||||||
|
|
||||||
def test_empty_filter_count(self):
|
def test_empty_filter_count(self):
|
||||||
|
|
|
@ -53,7 +53,8 @@ class AppsTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Tests when INSTALLED_APPS contains an incorrect app config.
|
Tests when INSTALLED_APPS contains an incorrect app config.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = "'apps.apps.BadConfig' must supply a name attribute."
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
with self.settings(INSTALLED_APPS=['apps.apps.BadConfig']):
|
with self.settings(INSTALLED_APPS=['apps.apps.BadConfig']):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -61,7 +62,8 @@ class AppsTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Tests when INSTALLED_APPS contains a class that isn't an app config.
|
Tests when INSTALLED_APPS contains a class that isn't an app config.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = "'apps.apps.NotAConfig' isn't a subclass of AppConfig."
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
with self.settings(INSTALLED_APPS=['apps.apps.NotAConfig']):
|
with self.settings(INSTALLED_APPS=['apps.apps.NotAConfig']):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -445,7 +445,11 @@ class NoBackendsTest(TestCase):
|
||||||
self.user = User.objects.create_user('test', 'test@example.com', 'test')
|
self.user = User.objects.create_user('test', 'test@example.com', 'test')
|
||||||
|
|
||||||
def test_raises_exception(self):
|
def test_raises_exception(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'No authentication backends have been defined. '
|
||||||
|
'Does AUTHENTICATION_BACKENDS contain anything?'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.user.has_perm(('perm', TestObj()))
|
self.user.has_perm(('perm', TestObj()))
|
||||||
|
|
||||||
|
|
||||||
|
@ -626,7 +630,11 @@ class ImproperlyConfiguredUserModelTest(TestCase):
|
||||||
request = HttpRequest()
|
request = HttpRequest()
|
||||||
request.session = self.client.session
|
request.session = self.client.session
|
||||||
|
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"AUTH_USER_MODEL refers to model 'thismodel.doesntexist' "
|
||||||
|
"that has not been installed"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
get_user(request)
|
get_user(request)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,13 +97,18 @@ class BasicTestCase(TestCase):
|
||||||
@override_settings(AUTH_USER_MODEL='badsetting')
|
@override_settings(AUTH_USER_MODEL='badsetting')
|
||||||
def test_swappable_user_bad_setting(self):
|
def test_swappable_user_bad_setting(self):
|
||||||
"The alternate user setting must point to something in the format app.model"
|
"The alternate user setting must point to something in the format app.model"
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = "AUTH_USER_MODEL must be of the form 'app_label.model_name'"
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
get_user_model()
|
get_user_model()
|
||||||
|
|
||||||
@override_settings(AUTH_USER_MODEL='thismodel.doesntexist')
|
@override_settings(AUTH_USER_MODEL='thismodel.doesntexist')
|
||||||
def test_swappable_user_nonexistent_model(self):
|
def test_swappable_user_nonexistent_model(self):
|
||||||
"The current user model must point to an installed model"
|
"The current user model must point to an installed model"
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"AUTH_USER_MODEL refers to model 'thismodel.doesntexist' "
|
||||||
|
"that has not been installed"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
get_user_model()
|
get_user_model()
|
||||||
|
|
||||||
def test_user_verbose_names_translatable(self):
|
def test_user_verbose_names_translatable(self):
|
||||||
|
|
|
@ -158,7 +158,8 @@ class ChangepasswordManagementCommandTestCase(TestCase):
|
||||||
A CommandError should be thrown by handle() if the user enters in
|
A CommandError should be thrown by handle() if the user enters in
|
||||||
mismatched passwords three times.
|
mismatched passwords three times.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(CommandError):
|
msg = "Aborting password change for user 'joe' after 3 attempts"
|
||||||
|
with self.assertRaisesMessage(CommandError, msg):
|
||||||
call_command('changepassword', username='joe', stdout=self.stdout, stderr=self.stderr)
|
call_command('changepassword', username='joe', stdout=self.stdout, stderr=self.stderr)
|
||||||
|
|
||||||
@mock.patch.object(changepassword.Command, '_get_pass', return_value='1234567890')
|
@mock.patch.object(changepassword.Command, '_get_pass', return_value='1234567890')
|
||||||
|
@ -316,7 +317,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase):
|
||||||
# We skip validation because the temporary substitution of the
|
# We skip validation because the temporary substitution of the
|
||||||
# swappable User model messes with validation.
|
# swappable User model messes with validation.
|
||||||
new_io = StringIO()
|
new_io = StringIO()
|
||||||
with self.assertRaises(CommandError):
|
with self.assertRaisesMessage(CommandError, 'You must use --email with --noinput.'):
|
||||||
call_command(
|
call_command(
|
||||||
"createsuperuser",
|
"createsuperuser",
|
||||||
interactive=False,
|
interactive=False,
|
||||||
|
|
|
@ -335,8 +335,8 @@ class ModelTest(TestCase):
|
||||||
self.assertEqual(article.headline, notlazy)
|
self.assertEqual(article.headline, notlazy)
|
||||||
|
|
||||||
def test_emptyqs(self):
|
def test_emptyqs(self):
|
||||||
# Can't be instantiated
|
msg = "EmptyQuerySet can't be instantiated"
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
EmptyQuerySet()
|
EmptyQuerySet()
|
||||||
self.assertIsInstance(Article.objects.none(), EmptyQuerySet)
|
self.assertIsInstance(Article.objects.none(), EmptyQuerySet)
|
||||||
self.assertNotIsInstance('', EmptyQuerySet)
|
self.assertNotIsInstance('', EmptyQuerySet)
|
||||||
|
@ -397,7 +397,8 @@ class ModelTest(TestCase):
|
||||||
def test_hash(self):
|
def test_hash(self):
|
||||||
# Value based on PK
|
# Value based on PK
|
||||||
self.assertEqual(hash(Article(id=1)), hash(1))
|
self.assertEqual(hash(Article(id=1)), hash(1))
|
||||||
with self.assertRaises(TypeError):
|
msg = 'Model instances without primary key value are unhashable'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
# No PK value -> unhashable (because save() would then change
|
# No PK value -> unhashable (because save() would then change
|
||||||
# hash)
|
# hash)
|
||||||
hash(Article())
|
hash(Article())
|
||||||
|
@ -618,7 +619,7 @@ class SelectOnSaveTests(TestCase):
|
||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
asos.save(force_update=True)
|
asos.save(force_update=True)
|
||||||
Article.objects.all().delete()
|
Article.objects.all().delete()
|
||||||
with self.assertRaises(DatabaseError):
|
with self.assertRaisesMessage(DatabaseError, 'Forced update did not affect any rows.'):
|
||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
asos.save(force_update=True)
|
asos.save(force_update=True)
|
||||||
|
|
||||||
|
@ -653,9 +654,13 @@ class SelectOnSaveTests(TestCase):
|
||||||
# This is not wanted behavior, but this is how Django has always
|
# This is not wanted behavior, but this is how Django has always
|
||||||
# behaved for databases that do not return correct information
|
# behaved for databases that do not return correct information
|
||||||
# about matched rows for UPDATE.
|
# about matched rows for UPDATE.
|
||||||
with self.assertRaises(DatabaseError):
|
with self.assertRaisesMessage(DatabaseError, 'Forced update did not affect any rows.'):
|
||||||
asos.save(force_update=True)
|
asos.save(force_update=True)
|
||||||
with self.assertRaises(DatabaseError):
|
msg = (
|
||||||
|
"An error occurred in the current transaction. You can't "
|
||||||
|
"execute queries until the end of the 'atomic' block."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(DatabaseError, msg):
|
||||||
asos.save(update_fields=['pub_date'])
|
asos.save(update_fields=['pub_date'])
|
||||||
finally:
|
finally:
|
||||||
Article._base_manager._queryset_class = orig_class
|
Article._base_manager._queryset_class = orig_class
|
||||||
|
@ -688,7 +693,8 @@ class ModelRefreshTests(TestCase):
|
||||||
|
|
||||||
def test_unknown_kwarg(self):
|
def test_unknown_kwarg(self):
|
||||||
s = SelfRef.objects.create()
|
s = SelfRef.objects.create()
|
||||||
with self.assertRaises(TypeError):
|
msg = "refresh_from_db() got an unexpected keyword argument 'unknown_kwarg'"
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
s.refresh_from_db(unknown_kwarg=10)
|
s.refresh_from_db(unknown_kwarg=10)
|
||||||
|
|
||||||
def test_refresh_fk(self):
|
def test_refresh_fk(self):
|
||||||
|
|
|
@ -108,7 +108,8 @@ class BulkCreateTests(TestCase):
|
||||||
"""
|
"""
|
||||||
valid_country = Country(name='Germany', iso_two_letter='DE')
|
valid_country = Country(name='Germany', iso_two_letter='DE')
|
||||||
invalid_country = Country(id=0, name='Poland', iso_two_letter='PL')
|
invalid_country = Country(id=0, name='Poland', iso_two_letter='PL')
|
||||||
with self.assertRaises(ValueError):
|
msg = 'The database backend does not accept 0 as a value for AutoField.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Country.objects.bulk_create([valid_country, invalid_country])
|
Country.objects.bulk_create([valid_country, invalid_country])
|
||||||
|
|
||||||
def test_batch_same_vals(self):
|
def test_batch_same_vals(self):
|
||||||
|
|
|
@ -179,7 +179,8 @@ class CheckCommandTests(SimpleTestCase):
|
||||||
|
|
||||||
@override_system_checks([simple_system_check, tagged_system_check])
|
@override_system_checks([simple_system_check, tagged_system_check])
|
||||||
def test_invalid_tag(self):
|
def test_invalid_tag(self):
|
||||||
with self.assertRaises(CommandError):
|
msg = 'There is no system check with the "missingtag" tag.'
|
||||||
|
with self.assertRaisesMessage(CommandError, msg):
|
||||||
call_command('check', tags=['missingtag'])
|
call_command('check', tags=['missingtag'])
|
||||||
|
|
||||||
@override_system_checks([simple_system_check])
|
@override_system_checks([simple_system_check])
|
||||||
|
|
|
@ -37,7 +37,11 @@ class CustomColumnsTests(TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_field_error(self):
|
def test_field_error(self):
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'firstname' into field. Choices are: "
|
||||||
|
"Author_ID, article, first_name, last_name, primary_set"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Author.objects.filter(firstname__exact="John")
|
Author.objects.filter(firstname__exact="John")
|
||||||
|
|
||||||
def test_attribute_error(self):
|
def test_attribute_error(self):
|
||||||
|
|
|
@ -319,7 +319,8 @@ class BilateralTransformTests(TestCase):
|
||||||
|
|
||||||
def test_bilateral_inner_qs(self):
|
def test_bilateral_inner_qs(self):
|
||||||
with register_lookup(models.CharField, UpperBilateralTransform):
|
with register_lookup(models.CharField, UpperBilateralTransform):
|
||||||
with self.assertRaises(NotImplementedError):
|
msg = 'Bilateral transformations on nested querysets are not supported.'
|
||||||
|
with self.assertRaisesMessage(NotImplementedError, msg):
|
||||||
Author.objects.filter(name__upper__in=Author.objects.values_list('name'))
|
Author.objects.filter(name__upper__in=Author.objects.values_list('name'))
|
||||||
|
|
||||||
def test_bilateral_multi_value(self):
|
def test_bilateral_multi_value(self):
|
||||||
|
@ -501,13 +502,14 @@ class LookupTransformCallOrderTests(TestCase):
|
||||||
def test_call_order(self):
|
def test_call_order(self):
|
||||||
with register_lookup(models.DateField, TrackCallsYearTransform):
|
with register_lookup(models.DateField, TrackCallsYearTransform):
|
||||||
# junk lookup - tries lookup, then transform, then fails
|
# junk lookup - tries lookup, then transform, then fails
|
||||||
with self.assertRaises(FieldError):
|
msg = "Unsupported lookup 'junk' for IntegerField or join on the field not permitted."
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Author.objects.filter(birthdate__testyear__junk=2012)
|
Author.objects.filter(birthdate__testyear__junk=2012)
|
||||||
self.assertEqual(TrackCallsYearTransform.call_order,
|
self.assertEqual(TrackCallsYearTransform.call_order,
|
||||||
['lookup', 'transform'])
|
['lookup', 'transform'])
|
||||||
TrackCallsYearTransform.call_order = []
|
TrackCallsYearTransform.call_order = []
|
||||||
# junk transform - tries transform only, then fails
|
# junk transform - tries transform only, then fails
|
||||||
with self.assertRaises(FieldError):
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Author.objects.filter(birthdate__testyear__junk__more_junk=2012)
|
Author.objects.filter(birthdate__testyear__junk__more_junk=2012)
|
||||||
self.assertEqual(TrackCallsYearTransform.call_order,
|
self.assertEqual(TrackCallsYearTransform.call_order,
|
||||||
['transform'])
|
['transform'])
|
||||||
|
|
|
@ -58,7 +58,8 @@ class CustomManagerTests(TestCase):
|
||||||
# Methods with queryset_only=False are copied even if they are private.
|
# Methods with queryset_only=False are copied even if they are private.
|
||||||
manager._optin_private_method()
|
manager._optin_private_method()
|
||||||
# Methods with queryset_only=True aren't copied even if they are public.
|
# Methods with queryset_only=True aren't copied even if they are public.
|
||||||
with self.assertRaises(AttributeError):
|
msg = "%r object has no attribute 'optout_public_method'" % manager.__class__.__name__
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
manager.optout_public_method()
|
manager.optout_public_method()
|
||||||
|
|
||||||
def test_manager_use_queryset_methods(self):
|
def test_manager_use_queryset_methods(self):
|
||||||
|
@ -93,7 +94,8 @@ class CustomManagerTests(TestCase):
|
||||||
querysets.
|
querysets.
|
||||||
"""
|
"""
|
||||||
Person.custom_queryset_custom_manager.manager_only()
|
Person.custom_queryset_custom_manager.manager_only()
|
||||||
with self.assertRaises(AttributeError):
|
msg = "'CustomQuerySet' object has no attribute 'manager_only'"
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
Person.custom_queryset_custom_manager.all().manager_only()
|
Person.custom_queryset_custom_manager.all().manager_only()
|
||||||
|
|
||||||
def test_queryset_and_manager(self):
|
def test_queryset_and_manager(self):
|
||||||
|
@ -116,7 +118,8 @@ class CustomManagerTests(TestCase):
|
||||||
The default manager, "objects", doesn't exist, because a custom one
|
The default manager, "objects", doesn't exist, because a custom one
|
||||||
was provided.
|
was provided.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(AttributeError):
|
msg = "type object 'Book' has no attribute 'objects'"
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
Book.objects
|
Book.objects
|
||||||
|
|
||||||
def test_filtering(self):
|
def test_filtering(self):
|
||||||
|
|
|
@ -145,7 +145,7 @@ class BasicCustomPKTests(TestCase):
|
||||||
# Or we can use the real attribute name for the primary key:
|
# Or we can use the real attribute name for the primary key:
|
||||||
self.assertEqual(e.employee_code, 123)
|
self.assertEqual(e.employee_code, 123)
|
||||||
|
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaisesMessage(AttributeError, "'Employee' object has no attribute 'id'"):
|
||||||
e.id
|
e.id
|
||||||
|
|
||||||
def test_in_bulk(self):
|
def test_in_bulk(self):
|
||||||
|
|
|
@ -60,7 +60,11 @@ class OnDeleteTests(TestCase):
|
||||||
|
|
||||||
def test_protect(self):
|
def test_protect(self):
|
||||||
a = create_a('protect')
|
a = create_a('protect')
|
||||||
with self.assertRaises(IntegrityError):
|
msg = (
|
||||||
|
"Cannot delete some instances of model 'R' because they are "
|
||||||
|
"referenced through a protected foreign key: 'A.protect'"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(IntegrityError, msg):
|
||||||
a.protect.delete()
|
a.protect.delete()
|
||||||
|
|
||||||
def test_do_nothing(self):
|
def test_do_nothing(self):
|
||||||
|
|
|
@ -244,9 +244,10 @@ class ProxyDeleteTest(TestCase):
|
||||||
self.assertEqual(len(FooFileProxy.objects.all()), 0)
|
self.assertEqual(len(FooFileProxy.objects.all()), 0)
|
||||||
|
|
||||||
def test_19187_values(self):
|
def test_19187_values(self):
|
||||||
with self.assertRaises(TypeError):
|
msg = 'Cannot call delete() after .values() or .values_list()'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
Image.objects.values().delete()
|
Image.objects.values().delete()
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
Image.objects.values_list().delete()
|
Image.objects.values_list().delete()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,16 +97,18 @@ class DistinctOnTests(TestCase):
|
||||||
|
|
||||||
def test_distinct_not_implemented_checks(self):
|
def test_distinct_not_implemented_checks(self):
|
||||||
# distinct + annotate not allowed
|
# distinct + annotate not allowed
|
||||||
with self.assertRaises(NotImplementedError):
|
msg = 'annotate() + distinct(fields) is not implemented.'
|
||||||
|
with self.assertRaisesMessage(NotImplementedError, msg):
|
||||||
Celebrity.objects.annotate(Max('id')).distinct('id')[0]
|
Celebrity.objects.annotate(Max('id')).distinct('id')[0]
|
||||||
with self.assertRaises(NotImplementedError):
|
with self.assertRaisesMessage(NotImplementedError, msg):
|
||||||
Celebrity.objects.distinct('id').annotate(Max('id'))[0]
|
Celebrity.objects.distinct('id').annotate(Max('id'))[0]
|
||||||
|
|
||||||
# However this check is done only when the query executes, so you
|
# However this check is done only when the query executes, so you
|
||||||
# can use distinct() to remove the fields before execution.
|
# can use distinct() to remove the fields before execution.
|
||||||
Celebrity.objects.distinct('id').annotate(Max('id')).distinct()[0]
|
Celebrity.objects.distinct('id').annotate(Max('id')).distinct()[0]
|
||||||
# distinct + aggregate not allowed
|
# distinct + aggregate not allowed
|
||||||
with self.assertRaises(NotImplementedError):
|
msg = 'aggregate() + distinct(fields) not implemented.'
|
||||||
|
with self.assertRaisesMessage(NotImplementedError, msg):
|
||||||
Celebrity.objects.distinct('id').aggregate(Max('id'))
|
Celebrity.objects.distinct('id').aggregate(Max('id'))
|
||||||
|
|
||||||
def test_distinct_on_in_ordered_subquery(self):
|
def test_distinct_on_in_ordered_subquery(self):
|
||||||
|
|
|
@ -246,7 +246,8 @@ class BasicExpressionsTests(TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
with self.assertRaises(FieldError):
|
msg = "Joined field references are not permitted in this query"
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Company.objects.exclude(
|
Company.objects.exclude(
|
||||||
ceo__firstname=F('point_of_contact__firstname')
|
ceo__firstname=F('point_of_contact__firstname')
|
||||||
).update(name=F('point_of_contact__lastname'))
|
).update(name=F('point_of_contact__lastname'))
|
||||||
|
@ -293,13 +294,15 @@ class BasicExpressionsTests(TestCase):
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
test_gmbh.point_of_contact = F("ceo")
|
test_gmbh.point_of_contact = F("ceo")
|
||||||
with self.assertRaises(ValueError):
|
msg = 'F(ceo)": "Company.point_of_contact" must be a "Employee" instance.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
test()
|
test()
|
||||||
|
|
||||||
test_gmbh.point_of_contact = test_gmbh.ceo
|
test_gmbh.point_of_contact = test_gmbh.ceo
|
||||||
test_gmbh.save()
|
test_gmbh.save()
|
||||||
test_gmbh.name = F("ceo__last_name")
|
test_gmbh.name = F("ceo__last_name")
|
||||||
with self.assertRaises(FieldError):
|
msg = 'Joined field references are not permitted in this query'
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
test_gmbh.save()
|
test_gmbh.save()
|
||||||
|
|
||||||
def test_object_update_unsaved_objects(self):
|
def test_object_update_unsaved_objects(self):
|
||||||
|
|
|
@ -128,17 +128,21 @@ class FlatpageTemplateTagTests(TestCase):
|
||||||
def render(t):
|
def render(t):
|
||||||
return Template(t).render(Context())
|
return Template(t).render(Context())
|
||||||
|
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = (
|
||||||
|
"get_flatpages expects a syntax of get_flatpages "
|
||||||
|
"['url_starts_with'] [for user] as context_name"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages %}")
|
render("{% load flatpages %}{% get_flatpages %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages as %}")
|
render("{% load flatpages %}{% get_flatpages as %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages cheesecake flatpages %}")
|
render("{% load flatpages %}{% get_flatpages cheesecake flatpages %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages as flatpages asdf %}")
|
render("{% load flatpages %}{% get_flatpages as flatpages asdf %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages cheesecake user as flatpages %}")
|
render("{% load flatpages %}{% get_flatpages cheesecake user as flatpages %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages for user as flatpages asdf %}")
|
render("{% load flatpages %}{% get_flatpages for user as flatpages asdf %}")
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
render("{% load flatpages %}{% get_flatpages prefix for user as flatpages asdf %}")
|
render("{% load flatpages %}{% get_flatpages prefix for user as flatpages asdf %}")
|
||||||
|
|
|
@ -20,13 +20,15 @@ class ForceTests(TestCase):
|
||||||
# Won't work because force_update and force_insert are mutually
|
# Won't work because force_update and force_insert are mutually
|
||||||
# exclusive
|
# exclusive
|
||||||
c.value = 4
|
c.value = 4
|
||||||
with self.assertRaises(ValueError):
|
msg = 'Cannot force both insert and updating in model saving.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
c.save(force_insert=True, force_update=True)
|
c.save(force_insert=True, force_update=True)
|
||||||
|
|
||||||
# Try to update something that doesn't have a primary key in the first
|
# Try to update something that doesn't have a primary key in the first
|
||||||
# place.
|
# place.
|
||||||
c1 = Counter(name="two", value=2)
|
c1 = Counter(name="two", value=2)
|
||||||
with self.assertRaises(ValueError):
|
msg = 'Cannot force an update in save() with no primary key.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
c1.save(force_update=True)
|
c1.save(force_update=True)
|
||||||
c1.save(force_insert=True)
|
c1.save(force_insert=True)
|
||||||
|
@ -40,7 +42,8 @@ class ForceTests(TestCase):
|
||||||
# Trying to update should still fail, even with manual primary keys, if
|
# Trying to update should still fail, even with manual primary keys, if
|
||||||
# the data isn't in the database already.
|
# the data isn't in the database already.
|
||||||
obj = WithCustomPK(name=1, value=1)
|
obj = WithCustomPK(name=1, value=1)
|
||||||
with self.assertRaises(DatabaseError):
|
msg = 'Forced update did not affect any rows.'
|
||||||
|
with self.assertRaisesMessage(DatabaseError, msg):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
obj.save(force_update=True)
|
obj.save(force_update=True)
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,12 @@ class MultiColumnFKTests(TestCase):
|
||||||
ArticleTag.objects.create(article=a1, name="foo")
|
ArticleTag.objects.create(article=a1, name="foo")
|
||||||
self.assertEqual(Article.objects.filter(tag__name="foo").count(), 1)
|
self.assertEqual(Article.objects.filter(tag__name="foo").count(), 1)
|
||||||
self.assertEqual(Article.objects.filter(tag__name="bar").count(), 0)
|
self.assertEqual(Article.objects.filter(tag__name="bar").count(), 0)
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'tags' into field. Choices are: "
|
||||||
|
"active_translation, active_translation_q, articletranslation, "
|
||||||
|
"id, idea_things, newsarticle, pub_date, tag"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.filter(tags__name="foo")
|
Article.objects.filter(tags__name="foo")
|
||||||
|
|
||||||
def test_many_to_many_related_query_name(self):
|
def test_many_to_many_related_query_name(self):
|
||||||
|
@ -377,7 +382,12 @@ class MultiColumnFKTests(TestCase):
|
||||||
a1.ideas.add(i1)
|
a1.ideas.add(i1)
|
||||||
self.assertEqual(Article.objects.filter(idea_things__name="idea1").count(), 1)
|
self.assertEqual(Article.objects.filter(idea_things__name="idea1").count(), 1)
|
||||||
self.assertEqual(Article.objects.filter(idea_things__name="idea2").count(), 0)
|
self.assertEqual(Article.objects.filter(idea_things__name="idea2").count(), 0)
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'ideas' into field. Choices are: "
|
||||||
|
"active_translation, active_translation_q, articletranslation, "
|
||||||
|
"id, idea_things, newsarticle, pub_date, tag"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.filter(ideas__name="idea1")
|
Article.objects.filter(ideas__name="idea1")
|
||||||
|
|
||||||
@translation.override('fi')
|
@translation.override('fi')
|
||||||
|
|
|
@ -18,9 +18,8 @@ class UUIDFieldTest(SimpleTestCase):
|
||||||
|
|
||||||
def test_uuidfield_3(self):
|
def test_uuidfield_3(self):
|
||||||
field = UUIDField()
|
field = UUIDField()
|
||||||
with self.assertRaises(ValidationError) as cm:
|
with self.assertRaisesMessage(ValidationError, 'Enter a valid UUID.'):
|
||||||
field.clean('550e8400')
|
field.clean('550e8400')
|
||||||
self.assertEqual(cm.exception.messages[0], 'Enter a valid UUID.')
|
|
||||||
|
|
||||||
def test_uuidfield_4(self):
|
def test_uuidfield_4(self):
|
||||||
field = UUIDField()
|
field = UUIDField()
|
||||||
|
|
|
@ -1338,7 +1338,8 @@ ArticleFormSet = formset_factory(ArticleForm)
|
||||||
|
|
||||||
class TestIsBoundBehavior(SimpleTestCase):
|
class TestIsBoundBehavior(SimpleTestCase):
|
||||||
def test_no_data_raises_validation_error(self):
|
def test_no_data_raises_validation_error(self):
|
||||||
with self.assertRaises(ValidationError):
|
msg = 'ManagementForm data is missing or has been tampered with'
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
ArticleFormSet({}).is_valid()
|
ArticleFormSet({}).is_valid()
|
||||||
|
|
||||||
def test_with_management_data_attrs_work_fine(self):
|
def test_with_management_data_attrs_work_fine(self):
|
||||||
|
|
|
@ -247,7 +247,11 @@ class RelatedModelFormTests(SimpleTestCase):
|
||||||
model = A
|
model = A
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
"Cannot create form field for 'ref' yet, because "
|
||||||
|
"its related model 'B' has not been loaded yet"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta})
|
ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta})
|
||||||
|
|
||||||
class B(models.Model):
|
class B(models.Model):
|
||||||
|
|
|
@ -347,7 +347,12 @@ class GenericRelationsTests(TestCase):
|
||||||
|
|
||||||
def test_generic_relation_related_name_default(self):
|
def test_generic_relation_related_name_default(self):
|
||||||
# GenericRelation isn't usable from the reverse side by default.
|
# GenericRelation isn't usable from the reverse side by default.
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'vegetable' into field. Choices are: "
|
||||||
|
"animal, content_object, content_type, content_type_id, id, "
|
||||||
|
"manualpk, object_id, tag, valuabletaggeditem"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
TaggedItem.objects.filter(vegetable__isnull=True)
|
TaggedItem.objects.filter(vegetable__isnull=True)
|
||||||
|
|
||||||
def test_multiple_gfk(self):
|
def test_multiple_gfk(self):
|
||||||
|
|
|
@ -273,7 +273,11 @@ class TemplateViewTest(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
A template view must provide a template name.
|
A template view must provide a template name.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"TemplateResponseMixin requires either a definition of "
|
||||||
|
"'template_name' or an implementation of 'get_template_names()'"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/template/no_template/')
|
self.client.get('/template/no_template/')
|
||||||
|
|
||||||
@require_jinja2
|
@require_jinja2
|
||||||
|
|
|
@ -79,7 +79,11 @@ class ArchiveIndexViewTests(TestDataMixin, TestCase):
|
||||||
self.assertTemplateUsed(res, 'generic_views/book_detail.html')
|
self.assertTemplateUsed(res, 'generic_views/book_detail.html')
|
||||||
|
|
||||||
def test_archive_view_invalid(self):
|
def test_archive_view_invalid(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'BookArchive is missing a QuerySet. Define BookArchive.model, '
|
||||||
|
'BookArchive.queryset, or override BookArchive.get_queryset().'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/dates/books/invalid/')
|
self.client.get('/dates/books/invalid/')
|
||||||
|
|
||||||
def test_archive_view_by_month(self):
|
def test_archive_view_by_month(self):
|
||||||
|
|
|
@ -175,7 +175,11 @@ class DetailViewTest(TestCase):
|
||||||
self.client.get('/detail/author/invalid/url/')
|
self.client.get('/detail/author/invalid/url/')
|
||||||
|
|
||||||
def test_invalid_queryset(self):
|
def test_invalid_queryset(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'AuthorDetail is missing a QuerySet. Define AuthorDetail.model, '
|
||||||
|
'AuthorDetail.queryset, or override AuthorDetail.get_queryset().'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/detail/author/invalid/qs/')
|
self.client.get('/detail/author/invalid/qs/')
|
||||||
|
|
||||||
def test_non_model_object_with_meta(self):
|
def test_non_model_object_with_meta(self):
|
||||||
|
|
|
@ -159,7 +159,11 @@ class CreateViewTests(TestCase):
|
||||||
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
|
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
|
||||||
|
|
||||||
def test_create_without_redirect(self):
|
def test_create_without_redirect(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'No URL to redirect to. Either provide a url or define a '
|
||||||
|
'get_absolute_url method on the Model.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.post('/edit/authors/create/naive/', {'name': 'Randall Munroe', 'slug': 'randall-munroe'})
|
self.client.post('/edit/authors/create/naive/', {'name': 'Randall Munroe', 'slug': 'randall-munroe'})
|
||||||
|
|
||||||
def test_create_restricted(self):
|
def test_create_restricted(self):
|
||||||
|
@ -312,9 +316,11 @@ class UpdateViewTests(TestCase):
|
||||||
name='Randall Munroe',
|
name='Randall Munroe',
|
||||||
slug='randall-munroe',
|
slug='randall-munroe',
|
||||||
)
|
)
|
||||||
# Should raise exception -- No redirect URL provided, and no
|
msg = (
|
||||||
# get_absolute_url provided
|
'No URL to redirect to. Either provide a url or define a '
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
'get_absolute_url method on the Model.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.post(
|
self.client.post(
|
||||||
'/edit/author/%d/update/naive/' % a.pk,
|
'/edit/author/%d/update/naive/' % a.pk,
|
||||||
{'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'}
|
{'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'}
|
||||||
|
@ -404,7 +410,6 @@ class DeleteViewTests(TestCase):
|
||||||
name='Randall Munroe',
|
name='Randall Munroe',
|
||||||
slug='randall-munroe',
|
slug='randall-munroe',
|
||||||
)
|
)
|
||||||
# Should raise exception -- No redirect URL provided, and no
|
msg = 'No URL to redirect to. Provide a success_url.'
|
||||||
# get_absolute_url provided
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
|
||||||
self.client.post('/edit/author/%d/delete/naive/' % a.pk)
|
self.client.post('/edit/author/%d/delete/naive/' % a.pk)
|
||||||
|
|
|
@ -200,7 +200,11 @@ class ListViewTests(TestCase):
|
||||||
self.assertTemplateUsed(res, 'generic_views/author_list.html')
|
self.assertTemplateUsed(res, 'generic_views/author_list.html')
|
||||||
|
|
||||||
def test_missing_items(self):
|
def test_missing_items(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'AuthorList is missing a QuerySet. Define AuthorList.model, '
|
||||||
|
'AuthorList.queryset, or override AuthorList.get_queryset().'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/list/authors/invalid/')
|
self.client.get('/list/authors/invalid/')
|
||||||
|
|
||||||
def test_paginated_list_view_does_not_load_entire_table(self):
|
def test_paginated_list_view_does_not_load_entire_table(self):
|
||||||
|
|
|
@ -118,7 +118,11 @@ class EarliestOrLatestTests(TestCase):
|
||||||
# "get_latest_by" set -- just pass in the field name manually.
|
# "get_latest_by" set -- just pass in the field name manually.
|
||||||
Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1))
|
Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1))
|
||||||
p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
|
p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
|
||||||
with self.assertRaises(AssertionError):
|
msg = (
|
||||||
|
"earliest() and latest() require either a field_name parameter or "
|
||||||
|
"'get_latest_by' in the model"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
Person.objects.latest()
|
Person.objects.latest()
|
||||||
self.assertEqual(Person.objects.latest("birthday"), p2)
|
self.assertEqual(Person.objects.latest("birthday"), p2)
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,8 @@ class URLPrefixTests(URLTestCaseBase):
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='i18n.patterns.urls.wrong')
|
@override_settings(ROOT_URLCONF='i18n.patterns.urls.wrong')
|
||||||
def test_invalid_prefix_use(self):
|
def test_invalid_prefix_use(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = 'Using i18n_patterns in an included URLconf is not allowed.'
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
reverse('account:register')
|
reverse('account:register')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,11 @@ class LookupTests(TestCase):
|
||||||
# However, an exception FieldDoesNotExist will be thrown if you specify
|
# However, an exception FieldDoesNotExist will be thrown if you specify
|
||||||
# a nonexistent field name in values() (a field that is neither in the
|
# a nonexistent field name in values() (a field that is neither in the
|
||||||
# model nor in extra(select)).
|
# model nor in extra(select)).
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'id_plus_two' into field. Choices are: "
|
||||||
|
"author, author_id, headline, id, id_plus_one, pub_date, slug, tag"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_two')
|
Article.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_two')
|
||||||
# If you don't specify field names to values(), all are returned.
|
# If you don't specify field names to values(), all are returned.
|
||||||
self.assertSequenceEqual(
|
self.assertSequenceEqual(
|
||||||
|
@ -733,11 +737,16 @@ class LookupTests(TestCase):
|
||||||
"""
|
"""
|
||||||
A lookup query containing non-fields raises the proper exception.
|
A lookup query containing non-fields raises the proper exception.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(FieldError):
|
msg = "Unsupported lookup 'blahblah' for CharField or join on the field not permitted."
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.filter(headline__blahblah=99)
|
Article.objects.filter(headline__blahblah=99)
|
||||||
with self.assertRaises(FieldError):
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.filter(headline__blahblah__exact=99)
|
Article.objects.filter(headline__blahblah__exact=99)
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'blahblah' into field. Choices are: "
|
||||||
|
"author, author_id, headline, id, pub_date, slug, tag"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Article.objects.filter(blahblah=99)
|
Article.objects.filter(blahblah=99)
|
||||||
|
|
||||||
def test_lookup_collision(self):
|
def test_lookup_collision(self):
|
||||||
|
|
|
@ -102,7 +102,7 @@ class M2MRegressionTests(TestCase):
|
||||||
c1 = TagCollection.objects.create(name='c1')
|
c1 = TagCollection.objects.create(name='c1')
|
||||||
c1.tags.set([t1, t2])
|
c1.tags.set([t1, t2])
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaisesMessage(TypeError, "'int' object is not iterable"):
|
||||||
c1.tags.set(7)
|
c1.tags.set(7)
|
||||||
|
|
||||||
c1.refresh_from_db()
|
c1.refresh_from_db()
|
||||||
|
|
|
@ -29,7 +29,11 @@ class ManyToManyTests(TestCase):
|
||||||
# Create an Article.
|
# Create an Article.
|
||||||
a5 = Article(headline='Django lets you reate Web apps easily')
|
a5 = Article(headline='Django lets you reate Web apps easily')
|
||||||
# You can't associate it with a Publication until it's been saved.
|
# You can't associate it with a Publication until it's been saved.
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'"<Article: Django lets you reate Web apps easily>" needs to have '
|
||||||
|
'a value for field "id" before this many-to-many relationship can be used.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
getattr(a5, 'publications')
|
getattr(a5, 'publications')
|
||||||
# Save it!
|
# Save it!
|
||||||
a5.save()
|
a5.save()
|
||||||
|
|
|
@ -406,7 +406,8 @@ class ManyToOneTests(TestCase):
|
||||||
self.assertEqual(a3.reporter.id, self.r2.id)
|
self.assertEqual(a3.reporter.id, self.r2.id)
|
||||||
|
|
||||||
# Get should respect explicit foreign keys as well.
|
# Get should respect explicit foreign keys as well.
|
||||||
with self.assertRaises(MultipleObjectsReturned):
|
msg = 'get() returned more than one Article -- it returned 2!'
|
||||||
|
with self.assertRaisesMessage(MultipleObjectsReturned, msg):
|
||||||
Article.objects.get(reporter_id=self.r.id)
|
Article.objects.get(reporter_id=self.r.id)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
repr(a3),
|
repr(a3),
|
||||||
|
@ -484,7 +485,11 @@ class ManyToOneTests(TestCase):
|
||||||
setattr(c, "parent", None)
|
setattr(c, "parent", None)
|
||||||
|
|
||||||
# You also can't assign an object of the wrong type here
|
# You also can't assign an object of the wrong type here
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<First: First object (1)>": "Child.parent" must '
|
||||||
|
'be a "Parent" instance.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
setattr(c, "parent", First(id=1, second=1))
|
setattr(c, "parent", First(id=1, second=1))
|
||||||
|
|
||||||
# You can assign None to Child.parent during object creation.
|
# You can assign None to Child.parent during object creation.
|
||||||
|
@ -550,7 +555,8 @@ class ManyToOneTests(TestCase):
|
||||||
|
|
||||||
p = Parent.objects.create(name="Parent")
|
p = Parent.objects.create(name="Parent")
|
||||||
c = Child.objects.create(name="Child", parent=p)
|
c = Child.objects.create(name="Child", parent=p)
|
||||||
with self.assertRaises(ValueError):
|
msg = 'Cannot assign "%r": "Child.parent" must be a "Parent" instance.' % c
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Child.objects.create(name="Grandchild", parent=c)
|
Child.objects.create(name="Grandchild", parent=c)
|
||||||
|
|
||||||
def test_fk_instantiation_outside_model(self):
|
def test_fk_instantiation_outside_model(self):
|
||||||
|
|
|
@ -757,8 +757,18 @@ class MakeMigrationsTests(MigrationTestBase):
|
||||||
makemigrations exits if it detects a conflict.
|
makemigrations exits if it detects a conflict.
|
||||||
"""
|
"""
|
||||||
with self.temporary_migration_module(module="migrations.test_migrations_conflict"):
|
with self.temporary_migration_module(module="migrations.test_migrations_conflict"):
|
||||||
with self.assertRaises(CommandError):
|
with self.assertRaises(CommandError) as context:
|
||||||
call_command("makemigrations")
|
call_command("makemigrations")
|
||||||
|
exception_message = str(context.exception)
|
||||||
|
self.assertIn(
|
||||||
|
'Conflicting migrations detected; multiple leaf nodes '
|
||||||
|
'in the migration graph:',
|
||||||
|
exception_message
|
||||||
|
)
|
||||||
|
self.assertIn('0002_second', exception_message)
|
||||||
|
self.assertIn('0002_conflicting_second', exception_message)
|
||||||
|
self.assertIn('in migrations', exception_message)
|
||||||
|
self.assertIn("To fix them run 'python manage.py makemigrations --merge'", exception_message)
|
||||||
|
|
||||||
def test_makemigrations_merge_no_conflict(self):
|
def test_makemigrations_merge_no_conflict(self):
|
||||||
"""
|
"""
|
||||||
|
@ -780,7 +790,8 @@ class MakeMigrationsTests(MigrationTestBase):
|
||||||
"""
|
"""
|
||||||
makemigrations exits if no app is specified with 'empty' mode.
|
makemigrations exits if no app is specified with 'empty' mode.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(CommandError):
|
msg = 'You must supply at least one app label when using --empty.'
|
||||||
|
with self.assertRaisesMessage(CommandError, msg):
|
||||||
call_command("makemigrations", empty=True)
|
call_command("makemigrations", empty=True)
|
||||||
|
|
||||||
def test_makemigrations_empty_migration(self):
|
def test_makemigrations_empty_migration(self):
|
||||||
|
|
|
@ -1945,7 +1945,7 @@ class OperationTests(OperationTestBase):
|
||||||
operation.database_backwards("test_runpython", editor, project_state, new_state)
|
operation.database_backwards("test_runpython", editor, project_state, new_state)
|
||||||
self.assertEqual(project_state.apps.get_model("test_runpython", "Pony").objects.count(), 0)
|
self.assertEqual(project_state.apps.get_model("test_runpython", "Pony").objects.count(), 0)
|
||||||
# Now test we can't use a string
|
# Now test we can't use a string
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, 'RunPython must be supplied with a callable'):
|
||||||
migrations.RunPython("print 'ahahaha'")
|
migrations.RunPython("print 'ahahaha'")
|
||||||
# And deconstruction
|
# And deconstruction
|
||||||
definition = operation.deconstruct()
|
definition = operation.deconstruct()
|
||||||
|
|
|
@ -21,7 +21,8 @@ class DecimalFieldTests(TestCase):
|
||||||
# Uses default rounding of ROUND_HALF_EVEN.
|
# Uses default rounding of ROUND_HALF_EVEN.
|
||||||
self.assertEqual(f.to_python(2.0625), Decimal('2.062'))
|
self.assertEqual(f.to_python(2.0625), Decimal('2.062'))
|
||||||
self.assertEqual(f.to_python(2.1875), Decimal('2.188'))
|
self.assertEqual(f.to_python(2.1875), Decimal('2.188'))
|
||||||
with self.assertRaises(ValidationError):
|
msg = "'abc' value must be a decimal number."
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
f.to_python('abc')
|
f.to_python('abc')
|
||||||
|
|
||||||
def test_default(self):
|
def test_default(self):
|
||||||
|
|
|
@ -21,8 +21,7 @@ class TestFloatField(TestCase):
|
||||||
instance.size = instance
|
instance.size = instance
|
||||||
msg = (
|
msg = (
|
||||||
'Tried to update field model_fields.FloatModel.size with a model '
|
'Tried to update field model_fields.FloatModel.size with a model '
|
||||||
'instance, %r. Use a value '
|
'instance, %r. Use a value compatible with FloatField.'
|
||||||
'compatible with FloatField.'
|
|
||||||
) % instance
|
) % instance
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
with self.assertRaisesMessage(TypeError, msg):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
@ -30,5 +29,5 @@ class TestFloatField(TestCase):
|
||||||
# Try setting field to object on retrieved object
|
# Try setting field to object on retrieved object
|
||||||
obj = FloatModel.objects.get(pk=instance.id)
|
obj = FloatModel.objects.get(pk=instance.id)
|
||||||
obj.size = obj
|
obj.size = obj
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
|
@ -180,7 +180,7 @@ class ModelFormBaseTest(TestCase):
|
||||||
def test_no_model_class(self):
|
def test_no_model_class(self):
|
||||||
class NoModelModelForm(forms.ModelForm):
|
class NoModelModelForm(forms.ModelForm):
|
||||||
pass
|
pass
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, 'ModelForm has no model class specified.'):
|
||||||
NoModelModelForm()
|
NoModelModelForm()
|
||||||
|
|
||||||
def test_empty_fields_to_fields_for_model(self):
|
def test_empty_fields_to_fields_for_model(self):
|
||||||
|
@ -326,7 +326,7 @@ class ModelFormBaseTest(TestCase):
|
||||||
fields = ('name', 'age')
|
fields = ('name', 'age')
|
||||||
|
|
||||||
def test_extra_field_modelform_factory(self):
|
def test_extra_field_modelform_factory(self):
|
||||||
with self.assertRaises(FieldError):
|
with self.assertRaisesMessage(FieldError, 'Unknown field(s) (no-field) specified for Person'):
|
||||||
modelform_factory(Person, fields=['no-field', 'name'])
|
modelform_factory(Person, fields=['no-field', 'name'])
|
||||||
|
|
||||||
def test_replace_field(self):
|
def test_replace_field(self):
|
||||||
|
@ -426,7 +426,8 @@ class ModelFormBaseTest(TestCase):
|
||||||
form = PriceFormWithoutQuantity({'price': '6.00'})
|
form = PriceFormWithoutQuantity({'price': '6.00'})
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
price = form.save(commit=False)
|
price = form.save(commit=False)
|
||||||
with self.assertRaises(ValidationError):
|
msg = "{'quantity': ['This field cannot be null.']}"
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
price.full_clean()
|
price.full_clean()
|
||||||
|
|
||||||
# The form should not validate fields that it doesn't contain even if they are
|
# The form should not validate fields that it doesn't contain even if they are
|
||||||
|
@ -498,11 +499,12 @@ class ModelFormBaseTest(TestCase):
|
||||||
pass # no model
|
pass # no model
|
||||||
|
|
||||||
# Can't create new form
|
# Can't create new form
|
||||||
with self.assertRaises(ValueError):
|
msg = 'ModelForm has no model class specified.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
InvalidModelForm()
|
InvalidModelForm()
|
||||||
|
|
||||||
# Even if you provide a model instance
|
# Even if you provide a model instance
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
InvalidModelForm(instance=Category)
|
InvalidModelForm(instance=Category)
|
||||||
|
|
||||||
def test_subcategory_form(self):
|
def test_subcategory_form(self):
|
||||||
|
@ -1301,10 +1303,11 @@ class ModelFormBasicTests(TestCase):
|
||||||
["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]
|
["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]
|
||||||
)
|
)
|
||||||
self.assertEqual(f.cleaned_data, {'url': 'foo'})
|
self.assertEqual(f.cleaned_data, {'url': 'foo'})
|
||||||
with self.assertRaises(ValueError):
|
msg = "The Category could not be created because the data didn't validate."
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
f.save()
|
f.save()
|
||||||
f = BaseCategoryForm({'name': '', 'slug': '', 'url': 'foo'})
|
f = BaseCategoryForm({'name': '', 'slug': '', 'url': 'foo'})
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
f.save()
|
f.save()
|
||||||
|
|
||||||
def test_multi_fields(self):
|
def test_multi_fields(self):
|
||||||
|
@ -1597,7 +1600,8 @@ class ModelChoiceFieldTests(TestCase):
|
||||||
# instantiated. This proves clean() checks the database during clean() rather
|
# instantiated. This proves clean() checks the database during clean() rather
|
||||||
# than caching it at time of instantiation.
|
# than caching it at time of instantiation.
|
||||||
Category.objects.get(url='4th').delete()
|
Category.objects.get(url='4th').delete()
|
||||||
with self.assertRaises(ValidationError):
|
msg = "['Select a valid choice. That choice is not one of the available choices.']"
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
f.clean(c4.id)
|
f.clean(c4.id)
|
||||||
|
|
||||||
def test_modelchoicefield_choices(self):
|
def test_modelchoicefield_choices(self):
|
||||||
|
@ -3045,7 +3049,11 @@ class LocalizedModelFormTest(TestCase):
|
||||||
self.assertTrue(f.fields['right'].localize)
|
self.assertTrue(f.fields['right'].localize)
|
||||||
|
|
||||||
def test_model_form_refuses_arbitrary_string(self):
|
def test_model_form_refuses_arbitrary_string(self):
|
||||||
with self.assertRaises(TypeError):
|
msg = (
|
||||||
|
"BrokenLocalizedTripleForm.Meta.localized_fields "
|
||||||
|
"cannot be a string. Did you mean to type: ('foo',)?"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
class BrokenLocalizedTripleForm(forms.ModelForm):
|
class BrokenLocalizedTripleForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Triple
|
model = Triple
|
||||||
|
|
|
@ -150,10 +150,11 @@ class AbstractInheritanceTests(TestCase):
|
||||||
def full_name(self):
|
def full_name(self):
|
||||||
return self.first_name + self.last_name
|
return self.first_name + self.last_name
|
||||||
|
|
||||||
with self.assertRaises(FieldDoesNotExist):
|
msg = "Descendant has no field named %r"
|
||||||
|
with self.assertRaisesMessage(FieldDoesNotExist, msg % 'middle_name'):
|
||||||
Descendant._meta.get_field('middle_name')
|
Descendant._meta.get_field('middle_name')
|
||||||
|
|
||||||
with self.assertRaises(FieldDoesNotExist):
|
with self.assertRaisesMessage(FieldDoesNotExist, msg % 'full_name'):
|
||||||
Descendant._meta.get_field('full_name')
|
Descendant._meta.get_field('full_name')
|
||||||
|
|
||||||
def test_overriding_field_removed_by_concrete_model(self):
|
def test_overriding_field_removed_by_concrete_model(self):
|
||||||
|
|
|
@ -43,7 +43,7 @@ class ModelInheritanceTests(TestCase):
|
||||||
|
|
||||||
# However, the CommonInfo class cannot be used as a normal model (it
|
# However, the CommonInfo class cannot be used as a normal model (it
|
||||||
# doesn't exist as a model).
|
# doesn't exist as a model).
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaisesMessage(AttributeError, "'CommonInfo' has no attribute 'objects'"):
|
||||||
CommonInfo.objects.all()
|
CommonInfo.objects.all()
|
||||||
|
|
||||||
def test_reverse_relation_for_different_hierarchy_tree(self):
|
def test_reverse_relation_for_different_hierarchy_tree(self):
|
||||||
|
@ -51,7 +51,12 @@ class ModelInheritanceTests(TestCase):
|
||||||
# Restaurant object cannot access that reverse relation, since it's not
|
# Restaurant object cannot access that reverse relation, since it's not
|
||||||
# part of the Place-Supplier Hierarchy.
|
# part of the Place-Supplier Hierarchy.
|
||||||
self.assertQuerysetEqual(Place.objects.filter(supplier__name="foo"), [])
|
self.assertQuerysetEqual(Place.objects.filter(supplier__name="foo"), [])
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'supplier' into field. Choices are: "
|
||||||
|
"address, chef, chef_id, id, italianrestaurant, lot, name, "
|
||||||
|
"place_ptr, place_ptr_id, provider, rating, serves_hot_dogs, serves_pizza"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Restaurant.objects.filter(supplier__name="foo")
|
Restaurant.objects.filter(supplier__name="foo")
|
||||||
|
|
||||||
def test_model_with_distinct_accessors(self):
|
def test_model_with_distinct_accessors(self):
|
||||||
|
@ -65,7 +70,8 @@ class ModelInheritanceTests(TestCase):
|
||||||
|
|
||||||
# The Post model doesn't have an attribute called
|
# The Post model doesn't have an attribute called
|
||||||
# 'attached_%(class)s_set'.
|
# 'attached_%(class)s_set'.
|
||||||
with self.assertRaises(AttributeError):
|
msg = "'Post' object has no attribute 'attached_%(class)s_set'"
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
getattr(post, "attached_%(class)s_set")
|
getattr(post, "attached_%(class)s_set")
|
||||||
|
|
||||||
def test_model_with_distinct_related_query_name(self):
|
def test_model_with_distinct_related_query_name(self):
|
||||||
|
|
|
@ -321,27 +321,39 @@ class QueryTestCase(TestCase):
|
||||||
|
|
||||||
mark = Person.objects.using('other').create(name="Mark Pilgrim")
|
mark = Person.objects.using('other').create(name="Mark Pilgrim")
|
||||||
# Set a foreign key set with an object from a different database
|
# Set a foreign key set with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<Person: Marty Alchin>": the current database '
|
||||||
|
'router prevents this relation.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='default'):
|
with transaction.atomic(using='default'):
|
||||||
marty.edited.set([pro, dive])
|
marty.edited.set([pro, dive])
|
||||||
|
|
||||||
# Add to an m2m with an object from a different database
|
# Add to an m2m with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot add "<Book: Dive into Python>": instance is on '
|
||||||
|
'database "default", value is on database "other"'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='default'):
|
with transaction.atomic(using='default'):
|
||||||
marty.book_set.add(dive)
|
marty.book_set.add(dive)
|
||||||
|
|
||||||
# Set a m2m with an object from a different database
|
# Set a m2m with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='default'):
|
with transaction.atomic(using='default'):
|
||||||
marty.book_set.set([pro, dive])
|
marty.book_set.set([pro, dive])
|
||||||
|
|
||||||
# Add to a reverse m2m with an object from a different database
|
# Add to a reverse m2m with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot add "<Person: Marty Alchin>": instance is on '
|
||||||
|
'database "other", value is on database "default"'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='other'):
|
with transaction.atomic(using='other'):
|
||||||
dive.authors.add(marty)
|
dive.authors.add(marty)
|
||||||
|
|
||||||
# Set a reverse m2m with an object from a different database
|
# Set a reverse m2m with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='other'):
|
with transaction.atomic(using='other'):
|
||||||
dive.authors.set([mark, marty])
|
dive.authors.set([mark, marty])
|
||||||
|
|
||||||
|
@ -537,16 +549,20 @@ class QueryTestCase(TestCase):
|
||||||
dive = Book.objects.using('other').create(title="Dive into Python", published=datetime.date(2009, 5, 4))
|
dive = Book.objects.using('other').create(title="Dive into Python", published=datetime.date(2009, 5, 4))
|
||||||
|
|
||||||
# Set a foreign key with an object from a different database
|
# Set a foreign key with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<Person: Marty Alchin>": the current database '
|
||||||
|
'router prevents this relation.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
dive.editor = marty
|
dive.editor = marty
|
||||||
|
|
||||||
# Set a foreign key set with an object from a different database
|
# Set a foreign key set with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='default'):
|
with transaction.atomic(using='default'):
|
||||||
marty.edited.set([pro, dive])
|
marty.edited.set([pro, dive])
|
||||||
|
|
||||||
# Add to a foreign key set with an object from a different database
|
# Add to a foreign key set with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='default'):
|
with transaction.atomic(using='default'):
|
||||||
marty.edited.add(dive)
|
marty.edited.add(dive)
|
||||||
|
|
||||||
|
@ -655,7 +671,11 @@ class QueryTestCase(TestCase):
|
||||||
|
|
||||||
# Set a one-to-one relation with an object from a different database
|
# Set a one-to-one relation with an object from a different database
|
||||||
alice_profile = UserProfile.objects.using('default').create(user=alice, flavor='chocolate')
|
alice_profile = UserProfile.objects.using('default').create(user=alice, flavor='chocolate')
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<UserProfile: UserProfile object (1)>": the '
|
||||||
|
'current database router prevents this relation.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
bob.userprofile = alice_profile
|
bob.userprofile = alice_profile
|
||||||
|
|
||||||
# BUT! if you assign a FK object when the base object hasn't
|
# BUT! if you assign a FK object when the base object hasn't
|
||||||
|
@ -810,11 +830,19 @@ class QueryTestCase(TestCase):
|
||||||
Review.objects.using('other').create(source="Python Weekly", content_object=dive)
|
Review.objects.using('other').create(source="Python Weekly", content_object=dive)
|
||||||
|
|
||||||
# Set a foreign key with an object from a different database
|
# Set a foreign key with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<ContentType: book>": the current database router '
|
||||||
|
'prevents this relation.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
review1.content_object = dive
|
review1.content_object = dive
|
||||||
|
|
||||||
# Add to a foreign key set with an object from a different database
|
# Add to a foreign key set with an object from a different database
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
"<Review: Python Monthly> instance isn't saved. "
|
||||||
|
"Use bulk=False or save the object first."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
with transaction.atomic(using='other'):
|
with transaction.atomic(using='other'):
|
||||||
dive.reviews.add(review1)
|
dive.reviews.add(review1)
|
||||||
|
|
||||||
|
@ -913,11 +941,15 @@ class QueryTestCase(TestCase):
|
||||||
# When you call __str__ on the query object, it doesn't know about using
|
# When you call __str__ on the query object, it doesn't know about using
|
||||||
# so it falls back to the default. If the subquery explicitly uses a
|
# so it falls back to the default. If the subquery explicitly uses a
|
||||||
# different database, an error should be raised.
|
# different database, an error should be raised.
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
"Subqueries aren't allowed across different databases. Force the "
|
||||||
|
"inner query to be evaluated using `list(inner_query)`."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
str(qs.query)
|
str(qs.query)
|
||||||
|
|
||||||
# Evaluating the query shouldn't work, either
|
# Evaluating the query shouldn't work, either
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
for obj in qs:
|
for obj in qs:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,12 @@ class NullQueriesTests(TestCase):
|
||||||
self.assertSequenceEqual(Choice.objects.exclude(choice=None).order_by('id'), [c1, c2])
|
self.assertSequenceEqual(Choice.objects.exclude(choice=None).order_by('id'), [c1, c2])
|
||||||
|
|
||||||
# Valid query, but fails because foo isn't a keyword
|
# Valid query, but fails because foo isn't a keyword
|
||||||
with self.assertRaises(FieldError):
|
msg = "Cannot resolve keyword 'foo' into field. Choices are: choice, id, poll, poll_id"
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Choice.objects.filter(foo__exact=None)
|
Choice.objects.filter(foo__exact=None)
|
||||||
|
|
||||||
# Can't use None on anything other than __exact and __iexact
|
# Can't use None on anything other than __exact and __iexact
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, 'Cannot use None as a query value'):
|
||||||
Choice.objects.filter(id__gt=None)
|
Choice.objects.filter(id__gt=None)
|
||||||
|
|
||||||
# Related managers use __exact=None implicitly if the object hasn't been saved.
|
# Related managers use __exact=None implicitly if the object hasn't been saved.
|
||||||
|
|
|
@ -226,7 +226,11 @@ class OneToOneTests(TestCase):
|
||||||
setattr(p, 'restaurant', None)
|
setattr(p, 'restaurant', None)
|
||||||
|
|
||||||
# You also can't assign an object of the wrong type here
|
# You also can't assign an object of the wrong type here
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
'Cannot assign "<Place: Demon Dogs the place>": '
|
||||||
|
'"Place.restaurant" must be a "Restaurant" instance.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
setattr(p, 'restaurant', p)
|
setattr(p, 'restaurant', p)
|
||||||
|
|
||||||
# Creation using keyword argument should cache the related object.
|
# Creation using keyword argument should cache the related object.
|
||||||
|
|
|
@ -199,14 +199,22 @@ class PrefetchRelatedTests(TestCase):
|
||||||
|
|
||||||
def test_attribute_error(self):
|
def test_attribute_error(self):
|
||||||
qs = Reader.objects.all().prefetch_related('books_read__xyz')
|
qs = Reader.objects.all().prefetch_related('books_read__xyz')
|
||||||
with self.assertRaises(AttributeError) as cm:
|
msg = (
|
||||||
|
"Cannot find 'xyz' on Book object, 'books_read__xyz' "
|
||||||
|
"is an invalid parameter to prefetch_related()"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg) as cm:
|
||||||
list(qs)
|
list(qs)
|
||||||
|
|
||||||
self.assertIn('prefetch_related', str(cm.exception))
|
self.assertIn('prefetch_related', str(cm.exception))
|
||||||
|
|
||||||
def test_invalid_final_lookup(self):
|
def test_invalid_final_lookup(self):
|
||||||
qs = Book.objects.prefetch_related('authors__name')
|
qs = Book.objects.prefetch_related('authors__name')
|
||||||
with self.assertRaises(ValueError) as cm:
|
msg = (
|
||||||
|
"'authors__name' does not resolve to an item that supports "
|
||||||
|
"prefetching - this is an invalid parameter to prefetch_related()."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg) as cm:
|
||||||
list(qs)
|
list(qs)
|
||||||
|
|
||||||
self.assertIn('prefetch_related', str(cm.exception))
|
self.assertIn('prefetch_related', str(cm.exception))
|
||||||
|
@ -337,14 +345,22 @@ class CustomPrefetchTests(TestCase):
|
||||||
|
|
||||||
def test_ambiguous(self):
|
def test_ambiguous(self):
|
||||||
# Ambiguous: Lookup was already seen with a different queryset.
|
# Ambiguous: Lookup was already seen with a different queryset.
|
||||||
with self.assertRaises(ValueError):
|
msg = (
|
||||||
|
"'houses' lookup was already seen with a different queryset. You "
|
||||||
|
"may need to adjust the ordering of your lookups."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
self.traverse_qs(
|
self.traverse_qs(
|
||||||
Person.objects.prefetch_related('houses__rooms', Prefetch('houses', queryset=House.objects.all())),
|
Person.objects.prefetch_related('houses__rooms', Prefetch('houses', queryset=House.objects.all())),
|
||||||
[['houses', 'rooms']]
|
[['houses', 'rooms']]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ambiguous: Lookup houses_lst doesn't yet exist when performing houses_lst__rooms.
|
# Ambiguous: Lookup houses_lst doesn't yet exist when performing houses_lst__rooms.
|
||||||
with self.assertRaises(AttributeError):
|
msg = (
|
||||||
|
"Cannot find 'houses_lst' on Person object, 'houses_lst__rooms' is "
|
||||||
|
"an invalid parameter to prefetch_related()"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
self.traverse_qs(
|
self.traverse_qs(
|
||||||
Person.objects.prefetch_related(
|
Person.objects.prefetch_related(
|
||||||
'houses_lst__rooms',
|
'houses_lst__rooms',
|
||||||
|
|
|
@ -2957,7 +2957,8 @@ class WhereNodeTest(TestCase):
|
||||||
class QuerySetExceptionTests(TestCase):
|
class QuerySetExceptionTests(TestCase):
|
||||||
def test_iter_exceptions(self):
|
def test_iter_exceptions(self):
|
||||||
qs = ExtraInfo.objects.only('author')
|
qs = ExtraInfo.objects.only('author')
|
||||||
with self.assertRaises(AttributeError):
|
msg = "'ManyToOneRel' object has no attribute 'attname'"
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
list(qs)
|
list(qs)
|
||||||
|
|
||||||
def test_invalid_qs_list(self):
|
def test_invalid_qs_list(self):
|
||||||
|
@ -3735,9 +3736,10 @@ class TestTicket24279(TestCase):
|
||||||
|
|
||||||
class TestInvalidValuesRelation(TestCase):
|
class TestInvalidValuesRelation(TestCase):
|
||||||
def test_invalid_values(self):
|
def test_invalid_values(self):
|
||||||
with self.assertRaises(ValueError):
|
msg = "invalid literal for int() with base 10: 'abc'"
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Annotation.objects.filter(tag='abc')
|
Annotation.objects.filter(tag='abc')
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Annotation.objects.filter(tag__in=[123, 'abc'])
|
Annotation.objects.filter(tag__in=[123, 'abc'])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,11 @@ class RedirectTests(TestCase):
|
||||||
|
|
||||||
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
||||||
def test_sites_not_installed(self):
|
def test_sites_not_installed(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'You cannot use RedirectFallbackMiddleware when '
|
||||||
|
'django.contrib.sites is not installed.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
RedirectFallbackMiddleware()
|
RedirectFallbackMiddleware()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,5 +46,9 @@ class ReverseLookupTests(TestCase):
|
||||||
"""
|
"""
|
||||||
If a related_name is given you can't use the field name instead
|
If a related_name is given you can't use the field name instead
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(FieldError):
|
msg = (
|
||||||
|
"Cannot resolve keyword 'choice' into field. Choices are: "
|
||||||
|
"creator, creator_id, id, poll_choice, question, related_choice"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
Poll.objects.get(choice__name__exact="This is the answer")
|
Poll.objects.get(choice__name__exact="This is the answer")
|
||||||
|
|
|
@ -246,7 +246,8 @@ class SelectForUpdateTests(TransactionTestCase):
|
||||||
A TransactionManagementError is raised
|
A TransactionManagementError is raised
|
||||||
when a select_for_update query is executed outside of a transaction.
|
when a select_for_update query is executed outside of a transaction.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
msg = 'select_for_update cannot be used outside of a transaction.'
|
||||||
|
with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
|
||||||
list(Person.objects.all().select_for_update())
|
list(Person.objects.all().select_for_update())
|
||||||
|
|
||||||
@skipUnlessDBFeature('has_select_for_update')
|
@skipUnlessDBFeature('has_select_for_update')
|
||||||
|
@ -257,7 +258,8 @@ class SelectForUpdateTests(TransactionTestCase):
|
||||||
only when the query is executed.
|
only when the query is executed.
|
||||||
"""
|
"""
|
||||||
people = Person.objects.all().select_for_update()
|
people = Person.objects.all().select_for_update()
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
msg = 'select_for_update cannot be used outside of a transaction.'
|
||||||
|
with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
|
||||||
list(people)
|
list(people)
|
||||||
|
|
||||||
@skipUnlessDBFeature('supports_select_for_update_with_limit')
|
@skipUnlessDBFeature('supports_select_for_update_with_limit')
|
||||||
|
|
|
@ -137,10 +137,6 @@ class SelectRelatedTests(TestCase):
|
||||||
.order_by('id')[0:1].get().genus.family.order.name)
|
.order_by('id')[0:1].get().genus.family.order.name)
|
||||||
self.assertEqual(s, 'Diptera')
|
self.assertEqual(s, 'Diptera')
|
||||||
|
|
||||||
def test_depth_fields_fails(self):
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
Species.objects.select_related('genus__family__order', depth=4)
|
|
||||||
|
|
||||||
def test_none_clears_list(self):
|
def test_none_clears_list(self):
|
||||||
queryset = Species.objects.select_related('genus').select_related(None)
|
queryset = Species.objects.select_related('genus').select_related(None)
|
||||||
self.assertIs(queryset.query.select_related, False)
|
self.assertIs(queryset.query.select_related, False)
|
||||||
|
|
|
@ -238,7 +238,7 @@ class SettingsTests(SimpleTestCase):
|
||||||
getattr(settings, 'TEST')
|
getattr(settings, 'TEST')
|
||||||
|
|
||||||
def test_settings_delete_wrapped(self):
|
def test_settings_delete_wrapped(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaisesMessage(TypeError, "can't delete _wrapped."):
|
||||||
delattr(settings, '_wrapped')
|
delattr(settings, '_wrapped')
|
||||||
|
|
||||||
def test_override_settings_delete(self):
|
def test_override_settings_delete(self):
|
||||||
|
|
|
@ -16,6 +16,10 @@ from .models import TestModel
|
||||||
|
|
||||||
|
|
||||||
class HTTPSitemapTests(SitemapTestsBase):
|
class HTTPSitemapTests(SitemapTestsBase):
|
||||||
|
use_sitemap_err_msg = (
|
||||||
|
'To use sitemaps, either enable the sites framework or pass a '
|
||||||
|
'Site/RequestSite object in your view.'
|
||||||
|
)
|
||||||
|
|
||||||
def test_simple_sitemap_index(self):
|
def test_simple_sitemap_index(self):
|
||||||
"A simple sitemap index can be rendered"
|
"A simple sitemap index can be rendered"
|
||||||
|
@ -207,7 +211,7 @@ class HTTPSitemapTests(SitemapTestsBase):
|
||||||
Sitemap.get_urls and no Site objects exist
|
Sitemap.get_urls and no Site objects exist
|
||||||
"""
|
"""
|
||||||
Site.objects.all().delete()
|
Site.objects.all().delete()
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
|
||||||
Sitemap().get_urls()
|
Sitemap().get_urls()
|
||||||
|
|
||||||
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
||||||
|
@ -217,7 +221,7 @@ class HTTPSitemapTests(SitemapTestsBase):
|
||||||
Sitemap.get_urls if Site objects exists, but the sites framework is not
|
Sitemap.get_urls if Site objects exists, but the sites framework is not
|
||||||
actually installed.
|
actually installed.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
|
||||||
Sitemap().get_urls()
|
Sitemap().get_urls()
|
||||||
|
|
||||||
def test_sitemap_item(self):
|
def test_sitemap_item(self):
|
||||||
|
|
|
@ -105,5 +105,10 @@ class TestMiscFinder(SimpleTestCase):
|
||||||
|
|
||||||
@override_settings(MEDIA_ROOT='')
|
@override_settings(MEDIA_ROOT='')
|
||||||
def test_location_empty(self):
|
def test_location_empty(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"The storage backend of the staticfiles finder "
|
||||||
|
"<class 'django.contrib.staticfiles.finders.DefaultStorageFinder'> "
|
||||||
|
"doesn't have a valid location."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
finders.DefaultStorageFinder()
|
finders.DefaultStorageFinder()
|
||||||
|
|
|
@ -452,7 +452,11 @@ class SyndicationFeedTest(FeedTestCase):
|
||||||
An ImproperlyConfigured is raised if no link could be found for the
|
An ImproperlyConfigured is raised if no link could be found for the
|
||||||
item(s).
|
item(s).
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
'Give your Article class a get_absolute_url() method, or define '
|
||||||
|
'an item_link() method in your Feed class.'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/syndication/articles/')
|
self.client.get('/syndication/articles/')
|
||||||
|
|
||||||
def test_template_feed(self):
|
def test_template_feed(self):
|
||||||
|
|
|
@ -332,11 +332,13 @@ class TranslationBlockTransTagTests(SimpleTestCase):
|
||||||
self.assertEqual(rendered, '2 andere Super-Ergebnisse')
|
self.assertEqual(rendered, '2 andere Super-Ergebnisse')
|
||||||
|
|
||||||
# Misuses
|
# Misuses
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = "Unknown argument for 'blocktrans' tag: %r."
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg % 'month="May"'):
|
||||||
Template('{% load i18n %}{% blocktrans context with month="May" %}{{ month }}{% endblocktrans %}')
|
Template('{% load i18n %}{% blocktrans context with month="May" %}{{ month }}{% endblocktrans %}')
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = '"context" in %r tag expected exactly one argument.' % 'blocktrans'
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
Template('{% load i18n %}{% blocktrans context %}{% endblocktrans %}')
|
Template('{% load i18n %}{% blocktrans context %}{% endblocktrans %}')
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
Template(
|
Template(
|
||||||
'{% load i18n %}{% blocktrans count number=2 context %}'
|
'{% load i18n %}{% blocktrans count number=2 context %}'
|
||||||
'{{ number }} super result{% plural %}{{ number }}'
|
'{{ number }} super result{% plural %}{{ number }}'
|
||||||
|
|
|
@ -43,7 +43,8 @@ class FilterSyntaxTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Raise TemplateSyntaxError for a nonexistent filter
|
Raise TemplateSyntaxError for a nonexistent filter
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = "Invalid filter: 'does_not_exist'"
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
self.engine.get_template('filter-syntax05')
|
self.engine.get_template('filter-syntax05')
|
||||||
|
|
||||||
@setup({'filter-syntax06': '{{ var|fil(ter) }}'})
|
@setup({'filter-syntax06': '{{ var|fil(ter) }}'})
|
||||||
|
@ -52,7 +53,7 @@ class FilterSyntaxTests(SimpleTestCase):
|
||||||
Raise TemplateSyntaxError when trying to access a filter containing
|
Raise TemplateSyntaxError when trying to access a filter containing
|
||||||
an illegal character
|
an illegal character
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, "Invalid filter: 'fil'"):
|
||||||
self.engine.get_template('filter-syntax06')
|
self.engine.get_template('filter-syntax06')
|
||||||
|
|
||||||
@setup({'filter-syntax07': "{% nothing_to_see_here %}"})
|
@setup({'filter-syntax07': "{% nothing_to_see_here %}"})
|
||||||
|
@ -60,7 +61,11 @@ class FilterSyntaxTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Raise TemplateSyntaxError for invalid block tags
|
Raise TemplateSyntaxError for invalid block tags
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = (
|
||||||
|
"Invalid block tag on line 1: 'nothing_to_see_here'. Did you "
|
||||||
|
"forget to register or load this tag?"
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
self.engine.get_template('filter-syntax07')
|
self.engine.get_template('filter-syntax07')
|
||||||
|
|
||||||
@setup({'filter-syntax08': "{% %}"})
|
@setup({'filter-syntax08': "{% %}"})
|
||||||
|
|
|
@ -6,6 +6,7 @@ from ..utils import setup
|
||||||
|
|
||||||
|
|
||||||
class WithTagTests(SimpleTestCase):
|
class WithTagTests(SimpleTestCase):
|
||||||
|
at_least_with_one_msg = "'with' expected at least one variable assignment"
|
||||||
|
|
||||||
@setup({'with01': '{% with key=dict.key %}{{ key }}{% endwith %}'})
|
@setup({'with01': '{% with key=dict.key %}{{ key }}{% endwith %}'})
|
||||||
def test_with01(self):
|
def test_with01(self):
|
||||||
|
@ -44,12 +45,12 @@ class WithTagTests(SimpleTestCase):
|
||||||
|
|
||||||
@setup({'with-error01': '{% with dict.key xx key %}{{ key }}{% endwith %}'})
|
@setup({'with-error01': '{% with dict.key xx key %}{{ key }}{% endwith %}'})
|
||||||
def test_with_error01(self):
|
def test_with_error01(self):
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, self.at_least_with_one_msg):
|
||||||
self.engine.render_to_string('with-error01', {'dict': {'key': 50}})
|
self.engine.render_to_string('with-error01', {'dict': {'key': 50}})
|
||||||
|
|
||||||
@setup({'with-error02': '{% with dict.key as %}{{ key }}{% endwith %}'})
|
@setup({'with-error02': '{% with dict.key as %}{{ key }}{% endwith %}'})
|
||||||
def test_with_error02(self):
|
def test_with_error02(self):
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaisesMessage(TemplateSyntaxError, self.at_least_with_one_msg):
|
||||||
self.engine.render_to_string('with-error02', {'dict': {'key': 50}})
|
self.engine.render_to_string('with-error02', {'dict': {'key': 50}})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ class ParserTests(SimpleTestCase):
|
||||||
|
|
||||||
# Filtered variables should reject access of attributes beginning with
|
# Filtered variables should reject access of attributes beginning with
|
||||||
# underscores.
|
# underscores.
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = "Variables and attributes may not begin with underscores: 'article._hidden'"
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
FilterExpression("article._hidden|upper", p)
|
FilterExpression("article._hidden|upper", p)
|
||||||
|
|
||||||
def test_variable_parsing(self):
|
def test_variable_parsing(self):
|
||||||
|
@ -64,7 +65,8 @@ class ParserTests(SimpleTestCase):
|
||||||
|
|
||||||
# Variables should reject access of attributes beginning with
|
# Variables should reject access of attributes beginning with
|
||||||
# underscores.
|
# underscores.
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = "Variables and attributes may not begin with underscores: 'article._hidden'"
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
Variable("article._hidden")
|
Variable("article._hidden")
|
||||||
|
|
||||||
# Variables should raise on non string type
|
# Variables should raise on non string type
|
||||||
|
|
|
@ -212,7 +212,8 @@ class AssertQuerysetEqualTests(TestCase):
|
||||||
def test_undefined_order(self):
|
def test_undefined_order(self):
|
||||||
# Using an unordered queryset with more than one ordered value
|
# Using an unordered queryset with more than one ordered value
|
||||||
# is an error.
|
# is an error.
|
||||||
with self.assertRaises(ValueError):
|
msg = 'Trying to compare non-ordered queryset against more than one ordered values'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Person.objects.all(),
|
Person.objects.all(),
|
||||||
[repr(self.p1), repr(self.p2)]
|
[repr(self.p1), repr(self.p2)]
|
||||||
|
@ -415,23 +416,29 @@ class AssertTemplateUsedContextManagerTests(SimpleTestCase):
|
||||||
self.assertTemplateUsed(response, 'template_used/base.html')
|
self.assertTemplateUsed(response, 'template_used/base.html')
|
||||||
|
|
||||||
def test_failure(self):
|
def test_failure(self):
|
||||||
with self.assertRaises(TypeError):
|
msg = 'response and/or template_name argument must be provided'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
with self.assertTemplateUsed():
|
with self.assertTemplateUsed():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
msg = 'No templates used to render the response'
|
||||||
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
with self.assertTemplateUsed(''):
|
with self.assertTemplateUsed(''):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
with self.assertTemplateUsed(''):
|
with self.assertTemplateUsed(''):
|
||||||
render_to_string('template_used/base.html')
|
render_to_string('template_used/base.html')
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
with self.assertTemplateUsed(template_name=''):
|
with self.assertTemplateUsed(template_name=''):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
msg = (
|
||||||
|
'template_used/base.html was not rendered. Following '
|
||||||
|
'templates were rendered: template_used/alternative.html'
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
with self.assertTemplateUsed('template_used/base.html'):
|
with self.assertTemplateUsed('template_used/base.html'):
|
||||||
render_to_string('template_used/alternative.html')
|
render_to_string('template_used/alternative.html')
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,8 @@ class LegacyDatabaseTests(TestCase):
|
||||||
@skipIfDBFeature('supports_timezones')
|
@skipIfDBFeature('supports_timezones')
|
||||||
def test_aware_datetime_unsupported(self):
|
def test_aware_datetime_unsupported(self):
|
||||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
|
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
|
||||||
with self.assertRaises(ValueError):
|
msg = 'backend does not support timezone-aware datetimes when USE_TZ is False.'
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Event.objects.create(dt=dt)
|
Event.objects.create(dt=dt)
|
||||||
|
|
||||||
def test_auto_now_and_auto_now_add(self):
|
def test_auto_now_and_auto_now_add(self):
|
||||||
|
@ -647,7 +648,11 @@ class UnsupportedTimeZoneDatabaseTests(TestCase):
|
||||||
connections.databases['tz']['TIME_ZONE'] = 'Asia/Bangkok'
|
connections.databases['tz']['TIME_ZONE'] = 'Asia/Bangkok'
|
||||||
tz_conn = connections['tz']
|
tz_conn = connections['tz']
|
||||||
try:
|
try:
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"Connection 'tz' cannot set TIME_ZONE because its engine "
|
||||||
|
"handles time zones conversions natively."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
tz_conn.cursor()
|
tz_conn.cursor()
|
||||||
finally:
|
finally:
|
||||||
connections['tz'].close() # in case the test fails
|
connections['tz'].close() # in case the test fails
|
||||||
|
@ -1033,7 +1038,8 @@ class TemplateTests(SimpleTestCase):
|
||||||
self.assertEqual(tpl.render(Context()), "Europe/Paris")
|
self.assertEqual(tpl.render(Context()), "Europe/Paris")
|
||||||
|
|
||||||
def test_get_current_timezone_templatetag_invalid_argument(self):
|
def test_get_current_timezone_templatetag_invalid_argument(self):
|
||||||
with self.assertRaises(TemplateSyntaxError):
|
msg = "'get_current_timezone' requires 'as variable' (got ['get_current_timezone'])"
|
||||||
|
with self.assertRaisesMessage(TemplateSyntaxError, msg):
|
||||||
Template("{% load tz %}{% get_current_timezone %}").render()
|
Template("{% load tz %}{% get_current_timezone %}").render()
|
||||||
|
|
||||||
@skipIf(sys.platform.startswith('win'), "Windows uses non-standard time zone names")
|
@skipIf(sys.platform.startswith('win'), "Windows uses non-standard time zone names")
|
||||||
|
|
|
@ -214,7 +214,8 @@ class TestConnectionOnCommit(TransactionTestCase):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
connection.set_autocommit(False)
|
connection.set_autocommit(False)
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
msg = 'on_commit() cannot be used in manual transaction management'
|
||||||
|
with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
|
||||||
transaction.on_commit(should_never_be_called)
|
transaction.on_commit(should_never_be_called)
|
||||||
finally:
|
finally:
|
||||||
connection.set_autocommit(True)
|
connection.set_autocommit(True)
|
||||||
|
|
|
@ -299,20 +299,21 @@ class AtomicMergeTests(TransactionTestCase):
|
||||||
class AtomicErrorsTests(TransactionTestCase):
|
class AtomicErrorsTests(TransactionTestCase):
|
||||||
|
|
||||||
available_apps = ['transactions']
|
available_apps = ['transactions']
|
||||||
|
forbidden_atomic_msg = "This is forbidden when an 'atomic' block is active."
|
||||||
|
|
||||||
def test_atomic_prevents_setting_autocommit(self):
|
def test_atomic_prevents_setting_autocommit(self):
|
||||||
autocommit = transaction.get_autocommit()
|
autocommit = transaction.get_autocommit()
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
with self.assertRaisesMessage(transaction.TransactionManagementError, self.forbidden_atomic_msg):
|
||||||
transaction.set_autocommit(not autocommit)
|
transaction.set_autocommit(not autocommit)
|
||||||
# Make sure autocommit wasn't changed.
|
# Make sure autocommit wasn't changed.
|
||||||
self.assertEqual(connection.autocommit, autocommit)
|
self.assertEqual(connection.autocommit, autocommit)
|
||||||
|
|
||||||
def test_atomic_prevents_calling_transaction_methods(self):
|
def test_atomic_prevents_calling_transaction_methods(self):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
with self.assertRaisesMessage(transaction.TransactionManagementError, self.forbidden_atomic_msg):
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
with self.assertRaisesMessage(transaction.TransactionManagementError, self.forbidden_atomic_msg):
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
|
|
||||||
def test_atomic_prevents_queries_in_broken_transaction(self):
|
def test_atomic_prevents_queries_in_broken_transaction(self):
|
||||||
|
@ -322,7 +323,11 @@ class AtomicErrorsTests(TransactionTestCase):
|
||||||
with self.assertRaises(IntegrityError):
|
with self.assertRaises(IntegrityError):
|
||||||
r2.save(force_insert=True)
|
r2.save(force_insert=True)
|
||||||
# The transaction is marked as needing rollback.
|
# The transaction is marked as needing rollback.
|
||||||
with self.assertRaises(transaction.TransactionManagementError):
|
msg = (
|
||||||
|
"An error occurred in the current transaction. You can't "
|
||||||
|
"execute queries until the end of the 'atomic' block."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
|
||||||
r2.save(force_update=True)
|
r2.save(force_update=True)
|
||||||
self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock")
|
self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock")
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,8 @@ class AdvancedTests(TestCase):
|
||||||
We do not support update on already sliced query sets.
|
We do not support update on already sliced query sets.
|
||||||
"""
|
"""
|
||||||
method = DataPoint.objects.all()[:2].update
|
method = DataPoint.objects.all()[:2].update
|
||||||
with self.assertRaises(AssertionError):
|
msg = 'Cannot update a query once a slice has been taken.'
|
||||||
|
with self.assertRaisesMessage(AssertionError, msg):
|
||||||
method(another_value='another thing')
|
method(another_value='another thing')
|
||||||
|
|
||||||
def test_update_respects_to_field(self):
|
def test_update_respects_to_field(self):
|
||||||
|
|
|
@ -5,6 +5,8 @@ from .models import Account, Employee, Person, Profile, ProxyEmployee
|
||||||
|
|
||||||
|
|
||||||
class UpdateOnlyFieldsTests(TestCase):
|
class UpdateOnlyFieldsTests(TestCase):
|
||||||
|
msg = 'The following fields do not exist in this model or are m2m fields: %s'
|
||||||
|
|
||||||
def test_update_fields_basic(self):
|
def test_update_fields_basic(self):
|
||||||
s = Person.objects.create(name='Sara', gender='F')
|
s = Person.objects.create(name='Sara', gender='F')
|
||||||
self.assertEqual(s.gender, 'F')
|
self.assertEqual(s.gender, 'F')
|
||||||
|
@ -120,7 +122,7 @@ class UpdateOnlyFieldsTests(TestCase):
|
||||||
a2 = Account.objects.create(num=2)
|
a2 = Account.objects.create(num=2)
|
||||||
e1.accounts.set([a1, a2])
|
e1.accounts.set([a1, a2])
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, self.msg % 'accounts'):
|
||||||
e1.save(update_fields=['accounts'])
|
e1.save(update_fields=['accounts'])
|
||||||
|
|
||||||
def test_update_fields_inheritance(self):
|
def test_update_fields_inheritance(self):
|
||||||
|
@ -201,10 +203,12 @@ class UpdateOnlyFieldsTests(TestCase):
|
||||||
def test_update_fields_incorrect_params(self):
|
def test_update_fields_incorrect_params(self):
|
||||||
s = Person.objects.create(name='Sara', gender='F')
|
s = Person.objects.create(name='Sara', gender='F')
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaisesMessage(ValueError, self.msg % 'first_name'):
|
||||||
s.save(update_fields=['first_name'])
|
s.save(update_fields=['first_name'])
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
# "name" is treated as an iterable so the output is something like
|
||||||
|
# "n, a, m, e" but the order isn't deterministic.
|
||||||
|
with self.assertRaisesMessage(ValueError, self.msg % ''):
|
||||||
s.save(update_fields="name")
|
s.save(update_fields="name")
|
||||||
|
|
||||||
def test_empty_update_fields(self):
|
def test_empty_update_fields(self):
|
||||||
|
|
|
@ -1067,7 +1067,12 @@ class NoRootUrlConfTests(SimpleTestCase):
|
||||||
"""Tests for handler404 and handler500 if ROOT_URLCONF is None"""
|
"""Tests for handler404 and handler500 if ROOT_URLCONF is None"""
|
||||||
|
|
||||||
def test_no_handler_exception(self):
|
def test_no_handler_exception(self):
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
msg = (
|
||||||
|
"The included URLconf 'None' does not appear to have any patterns "
|
||||||
|
"in it. If you see valid patterns in the file then the issue is "
|
||||||
|
"probably caused by a circular import."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
self.client.get('/test/me/')
|
self.client.get('/test/me/')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class CommandTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_explode(self):
|
def test_explode(self):
|
||||||
""" An unknown command raises CommandError """
|
""" An unknown command raises CommandError """
|
||||||
with self.assertRaises(CommandError):
|
with self.assertRaisesMessage(CommandError, "Unknown command: 'explode'"):
|
||||||
management.call_command(('explode',))
|
management.call_command(('explode',))
|
||||||
|
|
||||||
def test_system_exit(self):
|
def test_system_exit(self):
|
||||||
|
@ -215,5 +215,6 @@ class CommandRunTests(AdminScriptTestCase):
|
||||||
class UtilsTests(SimpleTestCase):
|
class UtilsTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_no_existent_external_program(self):
|
def test_no_existent_external_program(self):
|
||||||
with self.assertRaises(CommandError):
|
msg = 'Error executing a_42_command_that_doesnt_exist_42'
|
||||||
|
with self.assertRaisesMessage(CommandError, msg):
|
||||||
popen_wrapper(['a_42_command_that_doesnt_exist_42'])
|
popen_wrapper(['a_42_command_that_doesnt_exist_42'])
|
||||||
|
|
|
@ -334,7 +334,8 @@ class TestSimpleValidators(SimpleTestCase):
|
||||||
self.assertEqual(repr(v), "ValidationError({'first': ['First Problem']})")
|
self.assertEqual(repr(v), "ValidationError({'first': ['First Problem']})")
|
||||||
|
|
||||||
def test_regex_validator_flags(self):
|
def test_regex_validator_flags(self):
|
||||||
with self.assertRaises(TypeError):
|
msg = 'If the flags are set, regex must be a regular expression string.'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
RegexValidator(re.compile('a'), flags=re.IGNORECASE)
|
RegexValidator(re.compile('a'), flags=re.IGNORECASE)
|
||||||
|
|
||||||
def test_max_length_validator_message(self):
|
def test_max_length_validator_message(self):
|
||||||
|
|
Loading…
Reference in New Issue