1# -*- coding: utf-8 -*- 2from __future__ import unicode_literals 3 4from parameterized import parameterized, param 5from operator import attrgetter 6import six 7import regex as re 8 9from dateparser.languages.loader import default_loader 10from tests import BaseTestCase 11 12 13class TestLoading(BaseTestCase): 14 def setUp(self): 15 super(TestLoading, self).setUp() 16 self.locale_generator = NotImplemented 17 18 @classmethod 19 def setUpClass(cls): 20 cls.data_loader = default_loader 21 cls.data_loader._loaded_locales = {} 22 cls.data_loader._loaded_languages = {} 23 24 @parameterized.expand([ 25 param(given_languages=['es', 'fr', 'en'], 26 given_locales=None, 27 given_region=None, 28 loaded_languages=['en', 'es', 'fr'], 29 loaded_locales=['en', 'es', 'fr'], 30 expected_locales=['es', 'fr', 'en']), 31 32 param(given_languages=None, 33 given_locales=['fr-BF', 'ar-SO', 'asa'], 34 given_region=None, 35 loaded_languages=['en', 'es', 'fr', 'ar', 'asa'], 36 loaded_locales=['en', 'es', 'fr', 'fr-BF', 'ar-SO', 'asa'], 37 expected_locales=['fr-BF', 'ar-SO', 'asa']), 38 39 param(given_languages=None, 40 given_locales=['nl-CW', 'so-KE', 'sr-Latn-XK', 'zgh'], 41 given_region=None, 42 loaded_languages=['en', 'es', 'fr', 'ar', 'asa', 43 'nl', 'so', 'sr-Latn', 'zgh'], 44 loaded_locales=['en', 'es', 'fr', 'fr-BF', 'ar-SO', 'asa', 45 'nl-CW', 'so-KE', 'sr-Latn-XK', 'zgh'], 46 expected_locales=['nl-CW', 'so-KE', 'sr-Latn-XK', 'zgh']), 47 48 param(given_languages=['pt', 'zh-Hant', 'zh-Hans'], 49 given_locales=None, 50 given_region='MO', 51 loaded_languages=['en', 'es', 'fr', 'ar', 'asa', 'nl', 'so', 52 'sr-Latn', 'zgh', 'pt', 'zh-Hant', 'zh-Hans'], 53 loaded_locales=['en', 'es', 'fr', 'fr-BF', 'ar-SO', 'asa', 54 'nl-CW', 'so-KE', 'sr-Latn-XK', 'zgh', 55 'pt-MO', 'zh-Hant-MO', 'zh-Hans-MO'], 56 expected_locales=['pt-MO', 'zh-Hant-MO', 'zh-Hans-MO']), 57 58 param(given_languages=['pt', 'he'], 59 given_locales=['ru-UA', 'ckb-IR', 'sq-XK'], 60 given_region='MO', 61 loaded_languages=['en', 'es', 'fr', 'ar', 'asa', 'nl', 'so', 62 'sr-Latn', 'zgh', 'pt', 'zh-Hant', 'zh-Hans', 63 'ru', 'ckb', 'sq'], 64 loaded_locales=['en', 'es', 'fr', 'fr-BF', 'ar-SO', 'asa', 'nl-CW', 65 'so-KE', 'sr-Latn-XK', 'zgh', 'pt-MO', 'zh-Hant-MO', 66 'zh-Hans-MO', 'ru-UA', 'ckb-IR', 'sq-XK'], 67 expected_locales=['ru-UA', 'ckb-IR', 'sq-XK']), 68 69 param(given_languages=['da', 'ja'], 70 given_locales=['shi-Latn', 'teo-KE', 'ewo', 'vun'], 71 given_region='AO', 72 loaded_languages=['en', 'es', 'fr', 'ar', 'asa', 'nl', 'so', 73 'sr-Latn', 'zgh', 'pt', 'zh-Hant', 'zh-Hans', 74 'ru', 'ckb', 'sq', 'shi-Latn', 'teo', 'ewo', 'vun'], 75 loaded_locales=['en', 'es', 'fr', 'fr-BF', 'ar-SO', 'asa', 'nl-CW', 76 'so-KE', 'sr-Latn-XK', 'zgh', 'pt-MO', 'zh-Hant-MO', 77 'zh-Hans-MO', 'ru-UA', 'ckb-IR', 'sq-XK', 'shi-Latn', 78 'teo-KE', 'ewo', 'vun'], 79 expected_locales=['shi-Latn', 'teo-KE', 'ewo', 'vun']), 80 ]) 81 def test_loading(self, given_languages, given_locales, given_region, 82 loaded_languages, loaded_locales, expected_locales): 83 self.load_data(languages=given_languages, locales=given_locales, region=given_region) 84 self.then_locales_are_yielded_in_order(expected_locales) 85 self.then_loaded_languages_are(loaded_languages) 86 self.then_loaded_locales_are(loaded_locales) 87 88 def load_data(self, languages, locales, region): 89 self.locale_generator = self.data_loader.get_locales( 90 languages=languages, locales=locales, region=region, use_given_order=True) 91 92 def then_loaded_languages_are(self, loaded_languages): 93 six.assertCountEqual(self, loaded_languages, self.data_loader._loaded_languages.keys()) 94 95 def then_loaded_locales_are(self, loaded_locales): 96 six.assertCountEqual(self, loaded_locales, self.data_loader._loaded_locales.keys()) 97 98 def then_locales_are_yielded_in_order(self, expected_locales): 99 self.assertEqual(list(map(attrgetter('shortname'), 100 list(self.locale_generator))), expected_locales) 101 102 103class TestLocaleDataLoader(BaseTestCase): 104 UNKNOWN_LANGUAGES_EXCEPTION_RE = re.compile("Unknown language\(s\): (.+)") 105 UNKNOWN_LOCALES_EXCEPTION_RE = re.compile("Unknown locale\(s\): (.+)") 106 107 def setUp(self): 108 super(TestLocaleDataLoader, self).setUp() 109 self.data_loader = default_loader 110 self.data_loader._loaded_languages = {} 111 self.data_loader._loaded_locales = {} 112 113 @parameterized.expand([ 114 param(given_locales=['es-MX', 'ar-EG', 'fr-DJ']), 115 param(given_locales=['pt-MO', 'ru-KZ', 'es-CU']), 116 param(given_locales=['zh-Hans-HK', 'en-VG', 'my']), 117 param(given_locales=['tl', 'nl-SX', 'de-BE']), 118 ]) 119 def test_loading_with_given_order(self, given_locales): 120 self.load_data(given_locales, use_given_order=True) 121 self.then_locales_are_yielded_in_order(given_locales) 122 123 @parameterized.expand([ 124 param(given_locales=['os-RU', 'ln-CF', 'ee-TG'], 125 expected_locales=['ee-TG', 'ln-CF', 'os-RU']), 126 param(given_locales=['khq', 'ff-CM'], 127 expected_locales=['ff-CM', 'khq']), 128 param(given_locales=['en-CC', 'fr-BE', 'ar-KW'], 129 expected_locales=['en-CC', 'ar-KW', 'fr-BE']), 130 ]) 131 def test_loading_without_given_order(self, given_locales, expected_locales): 132 self.load_data(given_locales, use_given_order=False) 133 self.then_locales_are_yielded_in_order(expected_locales) 134 135 @parameterized.expand([ 136 param(given_locales=['sw-KE', 'ru-UA', 'he']), 137 param(given_locales=['de-IT', 'ta-MY', 'pa-Arab']), 138 param(given_locales=['bn-IN', 'pt-ST', 'ko-KP', 'ta']), 139 param(given_locales=['fr-NE', 'ar-SY']), 140 ]) 141 def test_get_locale_map_with_given_order(self, given_locales): 142 self.given_locale_map(locales=given_locales, use_given_order=True) 143 self.then_locale_map_in_order(given_locales) 144 145 @parameterized.expand([ 146 param(given_locales=['en-FJ', 'pt-CV', 'fr-RW'], 147 expected_locales=['en-FJ', 'fr-RW', 'pt-CV']), 148 param(given_locales=['pt-AO', 'hi', 'zh-Hans-SG', 'vi'], 149 expected_locales=['zh-Hans-SG', 'hi', 'pt-AO', 'vi']), 150 param(given_locales=['gsw-FR', 'es-BZ', 'ca-IT', 'qu-EC'], 151 expected_locales=['es-BZ', 'qu-EC', 'ca-IT', 'gsw-FR']), 152 ]) 153 def test_get_locale_map_without_given_order(self, given_locales, expected_locales): 154 self.given_locale_map(locales=given_locales, use_given_order=False) 155 self.then_locale_map_in_order(expected_locales) 156 157 @parameterized.expand([ 158 param(given_languages=['es', 'ar-001', 'xx'], 159 unknown_languages=['ar-001', 'xx']), 160 param(given_languages=['sr-Latn', 'sq', 'ii-Latn'], 161 unknown_languages=['ii-Latn']), 162 param(given_languages=['vol', 'bc'], 163 unknown_languages=['vol', 'bc']), 164 ]) 165 def test_error_raised_for_unknown_languages(self, given_languages, unknown_languages): 166 self.given_locale_map(languages=given_languages) 167 self.then_error_for_unknown_languages_raised(unknown_languages) 168 169 @parameterized.expand([ 170 param(given_locales=['es-AB', 'ar-001', 'fr-DJ'], 171 unknown_locales=['es-AB', 'ar-001']), 172 param(given_locales=['ru-MD', 'my-MY', 'zz'], 173 unknown_locales=['my-MY', 'zz']), 174 param(given_locales=['nl-SX', 'be-BE', 'ca-FR'], 175 unknown_locales=['be-BE']), 176 ]) 177 def test_error_raised_for_unknown_locales(self, given_locales, unknown_locales): 178 self.given_locale_map(locales=given_locales) 179 self.then_error_for_unknown_locales_raised(unknown_locales) 180 181 @parameterized.expand([ 182 param(given_locales=['en-TK', 'en-TO', 'zh']), 183 param(given_locales=['es-PY', 'es-IC', 'ja', 'es-DO']), 184 param(given_locales=['ca-TA', 'ca', 'fr']), 185 ]) 186 def test_error_raised_for_conflicting_locales(self, given_locales): 187 self.given_locale_map(locales=given_locales) 188 self.then_error_was_raised( 189 ValueError, "Locales should not have same language and different region") 190 191 @parameterized.expand([ 192 param(given_locales=['en-TK', 'en-TO', 'zh']), 193 param(given_locales=['es-PY', 'es-IC', 'ja', 'es-DO']), 194 param(given_locales=['af-NA', 'da', 'af']), 195 ]) 196 def test_conflicting_locales_load_if_allow_conflicting_locales(self, given_locales): 197 self.load_data(given_locales, use_given_order=True, allow_conflicting_locales=True) 198 self.then_locales_are_yielded_in_order(given_locales) 199 200 def load_data(self, given_locales, use_given_order=False, allow_conflicting_locales=False): 201 self.locale_generator = self.data_loader.get_locales( 202 locales=given_locales, use_given_order=use_given_order, 203 allow_conflicting_locales=allow_conflicting_locales) 204 205 def given_locale_map(self, languages=None, locales=None, use_given_order=True): 206 try: 207 self.locale_map = self.data_loader.get_locale_map( 208 languages=languages, locales=locales, use_given_order=use_given_order) 209 except Exception as error: 210 self.error = error 211 212 def then_locales_are_yielded_in_order(self, expected_locales): 213 self.assertEqual(list(map(attrgetter('shortname'), 214 list(self.locale_generator))), expected_locales) 215 216 def then_locale_map_in_order(self, expected_locales): 217 self.assertEqual(list(self.locale_map.keys()), expected_locales) 218 219 def then_error_for_unknown_languages_raised(self, unknown_languages): 220 self.assertIsInstance(self.error, ValueError) 221 match = self.UNKNOWN_LANGUAGES_EXCEPTION_RE.match(str(self.error)) 222 self.assertTrue(match) 223 languages = match.group(1).split(", ") 224 six.assertCountEqual(self, languages, [repr(l) for l in unknown_languages]) 225 226 def then_error_for_unknown_locales_raised(self, unknown_locales): 227 self.assertIsInstance(self.error, ValueError) 228 match = self.UNKNOWN_LOCALES_EXCEPTION_RE.match(str(self.error)) 229 self.assertTrue(match) 230 locales = match.group(1).split(", ") 231 six.assertCountEqual(self, locales, [repr(l) for l in unknown_locales]) 232