mirror of
https://github.com/django/django.git
synced 2025-04-12 03:22:21 +00:00
[1.10.x] Refs #26677 -- Simplified i18n test cleanups.
The fact that we aren't dealing with the Django source tree anymore allows us to drop several tearDown()/addCleanup() calls that were concerned with removing apiece files/dirs/symlinks created by test cases, as we are covered by the removal of the parent temporary tree anyways. Thanks Tim Graham for advice and review. Backport of bb7bb379e8cd91a91336946829519d64e919a1d2 from master
This commit is contained in:
parent
c1bd4679e8
commit
a079d5ceed
@ -3,9 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import gettext as gettext_module
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import tempfile
|
||||
import unittest
|
||||
from subprocess import Popen
|
||||
|
||||
@ -18,43 +16,20 @@ from django.core.management.utils import find_command
|
||||
from django.test import SimpleTestCase, mock, override_settings
|
||||
from django.test.utils import captured_stderr, captured_stdout
|
||||
from django.utils import six, translation
|
||||
from django.utils._os import upath
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six import StringIO
|
||||
from django.utils.translation import ugettext
|
||||
|
||||
from .utils import RunInTmpDirMixin, copytree
|
||||
|
||||
has_msgfmt = find_command('msgfmt')
|
||||
source_code_dir = os.path.dirname(upath(__file__))
|
||||
|
||||
|
||||
@unittest.skipUnless(has_msgfmt, 'msgfmt is mandatory for compilation tests')
|
||||
class MessageCompilationTests(SimpleTestCase):
|
||||
class MessageCompilationTests(RunInTmpDirMixin, SimpleTestCase):
|
||||
|
||||
work_subdir = 'commands'
|
||||
|
||||
def setUp(self):
|
||||
self._cwd = os.getcwd()
|
||||
self.work_dir = tempfile.mkdtemp(prefix='i18n_')
|
||||
self.test_dir = os.path.abspath(os.path.join(self.work_dir, self.work_subdir))
|
||||
shutil.copytree(os.path.join(source_code_dir, self.work_subdir), self.test_dir)
|
||||
# Make sure we step out of the temporary working tree before we
|
||||
# remove it as we might be pulling the rug from under our own feet
|
||||
# othewise. Rhis is especially true on Windows.
|
||||
# Remember cleanup actions registered with addCleanup() are called in
|
||||
# reverse so this ordering is important:
|
||||
self.addCleanup(self._rmrf, self.test_dir)
|
||||
self.addCleanup(os.chdir, self._cwd)
|
||||
os.chdir(self.test_dir)
|
||||
|
||||
def _rmrf(self, dname):
|
||||
if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir:
|
||||
return
|
||||
shutil.rmtree(dname)
|
||||
|
||||
def rmfile(self, filepath):
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
|
||||
|
||||
class PoFileTests(MessageCompilationTests):
|
||||
|
||||
@ -87,10 +62,6 @@ class PoFileContentsTests(MessageCompilationTests):
|
||||
LOCALE = 'fr'
|
||||
MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
|
||||
def setUp(self):
|
||||
super(PoFileContentsTests, self).setUp()
|
||||
self.addCleanup(os.unlink, os.path.join(self.test_dir, self.MO_FILE))
|
||||
|
||||
def test_percent_symbol_in_po_file(self):
|
||||
call_command('compilemessages', locale=[self.LOCALE], stdout=StringIO())
|
||||
self.assertTrue(os.path.exists(self.MO_FILE))
|
||||
@ -106,8 +77,6 @@ class MultipleLocaleCompilationTests(MessageCompilationTests):
|
||||
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')
|
||||
self.addCleanup(self.rmfile, os.path.join(localedir, self.MO_FILE_HR))
|
||||
self.addCleanup(self.rmfile, os.path.join(localedir, self.MO_FILE_FR))
|
||||
|
||||
def test_one_locale(self):
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
|
||||
@ -131,8 +100,7 @@ class ExcludedLocaleCompilationTests(MessageCompilationTests):
|
||||
|
||||
def setUp(self):
|
||||
super(ExcludedLocaleCompilationTests, self).setUp()
|
||||
shutil.copytree('canned_locale', 'locale')
|
||||
self.addCleanup(self._rmrf, os.path.join(self.test_dir, 'locale'))
|
||||
copytree('canned_locale', 'locale')
|
||||
|
||||
def test_command_help(self):
|
||||
with captured_stdout(), captured_stderr():
|
||||
@ -170,15 +138,11 @@ class ExcludedLocaleCompilationTests(MessageCompilationTests):
|
||||
class CompilationErrorHandling(MessageCompilationTests):
|
||||
def test_error_reported_by_msgfmt(self):
|
||||
# po file contains wrong po formatting.
|
||||
mo_file = 'locale/ja/LC_MESSAGES/django.mo'
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, mo_file))
|
||||
with self.assertRaises(CommandError):
|
||||
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).
|
||||
mo_file = 'locale/ko/LC_MESSAGES/django.mo'
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, mo_file))
|
||||
# Make sure the output of msgfmt is unaffected by the current locale.
|
||||
env = os.environ.copy()
|
||||
env.update({str('LANG'): str('C')})
|
||||
@ -202,11 +166,6 @@ class ProjectAndAppTests(MessageCompilationTests):
|
||||
PROJECT_MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
APP_MO_FILE = 'app_with_locale/locale/%s/LC_MESSAGES/django.mo' % LOCALE
|
||||
|
||||
def setUp(self):
|
||||
super(ProjectAndAppTests, self).setUp()
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, self.PROJECT_MO_FILE))
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, self.APP_MO_FILE))
|
||||
|
||||
|
||||
class FuzzyTranslationTest(ProjectAndAppTests):
|
||||
|
||||
|
@ -5,12 +5,10 @@ import io
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
import warnings
|
||||
from unittest import SkipTest, skipUnless
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import management
|
||||
from django.core.management import execute_from_command_line
|
||||
from django.core.management.base import CommandError
|
||||
@ -20,62 +18,23 @@ from django.core.management.utils import find_command
|
||||
from django.test import SimpleTestCase, mock, override_settings
|
||||
from django.test.utils import captured_stderr, captured_stdout
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six import StringIO
|
||||
from django.utils.translation import TranslatorCommentWarning
|
||||
|
||||
from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree
|
||||
|
||||
LOCALE = 'de'
|
||||
has_xgettext = find_command('xgettext')
|
||||
source_code_dir = os.path.dirname(upath(__file__))
|
||||
|
||||
|
||||
class POFileAssertionMixin(object):
|
||||
|
||||
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)
|
||||
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})
|
||||
|
||||
def assertMsgId(self, msgid, haystack, use_quotes=True):
|
||||
return self._assertPoKeyword('msgid', msgid, haystack, use_quotes=use_quotes)
|
||||
|
||||
|
||||
@skipUnless(has_xgettext, 'xgettext is mandatory for extraction tests')
|
||||
class ExtractorTests(POFileAssertionMixin, SimpleTestCase):
|
||||
class ExtractorTests(POFileAssertionMixin, RunInTmpDirMixin, SimpleTestCase):
|
||||
|
||||
work_subdir = 'commands'
|
||||
|
||||
PO_FILE = 'locale/%s/LC_MESSAGES/django.po' % LOCALE
|
||||
|
||||
def setUp(self):
|
||||
self.work_dir = tempfile.mkdtemp(prefix='i18n_')
|
||||
self.test_dir = os.path.abspath(os.path.join(self.work_dir, self.work_subdir))
|
||||
shutil.copytree(os.path.join(source_code_dir, self.work_subdir), self.test_dir)
|
||||
self._cwd = os.getcwd()
|
||||
|
||||
def _rmrf(self, dname):
|
||||
if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir:
|
||||
return
|
||||
shutil.rmtree(dname)
|
||||
|
||||
def rmfile(self, filepath):
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.test_dir)
|
||||
try:
|
||||
self._rmrf('locale/%s' % LOCALE)
|
||||
except OSError:
|
||||
pass
|
||||
os.chdir(self._cwd)
|
||||
|
||||
def _run_makemessages(self, **options):
|
||||
os.chdir(self.test_dir)
|
||||
out = StringIO()
|
||||
@ -177,7 +136,6 @@ class ExtractorTests(POFileAssertionMixin, SimpleTestCase):
|
||||
class BasicExtractorTests(ExtractorTests):
|
||||
|
||||
def test_comments_extractor(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with io.open(self.PO_FILE, 'r', encoding='utf-8') as fp:
|
||||
@ -211,7 +169,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
)
|
||||
|
||||
def test_special_char_extracted(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with io.open(self.PO_FILE, 'r', encoding='utf-8') as fp:
|
||||
@ -219,7 +176,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
self.assertMsgId("Non-breaking space\u00a0:", po_contents)
|
||||
|
||||
def test_blocktrans_trimmed(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -237,7 +193,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
self.assertTrue(MakeMessagesCommand.leave_locale_alone)
|
||||
|
||||
def test_extraction_error(self):
|
||||
os.chdir(self.test_dir)
|
||||
msg = (
|
||||
'Translation blocks must not include other block tags: blocktrans '
|
||||
'(file %s, line 3)' % os.path.join('templates', 'template_with_error.tpl')
|
||||
@ -248,9 +203,7 @@ class BasicExtractorTests(ExtractorTests):
|
||||
self.assertFalse(os.path.exists('./templates/template_with_error.tpl.py'))
|
||||
|
||||
def test_unicode_decode_error(self):
|
||||
os.chdir(self.test_dir)
|
||||
shutil.copyfile('./not_utf8.sample', './not_utf8.txt')
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'not_utf8.txt'))
|
||||
out = StringIO()
|
||||
management.call_command('makemessages', locale=[LOCALE], stdout=out)
|
||||
self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .",
|
||||
@ -265,9 +218,7 @@ class BasicExtractorTests(ExtractorTests):
|
||||
|
||||
def test_extraction_warning(self):
|
||||
"""test xgettext warning about multiple bare interpolation placeholders"""
|
||||
os.chdir(self.test_dir)
|
||||
shutil.copyfile('./code.sample', './code_sample.py')
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'code_sample.py'))
|
||||
out = StringIO()
|
||||
management.call_command('makemessages', locale=[LOCALE], stdout=out)
|
||||
self.assertIn("code_sample.py:4", force_text(out.getvalue()))
|
||||
@ -278,7 +229,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
{% trans %} and {% blocktrans %} template tags.
|
||||
Refs #14806.
|
||||
"""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -309,7 +259,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
self.assertMsgId("Translatable literal #8d %(a)s", po_contents)
|
||||
|
||||
def test_context_in_single_quotes(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -324,7 +273,6 @@ class BasicExtractorTests(ExtractorTests):
|
||||
|
||||
def test_template_comments(self):
|
||||
"""Template comment tags on the same line of other constructs (#19552)"""
|
||||
os.chdir(self.test_dir)
|
||||
# Test detection/end user reporting of old, incorrect templates
|
||||
# translator comments syntax
|
||||
with warnings.catch_warnings(record=True) as ws:
|
||||
@ -439,9 +387,7 @@ class BasicExtractorTests(ExtractorTests):
|
||||
def test_po_file_encoding_when_updating(self):
|
||||
"""Update of PO file doesn't corrupt it with non-UTF-8 encoding on Python3+Windows (#23271)"""
|
||||
BR_PO_BASE = 'locale/pt_BR/LC_MESSAGES/django'
|
||||
os.chdir(self.test_dir)
|
||||
shutil.copyfile(BR_PO_BASE + '.pristine', BR_PO_BASE + '.po')
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'locale', 'pt_BR', 'LC_MESSAGES', 'django.po'))
|
||||
management.call_command('makemessages', locale=['pt_BR'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(BR_PO_BASE + '.po'))
|
||||
with io.open(BR_PO_BASE + '.po', 'r', encoding='utf-8') as fp:
|
||||
@ -454,7 +400,6 @@ class JavascriptExtractorTests(ExtractorTests):
|
||||
PO_FILE = 'locale/%s/LC_MESSAGES/djangojs.po' % LOCALE
|
||||
|
||||
def test_javascript_literals(self):
|
||||
os.chdir(self.test_dir)
|
||||
_, po_contents = self._run_makemessages(domain='djangojs')
|
||||
self.assertMsgId('This literal should be included.', po_contents)
|
||||
self.assertMsgId('gettext_noop should, too.', po_contents)
|
||||
@ -529,15 +474,6 @@ class SymlinkExtractorTests(ExtractorTests):
|
||||
super(SymlinkExtractorTests, self).setUp()
|
||||
self.symlinked_dir = os.path.join(self.test_dir, 'templates_symlinked')
|
||||
|
||||
def tearDown(self):
|
||||
super(SymlinkExtractorTests, self).tearDown()
|
||||
os.chdir(self.test_dir)
|
||||
try:
|
||||
os.remove(self.symlinked_dir)
|
||||
except OSError:
|
||||
pass
|
||||
os.chdir(self._cwd)
|
||||
|
||||
def test_symlink(self):
|
||||
# On Python < 3.2 os.symlink() exists only on Unix
|
||||
if hasattr(os, 'symlink'):
|
||||
@ -568,17 +504,7 @@ class CopyPluralFormsExtractorTests(ExtractorTests):
|
||||
|
||||
PO_FILE_ES = 'locale/es/LC_MESSAGES/django.po'
|
||||
|
||||
def tearDown(self):
|
||||
super(CopyPluralFormsExtractorTests, self).tearDown()
|
||||
os.chdir(self.test_dir)
|
||||
try:
|
||||
self._rmrf('locale/es')
|
||||
except OSError:
|
||||
pass
|
||||
os.chdir(self._cwd)
|
||||
|
||||
def test_copy_plural_forms(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -587,7 +513,6 @@ class CopyPluralFormsExtractorTests(ExtractorTests):
|
||||
|
||||
def test_override_plural_forms(self):
|
||||
"""Ticket #20311."""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=['es'], extensions=['djtpl'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE_ES))
|
||||
with io.open(self.PO_FILE_ES, 'r', encoding='utf-8') as fp:
|
||||
@ -601,7 +526,6 @@ class CopyPluralFormsExtractorTests(ExtractorTests):
|
||||
found inside a {% trans %} tag and also in another file inside a
|
||||
{% blocktrans %} with a plural (#17375).
|
||||
"""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], extensions=['html', 'djtpl'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -614,7 +538,6 @@ class CopyPluralFormsExtractorTests(ExtractorTests):
|
||||
class NoWrapExtractorTests(ExtractorTests):
|
||||
|
||||
def test_no_wrap_enabled(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=True)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -626,7 +549,6 @@ class NoWrapExtractorTests(ExtractorTests):
|
||||
)
|
||||
|
||||
def test_no_wrap_disabled(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=False)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -643,14 +565,12 @@ class LocationCommentsTests(ExtractorTests):
|
||||
|
||||
def test_no_location_enabled(self):
|
||||
"""Behavior is correct if --no-location switch is specified. See #16903."""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=True)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
self.assertLocationCommentNotPresent(self.PO_FILE, None, 'test.html')
|
||||
|
||||
def test_no_location_disabled(self):
|
||||
"""Behavior is correct if --no-location switch isn't specified."""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=False)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
# #16903 -- Standard comment with source file relative path should be present
|
||||
@ -661,7 +581,6 @@ class LocationCommentsTests(ExtractorTests):
|
||||
Ensure no leaky paths in comments, e.g. #: path\to\file.html.py:123
|
||||
Refs #21209/#26341.
|
||||
"""
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||
with open(self.PO_FILE, 'r') as fp:
|
||||
@ -675,28 +594,16 @@ class KeepPotFileExtractorTests(ExtractorTests):
|
||||
|
||||
POT_FILE = 'locale/django.pot'
|
||||
|
||||
def tearDown(self):
|
||||
super(KeepPotFileExtractorTests, self).tearDown()
|
||||
os.chdir(self.test_dir)
|
||||
try:
|
||||
os.unlink(self.POT_FILE)
|
||||
except OSError:
|
||||
pass
|
||||
os.chdir(self._cwd)
|
||||
|
||||
def test_keep_pot_disabled_by_default(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
self.assertFalse(os.path.exists(self.POT_FILE))
|
||||
|
||||
def test_keep_pot_explicitly_disabled(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0,
|
||||
keep_pot=False)
|
||||
self.assertFalse(os.path.exists(self.POT_FILE))
|
||||
|
||||
def test_keep_pot_enabled(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0,
|
||||
keep_pot=True)
|
||||
self.assertTrue(os.path.exists(self.POT_FILE))
|
||||
@ -707,18 +614,7 @@ class MultipleLocaleExtractionTests(ExtractorTests):
|
||||
PO_FILE_DE = 'locale/de/LC_MESSAGES/django.po'
|
||||
LOCALES = ['pt', 'de', 'ch']
|
||||
|
||||
def tearDown(self):
|
||||
super(MultipleLocaleExtractionTests, self).tearDown()
|
||||
os.chdir(self.test_dir)
|
||||
for locale in self.LOCALES:
|
||||
try:
|
||||
self._rmrf('locale/%s' % locale)
|
||||
except OSError:
|
||||
pass
|
||||
os.chdir(self._cwd)
|
||||
|
||||
def test_multiple_locales(self):
|
||||
os.chdir(self.test_dir)
|
||||
management.call_command('makemessages', locale=['pt', 'de'], verbosity=0)
|
||||
self.assertTrue(os.path.exists(self.PO_FILE_PT))
|
||||
self.assertTrue(os.path.exists(self.PO_FILE_DE))
|
||||
@ -740,10 +636,8 @@ class ExcludedLocaleExtractionTests(ExtractorTests):
|
||||
|
||||
def setUp(self):
|
||||
super(ExcludedLocaleExtractionTests, self).setUp()
|
||||
os.chdir(self.test_dir) # ExtractorTests.tearDown() takes care of restoring.
|
||||
shutil.copytree('canned_locale', 'locale')
|
||||
copytree('canned_locale', 'locale')
|
||||
self._set_times_for_all_po_files()
|
||||
self.addCleanup(self._rmrf, os.path.join(self.test_dir, 'locale'))
|
||||
|
||||
def test_command_help(self):
|
||||
with captured_stdout(), captured_stderr():
|
||||
@ -783,7 +677,6 @@ class CustomLayoutExtractionTests(ExtractorTests):
|
||||
work_subdir = 'project_dir'
|
||||
|
||||
def test_no_locale_raises(self):
|
||||
os.chdir(self.test_dir)
|
||||
msg = "Unable to find a locale path to store translations for file"
|
||||
with self.assertRaisesMessage(management.CommandError, msg):
|
||||
management.call_command('makemessages', locale=LOCALE, verbosity=0)
|
||||
@ -795,10 +688,6 @@ class CustomLayoutExtractionTests(ExtractorTests):
|
||||
* translations outside of that app are in LOCALE_PATHS[0]
|
||||
"""
|
||||
with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'project_locale')]):
|
||||
os.chdir(self.test_dir)
|
||||
self.addCleanup(shutil.rmtree, os.path.join(settings.LOCALE_PATHS[0], LOCALE), True)
|
||||
self.addCleanup(shutil.rmtree, os.path.join(self.test_dir, 'app_with_locale', 'locale', LOCALE), True)
|
||||
|
||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0)
|
||||
project_de_locale = os.path.join(
|
||||
self.test_dir, 'project_locale', 'de', 'LC_MESSAGES', 'django.po')
|
||||
|
@ -9,7 +9,8 @@ from django.utils._os import upath
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import activate, get_language, trans_real
|
||||
|
||||
from .test_extraction import POFileAssertionMixin
|
||||
from .utils import POFileAssertionMixin
|
||||
|
||||
|
||||
SAMPLEPROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(upath(__file__))), 'sampleproject')
|
||||
SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, 'locale')
|
||||
|
67
tests/i18n/utils.py
Normal file
67
tests/i18n/utils.py
Normal file
@ -0,0 +1,67 @@
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from django.utils._os import upath
|
||||
|
||||
|
||||
source_code_dir = os.path.dirname(upath(__file__))
|
||||
|
||||
|
||||
def copytree(src, dst):
|
||||
shutil.copytree(src, dst, ignore=shutil.ignore_patterns('*.pyc', '__pycache__'))
|
||||
|
||||
|
||||
class POFileAssertionMixin(object):
|
||||
|
||||
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)
|
||||
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}
|
||||
)
|
||||
|
||||
def assertMsgId(self, msgid, haystack, use_quotes=True):
|
||||
return self._assertPoKeyword('msgid', msgid, haystack, use_quotes=use_quotes)
|
||||
|
||||
|
||||
class RunInTmpDirMixin(object):
|
||||
"""
|
||||
Allow i18n tests that need to generate .po/.mo files to run in an isolated
|
||||
temporary filesystem tree created by tempfile.mkdtemp() that contains a
|
||||
clean copy of the relevant test code.
|
||||
|
||||
Test classes using this mixin need to define a `work_subdir` attribute
|
||||
which designates the subdir under `tests/i18n/` that will be copied to the
|
||||
temporary tree from which its test cases will run.
|
||||
|
||||
The setUp() method sets the current working dir to the temporary tree.
|
||||
It'll be removed when cleaning up.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self._cwd = os.getcwd()
|
||||
self.work_dir = tempfile.mkdtemp(prefix='i18n_')
|
||||
self.test_dir = os.path.abspath(os.path.join(self.work_dir, self.work_subdir))
|
||||
copytree(os.path.join(source_code_dir, self.work_subdir), self.test_dir)
|
||||
# Step out of the temporary working tree before removing it to avoid
|
||||
# deletion problems on Windows. Cleanup actions registered with
|
||||
# addCleanup() are called in reverse so preserve this ordering.
|
||||
self.addCleanup(self._rmrf, self.test_dir)
|
||||
self.addCleanup(os.chdir, self._cwd)
|
||||
os.chdir(self.test_dir)
|
||||
|
||||
def _rmrf(self, dname):
|
||||
if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir:
|
||||
return
|
||||
shutil.rmtree(dname)
|
||||
|
||||
def rmfile(self, filepath):
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
Loading…
x
Reference in New Issue
Block a user