rename test dir to tests; add SkipTest for test_extract.py
This commit is contained in:
4
i18n/tests/__init__.py
Normal file
4
i18n/tests/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from test_extract import TestExtract
|
||||
from test_generate import TestGenerate
|
||||
from test_converter import TestConverter
|
||||
from test_dummy import TestDummy
|
||||
42
i18n/tests/test_converter.py
Normal file
42
i18n/tests/test_converter.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
import converter
|
||||
|
||||
class UpcaseConverter (converter.Converter):
|
||||
"""
|
||||
Converts a string to uppercase. Just used for testing.
|
||||
"""
|
||||
def inner_convert_string(self, string):
|
||||
return string.upper()
|
||||
|
||||
|
||||
class TestConverter(TestCase):
|
||||
"""
|
||||
Tests functionality of i18n/converter.py
|
||||
"""
|
||||
|
||||
def test_converter(self):
|
||||
"""
|
||||
Tests with a simple converter (converts strings to uppercase).
|
||||
Assert that embedded HTML and python tags are not converted.
|
||||
"""
|
||||
c = UpcaseConverter()
|
||||
test_cases = (
|
||||
# no tags
|
||||
('big bad wolf', 'BIG BAD WOLF'),
|
||||
# one html tag
|
||||
('big <strong>bad</strong> wolf', 'BIG <strong>BAD</strong> WOLF'),
|
||||
# two html tags
|
||||
('big <b>bad</b> <i>wolf</i>', 'BIG <b>BAD</b> <i>WOLF</i>'),
|
||||
# one python tag
|
||||
('big %(adjective)s wolf', 'BIG %(adjective)s WOLF'),
|
||||
# two python tags
|
||||
('big %(adjective)s %(noun)s', 'BIG %(adjective)s %(noun)s'),
|
||||
# both kinds of tags
|
||||
('<strong>big</strong> %(adjective)s %(noun)s',
|
||||
'<strong>BIG</strong> %(adjective)s %(noun)s'),
|
||||
)
|
||||
for (source, expected) in test_cases:
|
||||
result = c.convert(source)
|
||||
self.assertEquals(result, expected)
|
||||
50
i18n/tests/test_dummy.py
Normal file
50
i18n/tests/test_dummy.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import os, string, random
|
||||
from unittest import TestCase
|
||||
from polib import POEntry
|
||||
|
||||
import dummy
|
||||
|
||||
|
||||
class TestDummy(TestCase):
|
||||
"""
|
||||
Tests functionality of i18n/dummy.py
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.converter = dummy.Dummy()
|
||||
|
||||
def test_dummy(self):
|
||||
"""
|
||||
Tests with a dummy converter (adds spurious accents to strings).
|
||||
Assert that embedded HTML and python tags are not converted.
|
||||
"""
|
||||
test_cases = (("hello my name is Bond, James Bond",
|
||||
u'h\xe9ll\xf6 my n\xe4m\xe9 \xefs B\xf6nd, J\xe4m\xe9s B\xf6nd Lorem i#'),
|
||||
|
||||
('don\'t convert <a href="href">tag ids</a>',
|
||||
u'd\xf6n\'t \xe7\xf6nv\xe9rt <a href="href">t\xe4g \xefds</a> Lorem ipsu#'),
|
||||
|
||||
('don\'t convert %(name)s tags on %(date)s',
|
||||
u"d\xf6n't \xe7\xf6nv\xe9rt %(name)s t\xe4gs \xf6n %(date)s Lorem ips#")
|
||||
)
|
||||
for (source, expected) in test_cases:
|
||||
result = self.converter.convert(source)
|
||||
self.assertEquals(result, expected)
|
||||
|
||||
def test_singular(self):
|
||||
entry = POEntry()
|
||||
entry.msgid = 'A lovely day for a cup of tea.'
|
||||
expected = u'\xc0 l\xf6v\xe9ly d\xe4y f\xf6r \xe4 \xe7\xfcp \xf6f t\xe9\xe4. Lorem i#'
|
||||
self.converter.convert_msg(entry)
|
||||
self.assertEquals(entry.msgstr, expected)
|
||||
|
||||
def test_plural(self):
|
||||
entry = POEntry()
|
||||
entry.msgid = 'A lovely day for a cup of tea.'
|
||||
entry.msgid_plural = 'A lovely day for some cups of tea.'
|
||||
expected_s = u'\xc0 l\xf6v\xe9ly d\xe4y f\xf6r \xe4 \xe7\xfcp \xf6f t\xe9\xe4. Lorem i#'
|
||||
expected_p = u'\xc0 l\xf6v\xe9ly d\xe4y f\xf6r s\xf6m\xe9 \xe7\xfcps \xf6f t\xe9\xe4. Lorem ip#'
|
||||
self.converter.convert_msg(entry)
|
||||
result = entry.msgstr_plural
|
||||
self.assertEquals(result['0'], expected_s)
|
||||
self.assertEquals(result['1'], expected_p)
|
||||
85
i18n/tests/test_extract.py
Normal file
85
i18n/tests/test_extract.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import os, polib
|
||||
from unittest import TestCase
|
||||
from nose.plugins.skip import SkipTest
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import extract
|
||||
from execute import SOURCE_MSGS_DIR
|
||||
|
||||
# Make sure setup runs only once
|
||||
SETUP_HAS_RUN = False
|
||||
|
||||
class TestExtract(TestCase):
|
||||
"""
|
||||
Tests functionality of i18n/extract.py
|
||||
"""
|
||||
generated_files = ('django-partial.po', 'djangojs.po', 'mako.po')
|
||||
|
||||
def setUp(self):
|
||||
# Skip this test because it takes too long (>1 minute)
|
||||
# TODO: figure out how to declare a "long-running" test suite
|
||||
# and add this test to it.
|
||||
raise SkipTest()
|
||||
|
||||
global SETUP_HAS_RUN
|
||||
|
||||
# Subtract 1 second to help comparisons with file-modify time succeed,
|
||||
# since os.path.getmtime() is not millisecond-accurate
|
||||
self.start_time = datetime.now() - timedelta(seconds=1)
|
||||
super(TestExtract, self).setUp()
|
||||
if not SETUP_HAS_RUN:
|
||||
# Run extraction script. Warning, this takes 1 minute or more
|
||||
extract.main()
|
||||
SETUP_HAS_RUN = True
|
||||
|
||||
def get_files (self):
|
||||
"""
|
||||
This is a generator.
|
||||
Returns the fully expanded filenames for all extracted files
|
||||
Fails assertion if one of the files doesn't exist.
|
||||
"""
|
||||
for filename in self.generated_files:
|
||||
path = os.path.join(SOURCE_MSGS_DIR, filename)
|
||||
exists = os.path.exists(path)
|
||||
self.assertTrue(exists, msg='Missing file: %s' % filename)
|
||||
if exists:
|
||||
yield path
|
||||
|
||||
def test_files(self):
|
||||
"""
|
||||
Asserts that each auto-generated file has been modified since 'extract' was launched.
|
||||
Intended to show that the file has been touched by 'extract'.
|
||||
"""
|
||||
|
||||
for path in self.get_files():
|
||||
self.assertTrue(datetime.fromtimestamp(os.path.getmtime(path)) > self.start_time,
|
||||
msg='File not recently modified: %s' % os.path.basename(path))
|
||||
|
||||
def test_is_keystring(self):
|
||||
"""
|
||||
Verifies is_keystring predicate
|
||||
"""
|
||||
entry1 = polib.POEntry()
|
||||
entry2 = polib.POEntry()
|
||||
entry1.msgid = "_.lms.admin.warning.keystring"
|
||||
entry2.msgid = "This is not a keystring"
|
||||
self.assertTrue(extract.is_key_string(entry1.msgid))
|
||||
self.assertFalse(extract.is_key_string(entry2.msgid))
|
||||
|
||||
def test_headers(self):
|
||||
"""Verify all headers have been modified"""
|
||||
for path in self.get_files():
|
||||
po = polib.pofile(path)
|
||||
header = po.header
|
||||
self.assertEqual(header.find('edX translation file'), 0,
|
||||
msg='Missing header in %s:\n"%s"' % \
|
||||
(os.path.basename(path), header))
|
||||
|
||||
def test_metadata(self):
|
||||
"""Verify all metadata has been modified"""
|
||||
for path in self.get_files():
|
||||
po = polib.pofile(path)
|
||||
metadata = po.metadata
|
||||
value = metadata['Report-Msgid-Bugs-To']
|
||||
expected = 'translation_team@edx.org'
|
||||
self.assertEquals(expected, value)
|
||||
61
i18n/tests/test_generate.py
Normal file
61
i18n/tests/test_generate.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import os, string, random
|
||||
from unittest import TestCase
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import generate
|
||||
from execute import get_config, messages_dir, SOURCE_MSGS_DIR, SOURCE_LOCALE
|
||||
|
||||
class TestGenerate(TestCase):
|
||||
"""
|
||||
Tests functionality of i18n/generate.py
|
||||
"""
|
||||
generated_files = ('django-partial.po', 'djangojs.po', 'mako.po')
|
||||
|
||||
def setUp(self):
|
||||
self.configuration = get_config()
|
||||
|
||||
# Subtract 1 second to help comparisons with file-modify time succeed,
|
||||
# since os.path.getmtime() is not millisecond-accurate
|
||||
self.start_time = datetime.now() - timedelta(seconds=1)
|
||||
|
||||
def test_configuration(self):
|
||||
"""
|
||||
Make sure we have a valid configuration file,
|
||||
and that it contains an 'en' locale.
|
||||
"""
|
||||
self.assertIsNotNone(self.configuration)
|
||||
locales = self.configuration['locales']
|
||||
self.assertIsNotNone(locales)
|
||||
self.assertIsInstance(locales, list)
|
||||
self.assertIn('en', locales)
|
||||
|
||||
def test_merge(self):
|
||||
"""
|
||||
Tests merge script on English source files.
|
||||
"""
|
||||
filename = os.path.join(SOURCE_MSGS_DIR, random_name())
|
||||
generate.merge(SOURCE_LOCALE, target=filename)
|
||||
self.assertTrue(os.path.exists(filename))
|
||||
os.remove(filename)
|
||||
|
||||
def test_main(self):
|
||||
"""
|
||||
Runs generate.main() which should merge source files,
|
||||
then compile all sources in all configured languages.
|
||||
Validates output by checking all .mo files in all configured languages.
|
||||
.mo files should exist, and be recently created (modified
|
||||
after start of test suite)
|
||||
"""
|
||||
generate.main()
|
||||
for locale in self.configuration['locales']:
|
||||
for filename in ('django.mo', 'djangojs.mo'):
|
||||
path = os.path.join(messages_dir(locale), filename)
|
||||
exists = os.path.exists(path)
|
||||
self.assertTrue(exists, msg='Missing file in locale %s: %s' % (locale, filename))
|
||||
self.assertTrue(datetime.fromtimestamp(os.path.getmtime(path)) >= self.start_time,
|
||||
msg='File not recently modified: %s' % path)
|
||||
|
||||
def random_name(size=6):
|
||||
"""Returns random filename as string, like test-4BZ81W"""
|
||||
chars = string.ascii_uppercase + string.digits
|
||||
return 'test-' + ''.join(random.choice(chars) for x in range(size))
|
||||
Reference in New Issue
Block a user