Refs #27804 -- Used subTest() in several tests.
This commit is contained in:
parent
91b2bc3e70
commit
6092ea8fa6
|
@ -339,4 +339,5 @@ class AdminDocViewFunctionsTests(SimpleTestCase):
|
||||||
(r'^a/?$', '/a/'),
|
(r'^a/?$', '/a/'),
|
||||||
)
|
)
|
||||||
for pattern, output in tests:
|
for pattern, output in tests:
|
||||||
|
with self.subTest(pattern=pattern):
|
||||||
self.assertEqual(simplify_regex(pattern), output)
|
self.assertEqual(simplify_regex(pattern), output)
|
||||||
|
|
|
@ -47,6 +47,7 @@ class MultiDatabaseTests(TestCase):
|
||||||
@mock.patch('django.contrib.admin.options.transaction')
|
@mock.patch('django.contrib.admin.options.transaction')
|
||||||
def test_add_view(self, mock):
|
def test_add_view(self, mock):
|
||||||
for db in connections:
|
for db in connections:
|
||||||
|
with self.subTest(db=db):
|
||||||
Router.target_db = db
|
Router.target_db = db
|
||||||
self.client.force_login(self.superusers[db])
|
self.client.force_login(self.superusers[db])
|
||||||
self.client.post(
|
self.client.post(
|
||||||
|
@ -58,6 +59,7 @@ class MultiDatabaseTests(TestCase):
|
||||||
@mock.patch('django.contrib.admin.options.transaction')
|
@mock.patch('django.contrib.admin.options.transaction')
|
||||||
def test_change_view(self, mock):
|
def test_change_view(self, mock):
|
||||||
for db in connections:
|
for db in connections:
|
||||||
|
with self.subTest(db=db):
|
||||||
Router.target_db = db
|
Router.target_db = db
|
||||||
self.client.force_login(self.superusers[db])
|
self.client.force_login(self.superusers[db])
|
||||||
self.client.post(
|
self.client.post(
|
||||||
|
@ -69,6 +71,7 @@ class MultiDatabaseTests(TestCase):
|
||||||
@mock.patch('django.contrib.admin.options.transaction')
|
@mock.patch('django.contrib.admin.options.transaction')
|
||||||
def test_delete_view(self, mock):
|
def test_delete_view(self, mock):
|
||||||
for db in connections:
|
for db in connections:
|
||||||
|
with self.subTest(db=db):
|
||||||
Router.target_db = db
|
Router.target_db = db
|
||||||
self.client.force_login(self.superusers[db])
|
self.client.force_login(self.superusers[db])
|
||||||
self.client.post(
|
self.client.post(
|
||||||
|
|
|
@ -42,6 +42,7 @@ class MultiDatabaseTests(TestCase):
|
||||||
@mock.patch('django.contrib.auth.admin.transaction')
|
@mock.patch('django.contrib.auth.admin.transaction')
|
||||||
def test_add_view(self, mock):
|
def test_add_view(self, mock):
|
||||||
for db in connections:
|
for db in connections:
|
||||||
|
with self.subTest(db_connection=db):
|
||||||
Router.target_db = db
|
Router.target_db = db
|
||||||
self.client.force_login(self.superusers[db])
|
self.client.force_login(self.superusers[db])
|
||||||
self.client.post(reverse('test_adminsite:auth_user_add'), {
|
self.client.post(reverse('test_adminsite:auth_user_add'), {
|
||||||
|
|
|
@ -300,6 +300,7 @@ class TestUtilsHashPass(SimpleTestCase):
|
||||||
def test_upgrade(self):
|
def test_upgrade(self):
|
||||||
self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm)
|
self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm)
|
||||||
for algo in ('sha1', 'md5'):
|
for algo in ('sha1', 'md5'):
|
||||||
|
with self.subTest(algo=algo):
|
||||||
encoded = make_password('lètmein', hasher=algo)
|
encoded = make_password('lètmein', hasher=algo)
|
||||||
state = {'upgraded': False}
|
state = {'upgraded': False}
|
||||||
|
|
||||||
|
@ -327,6 +328,7 @@ class TestUtilsHashPass(SimpleTestCase):
|
||||||
def test_no_upgrade_on_incorrect_pass(self):
|
def test_no_upgrade_on_incorrect_pass(self):
|
||||||
self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm)
|
self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm)
|
||||||
for algo in ('sha1', 'md5'):
|
for algo in ('sha1', 'md5'):
|
||||||
|
with self.subTest(algo=algo):
|
||||||
encoded = make_password('lètmein', hasher=algo)
|
encoded = make_password('lètmein', hasher=algo)
|
||||||
state = {'upgraded': False}
|
state = {'upgraded': False}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ class AbstractBaseUserTests(TestCase):
|
||||||
# The normalization happens in AbstractBaseUser.clean()
|
# The normalization happens in AbstractBaseUser.clean()
|
||||||
ohm_username = 'iamtheΩ' # U+2126 OHM SIGN
|
ohm_username = 'iamtheΩ' # U+2126 OHM SIGN
|
||||||
for model in ('auth.User', 'auth_tests.CustomUser'):
|
for model in ('auth.User', 'auth_tests.CustomUser'):
|
||||||
with self.settings(AUTH_USER_MODEL=model):
|
with self.subTest(model=model), self.settings(AUTH_USER_MODEL=model):
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
user = User(**{User.USERNAME_FIELD: ohm_username, 'password': 'foo'})
|
user = User(**{User.USERNAME_FIELD: ohm_username, 'password': 'foo'})
|
||||||
user.clean()
|
user.clean()
|
||||||
|
|
|
@ -214,8 +214,10 @@ class UsernameValidatorsTests(TestCase):
|
||||||
]
|
]
|
||||||
v = validators.UnicodeUsernameValidator()
|
v = validators.UnicodeUsernameValidator()
|
||||||
for valid in valid_usernames:
|
for valid in valid_usernames:
|
||||||
|
with self.subTest(valid=valid):
|
||||||
v(valid)
|
v(valid)
|
||||||
for invalid in invalid_usernames:
|
for invalid in invalid_usernames:
|
||||||
|
with self.subTest(invalid=invalid):
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
v(invalid)
|
v(invalid)
|
||||||
|
|
||||||
|
@ -224,7 +226,9 @@ class UsernameValidatorsTests(TestCase):
|
||||||
invalid_usernames = ["o'connell", 'Éric', 'jean marc', "أحمد"]
|
invalid_usernames = ["o'connell", 'Éric', 'jean marc', "أحمد"]
|
||||||
v = validators.ASCIIUsernameValidator()
|
v = validators.ASCIIUsernameValidator()
|
||||||
for valid in valid_usernames:
|
for valid in valid_usernames:
|
||||||
|
with self.subTest(valid=valid):
|
||||||
v(valid)
|
v(valid)
|
||||||
for invalid in invalid_usernames:
|
for invalid in invalid_usernames:
|
||||||
|
with self.subTest(invalid=invalid):
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
v(invalid)
|
v(invalid)
|
||||||
|
|
|
@ -108,6 +108,7 @@ class AuthViewNamedURLTests(AuthViewsTestCase):
|
||||||
('password_reset_complete', [], {}),
|
('password_reset_complete', [], {}),
|
||||||
]
|
]
|
||||||
for name, args, kwargs in expected_named_urls:
|
for name, args, kwargs in expected_named_urls:
|
||||||
|
with self.subTest(name=name):
|
||||||
try:
|
try:
|
||||||
reverse(name, args=args, kwargs=kwargs)
|
reverse(name, args=args, kwargs=kwargs)
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
|
@ -559,15 +560,18 @@ class LoginTest(AuthViewsTestCase):
|
||||||
def test_security_check(self):
|
def test_security_check(self):
|
||||||
login_url = reverse('login')
|
login_url = reverse('login')
|
||||||
|
|
||||||
# Those URLs should not pass the security check
|
# These URLs should not pass the security check.
|
||||||
for bad_url in ('http://example.com',
|
bad_urls = (
|
||||||
|
'http://example.com',
|
||||||
'http:///example.com',
|
'http:///example.com',
|
||||||
'https://example.com',
|
'https://example.com',
|
||||||
'ftp://example.com',
|
'ftp://example.com',
|
||||||
'///example.com',
|
'///example.com',
|
||||||
'//example.com',
|
'//example.com',
|
||||||
'javascript:alert("XSS")'):
|
'javascript:alert("XSS")',
|
||||||
|
)
|
||||||
|
for bad_url in bad_urls:
|
||||||
|
with self.subTest(bad_url=bad_url):
|
||||||
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
||||||
'url': login_url,
|
'url': login_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
|
@ -578,18 +582,21 @@ class LoginTest(AuthViewsTestCase):
|
||||||
'password': 'password',
|
'password': 'password',
|
||||||
})
|
})
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertNotIn(bad_url, response.url,
|
self.assertNotIn(bad_url, response.url, '%s should be blocked' % bad_url)
|
||||||
"%s should be blocked" % bad_url)
|
|
||||||
|
|
||||||
# These URLs *should* still pass the security check
|
# These URLs should pass the security check.
|
||||||
for good_url in ('/view/?param=http://example.com',
|
good_urls = (
|
||||||
|
'/view/?param=http://example.com',
|
||||||
'/view/?param=https://example.com',
|
'/view/?param=https://example.com',
|
||||||
'/view?param=ftp://example.com',
|
'/view?param=ftp://example.com',
|
||||||
'view/?param=//example.com',
|
'view/?param=//example.com',
|
||||||
'https://testserver/',
|
'https://testserver/',
|
||||||
'HTTPS://testserver/',
|
'HTTPS://testserver/',
|
||||||
'//testserver/',
|
'//testserver/',
|
||||||
'/url%20with%20spaces/'): # see ticket #12534
|
'/url%20with%20spaces/',
|
||||||
|
)
|
||||||
|
for good_url in good_urls:
|
||||||
|
with self.subTest(good_url=good_url):
|
||||||
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
||||||
'url': login_url,
|
'url': login_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
|
@ -600,7 +607,7 @@ class LoginTest(AuthViewsTestCase):
|
||||||
'password': 'password',
|
'password': 'password',
|
||||||
})
|
})
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertIn(good_url, response.url, "%s should be allowed" % good_url)
|
self.assertIn(good_url, response.url, '%s should be allowed' % good_url)
|
||||||
|
|
||||||
def test_security_check_https(self):
|
def test_security_check_https(self):
|
||||||
login_url = reverse('login')
|
login_url = reverse('login')
|
||||||
|
@ -988,14 +995,18 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
def test_security_check(self):
|
def test_security_check(self):
|
||||||
logout_url = reverse('logout')
|
logout_url = reverse('logout')
|
||||||
|
|
||||||
# Those URLs should not pass the security check
|
# These URLs should not pass the security check.
|
||||||
for bad_url in ('http://example.com',
|
bad_urls = (
|
||||||
|
'http://example.com',
|
||||||
'http:///example.com',
|
'http:///example.com',
|
||||||
'https://example.com',
|
'https://example.com',
|
||||||
'ftp://example.com',
|
'ftp://example.com',
|
||||||
'///example.com',
|
'///example.com',
|
||||||
'//example.com',
|
'//example.com',
|
||||||
'javascript:alert("XSS")'):
|
'javascript:alert("XSS")',
|
||||||
|
)
|
||||||
|
for bad_url in bad_urls:
|
||||||
|
with self.subTest(bad_url=bad_url):
|
||||||
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
||||||
'url': logout_url,
|
'url': logout_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
|
@ -1004,19 +1015,22 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
self.login()
|
self.login()
|
||||||
response = self.client.get(nasty_url)
|
response = self.client.get(nasty_url)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertNotIn(bad_url, response.url,
|
self.assertNotIn(bad_url, response.url, '%s should be blocked' % bad_url)
|
||||||
"%s should be blocked" % bad_url)
|
|
||||||
self.confirm_logged_out()
|
self.confirm_logged_out()
|
||||||
|
|
||||||
# These URLs *should* still pass the security check
|
# These URLs should pass the security check.
|
||||||
for good_url in ('/view/?param=http://example.com',
|
good_urls = (
|
||||||
|
'/view/?param=http://example.com',
|
||||||
'/view/?param=https://example.com',
|
'/view/?param=https://example.com',
|
||||||
'/view?param=ftp://example.com',
|
'/view?param=ftp://example.com',
|
||||||
'view/?param=//example.com',
|
'view/?param=//example.com',
|
||||||
'https://testserver/',
|
'https://testserver/',
|
||||||
'HTTPS://testserver/',
|
'HTTPS://testserver/',
|
||||||
'//testserver/',
|
'//testserver/',
|
||||||
'/url%20with%20spaces/'): # see ticket #12534
|
'/url%20with%20spaces/',
|
||||||
|
)
|
||||||
|
for good_url in good_urls:
|
||||||
|
with self.subTest(good_url=good_url):
|
||||||
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
||||||
'url': logout_url,
|
'url': logout_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
|
@ -1025,7 +1039,7 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
self.login()
|
self.login()
|
||||||
response = self.client.get(safe_url)
|
response = self.client.get(safe_url)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertIn(good_url, response.url, "%s should be allowed" % good_url)
|
self.assertIn(good_url, response.url, '%s should be allowed' % good_url)
|
||||||
self.confirm_logged_out()
|
self.confirm_logged_out()
|
||||||
|
|
||||||
def test_security_check_https(self):
|
def test_security_check_https(self):
|
||||||
|
|
|
@ -169,6 +169,7 @@ class DummyCacheTests(SimpleTestCase):
|
||||||
'ascii2': {'x': 1}
|
'ascii2': {'x': 1}
|
||||||
}
|
}
|
||||||
for (key, value) in stuff.items():
|
for (key, value) in stuff.items():
|
||||||
|
with self.subTest(key=key):
|
||||||
cache.set(key, value)
|
cache.set(key, value)
|
||||||
self.assertIsNone(cache.get(key))
|
self.assertIsNone(cache.get(key))
|
||||||
|
|
||||||
|
@ -420,11 +421,13 @@ class BaseCacheTests:
|
||||||
}
|
}
|
||||||
# Test `set`
|
# Test `set`
|
||||||
for (key, value) in stuff.items():
|
for (key, value) in stuff.items():
|
||||||
|
with self.subTest(key=key):
|
||||||
cache.set(key, value)
|
cache.set(key, value)
|
||||||
self.assertEqual(cache.get(key), value)
|
self.assertEqual(cache.get(key), value)
|
||||||
|
|
||||||
# Test `add`
|
# Test `add`
|
||||||
for (key, value) in stuff.items():
|
for (key, value) in stuff.items():
|
||||||
|
with self.subTest(key=key):
|
||||||
cache.delete(key)
|
cache.delete(key)
|
||||||
cache.add(key, value)
|
cache.add(key, value)
|
||||||
self.assertEqual(cache.get(key), value)
|
self.assertEqual(cache.get(key), value)
|
||||||
|
@ -434,6 +437,7 @@ class BaseCacheTests:
|
||||||
cache.delete(key)
|
cache.delete(key)
|
||||||
cache.set_many(stuff)
|
cache.set_many(stuff)
|
||||||
for (key, value) in stuff.items():
|
for (key, value) in stuff.items():
|
||||||
|
with self.subTest(key=key):
|
||||||
self.assertEqual(cache.get(key), value)
|
self.assertEqual(cache.get(key), value)
|
||||||
|
|
||||||
def test_binary_string(self):
|
def test_binary_string(self):
|
||||||
|
@ -1151,6 +1155,7 @@ class BaseMemcachedTests(BaseCacheTests):
|
||||||
'server1.tld,server2:11211',
|
'server1.tld,server2:11211',
|
||||||
]
|
]
|
||||||
for location in locations:
|
for location in locations:
|
||||||
|
with self.subTest(location=location):
|
||||||
params = {'BACKEND': self.base_params['BACKEND'], 'LOCATION': location}
|
params = {'BACKEND': self.base_params['BACKEND'], 'LOCATION': location}
|
||||||
with self.settings(CACHES={'default': params}):
|
with self.settings(CACHES={'default': params}):
|
||||||
self.assertEqual(cache._servers, ['server1.tld', 'server2:11211'])
|
self.assertEqual(cache._servers, ['server1.tld', 'server2:11211'])
|
||||||
|
@ -1250,6 +1255,7 @@ class MemcachedCacheTests(BaseMemcachedTests, TestCase):
|
||||||
def test_memcached_uses_highest_pickle_version(self):
|
def test_memcached_uses_highest_pickle_version(self):
|
||||||
# Regression test for #19810
|
# Regression test for #19810
|
||||||
for cache_key in settings.CACHES:
|
for cache_key in settings.CACHES:
|
||||||
|
with self.subTest(cache_key=cache_key):
|
||||||
self.assertEqual(caches[cache_key]._cache.pickleProtocol, pickle.HIGHEST_PROTOCOL)
|
self.assertEqual(caches[cache_key]._cache.pickleProtocol, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
@override_settings(CACHES=caches_setting_for_tests(
|
@override_settings(CACHES=caches_setting_for_tests(
|
||||||
|
@ -1521,6 +1527,7 @@ class CacheUtils(SimpleTestCase):
|
||||||
('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
||||||
)
|
)
|
||||||
for initial_vary, newheaders, resulting_vary in headers:
|
for initial_vary, newheaders, resulting_vary in headers:
|
||||||
|
with self.subTest(initial_vary=initial_vary, newheaders=newheaders):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
if initial_vary is not None:
|
if initial_vary is not None:
|
||||||
response['Vary'] = initial_vary
|
response['Vary'] = initial_vary
|
||||||
|
@ -1605,6 +1612,7 @@ class CacheUtils(SimpleTestCase):
|
||||||
cc_delim_re = re.compile(r'\s*,\s*')
|
cc_delim_re = re.compile(r'\s*,\s*')
|
||||||
|
|
||||||
for initial_cc, newheaders, expected_cc in tests:
|
for initial_cc, newheaders, expected_cc in tests:
|
||||||
|
with self.subTest(initial_cc=initial_cc, newheaders=newheaders):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
if initial_cc is not None:
|
if initial_cc is not None:
|
||||||
response['Cache-Control'] = initial_cc
|
response['Cache-Control'] = initial_cc
|
||||||
|
@ -2179,6 +2187,7 @@ class TestWithTemplateResponse(SimpleTestCase):
|
||||||
('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
||||||
)
|
)
|
||||||
for initial_vary, newheaders, resulting_vary in headers:
|
for initial_vary, newheaders, resulting_vary in headers:
|
||||||
|
with self.subTest(initial_vary=initial_vary, newheaders=newheaders):
|
||||||
template = engines['django'].from_string("This is a test")
|
template = engines['django'].from_string("This is a test")
|
||||||
response = TemplateResponse(HttpRequest(), template)
|
response = TemplateResponse(HttpRequest(), template)
|
||||||
if initial_vary is not None:
|
if initial_vary is not None:
|
||||||
|
|
|
@ -45,6 +45,7 @@ class ContentTypesViewsTests(TestCase):
|
||||||
def test_shortcut_with_absolute_url(self):
|
def test_shortcut_with_absolute_url(self):
|
||||||
"Can view a shortcut for an Author object that has a get_absolute_url method"
|
"Can view a shortcut for an Author object that has a get_absolute_url method"
|
||||||
for obj in Author.objects.all():
|
for obj in Author.objects.all():
|
||||||
|
with self.subTest(obj=obj):
|
||||||
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk)
|
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk)
|
||||||
response = self.client.get(short_url)
|
response = self.client.get(short_url)
|
||||||
self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(), target_status_code=404)
|
self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(), target_status_code=404)
|
||||||
|
@ -55,6 +56,7 @@ class ContentTypesViewsTests(TestCase):
|
||||||
the tested URLs are: "http://...", "https://..." and "//..."
|
the tested URLs are: "http://...", "https://..." and "//..."
|
||||||
"""
|
"""
|
||||||
for obj in SchemeIncludedURL.objects.all():
|
for obj in SchemeIncludedURL.objects.all():
|
||||||
|
with self.subTest(obj=obj):
|
||||||
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(SchemeIncludedURL).id, obj.pk)
|
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(SchemeIncludedURL).id, obj.pk)
|
||||||
response = self.client.get(short_url)
|
response = self.client.get(short_url)
|
||||||
self.assertRedirects(response, obj.get_absolute_url(), fetch_redirect_response=False)
|
self.assertRedirects(response, obj.get_absolute_url(), fetch_redirect_response=False)
|
||||||
|
@ -65,6 +67,7 @@ class ContentTypesViewsTests(TestCase):
|
||||||
404.
|
404.
|
||||||
"""
|
"""
|
||||||
for obj in Article.objects.all():
|
for obj in Article.objects.all():
|
||||||
|
with self.subTest(obj=obj):
|
||||||
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk)
|
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk)
|
||||||
response = self.client.get(short_url)
|
response = self.client.get(short_url)
|
||||||
self.assertEqual(response.status_code, 404)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
|
@ -42,6 +42,7 @@ class CustomManagerTests(TestCase):
|
||||||
default Manager.
|
default Manager.
|
||||||
"""
|
"""
|
||||||
for manager_name in self.custom_manager_names:
|
for manager_name in self.custom_manager_names:
|
||||||
|
with self.subTest(manager_name=manager_name):
|
||||||
manager = getattr(Person, manager_name)
|
manager = getattr(Person, manager_name)
|
||||||
|
|
||||||
# Public methods are copied
|
# Public methods are copied
|
||||||
|
@ -52,6 +53,7 @@ class CustomManagerTests(TestCase):
|
||||||
|
|
||||||
def test_manager_honors_queryset_only(self):
|
def test_manager_honors_queryset_only(self):
|
||||||
for manager_name in self.custom_manager_names:
|
for manager_name in self.custom_manager_names:
|
||||||
|
with self.subTest(manager_name=manager_name):
|
||||||
manager = getattr(Person, manager_name)
|
manager = getattr(Person, manager_name)
|
||||||
# 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()
|
||||||
|
@ -64,6 +66,7 @@ class CustomManagerTests(TestCase):
|
||||||
Custom manager will use the queryset methods
|
Custom manager will use the queryset methods
|
||||||
"""
|
"""
|
||||||
for manager_name in self.custom_manager_names:
|
for manager_name in self.custom_manager_names:
|
||||||
|
with self.subTest(manager_name=manager_name):
|
||||||
manager = getattr(Person, manager_name)
|
manager = getattr(Person, manager_name)
|
||||||
queryset = manager.filter()
|
queryset = manager.filter()
|
||||||
self.assertQuerysetEqual(queryset, ["Bugs Bunny"], str)
|
self.assertQuerysetEqual(queryset, ["Bugs Bunny"], str)
|
||||||
|
|
|
@ -54,9 +54,9 @@ class DBTypeCasts(unittest.TestCase):
|
||||||
def test_typeCasts(self):
|
def test_typeCasts(self):
|
||||||
for k, v in TEST_CASES.items():
|
for k, v in TEST_CASES.items():
|
||||||
for inpt, expected in v:
|
for inpt, expected in v:
|
||||||
|
with self.subTest(k=k, inpt=inpt):
|
||||||
got = getattr(typecasts, k)(inpt)
|
got = getattr(typecasts, k)(inpt)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
got,
|
got, expected,
|
||||||
expected,
|
|
||||||
"In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got)
|
"In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got)
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,6 +38,7 @@ class FilePathFieldTest(SimpleTestCase):
|
||||||
('/django/forms/widgets.py', 'widgets.py')
|
('/django/forms/widgets.py', 'widgets.py')
|
||||||
]
|
]
|
||||||
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
||||||
|
with self.subTest(expected=exp):
|
||||||
self.assertEqual(exp[1], got[1])
|
self.assertEqual(exp[1], got[1])
|
||||||
self.assertTrue(got[0].endswith(exp[0]))
|
self.assertTrue(got[0].endswith(exp[0]))
|
||||||
msg = "'Select a valid choice. fields.py is not one of the available choices.'"
|
msg = "'Select a valid choice. fields.py is not one of the available choices.'"
|
||||||
|
@ -61,6 +62,7 @@ class FilePathFieldTest(SimpleTestCase):
|
||||||
('/django/forms/widgets.py', 'widgets.py')
|
('/django/forms/widgets.py', 'widgets.py')
|
||||||
]
|
]
|
||||||
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
||||||
|
with self.subTest(expected=exp):
|
||||||
self.assertEqual(exp[1], got[1])
|
self.assertEqual(exp[1], got[1])
|
||||||
self.assertTrue(got[0].endswith(exp[0]))
|
self.assertTrue(got[0].endswith(exp[0]))
|
||||||
|
|
||||||
|
@ -80,6 +82,7 @@ class FilePathFieldTest(SimpleTestCase):
|
||||||
('/django/forms/widgets.py', 'widgets.py')
|
('/django/forms/widgets.py', 'widgets.py')
|
||||||
]
|
]
|
||||||
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
for exp, got in zip(expected, fix_os_paths(f.choices)):
|
||||||
|
with self.subTest(expected=exp):
|
||||||
self.assertEqual(exp[1], got[1])
|
self.assertEqual(exp[1], got[1])
|
||||||
self.assertTrue(got[0].endswith(exp[0]))
|
self.assertTrue(got[0].endswith(exp[0]))
|
||||||
|
|
||||||
|
@ -93,6 +96,7 @@ class FilePathFieldTest(SimpleTestCase):
|
||||||
actual = fix_os_paths(f.choices)
|
actual = fix_os_paths(f.choices)
|
||||||
self.assertEqual(len(expected), len(actual))
|
self.assertEqual(len(expected), len(actual))
|
||||||
for exp, got in zip(expected, actual):
|
for exp, got in zip(expected, actual):
|
||||||
|
with self.subTest(expected=exp):
|
||||||
self.assertEqual(exp[1], got[1])
|
self.assertEqual(exp[1], got[1])
|
||||||
self.assertTrue(got[0].endswith(exp[0]))
|
self.assertTrue(got[0].endswith(exp[0]))
|
||||||
|
|
||||||
|
@ -110,5 +114,6 @@ class FilePathFieldTest(SimpleTestCase):
|
||||||
actual = fix_os_paths(f.choices)
|
actual = fix_os_paths(f.choices)
|
||||||
self.assertEqual(len(expected), len(actual))
|
self.assertEqual(len(expected), len(actual))
|
||||||
for exp, got in zip(expected, actual):
|
for exp, got in zip(expected, actual):
|
||||||
|
with self.subTest(expected=exp):
|
||||||
self.assertEqual(exp[1], got[1])
|
self.assertEqual(exp[1], got[1])
|
||||||
self.assertTrue(got[0].endswith(exp[0]))
|
self.assertTrue(got[0].endswith(exp[0]))
|
||||||
|
|
|
@ -127,6 +127,7 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
||||||
'http://العربية.idn.icann.org/',
|
'http://العربية.idn.icann.org/',
|
||||||
)
|
)
|
||||||
for url in urls:
|
for url in urls:
|
||||||
|
with self.subTest(url=url):
|
||||||
# Valid IDN
|
# Valid IDN
|
||||||
self.assertEqual(url, f.clean(url))
|
self.assertEqual(url, f.clean(url))
|
||||||
|
|
||||||
|
@ -138,6 +139,7 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
||||||
'http://[a34:9238::]:8080/',
|
'http://[a34:9238::]:8080/',
|
||||||
)
|
)
|
||||||
for url in urls:
|
for url in urls:
|
||||||
|
with self.subTest(url=url):
|
||||||
self.assertEqual(url, f.clean(url))
|
self.assertEqual(url, f.clean(url))
|
||||||
|
|
||||||
def test_urlfield_not_string(self):
|
def test_urlfield_not_string(self):
|
||||||
|
|
|
@ -3008,6 +3008,7 @@ Good luck picking a username that doesn't already exist.</p>
|
||||||
]
|
]
|
||||||
|
|
||||||
for args, kwargs, expected in testcases:
|
for args, kwargs, expected in testcases:
|
||||||
|
with self.subTest(args=args, kwargs=kwargs):
|
||||||
self.assertHTMLEqual(boundfield.label_tag(*args, **kwargs), expected)
|
self.assertHTMLEqual(boundfield.label_tag(*args, **kwargs), expected)
|
||||||
|
|
||||||
def test_boundfield_label_tag_no_id(self):
|
def test_boundfield_label_tag_no_id(self):
|
||||||
|
|
|
@ -335,12 +335,12 @@ class EmptyLabelTestCase(TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
for form, key, expected in tests:
|
for form, key, expected in tests:
|
||||||
|
with self.subTest(form=form):
|
||||||
f = form({'name': 'some-key', key: ''})
|
f = form({'name': 'some-key', key: ''})
|
||||||
self.assertTrue(f.is_valid())
|
self.assertTrue(f.is_valid())
|
||||||
m = f.save()
|
m = f.save()
|
||||||
self.assertEqual(expected, getattr(m, key))
|
self.assertEqual(expected, getattr(m, key))
|
||||||
self.assertEqual('No Preference',
|
self.assertEqual('No Preference', getattr(m, 'get_{}_display'.format(key))())
|
||||||
getattr(m, 'get_{}_display'.format(key))())
|
|
||||||
|
|
||||||
def test_empty_field_integer(self):
|
def test_empty_field_integer(self):
|
||||||
f = EmptyIntegerLabelChoiceForm()
|
f = EmptyIntegerLabelChoiceForm()
|
||||||
|
|
|
@ -68,10 +68,12 @@ class DistanceTest(TestCase):
|
||||||
qs1 = SouthTexasCity.objects.filter(point__dwithin=(self.stx_pnt, dist1))
|
qs1 = SouthTexasCity.objects.filter(point__dwithin=(self.stx_pnt, dist1))
|
||||||
qs2 = SouthTexasCityFt.objects.filter(point__dwithin=(self.stx_pnt, dist2))
|
qs2 = SouthTexasCityFt.objects.filter(point__dwithin=(self.stx_pnt, dist2))
|
||||||
for qs in qs1, qs2:
|
for qs in qs1, qs2:
|
||||||
|
with self.subTest(dist=dist, qs=qs):
|
||||||
self.assertEqual(tx_cities, self.get_names(qs))
|
self.assertEqual(tx_cities, self.get_names(qs))
|
||||||
|
|
||||||
# Now performing the `dwithin` queries on a geodetic coordinate system.
|
# Now performing the `dwithin` queries on a geodetic coordinate system.
|
||||||
for dist in au_dists:
|
for dist in au_dists:
|
||||||
|
with self.subTest(dist=dist):
|
||||||
if isinstance(dist, D) and not oracle:
|
if isinstance(dist, D) and not oracle:
|
||||||
type_error = True
|
type_error = True
|
||||||
else:
|
else:
|
||||||
|
@ -88,8 +90,9 @@ class DistanceTest(TestCase):
|
||||||
# Creating the query set.
|
# Creating the query set.
|
||||||
qs = AustraliaCity.objects.order_by('name')
|
qs = AustraliaCity.objects.order_by('name')
|
||||||
if type_error:
|
if type_error:
|
||||||
# A ValueError should be raised on PostGIS when trying to pass
|
# A ValueError should be raised on PostGIS when trying to
|
||||||
# Distance objects into a DWithin query using a geodetic field.
|
# pass Distance objects into a DWithin query using a
|
||||||
|
# geodetic field.
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
AustraliaCity.objects.filter(point__dwithin=(self.au_pnt, dist)).count()
|
AustraliaCity.objects.filter(point__dwithin=(self.au_pnt, dist)).count()
|
||||||
else:
|
else:
|
||||||
|
@ -298,6 +301,7 @@ class DistanceFunctionsTests(TestCase):
|
||||||
# Ensuring expected distances are returned for each distance queryset.
|
# Ensuring expected distances are returned for each distance queryset.
|
||||||
for qs in dist_qs:
|
for qs in dist_qs:
|
||||||
for i, c in enumerate(qs):
|
for i, c in enumerate(qs):
|
||||||
|
with self.subTest(c=c):
|
||||||
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
|
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
|
||||||
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
|
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
|
||||||
|
|
||||||
|
@ -318,6 +322,7 @@ class DistanceFunctionsTests(TestCase):
|
||||||
40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
|
40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
|
||||||
qs = AustraliaCity.objects.annotate(distance=Distance('point', ls)).order_by('name')
|
qs = AustraliaCity.objects.annotate(distance=Distance('point', ls)).order_by('name')
|
||||||
for city, distance in zip(qs, distances):
|
for city, distance in zip(qs, distances):
|
||||||
|
with self.subTest(city=city, distance=distance):
|
||||||
# Testing equivalence to within a meter (kilometer on SpatiaLite).
|
# Testing equivalence to within a meter (kilometer on SpatiaLite).
|
||||||
tol = -3 if spatialite else 0
|
tol = -3 if spatialite else 0
|
||||||
self.assertAlmostEqual(distance, city.distance.m, tol)
|
self.assertAlmostEqual(distance, city.distance.m, tol)
|
||||||
|
@ -349,6 +354,7 @@ class DistanceFunctionsTests(TestCase):
|
||||||
distance=Distance('point', hillsdale.point, spheroid=True)
|
distance=Distance('point', hillsdale.point, spheroid=True)
|
||||||
).order_by('id')
|
).order_by('id')
|
||||||
for i, c in enumerate(qs):
|
for i, c in enumerate(qs):
|
||||||
|
with self.subTest(c=c):
|
||||||
self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol)
|
self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol)
|
||||||
if postgis or spatialite:
|
if postgis or spatialite:
|
||||||
# PostGIS uses sphere-only distances by default, testing these as well.
|
# PostGIS uses sphere-only distances by default, testing these as well.
|
||||||
|
@ -356,6 +362,7 @@ class DistanceFunctionsTests(TestCase):
|
||||||
distance=Distance('point', hillsdale.point)
|
distance=Distance('point', hillsdale.point)
|
||||||
).order_by('id')
|
).order_by('id')
|
||||||
for i, c in enumerate(qs):
|
for i, c in enumerate(qs):
|
||||||
|
with self.subTest(c=c):
|
||||||
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
|
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
|
||||||
|
|
||||||
@skipIfDBFeature("supports_distance_geodetic")
|
@skipIfDBFeature("supports_distance_geodetic")
|
||||||
|
|
|
@ -15,6 +15,7 @@ class GeometryFieldTest(SimpleTestCase):
|
||||||
"Testing GeometryField initialization with defaults."
|
"Testing GeometryField initialization with defaults."
|
||||||
fld = forms.GeometryField()
|
fld = forms.GeometryField()
|
||||||
for bad_default in ('blah', 3, 'FoO', None, 0):
|
for bad_default in ('blah', 3, 'FoO', None, 0):
|
||||||
|
with self.subTest(bad_default=bad_default):
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
fld.clean(bad_default)
|
fld.clean(bad_default)
|
||||||
|
|
||||||
|
@ -50,8 +51,9 @@ class GeometryFieldTest(SimpleTestCase):
|
||||||
# By default, all geometry types are allowed.
|
# By default, all geometry types are allowed.
|
||||||
fld = forms.GeometryField()
|
fld = forms.GeometryField()
|
||||||
for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
|
for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
|
||||||
# `to_python` uses the SRID of OpenLayersWidget if the converted
|
with self.subTest(wkt=wkt):
|
||||||
# value doesn't have an SRID itself.
|
# to_python() uses the SRID of OpenLayersWidget if the
|
||||||
|
# converted value doesn't have an SRID.
|
||||||
self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.clean(wkt))
|
self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.clean(wkt))
|
||||||
|
|
||||||
pnt_fld = forms.GeometryField(geom_type='POINT')
|
pnt_fld = forms.GeometryField(geom_type='POINT')
|
||||||
|
@ -73,9 +75,11 @@ class GeometryFieldTest(SimpleTestCase):
|
||||||
fld = forms.GeometryField()
|
fld = forms.GeometryField()
|
||||||
# to_python returns the same GEOSGeometry for a WKT
|
# to_python returns the same GEOSGeometry for a WKT
|
||||||
for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
|
for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
|
||||||
|
with self.subTest(wkt=wkt):
|
||||||
self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.to_python(wkt))
|
self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.to_python(wkt))
|
||||||
# but raises a ValidationError for any other string
|
# but raises a ValidationError for any other string
|
||||||
for wkt in ('POINT(5)', 'MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'BLAH(0 0, 1 1)'):
|
for wkt in ('POINT(5)', 'MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'BLAH(0 0, 1 1)'):
|
||||||
|
with self.subTest(wkt=wkt):
|
||||||
with self.assertRaises(forms.ValidationError):
|
with self.assertRaises(forms.ValidationError):
|
||||||
fld.to_python(wkt)
|
fld.to_python(wkt)
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,7 @@ class DistanceTest(unittest.TestCase):
|
||||||
unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'),
|
unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'),
|
||||||
('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')]
|
('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')]
|
||||||
for nm, att in unit_tuple:
|
for nm, att in unit_tuple:
|
||||||
|
with self.subTest(nm=nm):
|
||||||
self.assertEqual(att, D.unit_attname(nm))
|
self.assertEqual(att, D.unit_attname(nm))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ class TestPostGISVersionCheck(unittest.TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
for version in versions:
|
for version in versions:
|
||||||
|
with self.subTest(version=version):
|
||||||
ops = FakePostGISOperations(version[0])
|
ops = FakePostGISOperations(version[0])
|
||||||
actual = ops.spatial_version
|
actual = ops.spatial_version
|
||||||
self.assertEqual(version[1:], actual)
|
self.assertEqual(version[1:], actual)
|
||||||
|
@ -84,6 +85,7 @@ class TestPostGISVersionCheck(unittest.TestCase):
|
||||||
versions = ['nope', '123']
|
versions = ['nope', '123']
|
||||||
|
|
||||||
for version in versions:
|
for version in versions:
|
||||||
|
with self.subTest(version=version):
|
||||||
ops = FakePostGISOperations(version)
|
ops = FakePostGISOperations(version)
|
||||||
with self.assertRaises(Exception):
|
with self.assertRaises(Exception):
|
||||||
ops.spatial_version
|
ops.spatial_version
|
||||||
|
|
Loading…
Reference in New Issue