diff options
Diffstat (limited to 'tests/urlpatterns')
| -rw-r--r-- | tests/urlpatterns/converter_urls.py | 4 | ||||
| -rw-r--r-- | tests/urlpatterns/converters.py | 6 | ||||
| -rw-r--r-- | tests/urlpatterns/included_urls.py | 4 | ||||
| -rw-r--r-- | tests/urlpatterns/more_urls.py | 2 | ||||
| -rw-r--r-- | tests/urlpatterns/path_base64_urls.py | 20 | ||||
| -rw-r--r-- | tests/urlpatterns/path_dynamic_urls.py | 4 | ||||
| -rw-r--r-- | tests/urlpatterns/path_same_name_urls.py | 32 | ||||
| -rw-r--r-- | tests/urlpatterns/path_urls.py | 36 | ||||
| -rw-r--r-- | tests/urlpatterns/test_resolvers.py | 12 | ||||
| -rw-r--r-- | tests/urlpatterns/tests.py | 317 |
10 files changed, 239 insertions, 198 deletions
diff --git a/tests/urlpatterns/converter_urls.py b/tests/urlpatterns/converter_urls.py index 0cc57bd46e..0de4b8e535 100644 --- a/tests/urlpatterns/converter_urls.py +++ b/tests/urlpatterns/converter_urls.py @@ -3,6 +3,6 @@ from django.urls import path from . import views urlpatterns = [ - path('{x}/<{x}:{x}>/'.format(x=name), views.empty_view, name=name) - for name in ('int', 'path', 'slug', 'str', 'uuid') + path("{x}/<{x}:{x}>/".format(x=name), views.empty_view, name=name) + for name in ("int", "path", "slug", "str", "uuid") ] diff --git a/tests/urlpatterns/converters.py b/tests/urlpatterns/converters.py index 14a65b0483..9e2af06269 100644 --- a/tests/urlpatterns/converters.py +++ b/tests/urlpatterns/converters.py @@ -2,13 +2,13 @@ import base64 class Base64Converter: - regex = r'[a-zA-Z0-9+/]*={0,2}' + regex = r"[a-zA-Z0-9+/]*={0,2}" def to_python(self, value): return base64.b64decode(value) def to_url(self, value): - return base64.b64encode(value).decode('ascii') + return base64.b64encode(value).decode("ascii") class DynamicConverter: @@ -17,7 +17,7 @@ class DynamicConverter: @property def regex(self): - return r'[0-9a-zA-Z]+' + return r"[0-9a-zA-Z]+" @regex.setter def regex(self): diff --git a/tests/urlpatterns/included_urls.py b/tests/urlpatterns/included_urls.py index 76e4551f57..957f0e2598 100644 --- a/tests/urlpatterns/included_urls.py +++ b/tests/urlpatterns/included_urls.py @@ -3,6 +3,6 @@ from django.urls import include, path from . import views urlpatterns = [ - path('extra/<extra>/', views.empty_view, name='inner-extra'), - path('', include('urlpatterns.more_urls')), + path("extra/<extra>/", views.empty_view, name="inner-extra"), + path("", include("urlpatterns.more_urls")), ] diff --git a/tests/urlpatterns/more_urls.py b/tests/urlpatterns/more_urls.py index c7d789dda0..bbfd962c4e 100644 --- a/tests/urlpatterns/more_urls.py +++ b/tests/urlpatterns/more_urls.py @@ -3,5 +3,5 @@ from django.urls import re_path from . import views urlpatterns = [ - re_path(r'^more/(?P<extra>\w+)/$', views.empty_view, name='inner-more'), + re_path(r"^more/(?P<extra>\w+)/$", views.empty_view, name="inner-more"), ] diff --git a/tests/urlpatterns/path_base64_urls.py b/tests/urlpatterns/path_base64_urls.py index afd11ac9f6..3ab14dbb79 100644 --- a/tests/urlpatterns/path_base64_urls.py +++ b/tests/urlpatterns/path_base64_urls.py @@ -2,22 +2,26 @@ from django.urls import include, path, register_converter from . import converters, views -register_converter(converters.Base64Converter, 'base64') +register_converter(converters.Base64Converter, "base64") subsubpatterns = [ - path('<base64:last_value>/', views.empty_view, name='subsubpattern-base64'), + path("<base64:last_value>/", views.empty_view, name="subsubpattern-base64"), ] subpatterns = [ - path('<base64:value>/', views.empty_view, name='subpattern-base64'), + path("<base64:value>/", views.empty_view, name="subpattern-base64"), path( - '<base64:value>/', - include((subsubpatterns, 'second-layer-namespaced-base64'), 'instance-ns-base64') + "<base64:value>/", + include( + (subsubpatterns, "second-layer-namespaced-base64"), "instance-ns-base64" + ), ), ] urlpatterns = [ - path('base64/<base64:value>/', views.empty_view, name='base64'), - path('base64/<base64:base>/subpatterns/', include(subpatterns)), - path('base64/<base64:base>/namespaced/', include((subpatterns, 'namespaced-base64'))), + path("base64/<base64:value>/", views.empty_view, name="base64"), + path("base64/<base64:base>/subpatterns/", include(subpatterns)), + path( + "base64/<base64:base>/namespaced/", include((subpatterns, "namespaced-base64")) + ), ] diff --git a/tests/urlpatterns/path_dynamic_urls.py b/tests/urlpatterns/path_dynamic_urls.py index 0e5afe1df0..6c3b9cc1c5 100644 --- a/tests/urlpatterns/path_dynamic_urls.py +++ b/tests/urlpatterns/path_dynamic_urls.py @@ -2,8 +2,8 @@ from django.urls import path, register_converter from . import converters, views -register_converter(converters.DynamicConverter, 'dynamic') +register_converter(converters.DynamicConverter, "dynamic") urlpatterns = [ - path('dynamic/<dynamic:value>/', views.empty_view, name='dynamic'), + path("dynamic/<dynamic:value>/", views.empty_view, name="dynamic"), ] diff --git a/tests/urlpatterns/path_same_name_urls.py b/tests/urlpatterns/path_same_name_urls.py index 7b4fd2e627..d7ea5431b1 100644 --- a/tests/urlpatterns/path_same_name_urls.py +++ b/tests/urlpatterns/path_same_name_urls.py @@ -2,33 +2,33 @@ from django.urls import path, re_path, register_converter from . import converters, views -register_converter(converters.DynamicConverter, 'to_url_value_error') +register_converter(converters.DynamicConverter, "to_url_value_error") urlpatterns = [ # Different number of arguments. - path('number_of_args/0/', views.empty_view, name='number_of_args'), - path('number_of_args/1/<value>/', views.empty_view, name='number_of_args'), + path("number_of_args/0/", views.empty_view, name="number_of_args"), + path("number_of_args/1/<value>/", views.empty_view, name="number_of_args"), # Different names of the keyword arguments. - path('kwargs_names/a/<a>/', views.empty_view, name='kwargs_names'), - path('kwargs_names/b/<b>/', views.empty_view, name='kwargs_names'), + path("kwargs_names/a/<a>/", views.empty_view, name="kwargs_names"), + path("kwargs_names/b/<b>/", views.empty_view, name="kwargs_names"), # Different path converters. - path('converter/path/<path:value>/', views.empty_view, name='converter'), - path('converter/str/<str:value>/', views.empty_view, name='converter'), - path('converter/slug/<slug:value>/', views.empty_view, name='converter'), - path('converter/int/<int:value>/', views.empty_view, name='converter'), - path('converter/uuid/<uuid:value>/', views.empty_view, name='converter'), + path("converter/path/<path:value>/", views.empty_view, name="converter"), + path("converter/str/<str:value>/", views.empty_view, name="converter"), + path("converter/slug/<slug:value>/", views.empty_view, name="converter"), + path("converter/int/<int:value>/", views.empty_view, name="converter"), + path("converter/uuid/<uuid:value>/", views.empty_view, name="converter"), # Different regular expressions. - re_path(r'^regex/uppercase/([A-Z]+)/', views.empty_view, name='regex'), - re_path(r'^regex/lowercase/([a-z]+)/', views.empty_view, name='regex'), + re_path(r"^regex/uppercase/([A-Z]+)/", views.empty_view, name="regex"), + re_path(r"^regex/lowercase/([a-z]+)/", views.empty_view, name="regex"), # converter.to_url() raises ValueError (no match). path( - 'converter_to_url/int/<value>/', + "converter_to_url/int/<value>/", views.empty_view, - name='converter_to_url', + name="converter_to_url", ), path( - 'converter_to_url/tiny_int/<to_url_value_error:value>/', + "converter_to_url/tiny_int/<to_url_value_error:value>/", views.empty_view, - name='converter_to_url', + name="converter_to_url", ), ] diff --git a/tests/urlpatterns/path_urls.py b/tests/urlpatterns/path_urls.py index afc15f30af..5ebdfe1b16 100644 --- a/tests/urlpatterns/path_urls.py +++ b/tests/urlpatterns/path_urls.py @@ -3,20 +3,30 @@ from django.urls import include, path, re_path from . import views urlpatterns = [ - path('articles/2003/', views.empty_view, name='articles-2003'), - path('articles/<int:year>/', views.empty_view, name='articles-year'), - path('articles/<int:year>/<int:month>/', views.empty_view, name='articles-year-month'), - path('articles/<int:year>/<int:month>/<int:day>/', views.empty_view, name='articles-year-month-day'), - path('users/', views.empty_view, name='users'), - path('users/<id>/', views.empty_view, name='user-with-id'), - path('included_urls/', include('urlpatterns.included_urls')), - re_path(r'^regex/(?P<pk>[0-9]+)/$', views.empty_view, name='regex'), - re_path(r'^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?', views.empty_view, name='regex_optional'), + path("articles/2003/", views.empty_view, name="articles-2003"), + path("articles/<int:year>/", views.empty_view, name="articles-year"), + path( + "articles/<int:year>/<int:month>/", views.empty_view, name="articles-year-month" + ), + path( + "articles/<int:year>/<int:month>/<int:day>/", + views.empty_view, + name="articles-year-month-day", + ), + path("users/", views.empty_view, name="users"), + path("users/<id>/", views.empty_view, name="user-with-id"), + path("included_urls/", include("urlpatterns.included_urls")), + re_path(r"^regex/(?P<pk>[0-9]+)/$", views.empty_view, name="regex"), + re_path( + r"^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?", + views.empty_view, + name="regex_optional", + ), re_path( - r'^regex_only_optional/(?:(?P<arg1>\d+)/)?', + r"^regex_only_optional/(?:(?P<arg1>\d+)/)?", views.empty_view, - name='regex_only_optional', + name="regex_only_optional", ), - path('', include('urlpatterns.more_urls')), - path('<lang>/<path:url>/', views.empty_view, name='lang-and-path'), + path("", include("urlpatterns.more_urls")), + path("<lang>/<path:url>/", views.empty_view, name="lang-and-path"), ] diff --git a/tests/urlpatterns/test_resolvers.py b/tests/urlpatterns/test_resolvers.py index eaca6096d9..cb831bbe1c 100644 --- a/tests/urlpatterns/test_resolvers.py +++ b/tests/urlpatterns/test_resolvers.py @@ -5,21 +5,19 @@ from django.utils.translation import gettext_lazy as _ class RegexPatternTests(SimpleTestCase): - def test_str(self): - self.assertEqual(str(RegexPattern(_('^translated/$'))), '^translated/$') + self.assertEqual(str(RegexPattern(_("^translated/$"))), "^translated/$") class RoutePatternTests(SimpleTestCase): - def test_str(self): - self.assertEqual(str(RoutePattern(_('translated/'))), 'translated/') + self.assertEqual(str(RoutePattern(_("translated/"))), "translated/") class ResolverCacheTests(SimpleTestCase): - @override_settings(ROOT_URLCONF='urlpatterns.path_urls') + @override_settings(ROOT_URLCONF="urlpatterns.path_urls") def test_resolver_cache_default__root_urlconf(self): # resolver for a default URLconf (passing no argument) and for the # settings.ROOT_URLCONF is the same cached object. - self.assertIs(get_resolver(), get_resolver('urlpatterns.path_urls')) - self.assertIsNot(get_resolver(), get_resolver('urlpatterns.path_dynamic_urls')) + self.assertIs(get_resolver(), get_resolver("urlpatterns.path_urls")) + self.assertIsNot(get_resolver(), get_resolver("urlpatterns.path_dynamic_urls")) diff --git a/tests/urlpatterns/tests.py b/tests/urlpatterns/tests.py index 262cb2e11e..cbe61278da 100644 --- a/tests/urlpatterns/tests.py +++ b/tests/urlpatterns/tests.py @@ -4,108 +4,113 @@ import uuid from django.core.exceptions import ImproperlyConfigured from django.test import SimpleTestCase from django.test.utils import override_settings -from django.urls import ( - NoReverseMatch, Resolver404, path, re_path, resolve, reverse, -) +from django.urls import NoReverseMatch, Resolver404, path, re_path, resolve, reverse from django.views import View from .converters import DynamicConverter from .views import empty_view -included_kwargs = {'base': b'hello', 'value': b'world'} +included_kwargs = {"base": b"hello", "value": b"world"} converter_test_data = ( # ('url', ('url_name', 'app_name', {kwargs})), # aGVsbG8= is 'hello' encoded in base64. - ('/base64/aGVsbG8=/', ('base64', '', {'value': b'hello'})), - ('/base64/aGVsbG8=/subpatterns/d29ybGQ=/', ('subpattern-base64', '', included_kwargs)), - ('/base64/aGVsbG8=/namespaced/d29ybGQ=/', ('subpattern-base64', 'namespaced-base64', included_kwargs)), + ("/base64/aGVsbG8=/", ("base64", "", {"value": b"hello"})), + ( + "/base64/aGVsbG8=/subpatterns/d29ybGQ=/", + ("subpattern-base64", "", included_kwargs), + ), + ( + "/base64/aGVsbG8=/namespaced/d29ybGQ=/", + ("subpattern-base64", "namespaced-base64", included_kwargs), + ), ) -@override_settings(ROOT_URLCONF='urlpatterns.path_urls') +@override_settings(ROOT_URLCONF="urlpatterns.path_urls") class SimplifiedURLTests(SimpleTestCase): - def test_path_lookup_without_parameters(self): - match = resolve('/articles/2003/') - self.assertEqual(match.url_name, 'articles-2003') + match = resolve("/articles/2003/") + self.assertEqual(match.url_name, "articles-2003") self.assertEqual(match.args, ()) self.assertEqual(match.kwargs, {}) - self.assertEqual(match.route, 'articles/2003/') + self.assertEqual(match.route, "articles/2003/") def test_path_lookup_with_typed_parameters(self): - match = resolve('/articles/2015/') - self.assertEqual(match.url_name, 'articles-year') + match = resolve("/articles/2015/") + self.assertEqual(match.url_name, "articles-year") self.assertEqual(match.args, ()) - self.assertEqual(match.kwargs, {'year': 2015}) - self.assertEqual(match.route, 'articles/<int:year>/') + self.assertEqual(match.kwargs, {"year": 2015}) + self.assertEqual(match.route, "articles/<int:year>/") def test_path_lookup_with_multiple_parameters(self): - match = resolve('/articles/2015/04/12/') - self.assertEqual(match.url_name, 'articles-year-month-day') + match = resolve("/articles/2015/04/12/") + self.assertEqual(match.url_name, "articles-year-month-day") self.assertEqual(match.args, ()) - self.assertEqual(match.kwargs, {'year': 2015, 'month': 4, 'day': 12}) - self.assertEqual(match.route, 'articles/<int:year>/<int:month>/<int:day>/') + self.assertEqual(match.kwargs, {"year": 2015, "month": 4, "day": 12}) + self.assertEqual(match.route, "articles/<int:year>/<int:month>/<int:day>/") def test_two_variable_at_start_of_path_pattern(self): - match = resolve('/en/foo/') - self.assertEqual(match.url_name, 'lang-and-path') - self.assertEqual(match.kwargs, {'lang': 'en', 'url': 'foo'}) - self.assertEqual(match.route, '<lang>/<path:url>/') + match = resolve("/en/foo/") + self.assertEqual(match.url_name, "lang-and-path") + self.assertEqual(match.kwargs, {"lang": "en", "url": "foo"}) + self.assertEqual(match.route, "<lang>/<path:url>/") def test_re_path(self): - match = resolve('/regex/1/') - self.assertEqual(match.url_name, 'regex') - self.assertEqual(match.kwargs, {'pk': '1'}) - self.assertEqual(match.route, '^regex/(?P<pk>[0-9]+)/$') + match = resolve("/regex/1/") + self.assertEqual(match.url_name, "regex") + self.assertEqual(match.kwargs, {"pk": "1"}) + self.assertEqual(match.route, "^regex/(?P<pk>[0-9]+)/$") def test_re_path_with_optional_parameter(self): for url, kwargs in ( - ('/regex_optional/1/2/', {'arg1': '1', 'arg2': '2'}), - ('/regex_optional/1/', {'arg1': '1'}), + ("/regex_optional/1/2/", {"arg1": "1", "arg2": "2"}), + ("/regex_optional/1/", {"arg1": "1"}), ): with self.subTest(url=url): match = resolve(url) - self.assertEqual(match.url_name, 'regex_optional') + self.assertEqual(match.url_name, "regex_optional") self.assertEqual(match.kwargs, kwargs) self.assertEqual( match.route, - r'^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?', + r"^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?", ) def test_re_path_with_missing_optional_parameter(self): - match = resolve('/regex_only_optional/') - self.assertEqual(match.url_name, 'regex_only_optional') + match = resolve("/regex_only_optional/") + self.assertEqual(match.url_name, "regex_only_optional") self.assertEqual(match.kwargs, {}) self.assertEqual(match.args, ()) self.assertEqual( match.route, - r'^regex_only_optional/(?:(?P<arg1>\d+)/)?', + r"^regex_only_optional/(?:(?P<arg1>\d+)/)?", ) def test_path_lookup_with_inclusion(self): - match = resolve('/included_urls/extra/something/') - self.assertEqual(match.url_name, 'inner-extra') - self.assertEqual(match.route, 'included_urls/extra/<extra>/') + match = resolve("/included_urls/extra/something/") + self.assertEqual(match.url_name, "inner-extra") + self.assertEqual(match.route, "included_urls/extra/<extra>/") def test_path_lookup_with_empty_string_inclusion(self): - match = resolve('/more/99/') - self.assertEqual(match.url_name, 'inner-more') - self.assertEqual(match.route, r'^more/(?P<extra>\w+)/$') + match = resolve("/more/99/") + self.assertEqual(match.url_name, "inner-more") + self.assertEqual(match.route, r"^more/(?P<extra>\w+)/$") def test_path_lookup_with_double_inclusion(self): - match = resolve('/included_urls/more/some_value/') - self.assertEqual(match.url_name, 'inner-more') - self.assertEqual(match.route, r'included_urls/more/(?P<extra>\w+)/$') + match = resolve("/included_urls/more/some_value/") + self.assertEqual(match.url_name, "inner-more") + self.assertEqual(match.route, r"included_urls/more/(?P<extra>\w+)/$") def test_path_reverse_without_parameter(self): - url = reverse('articles-2003') - self.assertEqual(url, '/articles/2003/') + url = reverse("articles-2003") + self.assertEqual(url, "/articles/2003/") def test_path_reverse_with_parameter(self): - url = reverse('articles-year-month-day', kwargs={'year': 2015, 'month': 4, 'day': 12}) - self.assertEqual(url, '/articles/2015/4/12/') + url = reverse( + "articles-year-month-day", kwargs={"year": 2015, "month": 4, "day": 12} + ) + self.assertEqual(url, "/articles/2015/4/12/") - @override_settings(ROOT_URLCONF='urlpatterns.path_base64_urls') + @override_settings(ROOT_URLCONF="urlpatterns.path_base64_urls") def test_converter_resolve(self): for url, (url_name, app_name, kwargs) in converter_test_data: with self.subTest(url=url): @@ -114,55 +119,55 @@ class SimplifiedURLTests(SimpleTestCase): self.assertEqual(match.app_name, app_name) self.assertEqual(match.kwargs, kwargs) - @override_settings(ROOT_URLCONF='urlpatterns.path_base64_urls') + @override_settings(ROOT_URLCONF="urlpatterns.path_base64_urls") def test_converter_reverse(self): for expected, (url_name, app_name, kwargs) in converter_test_data: if app_name: - url_name = '%s:%s' % (app_name, url_name) + url_name = "%s:%s" % (app_name, url_name) with self.subTest(url=url_name): url = reverse(url_name, kwargs=kwargs) self.assertEqual(url, expected) - @override_settings(ROOT_URLCONF='urlpatterns.path_base64_urls') + @override_settings(ROOT_URLCONF="urlpatterns.path_base64_urls") def test_converter_reverse_with_second_layer_instance_namespace(self): kwargs = included_kwargs.copy() - kwargs['last_value'] = b'world' - url = reverse('instance-ns-base64:subsubpattern-base64', kwargs=kwargs) - self.assertEqual(url, '/base64/aGVsbG8=/subpatterns/d29ybGQ=/d29ybGQ=/') + kwargs["last_value"] = b"world" + url = reverse("instance-ns-base64:subsubpattern-base64", kwargs=kwargs) + self.assertEqual(url, "/base64/aGVsbG8=/subpatterns/d29ybGQ=/d29ybGQ=/") def test_path_inclusion_is_matchable(self): - match = resolve('/included_urls/extra/something/') - self.assertEqual(match.url_name, 'inner-extra') - self.assertEqual(match.kwargs, {'extra': 'something'}) + match = resolve("/included_urls/extra/something/") + self.assertEqual(match.url_name, "inner-extra") + self.assertEqual(match.kwargs, {"extra": "something"}) def test_path_inclusion_is_reversible(self): - url = reverse('inner-extra', kwargs={'extra': 'something'}) - self.assertEqual(url, '/included_urls/extra/something/') + url = reverse("inner-extra", kwargs={"extra": "something"}) + self.assertEqual(url, "/included_urls/extra/something/") def test_invalid_kwargs(self): - msg = 'kwargs argument must be a dict, but got str.' + msg = "kwargs argument must be a dict, but got str." with self.assertRaisesMessage(TypeError, msg): - path('hello/', empty_view, 'name') + path("hello/", empty_view, "name") with self.assertRaisesMessage(TypeError, msg): - re_path('^hello/$', empty_view, 'name') + re_path("^hello/$", empty_view, "name") def test_invalid_converter(self): msg = "URL route 'foo/<nonexistent:var>/' uses invalid converter 'nonexistent'." with self.assertRaisesMessage(ImproperlyConfigured, msg): - path('foo/<nonexistent:var>/', empty_view) + path("foo/<nonexistent:var>/", empty_view) def test_invalid_view(self): - msg = 'view must be a callable or a list/tuple in the case of include().' + msg = "view must be a callable or a list/tuple in the case of include()." with self.assertRaisesMessage(TypeError, msg): - path('articles/', 'invalid_view') + path("articles/", "invalid_view") def test_invalid_view_instance(self): class EmptyCBV(View): pass - msg = 'view must be a callable, pass EmptyCBV.as_view(), not EmptyCBV().' + msg = "view must be a callable, pass EmptyCBV.as_view(), not EmptyCBV()." with self.assertRaisesMessage(TypeError, msg): - path('foo', EmptyCBV()) + path("foo", EmptyCBV()) def test_whitespace_in_route(self): msg = ( @@ -172,43 +177,42 @@ class SimplifiedURLTests(SimpleTestCase): for whitespace in string.whitespace: with self.subTest(repr(whitespace)): with self.assertRaisesMessage(ImproperlyConfigured, msg % whitespace): - path('space/<int:num>/extra/<str:%stest>' % whitespace, empty_view) + path("space/<int:num>/extra/<str:%stest>" % whitespace, empty_view) # Whitespaces are valid in paths. - p = path('space%s/<int:num>/' % string.whitespace, empty_view) - match = p.resolve('space%s/1/' % string.whitespace) - self.assertEqual(match.kwargs, {'num': 1}) + p = path("space%s/<int:num>/" % string.whitespace, empty_view) + match = p.resolve("space%s/1/" % string.whitespace) + self.assertEqual(match.kwargs, {"num": 1}) def test_path_trailing_newlines(self): tests = [ - '/articles/2003/\n', - '/articles/2010/\n', - '/en/foo/\n', - '/included_urls/extra/\n', - '/regex/1/\n', - '/users/1/\n', + "/articles/2003/\n", + "/articles/2010/\n", + "/en/foo/\n", + "/included_urls/extra/\n", + "/regex/1/\n", + "/users/1/\n", ] for url in tests: with self.subTest(url=url), self.assertRaises(Resolver404): resolve(url) -@override_settings(ROOT_URLCONF='urlpatterns.converter_urls') +@override_settings(ROOT_URLCONF="urlpatterns.converter_urls") class ConverterTests(SimpleTestCase): - def test_matching_urls(self): def no_converter(x): return x test_data = ( - ('int', {'0', '1', '01', 1234567890}, int), - ('str', {'abcxyz'}, no_converter), - ('path', {'allows.ANY*characters'}, no_converter), - ('slug', {'abcxyz-ABCXYZ_01234567890'}, no_converter), - ('uuid', {'39da9369-838e-4750-91a5-f7805cd82839'}, uuid.UUID), + ("int", {"0", "1", "01", 1234567890}, int), + ("str", {"abcxyz"}, no_converter), + ("path", {"allows.ANY*characters"}, no_converter), + ("slug", {"abcxyz-ABCXYZ_01234567890"}, no_converter), + ("uuid", {"39da9369-838e-4750-91a5-f7805cd82839"}, uuid.UUID), ) for url_name, url_suffixes, converter in test_data: for url_suffix in url_suffixes: - url = '/%s/%s/' % (url_name, url_suffix) + url = "/%s/%s/" % (url_name, url_suffix) with self.subTest(url=url): match = resolve(url) self.assertEqual(match.url_name, url_name) @@ -221,32 +225,38 @@ class ConverterTests(SimpleTestCase): # The converted value might be different for int (a # leading zero is lost in the conversion). converted_value = match.kwargs[url_name] - converted_url = '/%s/%s/' % (url_name, converted_value) - self.assertEqual(reverse(url_name, kwargs={url_name: converted_value}), converted_url) + converted_url = "/%s/%s/" % (url_name, converted_value) + self.assertEqual( + reverse(url_name, kwargs={url_name: converted_value}), + converted_url, + ) def test_nonmatching_urls(self): test_data = ( - ('int', {'-1', 'letters'}), - ('str', {'', '/'}), - ('path', {''}), - ('slug', {'', 'stars*notallowed'}), - ('uuid', { - '', - '9da9369-838e-4750-91a5-f7805cd82839', - '39da9369-838-4750-91a5-f7805cd82839', - '39da9369-838e-475-91a5-f7805cd82839', - '39da9369-838e-4750-91a-f7805cd82839', - '39da9369-838e-4750-91a5-f7805cd8283', - }), + ("int", {"-1", "letters"}), + ("str", {"", "/"}), + ("path", {""}), + ("slug", {"", "stars*notallowed"}), + ( + "uuid", + { + "", + "9da9369-838e-4750-91a5-f7805cd82839", + "39da9369-838-4750-91a5-f7805cd82839", + "39da9369-838e-475-91a5-f7805cd82839", + "39da9369-838e-4750-91a-f7805cd82839", + "39da9369-838e-4750-91a5-f7805cd8283", + }, + ), ) for url_name, url_suffixes in test_data: for url_suffix in url_suffixes: - url = '/%s/%s/' % (url_name, url_suffix) + url = "/%s/%s/" % (url_name, url_suffix) with self.subTest(url=url), self.assertRaises(Resolver404): resolve(url) -@override_settings(ROOT_URLCONF='urlpatterns.path_same_name_urls') +@override_settings(ROOT_URLCONF="urlpatterns.path_same_name_urls") class SameNameTests(SimpleTestCase): def test_matching_urls_same_name(self): @DynamicConverter.register_to_url @@ -256,37 +266,52 @@ class SameNameTests(SimpleTestCase): return value tests = [ - ('number_of_args', [ - ([], {}, '0/'), - ([1], {}, '1/1/'), - ]), - ('kwargs_names', [ - ([], {'a': 1}, 'a/1/'), - ([], {'b': 1}, 'b/1/'), - ]), - ('converter', [ - (['a/b'], {}, 'path/a/b/'), - (['a b'], {}, 'str/a%20b/'), - (['a-b'], {}, 'slug/a-b/'), - (['2'], {}, 'int/2/'), - ( - ['39da9369-838e-4750-91a5-f7805cd82839'], - {}, - 'uuid/39da9369-838e-4750-91a5-f7805cd82839/' - ), - ]), - ('regex', [ - (['ABC'], {}, 'uppercase/ABC/'), - (['abc'], {}, 'lowercase/abc/'), - ]), - ('converter_to_url', [ - ([6], {}, 'int/6/'), - ([1], {}, 'tiny_int/1/'), - ]), + ( + "number_of_args", + [ + ([], {}, "0/"), + ([1], {}, "1/1/"), + ], + ), + ( + "kwargs_names", + [ + ([], {"a": 1}, "a/1/"), + ([], {"b": 1}, "b/1/"), + ], + ), + ( + "converter", + [ + (["a/b"], {}, "path/a/b/"), + (["a b"], {}, "str/a%20b/"), + (["a-b"], {}, "slug/a-b/"), + (["2"], {}, "int/2/"), + ( + ["39da9369-838e-4750-91a5-f7805cd82839"], + {}, + "uuid/39da9369-838e-4750-91a5-f7805cd82839/", + ), + ], + ), + ( + "regex", + [ + (["ABC"], {}, "uppercase/ABC/"), + (["abc"], {}, "lowercase/abc/"), + ], + ), + ( + "converter_to_url", + [ + ([6], {}, "int/6/"), + ([1], {}, "tiny_int/1/"), + ], + ), ] for url_name, cases in tests: for args, kwargs, url_suffix in cases: - expected_url = '/%s/%s' % (url_name, url_suffix) + expected_url = "/%s/%s" % (url_name, url_suffix) with self.subTest(url=expected_url): self.assertEqual( reverse(url_name, args=args, kwargs=kwargs), @@ -301,7 +326,7 @@ class ParameterRestrictionTests(SimpleTestCase): "a valid Python identifier." ) with self.assertRaisesMessage(ImproperlyConfigured, msg): - path(r'hello/<int:1>/', lambda r: None) + path(r"hello/<int:1>/", lambda r: None) def test_non_identifier_parameter_name_causes_exception(self): msg = ( @@ -309,16 +334,16 @@ class ParameterRestrictionTests(SimpleTestCase): "isn't a valid Python identifier." ) with self.assertRaisesMessage(ImproperlyConfigured, msg): - path(r'b/<int:book.id>/', lambda r: None) + path(r"b/<int:book.id>/", lambda r: None) def test_allows_non_ascii_but_valid_identifiers(self): # \u0394 is "GREEK CAPITAL LETTER DELTA", a valid identifier. - p = path('hello/<str:\u0394>/', lambda r: None) - match = p.resolve('hello/1/') - self.assertEqual(match.kwargs, {'\u0394': '1'}) + p = path("hello/<str:\u0394>/", lambda r: None) + match = p.resolve("hello/1/") + self.assertEqual(match.kwargs, {"\u0394": "1"}) -@override_settings(ROOT_URLCONF='urlpatterns.path_dynamic_urls') +@override_settings(ROOT_URLCONF="urlpatterns.path_dynamic_urls") class ConversionExceptionTests(SimpleTestCase): """How are errors in Converter.to_python() and to_url() handled?""" @@ -326,26 +351,30 @@ class ConversionExceptionTests(SimpleTestCase): @DynamicConverter.register_to_python def raises_value_error(value): raise ValueError() + with self.assertRaises(Resolver404): - resolve('/dynamic/abc/') + resolve("/dynamic/abc/") def test_resolve_type_error_propagates(self): @DynamicConverter.register_to_python def raises_type_error(value): - raise TypeError('This type error propagates.') - with self.assertRaisesMessage(TypeError, 'This type error propagates.'): - resolve('/dynamic/abc/') + raise TypeError("This type error propagates.") + + with self.assertRaisesMessage(TypeError, "This type error propagates."): + resolve("/dynamic/abc/") def test_reverse_value_error_means_no_match(self): @DynamicConverter.register_to_url def raises_value_error(value): raise ValueError + with self.assertRaises(NoReverseMatch): - reverse('dynamic', kwargs={'value': object()}) + reverse("dynamic", kwargs={"value": object()}) def test_reverse_type_error_propagates(self): @DynamicConverter.register_to_url def raises_type_error(value): - raise TypeError('This type error propagates.') - with self.assertRaisesMessage(TypeError, 'This type error propagates.'): - reverse('dynamic', kwargs={'value': object()}) + raise TypeError("This type error propagates.") + + with self.assertRaisesMessage(TypeError, "This type error propagates."): + reverse("dynamic", kwargs={"value": object()}) |
