PageRenderTime 185ms CodeModel.GetById 30ms app.highlight 123ms RepoModel.GetById 18ms app.codeStats 1ms

/tests/regressiontests/i18n/tests.py

https://code.google.com/p/mango-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')