import os from pathlib import Path 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) @override_settings(LOCALE_PATHS=[Path(here) / "translations" / "locale"]) class LocaleRegexDescriptorPathLibTests(LocaleRegexDescriptorTests): pass