mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Refs #33476 -- Reformatted code with Black.
This commit is contained in:
committed by
Mariusz Felisiak
parent
f68fa8b45d
commit
9c19aff7c7
@@ -1,4 +1,5 @@
|
||||
from django.utils.translation import gettext as _, ngettext
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import ngettext
|
||||
|
||||
# Translators: This comment should be extracted
|
||||
dummy1 = _("This is a translatable string.")
|
||||
@@ -9,9 +10,9 @@ dummy2 = _("This is another translatable string.")
|
||||
# This file has a literal with plural forms. When processed first, makemessages
|
||||
# shouldn't create a .po file with duplicate `Plural-Forms` headers
|
||||
number = 3
|
||||
dummy3 = ngettext("%(number)s Foo", "%(number)s Foos", number) % {'number': number}
|
||||
dummy3 = ngettext("%(number)s Foo", "%(number)s Foos", number) % {"number": number}
|
||||
|
||||
dummy4 = _('Size')
|
||||
dummy4 = _("Size")
|
||||
|
||||
# This string is intentionally duplicated in test.html
|
||||
dummy5 = _('This literal should be included.')
|
||||
dummy5 = _("This literal should be included.")
|
||||
|
||||
@@ -8,18 +8,18 @@ from django.utils import translation
|
||||
@override_settings(
|
||||
USE_I18N=True,
|
||||
LOCALE_PATHS=[
|
||||
os.path.join(os.path.dirname(__file__), 'locale'),
|
||||
os.path.join(os.path.dirname(__file__), "locale"),
|
||||
],
|
||||
LANGUAGE_CODE='en',
|
||||
LANGUAGE_CODE="en",
|
||||
LANGUAGES=[
|
||||
('en', 'English'),
|
||||
('fr', 'French'),
|
||||
("en", "English"),
|
||||
("fr", "French"),
|
||||
],
|
||||
)
|
||||
class ContentTypeTests(TestCase):
|
||||
def test_verbose_name(self):
|
||||
company_type = ContentType.objects.get(app_label='i18n', model='company')
|
||||
with translation.override('en'):
|
||||
self.assertEqual(str(company_type), 'i18n | Company')
|
||||
with translation.override('fr'):
|
||||
self.assertEqual(str(company_type), 'i18n | Société')
|
||||
company_type = ContentType.objects.get(app_label="i18n", model="company")
|
||||
with translation.override("en"):
|
||||
self.assertEqual(str(company_type), "i18n | Company")
|
||||
with translation.override("fr"):
|
||||
self.assertEqual(str(company_type), "i18n | Société")
|
||||
|
||||
@@ -23,4 +23,4 @@ class CompanyForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Company
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class LoadingAppConfig(AppConfig):
|
||||
name = 'i18n.loading_app'
|
||||
name = "i18n.loading_app"
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class TestModel(models.Model):
|
||||
text = models.CharField(max_length=10, default=_('Anything'))
|
||||
text = models.CharField(max_length=10, default=_("Anything"))
|
||||
|
||||
|
||||
class Company(models.Model):
|
||||
@@ -15,4 +15,4 @@ class Company(models.Model):
|
||||
products_delivered = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Company')
|
||||
verbose_name = _("Company")
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# A user-defined format
|
||||
CUSTOM_DAY_FORMAT = 'd/m/Y CUSTOM'
|
||||
CUSTOM_DAY_FORMAT = "d/m/Y CUSTOM"
|
||||
|
||||
@@ -19,28 +19,30 @@ class PermanentRedirectLocaleMiddleWare(LocaleMiddleware):
|
||||
@override_settings(
|
||||
USE_I18N=True,
|
||||
LOCALE_PATHS=[
|
||||
os.path.join(os.path.dirname(__file__), 'locale'),
|
||||
os.path.join(os.path.dirname(__file__), "locale"),
|
||||
],
|
||||
LANGUAGE_CODE='en-us',
|
||||
LANGUAGE_CODE="en-us",
|
||||
LANGUAGES=[
|
||||
('nl', 'Dutch'),
|
||||
('en', 'English'),
|
||||
('pt-br', 'Brazilian Portuguese'),
|
||||
("nl", "Dutch"),
|
||||
("en", "English"),
|
||||
("pt-br", "Brazilian Portuguese"),
|
||||
],
|
||||
MIDDLEWARE=[
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
"django.middleware.locale.LocaleMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
],
|
||||
ROOT_URLCONF="i18n.patterns.urls.default",
|
||||
TEMPLATES=[
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.i18n",
|
||||
],
|
||||
},
|
||||
}
|
||||
],
|
||||
ROOT_URLCONF='i18n.patterns.urls.default',
|
||||
TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.i18n',
|
||||
],
|
||||
},
|
||||
}],
|
||||
)
|
||||
class URLTestCaseBase(SimpleTestCase):
|
||||
"""
|
||||
@@ -60,53 +62,58 @@ class URLPrefixTests(URLTestCaseBase):
|
||||
"""
|
||||
Tests if the `i18n_patterns` is adding the prefix correctly.
|
||||
"""
|
||||
|
||||
def test_not_prefixed(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
|
||||
self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/')
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
|
||||
self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("not-prefixed"), "/not-prefixed/")
|
||||
self.assertEqual(
|
||||
reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/"
|
||||
)
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("not-prefixed"), "/not-prefixed/")
|
||||
self.assertEqual(
|
||||
reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/"
|
||||
)
|
||||
|
||||
def test_prefixed(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('prefixed'), '/en/prefixed/')
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('prefixed'), '/nl/prefixed/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("prefixed"), "/en/prefixed/")
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("prefixed"), "/nl/prefixed/")
|
||||
with translation.override(None):
|
||||
self.assertEqual(reverse('prefixed'), '/%s/prefixed/' % settings.LANGUAGE_CODE)
|
||||
self.assertEqual(
|
||||
reverse("prefixed"), "/%s/prefixed/" % settings.LANGUAGE_CODE
|
||||
)
|
||||
|
||||
@override_settings(ROOT_URLCONF='i18n.patterns.urls.wrong')
|
||||
@override_settings(ROOT_URLCONF="i18n.patterns.urls.wrong")
|
||||
def test_invalid_prefix_use(self):
|
||||
msg = 'Using i18n_patterns in an included URLconf is not allowed.'
|
||||
msg = "Using i18n_patterns in an included URLconf is not allowed."
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
reverse('account:register')
|
||||
reverse("account:register")
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF='i18n.patterns.urls.disabled')
|
||||
@override_settings(ROOT_URLCONF="i18n.patterns.urls.disabled")
|
||||
class URLDisabledTests(URLTestCaseBase):
|
||||
|
||||
@override_settings(USE_I18N=False)
|
||||
def test_prefixed_i18n_disabled(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('prefixed'), '/prefixed/')
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('prefixed'), '/prefixed/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("prefixed"), "/prefixed/")
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("prefixed"), "/prefixed/")
|
||||
|
||||
|
||||
class RequestURLConfTests(SimpleTestCase):
|
||||
|
||||
@override_settings(ROOT_URLCONF='i18n.patterns.urls.path_unused')
|
||||
@override_settings(ROOT_URLCONF="i18n.patterns.urls.path_unused")
|
||||
def test_request_urlconf_considered(self):
|
||||
request = RequestFactory().get('/nl/')
|
||||
request.urlconf = 'i18n.patterns.urls.default'
|
||||
request = RequestFactory().get("/nl/")
|
||||
request.urlconf = "i18n.patterns.urls.default"
|
||||
middleware = LocaleMiddleware(lambda req: HttpResponse())
|
||||
with translation.override('nl'):
|
||||
with translation.override("nl"):
|
||||
middleware.process_request(request)
|
||||
self.assertEqual(request.LANGUAGE_CODE, 'nl')
|
||||
self.assertEqual(request.LANGUAGE_CODE, "nl")
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF='i18n.patterns.urls.path_unused')
|
||||
@override_settings(ROOT_URLCONF="i18n.patterns.urls.path_unused")
|
||||
class PathUnusedTests(URLTestCaseBase):
|
||||
"""
|
||||
If no i18n_patterns is used in root URLconfs, then no language activation
|
||||
@@ -114,10 +121,10 @@ class PathUnusedTests(URLTestCaseBase):
|
||||
"""
|
||||
|
||||
def test_no_lang_activate(self):
|
||||
response = self.client.get('/nl/foo/')
|
||||
response = self.client.get("/nl/foo/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'en')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
|
||||
self.assertEqual(response.headers["content-language"], "en")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "en")
|
||||
|
||||
|
||||
class URLTranslationTests(URLTestCaseBase):
|
||||
@@ -125,66 +132,90 @@ class URLTranslationTests(URLTestCaseBase):
|
||||
Tests if the pattern-strings are translated correctly (within the
|
||||
`i18n_patterns` and the normal `patterns` function).
|
||||
"""
|
||||
|
||||
def test_no_prefix_translated(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('no-prefix-translated'), '/translated/')
|
||||
self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/translated/yeah/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("no-prefix-translated"), "/translated/")
|
||||
self.assertEqual(
|
||||
reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
|
||||
"/translated/yeah/",
|
||||
)
|
||||
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('no-prefix-translated'), '/vertaald/')
|
||||
self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/vertaald/yeah/')
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("no-prefix-translated"), "/vertaald/")
|
||||
self.assertEqual(
|
||||
reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
|
||||
"/vertaald/yeah/",
|
||||
)
|
||||
|
||||
with translation.override('pt-br'):
|
||||
self.assertEqual(reverse('no-prefix-translated'), '/traduzidos/')
|
||||
self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/traduzidos/yeah/')
|
||||
with translation.override("pt-br"):
|
||||
self.assertEqual(reverse("no-prefix-translated"), "/traduzidos/")
|
||||
self.assertEqual(
|
||||
reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
|
||||
"/traduzidos/yeah/",
|
||||
)
|
||||
|
||||
def test_users_url(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('users'), '/en/users/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("users"), "/en/users/")
|
||||
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('users'), '/nl/gebruikers/')
|
||||
self.assertEqual(reverse('prefixed_xml'), '/nl/prefixed.xml')
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("users"), "/nl/gebruikers/")
|
||||
self.assertEqual(reverse("prefixed_xml"), "/nl/prefixed.xml")
|
||||
|
||||
with translation.override('pt-br'):
|
||||
self.assertEqual(reverse('users'), '/pt-br/usuarios/')
|
||||
with translation.override("pt-br"):
|
||||
self.assertEqual(reverse("users"), "/pt-br/usuarios/")
|
||||
|
||||
def test_translate_url_utility(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(translate_url('/en/nonexistent/', 'nl'), '/en/nonexistent/')
|
||||
self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/')
|
||||
with translation.override("en"):
|
||||
self.assertEqual(
|
||||
translate_url("/en/nonexistent/", "nl"), "/en/nonexistent/"
|
||||
)
|
||||
self.assertEqual(translate_url("/en/users/", "nl"), "/nl/gebruikers/")
|
||||
# Namespaced URL
|
||||
self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registreren/')
|
||||
self.assertEqual(
|
||||
translate_url("/en/account/register/", "nl"), "/nl/profiel/registreren/"
|
||||
)
|
||||
# path() URL pattern
|
||||
self.assertEqual(translate_url('/en/account/register-as-path/', 'nl'), '/nl/profiel/registreren-als-pad/')
|
||||
self.assertEqual(translation.get_language(), 'en')
|
||||
self.assertEqual(
|
||||
translate_url("/en/account/register-as-path/", "nl"),
|
||||
"/nl/profiel/registreren-als-pad/",
|
||||
)
|
||||
self.assertEqual(translation.get_language(), "en")
|
||||
# URL with parameters.
|
||||
self.assertEqual(
|
||||
translate_url('/en/with-arguments/regular-argument/', 'nl'),
|
||||
'/nl/with-arguments/regular-argument/',
|
||||
translate_url("/en/with-arguments/regular-argument/", "nl"),
|
||||
"/nl/with-arguments/regular-argument/",
|
||||
)
|
||||
self.assertEqual(
|
||||
translate_url('/en/with-arguments/regular-argument/optional.html', 'nl'),
|
||||
'/nl/with-arguments/regular-argument/optional.html',
|
||||
translate_url(
|
||||
"/en/with-arguments/regular-argument/optional.html", "nl"
|
||||
),
|
||||
"/nl/with-arguments/regular-argument/optional.html",
|
||||
)
|
||||
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/')
|
||||
self.assertEqual(translation.get_language(), 'nl')
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(translate_url("/nl/gebruikers/", "en"), "/en/users/")
|
||||
self.assertEqual(translation.get_language(), "nl")
|
||||
|
||||
|
||||
class URLNamespaceTests(URLTestCaseBase):
|
||||
"""
|
||||
Tests if the translations are still working within namespaces.
|
||||
"""
|
||||
def test_account_register(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(reverse('account:register'), '/en/account/register/')
|
||||
self.assertEqual(reverse('account:register-as-path'), '/en/account/register-as-path/')
|
||||
|
||||
with translation.override('nl'):
|
||||
self.assertEqual(reverse('account:register'), '/nl/profiel/registreren/')
|
||||
self.assertEqual(reverse('account:register-as-path'), '/nl/profiel/registreren-als-pad/')
|
||||
def test_account_register(self):
|
||||
with translation.override("en"):
|
||||
self.assertEqual(reverse("account:register"), "/en/account/register/")
|
||||
self.assertEqual(
|
||||
reverse("account:register-as-path"), "/en/account/register-as-path/"
|
||||
)
|
||||
|
||||
with translation.override("nl"):
|
||||
self.assertEqual(reverse("account:register"), "/nl/profiel/registreren/")
|
||||
self.assertEqual(
|
||||
reverse("account:register-as-path"), "/nl/profiel/registreren-als-pad/"
|
||||
)
|
||||
|
||||
|
||||
class URLRedirectTests(URLTestCaseBase):
|
||||
@@ -192,79 +223,81 @@ class URLRedirectTests(URLTestCaseBase):
|
||||
Tests if the user gets redirected to the right URL when there is no
|
||||
language-prefix in the request URL.
|
||||
"""
|
||||
|
||||
def test_no_prefix_response(self):
|
||||
response = self.client.get('/not-prefixed/')
|
||||
response = self.client.get("/not-prefixed/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_en_redirect(self):
|
||||
response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
|
||||
self.assertRedirects(response, '/en/account/register/')
|
||||
response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertRedirects(response, "/en/account/register/")
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_en_redirect_wrong_url(self):
|
||||
response = self.client.get('/profiel/registreren/', HTTP_ACCEPT_LANGUAGE='en')
|
||||
response = self.client.get("/profiel/registreren/", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_nl_redirect(self):
|
||||
response = self.client.get('/profiel/registreren/', HTTP_ACCEPT_LANGUAGE='nl')
|
||||
self.assertRedirects(response, '/nl/profiel/registreren/')
|
||||
response = self.client.get("/profiel/registreren/", HTTP_ACCEPT_LANGUAGE="nl")
|
||||
self.assertRedirects(response, "/nl/profiel/registreren/")
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_nl_redirect_wrong_url(self):
|
||||
response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='nl')
|
||||
response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="nl")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_pt_br_redirect(self):
|
||||
response = self.client.get('/conta/registre-se/', HTTP_ACCEPT_LANGUAGE='pt-br')
|
||||
self.assertRedirects(response, '/pt-br/conta/registre-se/')
|
||||
response = self.client.get("/conta/registre-se/", HTTP_ACCEPT_LANGUAGE="pt-br")
|
||||
self.assertRedirects(response, "/pt-br/conta/registre-se/")
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_pl_pl_redirect(self):
|
||||
# language from outside of the supported LANGUAGES list
|
||||
response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='pl-pl')
|
||||
self.assertRedirects(response, '/en/account/register/')
|
||||
response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="pl-pl")
|
||||
self.assertRedirects(response, "/en/account/register/")
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
@override_settings(
|
||||
MIDDLEWARE=[
|
||||
'i18n.patterns.tests.PermanentRedirectLocaleMiddleWare',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
"i18n.patterns.tests.PermanentRedirectLocaleMiddleWare",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
],
|
||||
)
|
||||
def test_custom_redirect_class(self):
|
||||
response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
|
||||
self.assertRedirects(response, '/en/account/register/', 301)
|
||||
response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertRedirects(response, "/en/account/register/", 301)
|
||||
|
||||
|
||||
class URLVaryAcceptLanguageTests(URLTestCaseBase):
|
||||
"""
|
||||
'Accept-Language' is not added to the Vary header when using prefixed URLs.
|
||||
"""
|
||||
|
||||
def test_no_prefix_response(self):
|
||||
response = self.client.get('/not-prefixed/')
|
||||
response = self.client.get("/not-prefixed/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.get('Vary'), 'Accept-Language')
|
||||
self.assertEqual(response.get("Vary"), "Accept-Language")
|
||||
|
||||
def test_en_redirect(self):
|
||||
"""
|
||||
The redirect to a prefixed URL depends on 'Accept-Language' and
|
||||
'Cookie', but once prefixed no header is set.
|
||||
"""
|
||||
response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
|
||||
self.assertRedirects(response, '/en/account/register/')
|
||||
self.assertEqual(response.get('Vary'), 'Accept-Language, Cookie')
|
||||
response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertRedirects(response, "/en/account/register/")
|
||||
self.assertEqual(response.get("Vary"), "Accept-Language, Cookie")
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFalse(response.get('Vary'))
|
||||
self.assertFalse(response.get("Vary"))
|
||||
|
||||
|
||||
class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
|
||||
@@ -272,18 +305,23 @@ class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
|
||||
Tests the redirect when the requested URL doesn't end with a slash
|
||||
(`settings.APPEND_SLASH=True`).
|
||||
"""
|
||||
|
||||
def test_not_prefixed_redirect(self):
|
||||
response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en')
|
||||
self.assertRedirects(response, '/not-prefixed/', 301)
|
||||
response = self.client.get("/not-prefixed", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertRedirects(response, "/not-prefixed/", 301)
|
||||
|
||||
def test_en_redirect(self):
|
||||
response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en', follow=True)
|
||||
response = self.client.get(
|
||||
"/account/register", HTTP_ACCEPT_LANGUAGE="en", follow=True
|
||||
)
|
||||
# We only want one redirect, bypassing CommonMiddleware
|
||||
self.assertEqual(response.redirect_chain, [('/en/account/register/', 302)])
|
||||
self.assertRedirects(response, '/en/account/register/', 302)
|
||||
self.assertEqual(response.redirect_chain, [("/en/account/register/", 302)])
|
||||
self.assertRedirects(response, "/en/account/register/", 302)
|
||||
|
||||
response = self.client.get('/prefixed.xml', HTTP_ACCEPT_LANGUAGE='en', follow=True)
|
||||
self.assertRedirects(response, '/en/prefixed.xml', 302)
|
||||
response = self.client.get(
|
||||
"/prefixed.xml", HTTP_ACCEPT_LANGUAGE="en", follow=True
|
||||
)
|
||||
self.assertRedirects(response, "/en/prefixed.xml", 302)
|
||||
|
||||
|
||||
class URLRedirectWithoutTrailingSlashSettingTests(URLTestCaseBase):
|
||||
@@ -291,105 +329,129 @@ class URLRedirectWithoutTrailingSlashSettingTests(URLTestCaseBase):
|
||||
Tests the redirect when the requested URL doesn't end with a slash
|
||||
(`settings.APPEND_SLASH=False`).
|
||||
"""
|
||||
|
||||
@override_settings(APPEND_SLASH=False)
|
||||
def test_not_prefixed_redirect(self):
|
||||
response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en')
|
||||
response = self.client.get("/not-prefixed", HTTP_ACCEPT_LANGUAGE="en")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
@override_settings(APPEND_SLASH=False)
|
||||
def test_en_redirect(self):
|
||||
response = self.client.get('/account/register-without-slash', HTTP_ACCEPT_LANGUAGE='en')
|
||||
self.assertRedirects(response, '/en/account/register-without-slash', 302)
|
||||
response = self.client.get(
|
||||
"/account/register-without-slash", HTTP_ACCEPT_LANGUAGE="en"
|
||||
)
|
||||
self.assertRedirects(response, "/en/account/register-without-slash", 302)
|
||||
|
||||
response = self.client.get(response.headers['location'])
|
||||
response = self.client.get(response.headers["location"])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class URLResponseTests(URLTestCaseBase):
|
||||
"""Tests if the response has the correct language code."""
|
||||
|
||||
def test_not_prefixed_with_prefix(self):
|
||||
response = self.client.get('/en/not-prefixed/')
|
||||
response = self.client.get("/en/not-prefixed/")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_en_url(self):
|
||||
response = self.client.get('/en/account/register/')
|
||||
response = self.client.get("/en/account/register/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'en')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
|
||||
self.assertEqual(response.headers["content-language"], "en")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "en")
|
||||
|
||||
def test_nl_url(self):
|
||||
response = self.client.get('/nl/profiel/registreren/')
|
||||
response = self.client.get("/nl/profiel/registreren/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'nl')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'nl')
|
||||
self.assertEqual(response.headers["content-language"], "nl")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "nl")
|
||||
|
||||
def test_wrong_en_prefix(self):
|
||||
response = self.client.get('/en/profiel/registreren/')
|
||||
response = self.client.get("/en/profiel/registreren/")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_wrong_nl_prefix(self):
|
||||
response = self.client.get('/nl/account/register/')
|
||||
response = self.client.get("/nl/account/register/")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_pt_br_url(self):
|
||||
response = self.client.get('/pt-br/conta/registre-se/')
|
||||
response = self.client.get("/pt-br/conta/registre-se/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'pt-br')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'pt-br')
|
||||
self.assertEqual(response.headers["content-language"], "pt-br")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "pt-br")
|
||||
|
||||
def test_en_path(self):
|
||||
response = self.client.get('/en/account/register-as-path/')
|
||||
response = self.client.get("/en/account/register-as-path/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'en')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
|
||||
self.assertEqual(response.headers["content-language"], "en")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "en")
|
||||
|
||||
def test_nl_path(self):
|
||||
response = self.client.get('/nl/profiel/registreren-als-pad/')
|
||||
response = self.client.get("/nl/profiel/registreren-als-pad/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers['content-language'], 'nl')
|
||||
self.assertEqual(response.context['LANGUAGE_CODE'], 'nl')
|
||||
self.assertEqual(response.headers["content-language"], "nl")
|
||||
self.assertEqual(response.context["LANGUAGE_CODE"], "nl")
|
||||
|
||||
|
||||
class URLRedirectWithScriptAliasTests(URLTestCaseBase):
|
||||
"""
|
||||
#21579 - LocaleMiddleware should respect the script prefix.
|
||||
"""
|
||||
|
||||
def test_language_prefix_with_script_prefix(self):
|
||||
prefix = '/script_prefix'
|
||||
prefix = "/script_prefix"
|
||||
with override_script_prefix(prefix):
|
||||
response = self.client.get('/prefixed/', HTTP_ACCEPT_LANGUAGE='en', SCRIPT_NAME=prefix)
|
||||
self.assertRedirects(response, '%s/en/prefixed/' % prefix, target_status_code=404)
|
||||
response = self.client.get(
|
||||
"/prefixed/", HTTP_ACCEPT_LANGUAGE="en", SCRIPT_NAME=prefix
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, "%s/en/prefixed/" % prefix, target_status_code=404
|
||||
)
|
||||
|
||||
|
||||
class URLTagTests(URLTestCaseBase):
|
||||
"""
|
||||
Test if the language tag works.
|
||||
"""
|
||||
|
||||
def test_strings_only(self):
|
||||
t = Template("""{% load i18n %}
|
||||
t = Template(
|
||||
"""{% load i18n %}
|
||||
{% language 'nl' %}{% url 'no-prefix-translated' %}{% endlanguage %}
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated' %}{% endlanguage %}""")
|
||||
self.assertEqual(t.render(Context({})).strip().split(),
|
||||
['/vertaald/', '/traduzidos/'])
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated' %}{% endlanguage %}"""
|
||||
)
|
||||
self.assertEqual(
|
||||
t.render(Context({})).strip().split(), ["/vertaald/", "/traduzidos/"]
|
||||
)
|
||||
|
||||
def test_context(self):
|
||||
ctx = Context({'lang1': 'nl', 'lang2': 'pt-br'})
|
||||
tpl = Template("""{% load i18n %}
|
||||
ctx = Context({"lang1": "nl", "lang2": "pt-br"})
|
||||
tpl = Template(
|
||||
"""{% load i18n %}
|
||||
{% language lang1 %}{% url 'no-prefix-translated' %}{% endlanguage %}
|
||||
{% language lang2 %}{% url 'no-prefix-translated' %}{% endlanguage %}""")
|
||||
self.assertEqual(tpl.render(ctx).strip().split(),
|
||||
['/vertaald/', '/traduzidos/'])
|
||||
{% language lang2 %}{% url 'no-prefix-translated' %}{% endlanguage %}"""
|
||||
)
|
||||
self.assertEqual(
|
||||
tpl.render(ctx).strip().split(), ["/vertaald/", "/traduzidos/"]
|
||||
)
|
||||
|
||||
def test_args(self):
|
||||
tpl = Template("""{% load i18n %}
|
||||
tpl = Template(
|
||||
"""{% load i18n %}
|
||||
{% language 'nl' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}""")
|
||||
self.assertEqual(tpl.render(Context({})).strip().split(),
|
||||
['/vertaald/apo/', '/traduzidos/apo/'])
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}"""
|
||||
)
|
||||
self.assertEqual(
|
||||
tpl.render(Context({})).strip().split(),
|
||||
["/vertaald/apo/", "/traduzidos/apo/"],
|
||||
)
|
||||
|
||||
def test_kwargs(self):
|
||||
tpl = Template("""{% load i18n %}
|
||||
tpl = Template(
|
||||
"""{% load i18n %}
|
||||
{% language 'nl' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}""")
|
||||
self.assertEqual(tpl.render(Context({})).strip().split(),
|
||||
['/vertaald/apo/', '/traduzidos/apo/'])
|
||||
{% language 'pt-br' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}"""
|
||||
)
|
||||
self.assertEqual(
|
||||
tpl.render(Context({})).strip().split(),
|
||||
["/vertaald/apo/", "/traduzidos/apo/"],
|
||||
)
|
||||
|
||||
@@ -3,23 +3,27 @@ from django.urls import include, path, re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
urlpatterns = [
|
||||
path('not-prefixed/', view, name='not-prefixed'),
|
||||
path('not-prefixed-include/', include('i18n.patterns.urls.included')),
|
||||
re_path(_(r'^translated/$'), view, name='no-prefix-translated'),
|
||||
re_path(_(r'^translated/(?P<slug>[\w-]+)/$'), view, name='no-prefix-translated-slug'),
|
||||
path("not-prefixed/", view, name="not-prefixed"),
|
||||
path("not-prefixed-include/", include("i18n.patterns.urls.included")),
|
||||
re_path(_(r"^translated/$"), view, name="no-prefix-translated"),
|
||||
re_path(
|
||||
_(r"^translated/(?P<slug>[\w-]+)/$"), view, name="no-prefix-translated-slug"
|
||||
),
|
||||
]
|
||||
|
||||
urlpatterns += i18n_patterns(
|
||||
path('prefixed/', view, name='prefixed'),
|
||||
path('prefixed.xml', view, name='prefixed_xml'),
|
||||
path("prefixed/", view, name="prefixed"),
|
||||
path("prefixed.xml", view, name="prefixed_xml"),
|
||||
re_path(
|
||||
_(r'^with-arguments/(?P<argument>[\w-]+)/(?:(?P<optional>[\w-]+).html)?$'),
|
||||
_(r"^with-arguments/(?P<argument>[\w-]+)/(?:(?P<optional>[\w-]+).html)?$"),
|
||||
view,
|
||||
name='with-arguments',
|
||||
name="with-arguments",
|
||||
),
|
||||
re_path(_(r"^users/$"), view, name="users"),
|
||||
re_path(
|
||||
_(r"^account/"), include("i18n.patterns.urls.namespace", namespace="account")
|
||||
),
|
||||
re_path(_(r'^users/$'), view, name='users'),
|
||||
re_path(_(r'^account/'), include('i18n.patterns.urls.namespace', namespace='account')),
|
||||
)
|
||||
|
||||
@@ -2,8 +2,8 @@ from django.conf.urls.i18n import i18n_patterns
|
||||
from django.urls import path
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
urlpatterns = i18n_patterns(
|
||||
path('prefixed/', view, name='prefixed'),
|
||||
path("prefixed/", view, name="prefixed"),
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from django.urls import path
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
urlpatterns = [
|
||||
path('foo/', view, name='not-prefixed-included-url'),
|
||||
path("foo/", view, name="not-prefixed-included-url"),
|
||||
]
|
||||
|
||||
@@ -2,11 +2,11 @@ from django.urls import path, re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
app_name = 'account'
|
||||
app_name = "account"
|
||||
urlpatterns = [
|
||||
re_path(_(r'^register/$'), view, name='register'),
|
||||
re_path(_(r'^register-without-slash$'), view, name='register-without-slash'),
|
||||
path(_('register-as-path/'), view, name='register-as-path'),
|
||||
re_path(_(r"^register/$"), view, name="register"),
|
||||
re_path(_(r"^register-without-slash$"), view, name="register-without-slash"),
|
||||
path(_("register-as-path/"), view, name="register-as-path"),
|
||||
]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from django.urls import re_path
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
urlpatterns = [
|
||||
re_path('^nl/foo/', view, name='not-translated'),
|
||||
re_path("^nl/foo/", view, name="not-translated"),
|
||||
]
|
||||
|
||||
@@ -3,5 +3,8 @@ from django.urls import include, re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
urlpatterns = i18n_patterns(
|
||||
re_path(_(r'^account/'), include('i18n.patterns.urls.wrong_namespace', namespace='account')),
|
||||
re_path(
|
||||
_(r"^account/"),
|
||||
include("i18n.patterns.urls.wrong_namespace", namespace="account"),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -3,9 +3,9 @@ from django.urls import re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
view = TemplateView.as_view(template_name='dummy.html')
|
||||
view = TemplateView.as_view(template_name="dummy.html")
|
||||
|
||||
app_name = 'account'
|
||||
app_name = "account"
|
||||
urlpatterns = i18n_patterns(
|
||||
re_path(_(r'^register/$'), view, name='register'),
|
||||
re_path(_(r"^register/$"), view, name="register"),
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.join('..', '..', '..')))
|
||||
sys.path.append(os.path.abspath(os.path.join("..", "..", "..")))
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sampleproject.settings")
|
||||
|
||||
@@ -31,7 +31,7 @@ import re
|
||||
import sys
|
||||
|
||||
proj_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.append(os.path.abspath(os.path.join(proj_dir, '..', '..', '..')))
|
||||
sys.path.append(os.path.abspath(os.path.join(proj_dir, "..", "..", "..")))
|
||||
|
||||
|
||||
def update_translation_catalogs():
|
||||
@@ -41,16 +41,16 @@ def update_translation_catalogs():
|
||||
prev_cwd = os.getcwd()
|
||||
|
||||
os.chdir(proj_dir)
|
||||
call_command('makemessages')
|
||||
call_command('compilemessages')
|
||||
call_command("makemessages")
|
||||
call_command("compilemessages")
|
||||
|
||||
# keep the diff friendly - remove 'POT-Creation-Date'
|
||||
pofile = os.path.join(proj_dir, 'locale', 'fr', 'LC_MESSAGES', 'django.po')
|
||||
pofile = os.path.join(proj_dir, "locale", "fr", "LC_MESSAGES", "django.po")
|
||||
|
||||
with open(pofile) as f:
|
||||
content = f.read()
|
||||
content = re.sub(r'^"POT-Creation-Date.+$\s', '', content, flags=re.MULTILINE)
|
||||
with open(pofile, 'w') as f:
|
||||
content = re.sub(r'^"POT-Creation-Date.+$\s', "", content, flags=re.MULTILINE)
|
||||
with open(pofile, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
os.chdir(prev_cwd)
|
||||
|
||||
@@ -7,12 +7,8 @@ from pathlib import Path
|
||||
from subprocess import run
|
||||
from unittest import mock
|
||||
|
||||
from django.core.management import (
|
||||
CommandError, call_command, execute_from_command_line,
|
||||
)
|
||||
from django.core.management.commands.makemessages import (
|
||||
Command as MakeMessagesCommand,
|
||||
)
|
||||
from django.core.management import CommandError, call_command, execute_from_command_line
|
||||
from django.core.management.commands.makemessages import Command as MakeMessagesCommand
|
||||
from django.core.management.utils import find_command
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.test.utils import captured_stderr, captured_stdout
|
||||
@@ -21,26 +17,30 @@ from django.utils.translation import gettext
|
||||
|
||||
from .utils import RunInTmpDirMixin, copytree
|
||||
|
||||
has_msgfmt = find_command('msgfmt')
|
||||
has_msgfmt = find_command("msgfmt")
|
||||
|
||||
|
||||
@unittest.skipUnless(has_msgfmt, 'msgfmt is mandatory for compilation tests')
|
||||
@unittest.skipUnless(has_msgfmt, "msgfmt is mandatory for compilation tests")
|
||||
class MessageCompilationTests(RunInTmpDirMixin, SimpleTestCase):
|
||||
|
||||
work_subdir = 'commands'
|
||||
work_subdir = "commands"
|
||||
|
||||
|
||||
class PoFileTests(MessageCompilationTests):
|
||||
|
||||
LOCALE = 'es_AR'
|
||||
MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
MO_FILE_EN = 'locale/en/LC_MESSAGES/django.mo'
|
||||
LOCALE = "es_AR"
|
||||
MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
|
||||
MO_FILE_EN = "locale/en/LC_MESSAGES/django.mo"
|
||||
|
||||
def test_bom_rejection(self):
|
||||
stderr = StringIO()
|
||||
with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors.'):
|
||||
call_command('compilemessages', locale=[self.LOCALE], verbosity=0, stderr=stderr)
|
||||
self.assertIn('file has a BOM (Byte Order Mark)', stderr.getvalue())
|
||||
with self.assertRaisesMessage(
|
||||
CommandError, "compilemessages generated one or more errors."
|
||||
):
|
||||
call_command(
|
||||
"compilemessages", locale=[self.LOCALE], verbosity=0, stderr=stderr
|
||||
)
|
||||
self.assertIn("file has a BOM (Byte Order Mark)", stderr.getvalue())
|
||||
self.assertFalse(os.path.exists(self.MO_FILE))
|
||||
|
||||
def test_no_write_access(self):
|
||||
@@ -50,11 +50,15 @@ class PoFileTests(MessageCompilationTests):
|
||||
old_mode = mo_file_en.stat().st_mode
|
||||
mo_file_en.chmod(stat.S_IREAD)
|
||||
# Ensure .po file is more recent than .mo file.
|
||||
mo_file_en.with_suffix('.po').touch()
|
||||
mo_file_en.with_suffix(".po").touch()
|
||||
try:
|
||||
with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors.'):
|
||||
call_command('compilemessages', locale=['en'], stderr=err_buffer, verbosity=0)
|
||||
self.assertIn('not writable location', err_buffer.getvalue())
|
||||
with self.assertRaisesMessage(
|
||||
CommandError, "compilemessages generated one or more errors."
|
||||
):
|
||||
call_command(
|
||||
"compilemessages", locale=["en"], stderr=err_buffer, verbosity=0
|
||||
)
|
||||
self.assertIn("not writable location", err_buffer.getvalue())
|
||||
finally:
|
||||
mo_file_en.chmod(old_mode)
|
||||
|
||||
@@ -62,19 +66,19 @@ class PoFileTests(MessageCompilationTests):
|
||||
mo_file_en = Path(self.MO_FILE_EN)
|
||||
mo_file_en.touch()
|
||||
stdout = StringIO()
|
||||
call_command('compilemessages', locale=['en'], stdout=stdout, verbosity=1)
|
||||
msg = '%s” is already compiled and up to date.' % mo_file_en.with_suffix('.po')
|
||||
call_command("compilemessages", locale=["en"], stdout=stdout, verbosity=1)
|
||||
msg = "%s” is already compiled and up to date." % mo_file_en.with_suffix(".po")
|
||||
self.assertIn(msg, stdout.getvalue())
|
||||
|
||||
|
||||
class PoFileContentsTests(MessageCompilationTests):
|
||||
# Ticket #11240
|
||||
|
||||
LOCALE = 'fr'
|
||||
MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
LOCALE = "fr"
|
||||
MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
|
||||
|
||||
def test_percent_symbol_in_po_file(self):
|
||||
call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
|
||||
call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE))
|
||||
|
||||
|
||||
@@ -85,19 +89,19 @@ class MultipleLocaleCompilationTests(MessageCompilationTests):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
localedir = os.path.join(self.test_dir, 'locale')
|
||||
self.MO_FILE_HR = os.path.join(localedir, 'hr/LC_MESSAGES/django.mo')
|
||||
self.MO_FILE_FR = os.path.join(localedir, 'fr/LC_MESSAGES/django.mo')
|
||||
localedir = os.path.join(self.test_dir, "locale")
|
||||
self.MO_FILE_HR = os.path.join(localedir, "hr/LC_MESSAGES/django.mo")
|
||||
self.MO_FILE_FR = os.path.join(localedir, "fr/LC_MESSAGES/django.mo")
|
||||
|
||||
def test_one_locale(self):
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
|
||||
call_command('compilemessages', locale=['hr'], verbosity=0)
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
|
||||
call_command("compilemessages", locale=["hr"], verbosity=0)
|
||||
|
||||
self.assertTrue(os.path.exists(self.MO_FILE_HR))
|
||||
|
||||
def test_multiple_locales(self):
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
|
||||
call_command('compilemessages', locale=['hr', 'fr'], verbosity=0)
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
|
||||
call_command("compilemessages", locale=["hr", "fr"], verbosity=0)
|
||||
|
||||
self.assertTrue(os.path.exists(self.MO_FILE_HR))
|
||||
self.assertTrue(os.path.exists(self.MO_FILE_FR))
|
||||
@@ -105,144 +109,164 @@ class MultipleLocaleCompilationTests(MessageCompilationTests):
|
||||
|
||||
class ExcludedLocaleCompilationTests(MessageCompilationTests):
|
||||
|
||||
work_subdir = 'exclude'
|
||||
work_subdir = "exclude"
|
||||
|
||||
MO_FILE = 'locale/%s/LC_MESSAGES/django.mo'
|
||||
MO_FILE = "locale/%s/LC_MESSAGES/django.mo"
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
copytree('canned_locale', 'locale')
|
||||
copytree("canned_locale", "locale")
|
||||
|
||||
def test_command_help(self):
|
||||
with captured_stdout(), captured_stderr():
|
||||
# `call_command` bypasses the parser; by calling
|
||||
# `execute_from_command_line` with the help subcommand we
|
||||
# ensure that there are no issues with the parser itself.
|
||||
execute_from_command_line(['django-admin', 'help', 'compilemessages'])
|
||||
execute_from_command_line(["django-admin", "help", "compilemessages"])
|
||||
|
||||
def test_one_locale_excluded(self):
|
||||
call_command('compilemessages', exclude=['it'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % 'fr'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
|
||||
call_command("compilemessages", exclude=["it"], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % "en"))
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % "fr"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "it"))
|
||||
|
||||
def test_multiple_locales_excluded(self):
|
||||
call_command('compilemessages', exclude=['it', 'fr'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
|
||||
call_command("compilemessages", exclude=["it", "fr"], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % "en"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "it"))
|
||||
|
||||
def test_one_locale_excluded_with_locale(self):
|
||||
call_command('compilemessages', locale=['en', 'fr'], exclude=['fr'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
|
||||
call_command(
|
||||
"compilemessages", locale=["en", "fr"], exclude=["fr"], verbosity=0
|
||||
)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % "en"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "it"))
|
||||
|
||||
def test_multiple_locales_excluded_with_locale(self):
|
||||
call_command('compilemessages', locale=['en', 'fr', 'it'], exclude=['fr', 'it'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
|
||||
call_command(
|
||||
"compilemessages",
|
||||
locale=["en", "fr", "it"],
|
||||
exclude=["fr", "it"],
|
||||
verbosity=0,
|
||||
)
|
||||
self.assertTrue(os.path.exists(self.MO_FILE % "en"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
|
||||
self.assertFalse(os.path.exists(self.MO_FILE % "it"))
|
||||
|
||||
|
||||
class IgnoreDirectoryCompilationTests(MessageCompilationTests):
|
||||
# Reuse the exclude directory since it contains some locale fixtures.
|
||||
work_subdir = 'exclude'
|
||||
MO_FILE = '%s/%s/LC_MESSAGES/django.mo'
|
||||
CACHE_DIR = Path('cache') / 'locale'
|
||||
NESTED_DIR = Path('outdated') / 'v1' / 'locale'
|
||||
work_subdir = "exclude"
|
||||
MO_FILE = "%s/%s/LC_MESSAGES/django.mo"
|
||||
CACHE_DIR = Path("cache") / "locale"
|
||||
NESTED_DIR = Path("outdated") / "v1" / "locale"
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
copytree('canned_locale', 'locale')
|
||||
copytree('canned_locale', self.CACHE_DIR)
|
||||
copytree('canned_locale', self.NESTED_DIR)
|
||||
copytree("canned_locale", "locale")
|
||||
copytree("canned_locale", self.CACHE_DIR)
|
||||
copytree("canned_locale", self.NESTED_DIR)
|
||||
|
||||
def assertAllExist(self, dir, langs):
|
||||
self.assertTrue(all(Path(self.MO_FILE % (dir, lang)).exists() for lang in langs))
|
||||
self.assertTrue(
|
||||
all(Path(self.MO_FILE % (dir, lang)).exists() for lang in langs)
|
||||
)
|
||||
|
||||
def assertNoneExist(self, dir, langs):
|
||||
self.assertTrue(all(Path(self.MO_FILE % (dir, lang)).exists() is False for lang in langs))
|
||||
self.assertTrue(
|
||||
all(Path(self.MO_FILE % (dir, lang)).exists() is False for lang in langs)
|
||||
)
|
||||
|
||||
def test_one_locale_dir_ignored(self):
|
||||
call_command('compilemessages', ignore=['cache'], verbosity=0)
|
||||
self.assertAllExist('locale', ['en', 'fr', 'it'])
|
||||
self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
|
||||
self.assertAllExist(self.NESTED_DIR, ['en', 'fr', 'it'])
|
||||
call_command("compilemessages", ignore=["cache"], verbosity=0)
|
||||
self.assertAllExist("locale", ["en", "fr", "it"])
|
||||
self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
|
||||
self.assertAllExist(self.NESTED_DIR, ["en", "fr", "it"])
|
||||
|
||||
def test_multiple_locale_dirs_ignored(self):
|
||||
call_command('compilemessages', ignore=['cache/locale', 'outdated'], verbosity=0)
|
||||
self.assertAllExist('locale', ['en', 'fr', 'it'])
|
||||
self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
|
||||
self.assertNoneExist(self.NESTED_DIR, ['en', 'fr', 'it'])
|
||||
call_command(
|
||||
"compilemessages", ignore=["cache/locale", "outdated"], verbosity=0
|
||||
)
|
||||
self.assertAllExist("locale", ["en", "fr", "it"])
|
||||
self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
|
||||
self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])
|
||||
|
||||
def test_ignores_based_on_pattern(self):
|
||||
call_command('compilemessages', ignore=['*/locale'], verbosity=0)
|
||||
self.assertAllExist('locale', ['en', 'fr', 'it'])
|
||||
self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
|
||||
self.assertNoneExist(self.NESTED_DIR, ['en', 'fr', 'it'])
|
||||
call_command("compilemessages", ignore=["*/locale"], verbosity=0)
|
||||
self.assertAllExist("locale", ["en", "fr", "it"])
|
||||
self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
|
||||
self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])
|
||||
|
||||
|
||||
class CompilationErrorHandling(MessageCompilationTests):
|
||||
def test_error_reported_by_msgfmt(self):
|
||||
# po file contains wrong po formatting.
|
||||
with self.assertRaises(CommandError):
|
||||
call_command('compilemessages', locale=['ja'], verbosity=0)
|
||||
call_command("compilemessages", locale=["ja"], verbosity=0)
|
||||
|
||||
def test_msgfmt_error_including_non_ascii(self):
|
||||
# po file contains invalid msgstr content (triggers non-ascii error content).
|
||||
# Make sure the output of msgfmt is unaffected by the current locale.
|
||||
env = os.environ.copy()
|
||||
env.update({'LC_ALL': 'C'})
|
||||
with mock.patch('django.core.management.utils.run', lambda *args, **kwargs: run(*args, env=env, **kwargs)):
|
||||
env.update({"LC_ALL": "C"})
|
||||
with mock.patch(
|
||||
"django.core.management.utils.run",
|
||||
lambda *args, **kwargs: run(*args, env=env, **kwargs),
|
||||
):
|
||||
cmd = MakeMessagesCommand()
|
||||
if cmd.gettext_version < (0, 18, 3):
|
||||
self.skipTest("python-brace-format is a recent gettext addition.")
|
||||
stderr = StringIO()
|
||||
with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors'):
|
||||
call_command('compilemessages', locale=['ko'], stdout=StringIO(), stderr=stderr)
|
||||
with self.assertRaisesMessage(
|
||||
CommandError, "compilemessages generated one or more errors"
|
||||
):
|
||||
call_command(
|
||||
"compilemessages", locale=["ko"], stdout=StringIO(), stderr=stderr
|
||||
)
|
||||
self.assertIn("' cannot start a field name", stderr.getvalue())
|
||||
|
||||
|
||||
class ProjectAndAppTests(MessageCompilationTests):
|
||||
LOCALE = 'ru'
|
||||
PROJECT_MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
APP_MO_FILE = 'app_with_locale/locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
LOCALE = "ru"
|
||||
PROJECT_MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
|
||||
APP_MO_FILE = "app_with_locale/locale/%s/LC_MESSAGES/django.mo" % LOCALE
|
||||
|
||||
|
||||
class FuzzyTranslationTest(ProjectAndAppTests):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
gettext_module._translations = {} # flush cache or test will be useless
|
||||
|
||||
def test_nofuzzy_compiling(self):
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
|
||||
call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
|
||||
call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
|
||||
with translation.override(self.LOCALE):
|
||||
self.assertEqual(gettext('Lenin'), 'Ленин')
|
||||
self.assertEqual(gettext('Vodka'), 'Vodka')
|
||||
self.assertEqual(gettext("Lenin"), "Ленин")
|
||||
self.assertEqual(gettext("Vodka"), "Vodka")
|
||||
|
||||
def test_fuzzy_compiling(self):
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
|
||||
call_command('compilemessages', locale=[self.LOCALE], fuzzy=True, verbosity=0)
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
|
||||
call_command(
|
||||
"compilemessages", locale=[self.LOCALE], fuzzy=True, verbosity=0
|
||||
)
|
||||
with translation.override(self.LOCALE):
|
||||
self.assertEqual(gettext('Lenin'), 'Ленин')
|
||||
self.assertEqual(gettext('Vodka'), 'Водка')
|
||||
self.assertEqual(gettext("Lenin"), "Ленин")
|
||||
self.assertEqual(gettext("Vodka"), "Водка")
|
||||
|
||||
|
||||
class AppCompilationTest(ProjectAndAppTests):
|
||||
|
||||
def test_app_locale_compiled(self):
|
||||
call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
|
||||
call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PROJECT_MO_FILE))
|
||||
self.assertTrue(os.path.exists(self.APP_MO_FILE))
|
||||
|
||||
|
||||
class PathLibLocaleCompilationTests(MessageCompilationTests):
|
||||
work_subdir = 'exclude'
|
||||
work_subdir = "exclude"
|
||||
|
||||
def test_locale_paths_pathlib(self):
|
||||
with override_settings(LOCALE_PATHS=[Path(self.test_dir) / 'canned_locale']):
|
||||
call_command('compilemessages', locale=['fr'], verbosity=0)
|
||||
self.assertTrue(os.path.exists('canned_locale/fr/LC_MESSAGES/django.mo'))
|
||||
with override_settings(LOCALE_PATHS=[Path(self.test_dir) / "canned_locale"]):
|
||||
call_command("compilemessages", locale=["fr"], verbosity=0)
|
||||
self.assertTrue(os.path.exists("canned_locale/fr/LC_MESSAGES/django.mo"))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,18 +5,28 @@ from django.test import SimpleTestCase
|
||||
|
||||
|
||||
class TranslatableFileTests(SimpleTestCase):
|
||||
|
||||
def test_repr(self):
|
||||
dirpath = 'dir'
|
||||
file_name = 'example'
|
||||
trans_file = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
|
||||
self.assertEqual(repr(trans_file), '<TranslatableFile: %s>' % os.path.join(dirpath, file_name))
|
||||
dirpath = "dir"
|
||||
file_name = "example"
|
||||
trans_file = TranslatableFile(
|
||||
dirpath=dirpath, file_name=file_name, locale_dir=None
|
||||
)
|
||||
self.assertEqual(
|
||||
repr(trans_file),
|
||||
"<TranslatableFile: %s>" % os.path.join(dirpath, file_name),
|
||||
)
|
||||
|
||||
def test_eq(self):
|
||||
dirpath = 'dir'
|
||||
file_name = 'example'
|
||||
trans_file = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
|
||||
trans_file_eq = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
|
||||
trans_file_not_eq = TranslatableFile(dirpath='tmp', file_name=file_name, locale_dir=None)
|
||||
dirpath = "dir"
|
||||
file_name = "example"
|
||||
trans_file = TranslatableFile(
|
||||
dirpath=dirpath, file_name=file_name, locale_dir=None
|
||||
)
|
||||
trans_file_eq = TranslatableFile(
|
||||
dirpath=dirpath, file_name=file_name, locale_dir=None
|
||||
)
|
||||
trans_file_not_eq = TranslatableFile(
|
||||
dirpath="tmp", file_name=file_name, locale_dir=None
|
||||
)
|
||||
self.assertEqual(trans_file, trans_file_eq)
|
||||
self.assertNotEqual(trans_file, trans_file_not_eq)
|
||||
|
||||
@@ -6,20 +6,22 @@ from django.utils.translation import activate, get_language, trans_real
|
||||
|
||||
from .utils import POFileAssertionMixin
|
||||
|
||||
SAMPLEPROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sampleproject')
|
||||
SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, 'locale')
|
||||
SAMPLEPROJECT_DIR = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "sampleproject"
|
||||
)
|
||||
SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, "locale")
|
||||
|
||||
|
||||
@override_settings(LOCALE_PATHS=[SAMPLEPROJECT_LOCALE])
|
||||
class FrenchTestCase(SimpleTestCase):
|
||||
"""Tests using the French translations of the sampleproject."""
|
||||
|
||||
PO_FILE = os.path.join(SAMPLEPROJECT_LOCALE, 'fr', 'LC_MESSAGES', 'django.po')
|
||||
PO_FILE = os.path.join(SAMPLEPROJECT_LOCALE, "fr", "LC_MESSAGES", "django.po")
|
||||
|
||||
def setUp(self):
|
||||
self._language = get_language()
|
||||
self._translations = trans_real._translations
|
||||
activate('fr')
|
||||
activate("fr")
|
||||
|
||||
def tearDown(self):
|
||||
trans_real._translations = self._translations
|
||||
@@ -42,19 +44,34 @@ class ExtractingStringsWithPercentSigns(POFileAssertionMixin, FrenchTestCase):
|
||||
self.po_contents = fp.read()
|
||||
|
||||
def test_trans_tag_with_percent_symbol_at_the_end(self):
|
||||
self.assertMsgId('Literal with a percent symbol at the end %%', self.po_contents)
|
||||
self.assertMsgId(
|
||||
"Literal with a percent symbol at the end %%", self.po_contents
|
||||
)
|
||||
|
||||
def test_trans_tag_with_percent_symbol_in_the_middle(self):
|
||||
self.assertMsgId('Literal with a percent %% symbol in the middle', self.po_contents)
|
||||
self.assertMsgId('It is 100%%', self.po_contents)
|
||||
self.assertMsgId(
|
||||
"Literal with a percent %% symbol in the middle", self.po_contents
|
||||
)
|
||||
self.assertMsgId("It is 100%%", self.po_contents)
|
||||
|
||||
def test_trans_tag_with_string_that_look_like_fmt_spec(self):
|
||||
self.assertMsgId('Looks like a str fmt spec %%s but should not be interpreted as such', self.po_contents)
|
||||
self.assertMsgId('Looks like a str fmt spec %% o but should not be interpreted as such', self.po_contents)
|
||||
self.assertMsgId(
|
||||
"Looks like a str fmt spec %%s but should not be interpreted as such",
|
||||
self.po_contents,
|
||||
)
|
||||
self.assertMsgId(
|
||||
"Looks like a str fmt spec %% o but should not be interpreted as such",
|
||||
self.po_contents,
|
||||
)
|
||||
|
||||
def test_adds_python_format_to_all_percent_signs(self):
|
||||
self.assertMsgId('1 percent sign %%, 2 percent signs %%%%, 3 percent signs %%%%%%', self.po_contents)
|
||||
self.assertMsgId('%(name)s says: 1 percent sign %%, 2 percent signs %%%%', self.po_contents)
|
||||
self.assertMsgId(
|
||||
"1 percent sign %%, 2 percent signs %%%%, 3 percent signs %%%%%%",
|
||||
self.po_contents,
|
||||
)
|
||||
self.assertMsgId(
|
||||
"%(name)s says: 1 percent sign %%, 2 percent signs %%%%", self.po_contents
|
||||
)
|
||||
|
||||
|
||||
class RenderingTemplatesWithPercentSigns(FrenchTestCase):
|
||||
@@ -67,69 +84,79 @@ class RenderingTemplatesWithPercentSigns(FrenchTestCase):
|
||||
"""
|
||||
|
||||
def test_translates_with_a_percent_symbol_at_the_end(self):
|
||||
expected = 'Littérale avec un symbole de pour cent à la fin %'
|
||||
expected = "Littérale avec un symbole de pour cent à la fin %"
|
||||
|
||||
trans_tpl = Template('{% load i18n %}{% translate "Literal with a percent symbol at the end %" %}')
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "Literal with a percent symbol at the end %" %}'
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), expected)
|
||||
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}Literal with a percent symbol at '
|
||||
'the end %{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}Literal with a percent symbol at "
|
||||
"the end %{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), expected)
|
||||
|
||||
def test_translates_with_percent_symbol_in_the_middle(self):
|
||||
expected = 'Pour cent littérale % avec un symbole au milieu'
|
||||
expected = "Pour cent littérale % avec un symbole au milieu"
|
||||
|
||||
trans_tpl = Template('{% load i18n %}{% translate "Literal with a percent % symbol in the middle" %}')
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "Literal with a percent % symbol in the middle" %}'
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), expected)
|
||||
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}Literal with a percent % symbol '
|
||||
'in the middle{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}Literal with a percent % symbol "
|
||||
"in the middle{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), expected)
|
||||
|
||||
def test_translates_with_percent_symbol_using_context(self):
|
||||
trans_tpl = Template('{% load i18n %}{% translate "It is 100%" %}')
|
||||
self.assertEqual(trans_tpl.render(Context({})), 'Il est de 100%')
|
||||
trans_tpl = Template('{% load i18n %}{% translate "It is 100%" context "female" %}')
|
||||
self.assertEqual(trans_tpl.render(Context({})), 'Elle est de 100%')
|
||||
self.assertEqual(trans_tpl.render(Context({})), "Il est de 100%")
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "It is 100%" context "female" %}'
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), "Elle est de 100%")
|
||||
|
||||
block_tpl = Template('{% load i18n %}{% blocktranslate %}It is 100%{% endblocktranslate %}')
|
||||
self.assertEqual(block_tpl.render(Context({})), 'Il est de 100%')
|
||||
block_tpl = Template('{% load i18n %}{% blocktranslate context "female" %}It is 100%{% endblocktranslate %}')
|
||||
self.assertEqual(block_tpl.render(Context({})), 'Elle est de 100%')
|
||||
block_tpl = Template(
|
||||
"{% load i18n %}{% blocktranslate %}It is 100%{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), "Il est de 100%")
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate context "female" %}It is 100%{% endblocktranslate %}'
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), "Elle est de 100%")
|
||||
|
||||
def test_translates_with_string_that_look_like_fmt_spec_with_trans(self):
|
||||
# tests "%s"
|
||||
expected = ('On dirait un spec str fmt %s mais ne devrait pas être interprété comme plus disponible')
|
||||
expected = "On dirait un spec str fmt %s mais ne devrait pas être interprété comme plus disponible"
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "Looks like a str fmt spec %s but '
|
||||
'should not be interpreted as such" %}'
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), expected)
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}Looks like a str fmt spec %s but '
|
||||
'should not be interpreted as such{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}Looks like a str fmt spec %s but "
|
||||
"should not be interpreted as such{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), expected)
|
||||
|
||||
# tests "% o"
|
||||
expected = ('On dirait un spec str fmt % o mais ne devrait pas être interprété comme plus disponible')
|
||||
expected = "On dirait un spec str fmt % o mais ne devrait pas être interprété comme plus disponible"
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "Looks like a str fmt spec % o but should not be '
|
||||
'interpreted as such" %}'
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), expected)
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}Looks like a str fmt spec % o but should not be '
|
||||
'interpreted as such{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}Looks like a str fmt spec % o but should not be "
|
||||
"interpreted as such{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), expected)
|
||||
|
||||
def test_translates_multiple_percent_signs(self):
|
||||
expected = ('1 % signe pour cent, signes %% 2 pour cent, trois signes de pourcentage %%%')
|
||||
expected = "1 % signe pour cent, signes %% 2 pour cent, trois signes de pourcentage %%%"
|
||||
|
||||
trans_tpl = Template(
|
||||
'{% load i18n %}{% translate "1 percent sign %, 2 percent signs %%, '
|
||||
@@ -137,16 +164,16 @@ class RenderingTemplatesWithPercentSigns(FrenchTestCase):
|
||||
)
|
||||
self.assertEqual(trans_tpl.render(Context({})), expected)
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}1 percent sign %, 2 percent signs '
|
||||
'%%, 3 percent signs %%%{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}1 percent sign %, 2 percent signs "
|
||||
"%%, 3 percent signs %%%{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(block_tpl.render(Context({})), expected)
|
||||
|
||||
block_tpl = Template(
|
||||
'{% load i18n %}{% blocktranslate %}{{name}} says: 1 percent sign %, '
|
||||
'2 percent signs %%{% endblocktranslate %}'
|
||||
"{% load i18n %}{% blocktranslate %}{{name}} says: 1 percent sign %, "
|
||||
"2 percent signs %%{% endblocktranslate %}"
|
||||
)
|
||||
self.assertEqual(
|
||||
block_tpl.render(Context({"name": "Django"})),
|
||||
'Django dit: 1 pour cent signe %, deux signes de pourcentage %%'
|
||||
"Django dit: 1 pour cent signe %, deux signes de pourcentage %%",
|
||||
)
|
||||
|
||||
1931
tests/i18n/tests.py
1931
tests/i18n/tests.py
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
string1 = _('This is a translatable string.')
|
||||
string2 = _('This is another translatable string.')
|
||||
string1 = _("This is a translatable string.")
|
||||
string2 = _("This is another translatable string.")
|
||||
|
||||
@@ -4,6 +4,6 @@ from django.urls import path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
urlpatterns = i18n_patterns(
|
||||
path('simple/', lambda r: HttpResponse()),
|
||||
path('streaming/', lambda r: StreamingHttpResponse([_('Yes'), '/', _('No')])),
|
||||
path("simple/", lambda r: HttpResponse()),
|
||||
path("streaming/", lambda r: StreamingHttpResponse([_("Yes"), "/", _("No")])),
|
||||
)
|
||||
|
||||
@@ -4,8 +4,8 @@ from django.urls import path, re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
urlpatterns = i18n_patterns(
|
||||
re_path(r'^(?P<arg>[\w-]+)-page', lambda request, **arg: HttpResponse(_('Yes'))),
|
||||
path('simple/', lambda r: HttpResponse(_('Yes'))),
|
||||
re_path(r'^(.+)/(.+)/$', lambda *args: HttpResponse()),
|
||||
re_path(r"^(?P<arg>[\w-]+)-page", lambda request, **arg: HttpResponse(_("Yes"))),
|
||||
path("simple/", lambda r: HttpResponse(_("Yes"))),
|
||||
re_path(r"^(.+)/(.+)/$", lambda *args: HttpResponse()),
|
||||
prefix_default_language=False,
|
||||
)
|
||||
|
||||
@@ -7,25 +7,25 @@ source_code_dir = os.path.dirname(__file__)
|
||||
|
||||
|
||||
def copytree(src, dst):
|
||||
shutil.copytree(src, dst, ignore=shutil.ignore_patterns('__pycache__'))
|
||||
shutil.copytree(src, dst, ignore=shutil.ignore_patterns("__pycache__"))
|
||||
|
||||
|
||||
class POFileAssertionMixin:
|
||||
|
||||
def _assertPoKeyword(self, keyword, expected_value, haystack, use_quotes=True):
|
||||
q = '"'
|
||||
if use_quotes:
|
||||
expected_value = '"%s"' % expected_value
|
||||
q = "'"
|
||||
needle = '%s %s' % (keyword, expected_value)
|
||||
needle = "%s %s" % (keyword, expected_value)
|
||||
expected_value = re.escape(expected_value)
|
||||
return self.assertTrue(
|
||||
re.search('^%s %s' % (keyword, expected_value), haystack, re.MULTILINE),
|
||||
'Could not find %(q)s%(n)s%(q)s in generated PO file' % {'n': needle, 'q': q}
|
||||
re.search("^%s %s" % (keyword, expected_value), haystack, re.MULTILINE),
|
||||
"Could not find %(q)s%(n)s%(q)s in generated PO file"
|
||||
% {"n": needle, "q": q},
|
||||
)
|
||||
|
||||
def assertMsgId(self, msgid, haystack, use_quotes=True):
|
||||
return self._assertPoKeyword('msgid', msgid, haystack, use_quotes=use_quotes)
|
||||
return self._assertPoKeyword("msgid", msgid, haystack, use_quotes=use_quotes)
|
||||
|
||||
|
||||
class RunInTmpDirMixin:
|
||||
@@ -44,7 +44,7 @@ class RunInTmpDirMixin:
|
||||
|
||||
def setUp(self):
|
||||
self._cwd = os.getcwd()
|
||||
self.work_dir = tempfile.mkdtemp(prefix='i18n_')
|
||||
self.work_dir = tempfile.mkdtemp(prefix="i18n_")
|
||||
# Resolve symlinks, if any, in test directory paths.
|
||||
self.test_dir = os.path.realpath(os.path.join(self.work_dir, self.work_subdir))
|
||||
copytree(os.path.join(source_code_dir, self.work_subdir), self.test_dir)
|
||||
@@ -56,6 +56,9 @@ class RunInTmpDirMixin:
|
||||
os.chdir(self.test_dir)
|
||||
|
||||
def _rmrf(self, dname):
|
||||
if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir:
|
||||
if (
|
||||
os.path.commonprefix([self.test_dir, os.path.abspath(dname)])
|
||||
!= self.test_dir
|
||||
):
|
||||
return
|
||||
shutil.rmtree(dname)
|
||||
|
||||
Reference in New Issue
Block a user