diff options
Diffstat (limited to 'tests/test_locale.py')
| -rw-r--r-- | tests/test_locale.py | 459 |
1 files changed, 216 insertions, 243 deletions
diff --git a/tests/test_locale.py b/tests/test_locale.py index d24fdfb..eaeb8e1 100644 --- a/tests/test_locale.py +++ b/tests/test_locale.py @@ -1,244 +1,217 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -import os -import sys - - -# needed if @unittest.expectedFailure is used -try: - import unittest2 as unittest -except: - import unittest - -import nikola.nikola -import nikola.utils -from .base import LocaleSupportInTesting - -LocaleSupportInTesting.initialize_locales_for_testing('bilingual') -lang_11, loc_11 = LocaleSupportInTesting.langlocales['default'] -lang_22, loc_22 = LocaleSupportInTesting.langlocales['other'] - - -# these are candidates to hardcoded locales, using str() for py2x setlocale -loc_C = str('C') -loc_Cutf8 = str('C.utf8') - -if sys.platform != 'win32': - nikola.nikola.workaround_empty_LC_ALL_posix() - - -class TestHarcodedFallbacks(unittest.TestCase): - def test_hardcoded_fallbacks_work(self): - # keep in sync with nikola.valid_locale_fallback - if sys.platform == 'win32': - self.assertTrue(nikola.nikola.is_valid_locale(str('English'))) - self.assertTrue(nikola.nikola.is_valid_locale(str('C'))) - else: - # the 1st is desired in Travis, not a problem if fails in user host - self.assertTrue(nikola.nikola.is_valid_locale(str('en_US.utf8'))) - # this is supposed to be always valid, and we need an universal - # fallback. Failure is not a problem in user host if he / she - # sets a valid (in his host) locale_fallback. - self.assertTrue(nikola.nikola.is_valid_locale(str('C'))) - - -class TestConfigLocale(unittest.TestCase): - - def test_implicit_fallback(self): - locale_fallback = None - sanitized_fallback = nikola.nikola.valid_locale_fallback( - desired_locale=locale_fallback) - self.assertTrue(nikola.nikola.is_valid_locale(sanitized_fallback)) - - def test_explicit_good_fallback(self): - locale_fallback = loc_22 - sanitized_fallback = nikola.nikola.valid_locale_fallback( - desired_locale=locale_fallback) - self.assertEquals(sanitized_fallback, locale_fallback) - - def test_explicit_bad_fallback(self): - locale_fallback = str('xyz') - sanitized_fallback = nikola.nikola.valid_locale_fallback( - desired_locale=locale_fallback) - self.assertTrue(nikola.nikola.is_valid_locale(sanitized_fallback)) - - def test_explicit_good_default(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - loc_11, - {}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertEquals(fallback, locale_fallback) - self.assertEquals(default, locale_default) - - def test_explicit_bad_default(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - str('xyz'), - {}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertEquals(fallback, locale_fallback) - self.assertEquals(default, fallback) - - def test_extra_locales_deleted(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - None, - {'@z': loc_22}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertTrue('@z' not in locales) - - def test_explicit_good_locale_retained(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - loc_22, - {lang_11: loc_11}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertEquals(locales[lang_11], str(LOCALES[lang_11])) - - def test_explicit_bad_locale_replaced_with_fallback(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - loc_11, - {lang_11: str('xyz')}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertEquals(locales['en'], locale_fallback) - - def test_impicit_locale_when_default_locale_defined(self): - locale_fallback, locale_default, LOCALES, translations = ( - loc_11, - loc_22, - {}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - self.assertEquals(locales['en'], locale_default) - - def test_impicit_locale_when_default_locale_is_not_defined(self): - # legacy mode, compat v6.0.4 : guess locale from lang - locale_fallback, locale_default, LOCALES, translations = ( - loc_22, - None, - {}, - {lang_11: ''}, - ) - fallback, default, locales = nikola.nikola.sanitized_locales( - locale_fallback, - locale_default, - LOCALES, - translations) - if sys.platform == 'win32': - guess_locale_for_lang = nikola.nikola.guess_locale_from_lang_windows - else: - guess_locale_for_lang = nikola.nikola.guess_locale_from_lang_posix - - self.assertEquals(locales[lang_11], guess_locale_for_lang(lang_11)) - - -class TestCalendarRelated(unittest.TestCase): - def test_type_of_month_name(self): - """validate assumption calendar month name is of type str - - Yes, both in windows and linuxTravis, py 26, 27, 33 - """ - import calendar - if sys.version_info[0] == 3: # Python 3 - with calendar.different_locale(loc_11): - s = calendar.month_name[1] - else: # Python 2 - with calendar.TimeEncoding(loc_11): - s = calendar.month_name[1] - self.assertTrue(type(s) == str) - - -class TestLocaleBorg(unittest.TestCase): - def test_initial_lang(self): - lang_11, loc_11 = LocaleSupportInTesting.langlocales['default'] - lang_22, loc_22 = LocaleSupportInTesting.langlocales['other'] - - locales = {lang_11: loc_11, lang_22: loc_22} - initial_lang = lang_22 - nikola.utils.LocaleBorg.initialize(locales, initial_lang) - self.assertEquals(initial_lang, nikola.utils.LocaleBorg().current_lang) - - def test_remembers_last_lang(self): - lang_11, loc_11 = LocaleSupportInTesting.langlocales['default'] - lang_22, loc_22 = LocaleSupportInTesting.langlocales['other'] - - locales = {lang_11: loc_11, lang_22: loc_22} - initial_lang = lang_22 - nikola.utils.LocaleBorg.initialize(locales, initial_lang) - - nikola.utils.LocaleBorg().set_locale(lang_11) - self.assertTrue(nikola.utils.LocaleBorg().current_lang, lang_11) - - def test_services_ensure_initialization(self): - nikola.utils.LocaleBorg.reset() - self.assertRaises(Exception, nikola.utils.LocaleBorg) - - def test_services_reject_dumb_wrong_call(self): - lang_11, loc_11 = LocaleSupportInTesting.langlocales['default'] - nikola.utils.LocaleBorg.reset() - self.assertRaises(Exception, nikola.utils.LocaleBorg.set_locale, lang_11) - self.assertRaises(Exception, getattr, nikola.utils.LocaleBorg, 'current_lang') - - def test_set_locale_raises_on_invalid_lang(self): - lang_11, loc_11 = LocaleSupportInTesting.langlocales['default'] - lang_22, loc_22 = LocaleSupportInTesting.langlocales['other'] - - locales = {lang_11: loc_11, lang_22: loc_22} - initial_lang = lang_22 - nikola.utils.LocaleBorg.initialize(locales, initial_lang) - self.assertRaises(KeyError, nikola.utils.LocaleBorg().set_locale, '@z') - - -class TestTestPreconditions(unittest.TestCase): - """If this fails the other test in this module are mostly nonsense, and - probably same for tests of multilingual features. - - Failure probably means the OS support for the failing locale is not - instaled or environmet variables NIKOLA_LOCALE_DEFAULT or - NIKOLA_LOCALE_OTHER with bad values. - """ - def test_langlocale_default_availability(self): - msg = "META ERROR: The pair lang, locale : {0} {1} is invalid" - self.assertTrue(nikola.nikola.is_valid_locale(loc_11), msg.format(lang_11, loc_11)) +import datetime +import unittest.mock - def test_langlocale_other_availability(self): - msg = "META ERROR: The pair lang, locale : {0} {1} is invalid" - self.assertTrue(nikola.nikola.is_valid_locale(loc_22), msg.format(lang_22, loc_22)) +import dateutil +import pytest + +from nikola.nikola import LEGAL_VALUES +from nikola.utils import ( + LocaleBorg, + LocaleBorgUninitializedException, + TranslatableSetting, +) + +TESLA_BIRTHDAY = datetime.date(1856, 7, 10) +TESLA_BIRTHDAY_DT = datetime.datetime(1856, 7, 10, 12, 34, 56) +DT_EN_US = "July 10, 1856 at 12:34:56 PM UTC" +DT_PL = "10 lipca 1856 12:34:56 UTC" + + +@pytest.mark.parametrize("initial_lang", [None, ""]) +def test_initilalize_failure(initial_lang): + with pytest.raises(ValueError): + LocaleBorg.initialize({}, initial_lang) + + assert not LocaleBorg.initialized + + +@pytest.mark.parametrize("initial_lang", ["en", "pl"]) +def test_initialize(initial_lang): + LocaleBorg.initialize({}, initial_lang) + assert LocaleBorg.initialized + assert LocaleBorg().current_lang == initial_lang + + +def test_uninitialized_error(): + with pytest.raises(LocaleBorgUninitializedException): + LocaleBorg() + + +@pytest.mark.parametrize( + "locale, expected_current_lang", + [ + ("pl", "pl"), + pytest.param( + "xx", "xx", id="fake language" + ), # used to ensure any locale can be supported + ], +) +def test_set_locale(base_config, locale, expected_current_lang): + LocaleBorg().set_locale(locale) + assert LocaleBorg.initialized + assert LocaleBorg().current_lang == expected_current_lang + + +def test_set_locale_for_template(): + LocaleBorg.initialize({}, "en") + assert LocaleBorg().set_locale("xz") == "" # empty string for template ease of use + + +def test_format_date_webiso_basic(base_config): + with unittest.mock.patch("babel.dates.format_datetime") as m: + formatted_date = LocaleBorg().formatted_date("webiso", TESLA_BIRTHDAY_DT) + assert formatted_date == "1856-07-10T12:34:56" + m.assert_not_called() + + +@pytest.mark.parametrize("lang", ["en", "pl"]) +def test_format_date_basic(base_config, lang): + LocaleBorg.initialize({}, lang) + formatted_date = LocaleBorg().formatted_date( + "yyyy-MM-dd HH:mm:ss", TESLA_BIRTHDAY_DT + ) + assert formatted_date == "1856-07-10 12:34:56" + + +def test_format_date_long(base_config): + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT) == DT_EN_US + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, "en") == DT_EN_US + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, "pl") == DT_PL + LocaleBorg().set_locale("pl") + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT) == DT_PL + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, "en") == DT_EN_US + + +def test_format_date_timezone(base_config): + tesla_150_birthday_dtz = datetime.datetime( + 2006, 7, 10, 12, 34, 56, tzinfo=dateutil.tz.gettz("America/New_York") + ) + formatted_date = LocaleBorg().formatted_date("long", tesla_150_birthday_dtz) + assert formatted_date == "July 10, 2006 at 12:34:56 PM -0400" + + nodst = datetime.datetime( + 2006, 1, 10, 12, 34, 56, tzinfo=dateutil.tz.gettz("America/New_York") + ) + formatted_date = LocaleBorg().formatted_date("long", nodst) + assert formatted_date == "January 10, 2006 at 12:34:56 PM -0500" + + +@pytest.mark.parametrize( + "english_variant, expected_date", + [ + pytest.param("en_US", DT_EN_US, id="US"), + pytest.param("en_GB", "10 July 1856 at 12:34:56 UTC", id="GB"), + ], +) +def test_format_date_locale_variants(english_variant, expected_date): + LocaleBorg.initialize({"en": english_variant}, "en") + assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, "en") == expected_date + + +@pytest.mark.parametrize( + "lang, expected_string", [("en", "en July"), ("pl", "lipca pl")] +) +def test_format_date_translatablesetting(base_config, lang, expected_string): + df = TranslatableSetting( + "DATE_FORMAT", {"en": "'en' MMMM", "pl": "MMMM 'pl'"}, {"en": "", "pl": ""} + ) + assert LocaleBorg().formatted_date(df, TESLA_BIRTHDAY_DT, lang) == expected_string + + +@pytest.mark.parametrize( + "lang, expected_string", + [ + pytest.param(None, "Foo July Bar", id="default"), + pytest.param("pl", "Foo lipiec Bar", id="pl"), + ], +) +def test_format_date_in_string_month(base_config, lang, expected_string): + formatted_date = LocaleBorg().format_date_in_string( + "Foo {month} Bar", TESLA_BIRTHDAY, lang + ) + assert formatted_date == expected_string + + +@pytest.mark.parametrize( + "lang, expected_string", + [ + pytest.param(None, "Foo July 1856 Bar", id="default"), + pytest.param("pl", "Foo lipiec 1856 Bar", id="pl"), + ], +) +def test_format_date_in_string_month_year(base_config, lang, expected_string): + formatted_date = LocaleBorg().format_date_in_string( + "Foo {month_year} Bar", TESLA_BIRTHDAY, lang + ) + assert formatted_date == expected_string + + +@pytest.mark.parametrize( + "lang, expected_string", + [ + pytest.param(None, "Foo July 10, 1856 Bar", id="default"), + pytest.param("pl", "Foo 10 lipca 1856 Bar", id="pl"), + ], +) +def test_format_date_in_string_month_day_year(base_config, lang, expected_string): + formatted_date = LocaleBorg().format_date_in_string( + "Foo {month_day_year} Bar", TESLA_BIRTHDAY, lang + ) + assert formatted_date == expected_string + + +@pytest.mark.parametrize( + "lang, expected_string", + [ + pytest.param(None, "Foo 10 July 1856 Bar", id="default"), + pytest.param("pl", "Foo 10 lipca 1856 Bar", id="pl"), + ], +) +def test_format_date_in_string_month_day_year_gb(lang, expected_string): + LocaleBorg.initialize({"en": "en_GB"}, "en") + formatted_date = LocaleBorg().format_date_in_string( + "Foo {month_day_year} Bar", TESLA_BIRTHDAY, lang + ) + assert formatted_date == expected_string + + +@pytest.mark.parametrize( + "message, expected_string", + [ + ("Foo {month:'miesiąca' MMMM} Bar", "Foo miesiąca lipca Bar"), + ("Foo {month_year:MMMM yyyy} Bar", "Foo lipca 1856 Bar"), + ], +) +def test_format_date_in_string_customization(base_config, message, expected_string): + formatted_date = LocaleBorg().format_date_in_string(message, TESLA_BIRTHDAY, "pl") + assert formatted_date == expected_string + + +@pytest.mark.parametrize( + "lang, expected_format", + [("sr", "10. јул 1856. 12:34:56 UTC"), ("sr_latin", "10. jul 1856. 12:34:56 UTC")], +) +def test_locale_base(lang, expected_format): + LocaleBorg.initialize(LEGAL_VALUES["LOCALES_BASE"], "en") + formatted_date = LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, lang) + assert formatted_date == expected_format + + +@pytest.fixture(autouse=True) +def localeborg_reset(): + """ + Reset the LocaleBorg before and after every test. + """ + LocaleBorg.reset() + assert not LocaleBorg.initialized + try: + yield + finally: + LocaleBorg.reset() + assert not LocaleBorg.initialized + + +@pytest.fixture +def base_config(): + """A base config of LocaleBorg.""" + LocaleBorg.initialize({}, "en") |
