From df41b5a05d4e00e80e73afe629072e37873e767a Mon Sep 17 00:00:00 2001 From: Sjoerd Job Postmus Date: Thu, 20 Oct 2016 19:29:04 +0200 Subject: Fixed #28593 -- Added a simplified URL routing syntax per DEP 0201. Thanks Aymeric Augustin for shepherding the DEP and patch review. Thanks Marten Kenbeek and Tim Graham for contributing to the code. Thanks Tom Christie, Shai Berger, and Tim Graham for the docs. --- .../test_localeregexdescriptor.py | 54 +++++++++++++++++++++ .../test_localeregexprovider.py | 55 ---------------------- tests/urlpatterns_reverse/tests.py | 35 +++++++------- 3 files changed, 72 insertions(+), 72 deletions(-) create mode 100644 tests/urlpatterns_reverse/test_localeregexdescriptor.py delete mode 100644 tests/urlpatterns_reverse/test_localeregexprovider.py (limited to 'tests/urlpatterns_reverse') diff --git a/tests/urlpatterns_reverse/test_localeregexdescriptor.py b/tests/urlpatterns_reverse/test_localeregexdescriptor.py new file mode 100644 index 0000000000..25e6cd962a --- /dev/null +++ b/tests/urlpatterns_reverse/test_localeregexdescriptor.py @@ -0,0 +1,54 @@ +import os +from unittest import mock + +from django.core.exceptions import ImproperlyConfigured +from django.test import SimpleTestCase, override_settings +from django.urls.resolvers import LocaleRegexDescriptor, RegexPattern +from django.utils import translation + +here = os.path.dirname(os.path.abspath(__file__)) + + +@override_settings(LOCALE_PATHS=[os.path.join(here, 'translations', 'locale')]) +class LocaleRegexDescriptorTests(SimpleTestCase): + def setUp(self): + translation.trans_real._translations = {} + + def tearDown(self): + translation.trans_real._translations = {} + + def test_translated_regex_compiled_per_language(self): + provider = RegexPattern(translation.gettext_lazy('^foo/$')) + with translation.override('de'): + de_compiled = provider.regex + # compiled only once per language + error = AssertionError('tried to compile url regex twice for the same language') + with mock.patch('django.urls.resolvers.re.compile', side_effect=error): + de_compiled_2 = provider.regex + with translation.override('fr'): + fr_compiled = provider.regex + self.assertEqual(fr_compiled.pattern, '^foo-fr/$') + self.assertEqual(de_compiled.pattern, '^foo-de/$') + self.assertEqual(de_compiled, de_compiled_2) + + def test_nontranslated_regex_compiled_once(self): + provider = RegexPattern('^foo/$') + with translation.override('de'): + de_compiled = provider.regex + with translation.override('fr'): + # compiled only once, regardless of language + error = AssertionError('tried to compile non-translated url regex twice') + with mock.patch('django.urls.resolvers.re.compile', side_effect=error): + fr_compiled = provider.regex + self.assertEqual(de_compiled.pattern, '^foo/$') + self.assertEqual(fr_compiled.pattern, '^foo/$') + + def test_regex_compile_error(self): + """Regex errors are re-raised as ImproperlyConfigured.""" + provider = RegexPattern('*') + msg = '"*" is not a valid regular expression: nothing to repeat' + with self.assertRaisesMessage(ImproperlyConfigured, msg): + provider.regex + + def test_access_locale_regex_descriptor(self): + self.assertIsInstance(RegexPattern.regex, LocaleRegexDescriptor) diff --git a/tests/urlpatterns_reverse/test_localeregexprovider.py b/tests/urlpatterns_reverse/test_localeregexprovider.py deleted file mode 100644 index 1fbba849c6..0000000000 --- a/tests/urlpatterns_reverse/test_localeregexprovider.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -from unittest import mock - -from django.core.exceptions import ImproperlyConfigured -from django.test import SimpleTestCase, override_settings -from django.urls import LocaleRegexProvider -from django.urls.resolvers import LocaleRegexDescriptor -from django.utils import translation - -here = os.path.dirname(os.path.abspath(__file__)) - - -@override_settings(LOCALE_PATHS=[os.path.join(here, 'translations', 'locale')]) -class LocaleRegexProviderTests(SimpleTestCase): - def setUp(self): - translation.trans_real._translations = {} - - def tearDown(self): - translation.trans_real._translations = {} - - def test_translated_regex_compiled_per_language(self): - provider = LocaleRegexProvider(translation.gettext_lazy('^foo/$')) - with translation.override('de'): - de_compiled = provider.regex - # compiled only once per language - error = AssertionError('tried to compile url regex twice for the same language') - with mock.patch('django.urls.resolvers.re.compile', side_effect=error): - de_compiled_2 = provider.regex - with translation.override('fr'): - fr_compiled = provider.regex - self.assertEqual(fr_compiled.pattern, '^foo-fr/$') - self.assertEqual(de_compiled.pattern, '^foo-de/$') - self.assertEqual(de_compiled, de_compiled_2) - - def test_nontranslated_regex_compiled_once(self): - provider = LocaleRegexProvider('^foo/$') - with translation.override('de'): - de_compiled = provider.regex - with translation.override('fr'): - # compiled only once, regardless of language - error = AssertionError('tried to compile non-translated url regex twice') - with mock.patch('django.urls.resolvers.re.compile', side_effect=error): - fr_compiled = provider.regex - self.assertEqual(de_compiled.pattern, '^foo/$') - self.assertEqual(fr_compiled.pattern, '^foo/$') - - def test_regex_compile_error(self): - """Regex errors are re-raised as ImproperlyConfigured.""" - provider = LocaleRegexProvider('*') - msg = '"*" is not a valid regular expression: nothing to repeat' - with self.assertRaisesMessage(ImproperlyConfigured, msg): - provider.regex - - def test_access_locale_regex_descriptor(self): - self.assertIsInstance(LocaleRegexProvider.regex, LocaleRegexDescriptor) diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index e3b522f55f..86f7ed5667 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -17,9 +17,10 @@ from django.shortcuts import redirect from django.test import SimpleTestCase, TestCase, override_settings from django.test.utils import override_script_prefix from django.urls import ( - NoReverseMatch, RegexURLPattern, RegexURLResolver, Resolver404, - ResolverMatch, get_callable, get_resolver, resolve, reverse, reverse_lazy, + NoReverseMatch, Resolver404, ResolverMatch, URLPattern, URLResolver, + get_callable, get_resolver, resolve, reverse, reverse_lazy, ) +from django.urls.resolvers import RegexPattern from . import middleware, urlconf_outer, views from .utils import URLObject @@ -259,9 +260,9 @@ class NoURLPatternsTests(SimpleTestCase): def test_no_urls_exception(self): """ - RegexURLResolver should raise an exception when no urlpatterns exist. + URLResolver should raise an exception when no urlpatterns exist. """ - resolver = RegexURLResolver(r'^$', settings.ROOT_URLCONF) + resolver = URLResolver(RegexPattern(r'^$'), settings.ROOT_URLCONF) with self.assertRaisesMessage( ImproperlyConfigured, @@ -368,13 +369,13 @@ class URLPatternReverse(SimpleTestCase): class ResolverTests(SimpleTestCase): def test_resolver_repr(self): """ - Test repr of RegexURLResolver, especially when urlconf_name is a list + Test repr of URLResolver, especially when urlconf_name is a list (#17892). """ # Pick a resolver from a namespaced URLconf resolver = get_resolver('urlpatterns_reverse.namespace_urls') sub_resolver = resolver.namespace_dict['test-ns1'][1] - self.assertIn('', repr(sub_resolver)) + self.assertIn('', repr(sub_resolver)) def test_reverse_lazy_object_coercion_by_resolve(self): """ @@ -445,13 +446,13 @@ class ResolverTests(SimpleTestCase): # you try to resolve a nonexistent URL in the first level of included # URLs in named_urls.py (e.g., '/included/nonexistent-url') url_types_names = [ - [{'type': RegexURLPattern, 'name': 'named-url1'}], - [{'type': RegexURLPattern, 'name': 'named-url2'}], - [{'type': RegexURLPattern, 'name': None}], - [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': 'named-url3'}], - [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': 'named-url4'}], - [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': None}], - [{'type': RegexURLResolver}, {'type': RegexURLResolver}], + [{'type': URLPattern, 'name': 'named-url1'}], + [{'type': URLPattern, 'name': 'named-url2'}], + [{'type': URLPattern, 'name': None}], + [{'type': URLResolver}, {'type': URLPattern, 'name': 'named-url3'}], + [{'type': URLResolver}, {'type': URLPattern, 'name': 'named-url4'}], + [{'type': URLResolver}, {'type': URLPattern, 'name': None}], + [{'type': URLResolver}, {'type': URLResolver}], ] with self.assertRaisesMessage(Resolver404, 'tried') as cm: resolve('/included/nonexistent-url', urlconf=urls) @@ -494,10 +495,10 @@ class ResolverTests(SimpleTestCase): def test_populate_concurrency(self): """ - RegexURLResolver._populate() can be called concurrently, but not more + URLResolver._populate() can be called concurrently, but not more than once per thread (#26888). """ - resolver = RegexURLResolver(r'^/', 'urlpatterns_reverse.urls') + resolver = URLResolver(RegexPattern(r'^/'), 'urlpatterns_reverse.urls') resolver._local.populating = True thread = threading.Thread(target=resolver._populate) thread.start() @@ -1039,8 +1040,8 @@ class ErrorHandlerResolutionTests(SimpleTestCase): def setUp(self): urlconf = 'urlpatterns_reverse.urls_error_handlers' urlconf_callables = 'urlpatterns_reverse.urls_error_handlers_callables' - self.resolver = RegexURLResolver(r'^$', urlconf) - self.callable_resolver = RegexURLResolver(r'^$', urlconf_callables) + self.resolver = URLResolver(RegexPattern(r'^$'), urlconf) + self.callable_resolver = URLResolver(RegexPattern(r'^$'), urlconf_callables) def test_named_handlers(self): handler = (empty_view, {}) -- cgit v1.3