/tests/regressiontests/i18n/tests.py
Python | 897 lines | 720 code | 95 blank | 82 comment | 5 complexity | 956f4a9fa8c95f905309b46cda83fa4f MD5 | raw file
1# -*- encoding: utf-8 -*- 2import datetime 3import decimal 4import os 5import sys 6import pickle 7from threading import local 8 9from django.conf import settings 10from django.template import Template, Context 11from django.utils.formats import (get_format, date_format, time_format, 12 localize, localize_input, iter_format_modules, get_format_modules) 13from django.utils.importlib import import_module 14from django.utils.numberformat import format as nformat 15from django.utils.safestring import mark_safe, SafeString, SafeUnicode 16from django.utils.translation import (ugettext, ugettext_lazy, activate, 17 deactivate, gettext_lazy, pgettext, npgettext, to_locale, 18 get_language_info, get_language) 19from django.utils.unittest import TestCase 20 21 22from forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm 23from models import Company, TestModel 24 25from commands.tests import * 26 27from test_warnings import DeprecationWarningTests 28 29class TranslationTests(TestCase): 30 31 def test_lazy_objects(self): 32 """ 33 Format string interpolation should work with *_lazy objects. 34 """ 35 s = ugettext_lazy('Add %(name)s') 36 d = {'name': 'Ringo'} 37 self.assertEqual(u'Add Ringo', s % d) 38 activate('de') 39 try: 40 self.assertEqual(u'Ringo hinzuf\xfcgen', s % d) 41 activate('pl') 42 self.assertEqual(u'Dodaj Ringo', s % d) 43 finally: 44 deactivate() 45 46 # It should be possible to compare *_lazy objects. 47 s1 = ugettext_lazy('Add %(name)s') 48 self.assertEqual(True, s == s1) 49 s2 = gettext_lazy('Add %(name)s') 50 s3 = gettext_lazy('Add %(name)s') 51 self.assertEqual(True, s2 == s3) 52 self.assertEqual(True, s == s2) 53 s4 = ugettext_lazy('Some other string') 54 self.assertEqual(False, s == s4) 55 56 def test_lazy_pickle(self): 57 s1 = ugettext_lazy("test") 58 self.assertEqual(unicode(s1), "test") 59 s2 = pickle.loads(pickle.dumps(s1)) 60 self.assertEqual(unicode(s2), "test") 61 62 def test_pgettext(self): 63 # Reset translation catalog to include other/locale/de 64 self.old_locale_paths = settings.LOCALE_PATHS 65 settings.LOCALE_PATHS += (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),) 66 from django.utils.translation import trans_real 67 trans_real._active = local() 68 trans_real._translations = {} 69 activate('de') 70 71 self.assertEqual(pgettext("unexisting", "May"), u"May") 72 self.assertEqual(pgettext("month name", "May"), u"Mai") 73 self.assertEqual(pgettext("verb", "May"), u"Kann") 74 self.assertEqual(npgettext("search", "%d result", "%d results", 4) % 4, u"4 Resultate") 75 76 settings.LOCALE_PATHS = self.old_locale_paths 77 78 def test_string_concat(self): 79 """ 80 unicode(string_concat(...)) should not raise a TypeError - #4796 81 """ 82 import django.utils.translation 83 self.assertEqual(u'django', unicode(django.utils.translation.string_concat("dja", "ngo"))) 84 85 def test_safe_status(self): 86 """ 87 Translating a string requiring no auto-escaping shouldn't change the "safe" status. 88 """ 89 s = mark_safe('Password') 90 self.assertEqual(SafeString, type(s)) 91 activate('de') 92 try: 93 self.assertEqual(SafeUnicode, type(ugettext(s))) 94 finally: 95 deactivate() 96 self.assertEqual('aPassword', SafeString('a') + s) 97 self.assertEqual('Passworda', s + SafeString('a')) 98 self.assertEqual('Passworda', s + mark_safe('a')) 99 self.assertEqual('aPassword', mark_safe('a') + s) 100 self.assertEqual('as', mark_safe('a') + mark_safe('s')) 101 102 def test_maclines(self): 103 """ 104 Translations on files with mac or dos end of lines will be converted 105 to unix eof in .po catalogs, and they have to match when retrieved 106 """ 107 from django.utils.translation.trans_real import translation 108 ca_translation = translation('ca') 109 ca_translation._catalog[u'Mac\nEOF\n'] = u'Catalan Mac\nEOF\n' 110 ca_translation._catalog[u'Win\nEOF\n'] = u'Catalan Win\nEOF\n' 111 activate('ca') 112 try: 113 self.assertEqual(u'Catalan Mac\nEOF\n', ugettext(u'Mac\rEOF\r')) 114 self.assertEqual(u'Catalan Win\nEOF\n', ugettext(u'Win\r\nEOF\r\n')) 115 finally: 116 deactivate() 117 118 def test_to_locale(self): 119 """ 120 Tests the to_locale function and the special case of Serbian Latin 121 (refs #12230 and r11299) 122 """ 123 self.assertEqual(to_locale('en-us'), 'en_US') 124 self.assertEqual(to_locale('sr-lat'), 'sr_Lat') 125 126 def test_to_language(self): 127 """ 128 Test the to_language function 129 """ 130 from django.utils.translation.trans_real import to_language 131 self.assertEqual(to_language('en_US'), 'en-us') 132 self.assertEqual(to_language('sr_Lat'), 'sr-lat') 133 134 135class FormattingTests(TestCase): 136 137 def setUp(self): 138 self.use_i18n = settings.USE_I18N 139 self.use_l10n = settings.USE_L10N 140 self.use_thousand_separator = settings.USE_THOUSAND_SEPARATOR 141 self.thousand_separator = settings.THOUSAND_SEPARATOR 142 self.number_grouping = settings.NUMBER_GROUPING 143 self.n = decimal.Decimal('66666.666') 144 self.f = 99999.999 145 self.d = datetime.date(2009, 12, 31) 146 self.dt = datetime.datetime(2009, 12, 31, 20, 50) 147 self.t = datetime.time(10, 15, 48) 148 self.l = 10000L 149 self.ctxt = Context({ 150 'n': self.n, 151 't': self.t, 152 'd': self.d, 153 'dt': self.dt, 154 'f': self.f, 155 'l': self.l, 156 }) 157 158 def tearDown(self): 159 # Restore defaults 160 settings.USE_I18N = self.use_i18n 161 settings.USE_L10N = self.use_l10n 162 settings.USE_THOUSAND_SEPARATOR = self.use_thousand_separator 163 settings.THOUSAND_SEPARATOR = self.thousand_separator 164 settings.NUMBER_GROUPING = self.number_grouping 165 166 def test_locale_independent(self): 167 """ 168 Localization of numbers 169 """ 170 settings.USE_L10N = True 171 settings.USE_THOUSAND_SEPARATOR = False 172 self.assertEqual(u'66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) 173 self.assertEqual(u'66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) 174 175 settings.USE_THOUSAND_SEPARATOR = True 176 self.assertEqual(u'66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) 177 self.assertEqual(u'6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) 178 self.assertEqual(u'-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) 179 self.assertEqual(u'-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1)) 180 self.assertEqual(u'10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1)) 181 182 # date filter 183 self.assertEqual(u'31.12.2009 ? 20:50', Template('{{ dt|date:"d.m.Y ? H:i" }}').render(self.ctxt)) 184 self.assertEqual(u'? 10:15', Template('{{ t|time:"? H:i" }}').render(self.ctxt)) 185 186 def test_l10n_disabled(self): 187 """ 188 Catalan locale with format i18n disabled translations will be used, 189 but not formats 190 """ 191 settings.USE_L10N = False 192 activate('ca') 193 try: 194 self.assertEqual(u'N j, Y', get_format('DATE_FORMAT')) 195 self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) 196 self.assertEqual(u'.', get_format('DECIMAL_SEPARATOR')) 197 self.assertEqual(u'10:15 a.m.', time_format(self.t)) 198 self.assertEqual(u'des. 31, 2009', date_format(self.d)) 199 self.assertEqual(u'desembre 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) 200 self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) 201 self.assertEqual(u'No localizable', localize('No localizable')) 202 self.assertEqual(u'66666.666', localize(self.n)) 203 self.assertEqual(u'99999.999', localize(self.f)) 204 self.assertEqual(u'10000', localize(self.l)) 205 self.assertEqual(u'des. 31, 2009', localize(self.d)) 206 self.assertEqual(u'des. 31, 2009, 8:50 p.m.', localize(self.dt)) 207 self.assertEqual(u'66666.666', Template('{{ n }}').render(self.ctxt)) 208 self.assertEqual(u'99999.999', Template('{{ f }}').render(self.ctxt)) 209 self.assertEqual(u'des. 31, 2009', Template('{{ d }}').render(self.ctxt)) 210 self.assertEqual(u'des. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt)) 211 self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) 212 self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) 213 self.assertEqual(u'10:15 a.m.', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)) 214 self.assertEqual(u'12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) 215 self.assertEqual(u'12/31/2009 8:50 p.m.', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) 216 217 form = I18nForm({ 218 'decimal_field': u'66666,666', 219 'float_field': u'99999,999', 220 'date_field': u'31/12/2009', 221 'datetime_field': u'31/12/2009 20:50', 222 'time_field': u'20:50', 223 'integer_field': u'1.234', 224 }) 225 self.assertEqual(False, form.is_valid()) 226 self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['float_field']) 227 self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['decimal_field']) 228 self.assertEqual([u'Introdu\xefu una data v\xe0lida.'], form.errors['date_field']) 229 self.assertEqual([u'Introdu\xefu una data/hora v\xe0lides.'], form.errors['datetime_field']) 230 self.assertEqual([u'Introdu\xefu un n\xfamero sencer.'], form.errors['integer_field']) 231 232 form2 = SelectDateForm({ 233 'date_field_month': u'12', 234 'date_field_day': u'31', 235 'date_field_year': u'2009' 236 }) 237 self.assertEqual(True, form2.is_valid()) 238 self.assertEqual(datetime.date(2009, 12, 31), form2.cleaned_data['date_field']) 239 self.assertEqual( 240 u'<select name="mydate_month" id="id_mydate_month">\n<option value="1">gener</option>\n<option value="2">febrer</option>\n<option value="3">mar\xe7</option>\n<option value="4">abril</option>\n<option value="5">maig</option>\n<option value="6">juny</option>\n<option value="7">juliol</option>\n<option value="8">agost</option>\n<option value="9">setembre</option>\n<option value="10">octubre</option>\n<option value="11">novembre</option>\n<option value="12" selected="selected">desembre</option>\n</select>\n<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', 241 SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) 242 ) 243 244 # We shouldn't change the behavior of the floatformat filter re: 245 # thousand separator and grouping when USE_L10N is False even 246 # if the USE_THOUSAND_SEPARATOR, NUMBER_GROUPING and 247 # THOUSAND_SEPARATOR settings are specified 248 settings.USE_THOUSAND_SEPARATOR = True 249 settings.NUMBER_GROUPING = 1 250 settings.THOUSAND_SEPARATOR = '!' 251 self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) 252 self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) 253 finally: 254 deactivate() 255 256 def test_l10n_enabled(self): 257 settings.USE_L10N = True 258 # Catalan locale 259 activate('ca') 260 try: 261 self.assertEqual('j \de F \de Y', get_format('DATE_FORMAT')) 262 self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK')) 263 self.assertEqual(',', get_format('DECIMAL_SEPARATOR')) 264 self.assertEqual(u'10:15:48', time_format(self.t)) 265 self.assertEqual(u'31 de desembre de 2009', date_format(self.d)) 266 self.assertEqual(u'desembre del 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) 267 self.assertEqual(u'31/12/2009 20:50', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) 268 self.assertEqual('No localizable', localize('No localizable')) 269 270 settings.USE_THOUSAND_SEPARATOR = True 271 self.assertEqual(u'66.666,666', localize(self.n)) 272 self.assertEqual(u'99.999,999', localize(self.f)) 273 self.assertEqual(u'10.000', localize(self.l)) 274 self.assertEqual(u'True', localize(True)) 275 276 settings.USE_THOUSAND_SEPARATOR = False 277 self.assertEqual(u'66666,666', localize(self.n)) 278 self.assertEqual(u'99999,999', localize(self.f)) 279 self.assertEqual(u'10000', localize(self.l)) 280 self.assertEqual(u'31 de desembre de 2009', localize(self.d)) 281 self.assertEqual(u'31 de desembre de 2009 a les 20:50', localize(self.dt)) 282 283 settings.USE_THOUSAND_SEPARATOR = True 284 self.assertEqual(u'66.666,666', Template('{{ n }}').render(self.ctxt)) 285 self.assertEqual(u'99.999,999', Template('{{ f }}').render(self.ctxt)) 286 self.assertEqual(u'10.000', Template('{{ l }}').render(self.ctxt)) 287 288 form3 = I18nForm({ 289 'decimal_field': u'66.666,666', 290 'float_field': u'99.999,999', 291 'date_field': u'31/12/2009', 292 'datetime_field': u'31/12/2009 20:50', 293 'time_field': u'20:50', 294 'integer_field': u'1.234', 295 }) 296 self.assertEqual(True, form3.is_valid()) 297 self.assertEqual(decimal.Decimal('66666.666'), form3.cleaned_data['decimal_field']) 298 self.assertEqual(99999.999, form3.cleaned_data['float_field']) 299 self.assertEqual(datetime.date(2009, 12, 31), form3.cleaned_data['date_field']) 300 self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form3.cleaned_data['datetime_field']) 301 self.assertEqual(datetime.time(20, 50), form3.cleaned_data['time_field']) 302 self.assertEqual(1234, form3.cleaned_data['integer_field']) 303 304 settings.USE_THOUSAND_SEPARATOR = False 305 self.assertEqual(u'66666,666', Template('{{ n }}').render(self.ctxt)) 306 self.assertEqual(u'99999,999', Template('{{ f }}').render(self.ctxt)) 307 self.assertEqual(u'31 de desembre de 2009', Template('{{ d }}').render(self.ctxt)) 308 self.assertEqual(u'31 de desembre de 2009 a les 20:50', Template('{{ dt }}').render(self.ctxt)) 309 self.assertEqual(u'66666,67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) 310 self.assertEqual(u'100000,0', Template('{{ f|floatformat }}').render(self.ctxt)) 311 self.assertEqual(u'10:15:48', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)) 312 self.assertEqual(u'31/12/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) 313 self.assertEqual(u'31/12/2009 20:50', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) 314 315 form4 = I18nForm({ 316 'decimal_field': u'66666,666', 317 'float_field': u'99999,999', 318 'date_field': u'31/12/2009', 319 'datetime_field': u'31/12/2009 20:50', 320 'time_field': u'20:50', 321 'integer_field': u'1234', 322 }) 323 self.assertEqual(True, form4.is_valid()) 324 self.assertEqual(decimal.Decimal('66666.666'), form4.cleaned_data['decimal_field']) 325 self.assertEqual(99999.999, form4.cleaned_data['float_field']) 326 self.assertEqual(datetime.date(2009, 12, 31), form4.cleaned_data['date_field']) 327 self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form4.cleaned_data['datetime_field']) 328 self.assertEqual(datetime.time(20, 50), form4.cleaned_data['time_field']) 329 self.assertEqual(1234, form4.cleaned_data['integer_field']) 330 331 form5 = SelectDateForm({ 332 'date_field_month': u'12', 333 'date_field_day': u'31', 334 'date_field_year': u'2009' 335 }) 336 self.assertEqual(True, form5.is_valid()) 337 self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field']) 338 self.assertEqual( 339 u'<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_month" id="id_mydate_month">\n<option value="1">gener</option>\n<option value="2">febrer</option>\n<option value="3">mar\xe7</option>\n<option value="4">abril</option>\n<option value="5">maig</option>\n<option value="6">juny</option>\n<option value="7">juliol</option>\n<option value="8">agost</option>\n<option value="9">setembre</option>\n<option value="10">octubre</option>\n<option value="11">novembre</option>\n<option value="12" selected="selected">desembre</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', 340 SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) 341 ) 342 finally: 343 deactivate() 344 345 # Russian locale (with E as month) 346 activate('ru') 347 try: 348 self.assertEqual( 349 u'<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_month" id="id_mydate_month">\n<option value="1">\u042f\u043d\u0432\u0430\u0440\u044c</option>\n<option value="2">\u0424\u0435\u0432\u0440\u0430\u043b\u044c</option>\n<option value="3">\u041c\u0430\u0440\u0442</option>\n<option value="4">\u0410\u043f\u0440\u0435\u043b\u044c</option>\n<option value="5">\u041c\u0430\u0439</option>\n<option value="6">\u0418\u044e\u043d\u044c</option>\n<option value="7">\u0418\u044e\u043b\u044c</option>\n<option value="8">\u0410\u0432\u0433\u0443\u0441\u0442</option>\n<option value="9">\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c</option>\n<option value="10">\u041e\u043a\u0442\u044f\u0431\u0440\u044c</option>\n<option value="11">\u041d\u043e\u044f\u0431\u0440\u044c</option>\n<option value="12" selected="selected">\u0414\u0435\u043a\u0430\u0431\u0440\u044c</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', 350 SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) 351 ) 352 finally: 353 deactivate() 354 355 # English locale 356 activate('en') 357 try: 358 self.assertEqual('N j, Y', get_format('DATE_FORMAT')) 359 self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) 360 self.assertEqual('.', get_format('DECIMAL_SEPARATOR')) 361 self.assertEqual(u'Dec. 31, 2009', date_format(self.d)) 362 self.assertEqual(u'December 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) 363 self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) 364 self.assertEqual(u'No localizable', localize('No localizable')) 365 366 settings.USE_THOUSAND_SEPARATOR = True 367 self.assertEqual(u'66,666.666', localize(self.n)) 368 self.assertEqual(u'99,999.999', localize(self.f)) 369 self.assertEqual(u'10,000', localize(self.l)) 370 371 settings.USE_THOUSAND_SEPARATOR = False 372 self.assertEqual(u'66666.666', localize(self.n)) 373 self.assertEqual(u'99999.999', localize(self.f)) 374 self.assertEqual(u'10000', localize(self.l)) 375 self.assertEqual(u'Dec. 31, 2009', localize(self.d)) 376 self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', localize(self.dt)) 377 378 settings.USE_THOUSAND_SEPARATOR = True 379 self.assertEqual(u'66,666.666', Template('{{ n }}').render(self.ctxt)) 380 self.assertEqual(u'99,999.999', Template('{{ f }}').render(self.ctxt)) 381 self.assertEqual(u'10,000', Template('{{ l }}').render(self.ctxt)) 382 383 settings.USE_THOUSAND_SEPARATOR = False 384 self.assertEqual(u'66666.666', Template('{{ n }}').render(self.ctxt)) 385 self.assertEqual(u'99999.999', Template('{{ f }}').render(self.ctxt)) 386 self.assertEqual(u'Dec. 31, 2009', Template('{{ d }}').render(self.ctxt)) 387 self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt)) 388 self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) 389 self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) 390 self.assertEqual(u'12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) 391 self.assertEqual(u'12/31/2009 8:50 p.m.', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) 392 393 form5 = I18nForm({ 394 'decimal_field': u'66666.666', 395 'float_field': u'99999.999', 396 'date_field': u'12/31/2009', 397 'datetime_field': u'12/31/2009 20:50', 398 'time_field': u'20:50', 399 'integer_field': u'1234', 400 }) 401 self.assertEqual(True, form5.is_valid()) 402 self.assertEqual(decimal.Decimal('66666.666'), form5.cleaned_data['decimal_field']) 403 self.assertEqual(99999.999, form5.cleaned_data['float_field']) 404 self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field']) 405 self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form5.cleaned_data['datetime_field']) 406 self.assertEqual(datetime.time(20, 50), form5.cleaned_data['time_field']) 407 self.assertEqual(1234, form5.cleaned_data['integer_field']) 408 409 form6 = SelectDateForm({ 410 'date_field_month': u'12', 411 'date_field_day': u'31', 412 'date_field_year': u'2009' 413 }) 414 self.assertEqual(True, form6.is_valid()) 415 self.assertEqual(datetime.date(2009, 12, 31), form6.cleaned_data['date_field']) 416 self.assertEqual( 417 u'<select name="mydate_month" id="id_mydate_month">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12" selected="selected">December</option>\n</select>\n<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', 418 SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) 419 ) 420 finally: 421 deactivate() 422 423 def test_sub_locales(self): 424 """ 425 Check if sublocales fall back to the main locale 426 """ 427 settings.USE_L10N = True 428 activate('de-at') 429 settings.USE_THOUSAND_SEPARATOR = True 430 try: 431 self.assertEqual(u'66.666,666', Template('{{ n }}').render(self.ctxt)) 432 finally: 433 deactivate() 434 435 activate('es-us') 436 try: 437 self.assertEqual(u'31 de diciembre de 2009', date_format(self.d)) 438 finally: 439 deactivate() 440 441 def test_localized_input(self): 442 """ 443 Tests if form input is correctly localized 444 """ 445 settings.USE_L10N = True 446 activate('de-at') 447 try: 448 form6 = CompanyForm({ 449 'name': u'acme', 450 'date_added': datetime.datetime(2009, 12, 31, 6, 0, 0), 451 'cents_payed': decimal.Decimal('59.47'), 452 'products_delivered': 12000, 453 }) 454 self.assertEqual(True, form6.is_valid()) 455 self.assertEqual( 456 form6.as_ul(), 457 u'<li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" value="acme" maxlength="50" /></li>\n<li><label for="id_date_added">Date added:</label> <input type="text" name="date_added" value="31.12.2009 06:00:00" id="id_date_added" /></li>\n<li><label for="id_cents_payed">Cents payed:</label> <input type="text" name="cents_payed" value="59,47" id="id_cents_payed" /></li>\n<li><label for="id_products_delivered">Products delivered:</label> <input type="text" name="products_delivered" value="12000" id="id_products_delivered" /></li>' 458 ) 459 self.assertEqual(localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)), '31.12.2009 06:00:00') 460 self.assertEqual(datetime.datetime(2009, 12, 31, 6, 0, 0), form6.cleaned_data['date_added']) 461 settings.USE_THOUSAND_SEPARATOR = True 462 # Checking for the localized "products_delivered" field 463 self.assertTrue(u'<input type="text" name="products_delivered" value="12.000" id="id_products_delivered" />' in form6.as_ul()) 464 finally: 465 deactivate() 466 467 def test_iter_format_modules(self): 468 """ 469 Tests the iter_format_modules function. 470 """ 471 activate('de-at') 472 old_format_module_path = settings.FORMAT_MODULE_PATH 473 try: 474 settings.USE_L10N = True 475 de_format_mod = import_module('django.conf.locale.de.formats') 476 self.assertEqual(list(iter_format_modules('de')), [de_format_mod]) 477 settings.FORMAT_MODULE_PATH = 'regressiontests.i18n.other.locale' 478 test_de_format_mod = import_module('regressiontests.i18n.other.locale.de.formats') 479 self.assertEqual(list(iter_format_modules('de')), [test_de_format_mod, de_format_mod]) 480 finally: 481 settings.FORMAT_MODULE_PATH = old_format_module_path 482 deactivate() 483 484 def test_iter_format_modules_stability(self): 485 """ 486 Tests the iter_format_modules function always yields format modules in 487 a stable and correct order in presence of both base ll and ll_CC formats. 488 """ 489 settings.USE_L10N = True 490 en_format_mod = import_module('django.conf.locale.en.formats') 491 en_gb_format_mod = import_module('django.conf.locale.en_GB.formats') 492 self.assertEqual(list(iter_format_modules('en-gb')), [en_gb_format_mod, en_format_mod]) 493 494 def test_get_format_modules_stability(self): 495 activate('de') 496 old_format_module_path = settings.FORMAT_MODULE_PATH 497 settings.FORMAT_MODULE_PATH = 'regressiontests.i18n.other.locale' 498 try: 499 settings.USE_L10N = True 500 old = "%r" % get_format_modules(reverse=True) 501 new = "%r" % get_format_modules(reverse=True) # second try 502 self.assertEqual(new, old, 'Value returned by get_formats_modules() must be preserved between calls.') 503 finally: 504 settings.FORMAT_MODULE_PATH = old_format_module_path 505 deactivate() 506 507 def test_localize_templatetag_and_filter(self): 508 """ 509 Tests the {% localize %} templatetag 510 """ 511 context = Context({'value': 3.14 }) 512 template1 = Template("{% load l10n %}{% localize %}{{ value }}{% endlocalize %};{% localize on %}{{ value }}{% endlocalize %}") 513 template2 = Template("{% load l10n %}{{ value }};{% localize off %}{{ value }};{% endlocalize %}{{ value }}") 514 template3 = Template('{% load l10n %}{{ value }};{{ value|unlocalize }}') 515 template4 = Template('{% load l10n %}{{ value }};{{ value|localize }}') 516 output1 = '3,14;3,14' 517 output2 = '3,14;3.14;3,14' 518 output3 = '3,14;3.14' 519 output4 = '3.14;3,14' 520 old_localize = settings.USE_L10N 521 try: 522 activate('de') 523 settings.USE_L10N = False 524 self.assertEqual(template1.render(context), output1) 525 self.assertEqual(template4.render(context), output4) 526 settings.USE_L10N = True 527 self.assertEqual(template1.render(context), output1) 528 self.assertEqual(template2.render(context), output2) 529 self.assertEqual(template3.render(context), output3) 530 finally: 531 deactivate() 532 settings.USE_L10N = old_localize 533 534class MiscTests(TestCase): 535 536 def test_parse_spec_http_header(self): 537 """ 538 Testing HTTP header parsing. First, we test that we can parse the 539 values according to the spec (and that we extract all the pieces in 540 the right order). 541 """ 542 from django.utils.translation.trans_real import parse_accept_lang_header 543 p = parse_accept_lang_header 544 # Good headers. 545 self.assertEqual([('de', 1.0)], p('de')) 546 self.assertEqual([('en-AU', 1.0)], p('en-AU')) 547 self.assertEqual([('*', 1.0)], p('*;q=1.00')) 548 self.assertEqual([('en-AU', 0.123)], p('en-AU;q=0.123')) 549 self.assertEqual([('en-au', 0.5)], p('en-au;q=0.5')) 550 self.assertEqual([('en-au', 1.0)], p('en-au;q=1.0')) 551 self.assertEqual([('da', 1.0), ('en', 0.5), ('en-gb', 0.25)], p('da, en-gb;q=0.25, en;q=0.5')) 552 self.assertEqual([('en-au-xx', 1.0)], p('en-au-xx')) 553 self.assertEqual([('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)], p('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125')) 554 self.assertEqual([('*', 1.0)], p('*')) 555 self.assertEqual([('de', 1.0)], p('de;q=0.')) 556 self.assertEqual([], p('')) 557 558 # Bad headers; should always return []. 559 self.assertEqual([], p('en-gb;q=1.0000')) 560 self.assertEqual([], p('en;q=0.1234')) 561 self.assertEqual([], p('en;q=.2')) 562 self.assertEqual([], p('abcdefghi-au')) 563 self.assertEqual([], p('**')) 564 self.assertEqual([], p('en,,gb')) 565 self.assertEqual([], p('en-au;q=0.1.0')) 566 self.assertEqual([], p('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en')) 567 self.assertEqual([], p('da, en-gb;q=0.8, en;q=0.7,#')) 568 self.assertEqual([], p('de;q=2.0')) 569 self.assertEqual([], p('de;q=0.a')) 570 self.assertEqual([], p('')) 571 572 def test_parse_literal_http_header(self): 573 """ 574 Now test that we parse a literal HTTP header correctly. 575 """ 576 from django.utils.translation.trans_real import get_language_from_request 577 g = get_language_from_request 578 from django.http import HttpRequest 579 r = HttpRequest 580 r.COOKIES = {} 581 r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'} 582 self.assertEqual('pt-br', g(r)) 583 584 r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'} 585 self.assertEqual('pt', g(r)) 586 587 r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'} 588 self.assertEqual('es', g(r)) 589 590 r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'} 591 self.assertEqual('es-ar', g(r)) 592 593 # Python 2.3 and 2.4 return slightly different results for completely 594 # bogus locales, so we omit this test for that anything below 2.4. 595 # It's relatively harmless in any cases (GIGO). This also means this 596 # won't be executed on Jython currently, but life's like that 597 # sometimes. (On those platforms, passing in a truly bogus locale 598 # will get you the default locale back.) 599 if sys.version_info >= (2, 5): 600 # This test assumes there won't be a Django translation to a US 601 # variation of the Spanish language, a safe assumption. When the 602 # user sets it as the preferred language, the main 'es' 603 # translation should be selected instead. 604 r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'} 605 self.assertEqual(g(r), 'es') 606 607 # This tests the following scenario: there isn't a main language (zh) 608 # translation of Django but there is a translation to variation (zh_CN) 609 # the user sets zh-cn as the preferred language, it should be selected 610 # by Django without falling back nor ignoring it. 611 r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'} 612 self.assertEqual(g(r), 'zh-cn') 613 614 def test_parse_language_cookie(self): 615 """ 616 Now test that we parse language preferences stored in a cookie correctly. 617 """ 618 from django.utils.translation.trans_real import get_language_from_request 619 g = get_language_from_request 620 from django.http import HttpRequest 621 r = HttpRequest 622 r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt-br'} 623 r.META = {} 624 self.assertEqual('pt-br', g(r)) 625 626 r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt'} 627 r.META = {} 628 self.assertEqual('pt', g(r)) 629 630 r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es'} 631 r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'} 632 self.assertEqual('es', g(r)) 633 634 # Python 2.3 and 2.4 return slightly different results for completely 635 # bogus locales, so we omit this test for that anything below 2.4. 636 # It's relatively harmless in any cases (GIGO). This also means this 637 # won't be executed on Jython currently, but life's like that 638 # sometimes. (On those platforms, passing in a truly bogus locale 639 # will get you the default locale back.) 640 if sys.version_info >= (2, 5): 641 # This test assumes there won't be a Django translation to a US 642 # variation of the Spanish language, a safe assumption. When the 643 # user sets it as the preferred language, the main 'es' 644 # translation should be selected instead. 645 r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es-us'} 646 r.META = {} 647 self.assertEqual(g(r), 'es') 648 649 # This tests the following scenario: there isn't a main language (zh) 650 # translation of Django but there is a translation to variation (zh_CN) 651 # the user sets zh-cn as the preferred language, it should be selected 652 # by Django without falling back nor ignoring it. 653 r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'zh-cn'} 654 r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'} 655 self.assertEqual(g(r), 'zh-cn') 656 657class ResolutionOrderI18NTests(TestCase): 658 659 def setUp(self): 660 from django.utils.translation import trans_real 661 # Okay, this is brutal, but we have no other choice to fully reset 662 # the translation framework 663 trans_real._active = local() 664 trans_real._translations = {} 665 activate('de') 666 667 def tearDown(self): 668 deactivate() 669 670 def assertUgettext(self, msgid, msgstr): 671 result = ugettext(msgid) 672 self.assertTrue(msgstr in result, ("The string '%s' isn't in the " 673 "translation of '%s'; the actual result is '%s'." % (msgstr, msgid, result))) 674 675class AppResolutionOrderI18NTests(ResolutionOrderI18NTests): 676 677 def setUp(self): 678 self.old_installed_apps = settings.INSTALLED_APPS 679 settings.INSTALLED_APPS = ['regressiontests.i18n.resolution'] + list(settings.INSTALLED_APPS) 680 super(AppResolutionOrderI18NTests, self).setUp() 681 682 def tearDown(self): 683 settings.INSTALLED_APPS = self.old_installed_apps 684 super(AppResolutionOrderI18NTests, self).tearDown() 685 686 def test_app_translation(self): 687 self.assertUgettext('Date/time', 'APP') 688 689class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests): 690 691 def setUp(self): 692 self.old_locale_paths = settings.LOCALE_PATHS 693 settings.LOCALE_PATHS += (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),) 694 super(LocalePathsResolutionOrderI18NTests, self).setUp() 695 696 def tearDown(self): 697 settings.LOCALE_PATHS = self.old_locale_paths 698 super(LocalePathsResolutionOrderI18NTests, self).tearDown() 699 700 def test_locale_paths_translation(self): 701 self.assertUgettext('Time', 'LOCALE_PATHS') 702 703 def test_locale_paths_override_app_translation(self): 704 old_installed_apps = settings.INSTALLED_APPS 705 settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.i18n.resolution'] 706 try: 707 self.assertUgettext('Time', 'LOCALE_PATHS') 708 finally: 709 settings.INSTALLED_APPS = old_installed_apps 710 711 def test_locale_paths_override_project_translation(self): 712 old_settings_module = settings.SETTINGS_MODULE 713 settings.SETTINGS_MODULE = 'regressiontests' 714 try: 715 self.assertUgettext('Date/time', 'LOCALE_PATHS') 716 finally: 717 settings.SETTINGS_MODULE = old_settings_module 718 719class ProjectResolutionOrderI18NTests(ResolutionOrderI18NTests): 720 721 def setUp(self): 722 self.old_settings_module = settings.SETTINGS_MODULE 723 settings.SETTINGS_MODULE = 'regressiontests' 724 super(ProjectResolutionOrderI18NTests, self).setUp() 725 726 def tearDown(self): 727 settings.SETTINGS_MODULE = self.old_settings_module 728 super(ProjectResolutionOrderI18NTests, self).tearDown() 729 730 def test_project_translation(self): 731 self.assertUgettext('Date/time', 'PROJECT') 732 733 def test_project_override_app_translation(self): 734 old_installed_apps = settings.INSTALLED_APPS 735 settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.i18n.resolution'] 736 try: 737 self.assertUgettext('Date/time', 'PROJECT') 738 finally: 739 settings.INSTALLED_APPS = old_installed_apps 740 741class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests): 742 743 def test_django_fallback(self): 744 self.assertEqual(ugettext('Date/time'), 'Datum/Zeit') 745 746 747class TestModels(TestCase): 748 def test_lazy(self): 749 tm = TestModel() 750 tm.save() 751 752 def test_safestr(self): 753 c = Company(cents_payed=12, products_delivered=1) 754 c.name = SafeUnicode(u'Ińtërnâtiônŕlizćtiřn1') 755 c.save() 756 c.name = SafeString(u'Ińtërnâtiônŕlizćtiřn1'.encode('utf-8')) 757 c.save() 758 759 760class TestLanguageInfo(TestCase): 761 def test_localized_language_info(self): 762 li = get_language_info('de') 763 self.assertEqual(li['code'], 'de') 764 self.assertEqual(li['name_local'], u'Deutsch') 765 self.assertEqual(li['name'], 'German') 766 self.assertEqual(li['bidi'], False) 767 768 769class MultipleLocaleActivationTests(TestCase): 770 """ 771 Tests for template rendering behavior when multiple locales are activated 772 during the lifetime of the same process. 773 """ 774 def setUp(self): 775 self._old_language = get_language() 776 777 def tearDown(self): 778 activate(self._old_language) 779 780 def test_single_locale_activation(self): 781 """ 782 Simple baseline behavior with one locale for all the supported i18n constructs. 783 """ 784 activate('fr') 785 self.assertEqual(Template("{{ _('Yes') }}").render(Context({})), 'Oui') 786 self.assertEqual(Template("{% load i18n %}{% trans 'Yes' %}").render(Context({})), 'Oui') 787 self.assertEqual(Template("{% load i18n %}{% blocktrans %}Yes{% endblocktrans %}").render(Context({})), 'Oui') 788 789 # Literal marked up with _() in a filter expression 790 791 def test_multiple_locale_filter(self): 792 activate('de') 793 t = Template("{% load i18n %}{{ 0|yesno:_('yes,no,maybe') }}") 794 activate(self._old_language) 795 activate('nl') 796 self.assertEqual(t.render(Context({})), 'nee') 797 798 def test_multiple_locale_filter_deactivate(self): 799 activate('de') 800 t = Template("{% load i18n %}{{ 0|yesno:_('yes,no,maybe') }}") 801 deactivate() 802 activate('nl') 803 self.assertEqual(t.render(Context({})), 'nee') 804 805 def test_multiple_locale_filter_direct_switch(self): 806 activate('de') 807 t = Template("{% load i18n %}{{ 0|yesno:_('yes,no,maybe') }}") 808 activate('nl') 809 self.assertEqual(t.render(Context({})), 'nee') 810 811 # Literal marked up with _() 812 813 def test_multiple_locale(self): 814 activate('de') 815 t = Template("{{ _('No') }}") 816 activate(self._old_language) 817 activate('nl') 818 self.assertEqual(t.render(Context({})), 'Nee') 819 820 def test_multiple_locale_deactivate(self): 821 activate('de') 822 t = Template("{{ _('No') }}") 823 deactivate() 824 activate('nl') 825 self.assertEqual(t.render(Context({})), 'Nee') 826 827 def test_multiple_locale_direct_switch(self): 828 activate('de') 829 t = Template("{{ _('No') }}") 830 activate('nl') 831 self.assertEqual(t.render(Context({})), 'Nee') 832 833 # Literal marked up with _(), loading the i18n template tag library 834 835 def test_multiple_locale_loadi18n(self): 836 activate('de') 837 t = Template("{% load i18n %}{{ _('No') }}") 838 activate(self._old_language) 839 activate('nl') 840 self.assertEqual(t.render(Context({})), 'Nee') 841 842 def test_multiple_locale_loadi18n_deactivate(self): 843 activate('de') 844 t = Template("{% load i18n %}{{ _('No') }}") 845 deactivate() 846 activate('nl') 847 self.assertEqual(t.render(Context({})), 'Nee') 848 849 def test_multiple_locale_loadi18n_direct_switch(self): 850 activate('de') 851 t = Template("{% load i18n %}{{ _('No') }}") 852 activate('nl') 853 self.assertEqual(t.render(Context({})), 'Nee') 854 855 # trans i18n tag 856 857 def test_multiple_locale_trans(self): 858 activate('de') 859 t = Template("{% load i18n %}{% trans 'No' %}") 860 activate(self._old_language) 861 activate('nl') 862 self.assertEqual(t.render(Context({})), 'Nee') 863 864 def test_multiple_locale_deactivate_trans(self): 865 activate('de') 866 t = Template("{% load i18n %}{% trans 'No' %}") 867 deactivate() 868 activate('nl') 869 self.assertEqual(t.render(Context({})), 'Nee') 870 871 def test_multiple_locale_direct_switch_trans(self): 872 activate('de') 873 t = Template("{% load i18n %}{% trans 'No' %}") 874 activate('nl') 875 self.assertEqual(t.render(Context({})), 'Nee') 876 877 # blocktrans i18n tag 878 879 def test_multiple_locale_btrans(self): 880 activate('de') 881 t = Template("{% load i18n %}{% blocktrans %}No{% endblocktrans %}") 882 activate(self._old_language) 883 activate('nl') 884 self.assertEqual(t.render(Context({})), 'Nee') 885 886 def test_multiple_locale_deactivate_btrans(self): 887 activate('de') 888 t = Template("{% load i18n %}{% blocktrans %}No{% endblocktrans %}") 889 deactivate() 890 activate('nl') 891 self.assertEqual(t.render(Context({})), 'Nee') 892 893 def test_multiple_locale_direct_switch_btrans(self): 894 activate('de') 895 t = Template("{% load i18n %}{% blocktrans %}No{% endblocktrans %}") 896 activate('nl') 897 self.assertEqual(t.render(Context({})), 'Nee')