2010-01-02 05:38:58 +08:00
# -*- encoding: utf-8 -*-
2013-07-30 01:19:04 +08:00
from __future__ import unicode_literals
2011-10-14 05:34:56 +08:00
2010-04-19 20:40:46 +08:00
import datetime
import decimal
2014-05-01 00:04:30 +08:00
import gettext as gettext_module
2010-02-16 20:17:17 +08:00
import os
2010-04-19 20:40:46 +08:00
import pickle
2015-01-28 20:35:27 +08:00
from contextlib import contextmanager
from importlib import import_module
2011-01-17 17:52:47 +08:00
from threading import local
2014-05-03 01:31:22 +08:00
from unittest import skipUnless
2009-12-24 22:23:52 +08:00
2015-01-26 11:28:57 +08:00
from django import forms
2009-12-24 22:23:52 +08:00
from django . conf import settings
2015-04-25 03:35:30 +08:00
from django . template import Context , Template , TemplateSyntaxError
2015-01-28 20:35:27 +08:00
from django . test import RequestFactory , TestCase , override_settings
from django . utils import six , translation
2012-12-08 18:13:52 +08:00
from django . utils . _os import upath
2015-01-28 20:35:27 +08:00
from django . utils . formats import (
date_format , get_format , get_format_modules , iter_format_modules , localize ,
localize_input , reset_format_cache , sanitize_separators , time_format ,
)
from django . utils . numberformat import format as nformat
from django . utils . safestring import SafeBytes , SafeString , SafeText , mark_safe
2012-07-20 18:45:19 +08:00
from django . utils . six import PY3
2015-01-28 20:35:27 +08:00
from django . utils . translation import (
LANGUAGE_SESSION_KEY , activate , check_for_language , deactivate ,
2015-04-03 18:11:54 +08:00
get_language , get_language_bidi , get_language_from_request ,
get_language_info , gettext , gettext_lazy , ngettext_lazy , npgettext ,
npgettext_lazy , pgettext , pgettext_lazy , string_concat , to_locale ,
trans_real , ugettext , ugettext_lazy , ungettext , ungettext_lazy ,
2015-01-28 20:35:27 +08:00
)
2010-09-13 04:03:39 +08:00
2015-01-28 20:35:27 +08:00
from . forms import CompanyForm , I18nForm , SelectDateForm
2011-10-14 05:34:56 +08:00
from . models import Company , TestModel
2009-12-31 06:11:48 +08:00
2012-12-08 18:13:52 +08:00
here = os . path . dirname ( os . path . abspath ( upath ( __file__ ) ) )
2015-01-22 00:55:57 +08:00
extended_locale_paths = settings . LOCALE_PATHS + [
2012-10-22 20:45:41 +08:00
os . path . join ( here , ' other ' , ' locale ' ) ,
2015-01-22 00:55:57 +08:00
]
2011-09-08 21:24:41 +08:00
2014-03-02 04:46:23 +08:00
2014-03-01 03:40:03 +08:00
@contextmanager
def patch_formats ( lang , * * settings ) :
from django . utils . formats import _format_cache
# Populate _format_cache with temporary values
for key , value in settings . items ( ) :
_format_cache [ ( key , lang ) ] = value
try :
yield
finally :
reset_format_cache ( )
2013-05-19 17:44:46 +08:00
2014-01-26 22:28:33 +08:00
class TranslationTests ( TestCase ) :
2009-12-23 01:58:49 +08:00
2015-03-21 02:45:53 +08:00
@translation.override ( ' fr ' )
def test_plural ( self ) :
"""
Test plurals with ungettext . French differs from English in that 0 is singular .
"""
self . assertEqual ( ungettext ( " %d year " , " %d years " , 0 ) % 0 , " 0 année " )
self . assertEqual ( ungettext ( " %d year " , " %d years " , 2 ) % 2 , " 2 années " )
self . assertEqual ( ungettext ( " %(size)d byte " , " %(size)d bytes " , 0 ) % { ' size ' : 0 } , " 0 octet " )
self . assertEqual ( ungettext ( " %(size)d byte " , " %(size)d bytes " , 2 ) % { ' size ' : 2 } , " 2 octets " )
2011-05-06 21:29:32 +08:00
def test_override ( self ) :
activate ( ' de ' )
2014-01-26 22:28:33 +08:00
try :
with translation . override ( ' pl ' ) :
self . assertEqual ( get_language ( ) , ' pl ' )
self . assertEqual ( get_language ( ) , ' de ' )
with translation . override ( None ) :
2015-01-08 18:11:35 +08:00
self . assertEqual ( get_language ( ) , None )
2014-01-26 22:28:33 +08:00
self . assertEqual ( get_language ( ) , ' de ' )
finally :
deactivate ( )
2011-05-06 21:29:32 +08:00
2014-08-20 00:44:10 +08:00
def test_override_decorator ( self ) :
@translation.override ( ' pl ' )
def func_pl ( ) :
self . assertEqual ( get_language ( ) , ' pl ' )
@translation.override ( None )
def func_none ( ) :
2015-01-08 18:11:35 +08:00
self . assertEqual ( get_language ( ) , None )
2014-08-20 00:44:10 +08:00
try :
2014-08-29 04:26:37 +08:00
activate ( ' de ' )
2014-08-20 00:44:10 +08:00
func_pl ( )
self . assertEqual ( get_language ( ) , ' de ' )
func_none ( )
self . assertEqual ( get_language ( ) , ' de ' )
finally :
deactivate ( )
2014-08-29 04:26:37 +08:00
def test_override_exit ( self ) :
"""
Test that the language restored is the one used when the function was
called , not the one used when the decorator was initialized . refs #23381
"""
activate ( ' fr ' )
2014-08-29 21:42:22 +08:00
2014-08-29 04:26:37 +08:00
@translation.override ( ' pl ' )
def func_pl ( ) :
pass
deactivate ( )
try :
activate ( ' en ' )
func_pl ( )
self . assertEqual ( get_language ( ) , ' en ' )
finally :
deactivate ( )
2009-12-23 01:58:49 +08:00
def test_lazy_objects ( self ) :
"""
Format string interpolation should work with * _lazy objects .
"""
s = ugettext_lazy ( ' Add %(name)s ' )
d = { ' name ' : ' Ringo ' }
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' Add Ringo ' , s % d )
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' Ringo hinzuf \xfc gen ' , s % d )
2011-05-06 21:29:44 +08:00
with translation . override ( ' pl ' ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' Dodaj Ringo ' , s % d )
2009-12-23 01:58:49 +08:00
# It should be possible to compare *_lazy objects.
s1 = ugettext_lazy ( ' Add %(name)s ' )
2015-04-27 22:59:16 +08:00
self . assertEqual ( s , s1 )
2009-12-23 01:58:49 +08:00
s2 = gettext_lazy ( ' Add %(name)s ' )
s3 = gettext_lazy ( ' Add %(name)s ' )
2015-04-27 22:59:16 +08:00
self . assertEqual ( s2 , s3 )
self . assertEqual ( s , s2 )
2009-12-23 01:58:49 +08:00
s4 = ugettext_lazy ( ' Some other string ' )
2015-04-27 22:59:16 +08:00
self . assertNotEqual ( s , s4 )
2009-12-23 01:58:49 +08:00
2014-05-03 01:31:22 +08:00
@skipUnless ( six . PY2 , " No more bytestring translations on PY3 " )
def test_lazy_and_bytestrings ( self ) :
# On Python 2, (n)gettext_lazy should not transform a bytestring to unicode
self . assertEqual ( gettext_lazy ( b " test " ) . upper ( ) , b " TEST " )
self . assertEqual ( ( ngettext_lazy ( b " %d test " , b " %d tests " ) % 1 ) . upper ( ) , b " 1 TEST " )
# Other versions of lazy functions always return unicode
self . assertEqual ( ugettext_lazy ( b " test " ) . upper ( ) , " TEST " )
self . assertEqual ( ( ungettext_lazy ( b " %d test " , b " %d tests " ) % 1 ) . upper ( ) , " 1 TEST " )
self . assertEqual ( pgettext_lazy ( b " context " , b " test " ) . upper ( ) , " TEST " )
self . assertEqual (
( npgettext_lazy ( b " context " , b " %d test " , b " %d tests " ) % 1 ) . upper ( ) ,
" 1 TEST "
)
2012-11-14 17:50:15 +08:00
2010-04-19 20:40:46 +08:00
def test_lazy_pickle ( self ) :
s1 = ugettext_lazy ( " test " )
2012-07-20 20:48:51 +08:00
self . assertEqual ( six . text_type ( s1 ) , " test " )
2010-04-19 20:40:46 +08:00
s2 = pickle . loads ( pickle . dumps ( s1 ) )
2012-07-20 20:48:51 +08:00
self . assertEqual ( six . text_type ( s2 ) , " test " )
2010-04-19 20:40:46 +08:00
2013-01-31 03:28:16 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
def test_ungettext_lazy ( self ) :
2013-02-02 17:56:41 +08:00
simple_with_format = ungettext_lazy ( ' %d good result ' , ' %d good results ' )
simple_str_with_format = ngettext_lazy ( str ( ' %d good result ' ) , str ( ' %d good results ' ) )
simple_context_with_format = npgettext_lazy ( ' Exclamation ' , ' %d good result ' , ' %d good results ' )
simple_without_format = ungettext_lazy ( ' good result ' , ' good results ' )
2013-01-31 03:28:16 +08:00
with translation . override ( ' de ' ) :
2013-02-02 17:56:41 +08:00
self . assertEqual ( simple_with_format % 1 , ' 1 gutes Resultat ' )
self . assertEqual ( simple_with_format % 4 , ' 4 guten Resultate ' )
self . assertEqual ( simple_str_with_format % 1 , str ( ' 1 gutes Resultat ' ) )
self . assertEqual ( simple_str_with_format % 4 , str ( ' 4 guten Resultate ' ) )
self . assertEqual ( simple_context_with_format % 1 , ' 1 gutes Resultat! ' )
self . assertEqual ( simple_context_with_format % 4 , ' 4 guten Resultate! ' )
self . assertEqual ( simple_without_format % 1 , ' gutes Resultat ' )
self . assertEqual ( simple_without_format % 4 , ' guten Resultate ' )
2013-01-31 03:28:16 +08:00
2013-02-02 17:56:41 +08:00
complex_nonlazy = ungettext_lazy ( ' Hi %(name)s , %(num)d good result ' , ' Hi %(name)s , %(num)d good results ' , 4 )
complex_deferred = ungettext_lazy ( ' Hi %(name)s , %(num)d good result ' , ' Hi %(name)s , %(num)d good results ' , ' num ' )
complex_str_nonlazy = ngettext_lazy ( str ( ' Hi %(name)s , %(num)d good result ' ) , str ( ' Hi %(name)s , %(num)d good results ' ) , 4 )
complex_str_deferred = ngettext_lazy ( str ( ' Hi %(name)s , %(num)d good result ' ) , str ( ' Hi %(name)s , %(num)d good results ' ) , ' num ' )
complex_context_nonlazy = npgettext_lazy ( ' Greeting ' , ' Hi %(name)s , %(num)d good result ' , ' Hi %(name)s , %(num)d good results ' , 4 )
complex_context_deferred = npgettext_lazy ( ' Greeting ' , ' Hi %(name)s , %(num)d good result ' , ' Hi %(name)s , %(num)d good results ' , ' num ' )
2013-01-31 03:28:16 +08:00
with translation . override ( ' de ' ) :
2013-02-02 17:56:41 +08:00
self . assertEqual ( complex_nonlazy % { ' num ' : 4 , ' name ' : ' Jim ' } , ' Hallo Jim, 4 guten Resultate ' )
self . assertEqual ( complex_deferred % { ' name ' : ' Jim ' , ' num ' : 1 } , ' Hallo Jim, 1 gutes Resultat ' )
self . assertEqual ( complex_deferred % { ' name ' : ' Jim ' , ' num ' : 5 } , ' Hallo Jim, 5 guten Resultate ' )
2013-01-31 03:28:16 +08:00
with six . assertRaisesRegex ( self , KeyError , ' Your dictionary lacks key.* ' ) :
2013-02-02 17:56:41 +08:00
complex_deferred % { ' name ' : ' Jim ' }
self . assertEqual ( complex_str_nonlazy % { ' num ' : 4 , ' name ' : ' Jim ' } , str ( ' Hallo Jim, 4 guten Resultate ' ) )
self . assertEqual ( complex_str_deferred % { ' name ' : ' Jim ' , ' num ' : 1 } , str ( ' Hallo Jim, 1 gutes Resultat ' ) )
self . assertEqual ( complex_str_deferred % { ' name ' : ' Jim ' , ' num ' : 5 } , str ( ' Hallo Jim, 5 guten Resultate ' ) )
2013-01-31 03:28:16 +08:00
with six . assertRaisesRegex ( self , KeyError , ' Your dictionary lacks key.* ' ) :
2013-02-02 17:56:41 +08:00
complex_str_deferred % { ' name ' : ' Jim ' }
self . assertEqual ( complex_context_nonlazy % { ' num ' : 4 , ' name ' : ' Jim ' } , ' Willkommen Jim, 4 guten Resultate ' )
self . assertEqual ( complex_context_deferred % { ' name ' : ' Jim ' , ' num ' : 1 } , ' Willkommen Jim, 1 gutes Resultat ' )
self . assertEqual ( complex_context_deferred % { ' name ' : ' Jim ' , ' num ' : 5 } , ' Willkommen Jim, 5 guten Resultate ' )
2013-01-31 03:28:16 +08:00
with six . assertRaisesRegex ( self , KeyError , ' Your dictionary lacks key.* ' ) :
2013-02-02 17:56:41 +08:00
complex_context_deferred % { ' name ' : ' Jim ' }
2013-01-31 03:28:16 +08:00
2014-08-31 06:18:58 +08:00
@skipUnless ( six . PY2 , " PY3 doesn ' t have distinct int and long types " )
2014-08-31 00:48:55 +08:00
def test_ungettext_lazy_long ( self ) :
"""
Regression test for #22820: int and long should be treated alike in ungettext_lazy.
"""
result = ungettext_lazy ( ' %(name)s has %(num)d good result ' , ' %(name)s has %(num)d good results ' , 4 )
self . assertEqual ( result % { ' name ' : ' Joe ' , ' num ' : 4 } , " Joe has 4 good results " )
# Now with a long
result = ungettext_lazy ( ' %(name)s has %(num)d good result ' , ' %(name)s has %(num)d good results ' , long ( 4 ) )
self . assertEqual ( result % { ' name ' : ' Joe ' , ' num ' : 4 } , " Joe has 4 good results " )
2012-10-22 20:45:41 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
2010-11-04 18:48:27 +08:00
def test_pgettext ( self ) :
2012-10-22 20:45:41 +08:00
trans_real . _active = local ( )
trans_real . _translations = { }
with translation . override ( ' de ' ) :
self . assertEqual ( pgettext ( " unexisting " , " May " ) , " May " )
self . assertEqual ( pgettext ( " month name " , " May " ) , " Mai " )
self . assertEqual ( pgettext ( " verb " , " May " ) , " Kann " )
self . assertEqual ( npgettext ( " search " , " %d result " , " %d results " , 4 ) % 4 , " 4 Resultate " )
2010-11-04 18:48:27 +08:00
2012-10-22 20:45:41 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
2011-10-19 12:59:47 +08:00
def test_template_tags_pgettext ( self ) :
"""
Ensure that message contexts are taken into account the { % trans % } and
{ % blocktrans % } template tags .
Refs #14806.
"""
2012-10-22 20:45:41 +08:00
trans_real . _active = local ( )
trans_real . _translations = { }
with translation . override ( ' de ' ) :
# {% trans %} -----------------------------------
# Inexisting context...
t = Template ( ' { % lo ad i18n % } { % trans " May " context " unexisting " % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' May ' )
# Existing context...
# Using a literal
t = Template ( ' { % lo ad i18n % } { % trans " May " context " month name " % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % trans " May " context " verb " % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Kann ' )
# Using a variable
t = Template ( ' { % lo ad i18n % } { % trans " May " context message_context % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' month name ' } ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % trans " May " context message_context % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' verb ' } ) )
self . assertEqual ( rendered , ' Kann ' )
# Using a filter
t = Template ( ' { % lo ad i18n % } { % trans " May " context message_context|lower % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' MONTH NAME ' } ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % trans " May " context message_context|lower % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' VERB ' } ) )
self . assertEqual ( rendered , ' Kann ' )
# Using 'as'
t = Template ( ' { % lo ad i18n % } { % trans " May " context " month name " as var % }Value: {{ var }} ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Value: Mai ' )
t = Template ( ' { % lo ad i18n % } { % trans " May " as var context " verb " % }Value: {{ var }} ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Value: Kann ' )
# {% blocktrans %} ------------------------------
# Inexisting context...
t = Template ( ' { % lo ad i18n % } { % blocktrans context " unexisting " % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' May ' )
# Existing context...
# Using a literal
t = Template ( ' { % lo ad i18n % } { % blocktrans context " month name " % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context " verb " % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Kann ' )
# Using a variable
t = Template ( ' { % lo ad i18n % } { % blocktrans context message_context % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' month name ' } ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context message_context % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' verb ' } ) )
self . assertEqual ( rendered , ' Kann ' )
# Using a filter
t = Template ( ' { % lo ad i18n % } { % blocktrans context message_context|lower % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' MONTH NAME ' } ) )
self . assertEqual ( rendered , ' Mai ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context message_context|lower % }May { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' message_context ' : ' VERB ' } ) )
self . assertEqual ( rendered , ' Kann ' )
# Using 'count'
t = Template ( ' { % lo ad i18n % } { % blocktrans count number=1 context " super search " % } {{ number }} super result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' 1 Super-Ergebnis ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans count number=2 context " super search " % } {{ number }} super result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' 2 Super-Ergebnisse ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context " other super search " count number=1 % } {{ number }} super result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' 1 anderen Super-Ergebnis ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context " other super search " count number=2 % } {{ number }} super result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' 2 andere Super-Ergebnisse ' )
# Using 'with'
t = Template ( ' { % lo ad i18n % } { % blocktrans with num_comments=5 context " comment count " % }There are {{ num_comments }} comments { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Es gibt 5 Kommentare ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans with num_comments=5 context " other comment count " % }There are {{ num_comments }} comments { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Andere: Es gibt 5 Kommentare ' )
2013-11-03 03:01:17 +08:00
# Using trimmed
t = Template ( ' { % lo ad i18n % } { % blocktrans trimmed % } \n \n There \n \t are 5 \n \n comments \n { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' There are 5 comments ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans with num_comments=5 context " comment count " trimmed % } \n \n There are \t \n \t {{ num_comments }} comments \n \n { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' Es gibt 5 Kommentare ' )
t = Template ( ' { % lo ad i18n % } { % blocktrans context " other super search " count number=2 trimmed % } \n {{ number }} super \n result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
rendered = t . render ( Context ( ) )
self . assertEqual ( rendered , ' 2 andere Super-Ergebnisse ' )
2012-10-22 20:45:41 +08:00
# Mis-uses
self . assertRaises ( TemplateSyntaxError , Template , ' { % lo ad i18n % } { % blocktrans context with month= " May " % } {{ month }} { % e ndblocktrans % } ' )
self . assertRaises ( TemplateSyntaxError , Template , ' { % lo ad i18n % } { % blocktrans context % } { % e ndblocktrans % } ' )
self . assertRaises ( TemplateSyntaxError , Template , ' { % lo ad i18n % } { % blocktrans count number=2 context % } {{ number }} super result { % plural % } {{ number }} super results { % e ndblocktrans % } ' )
2011-10-19 12:59:47 +08:00
2009-12-23 01:58:49 +08:00
def test_string_concat ( self ) :
"""
2012-07-20 20:48:51 +08:00
six . text_type ( string_concat ( . . . ) ) should not raise a TypeError - #4796
2009-12-23 01:58:49 +08:00
"""
2014-01-26 22:28:33 +08:00
self . assertEqual ( ' django ' , six . text_type ( string_concat ( " dja " , " ngo " ) ) )
2009-12-23 01:58:49 +08:00
2014-09-07 19:56:34 +08:00
def test_empty_value ( self ) :
"""
Empty value must stay empty after being translated ( #23196).
"""
with translation . override ( ' de ' ) :
self . assertEqual ( " " , ugettext ( " " ) )
2014-09-21 23:28:37 +08:00
self . assertEqual ( str ( " " ) , gettext ( str ( " " ) ) )
2014-09-07 19:56:34 +08:00
s = mark_safe ( " " )
self . assertEqual ( s , ugettext ( s ) )
2009-12-23 01:58:49 +08:00
def test_safe_status ( self ) :
"""
Translating a string requiring no auto - escaping shouldn ' t change the " safe " status.
"""
2012-08-18 17:30:48 +08:00
s = mark_safe ( str ( ' Password ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( SafeString , type ( s ) )
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
2012-08-18 22:04:06 +08:00
self . assertEqual ( SafeText , type ( ugettext ( s ) ) )
self . assertEqual ( ' aPassword ' , SafeText ( ' a ' ) + s )
self . assertEqual ( ' Passworda ' , s + SafeText ( ' a ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( ' Passworda ' , s + mark_safe ( ' a ' ) )
self . assertEqual ( ' aPassword ' , mark_safe ( ' a ' ) + s )
self . assertEqual ( ' as ' , mark_safe ( ' a ' ) + mark_safe ( ' s ' ) )
def test_maclines ( self ) :
"""
Translations on files with mac or dos end of lines will be converted
to unix eof in . po catalogs , and they have to match when retrieved
"""
2012-10-22 20:45:41 +08:00
ca_translation = trans_real . translation ( ' ca ' )
2012-06-08 00:08:47 +08:00
ca_translation . _catalog [ ' Mac \n EOF \n ' ] = ' Catalan Mac \n EOF \n '
ca_translation . _catalog [ ' Win \n EOF \n ' ] = ' Catalan Win \n EOF \n '
2011-05-06 21:29:44 +08:00
with translation . override ( ' ca ' , deactivate = True ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' Catalan Mac \n EOF \n ' , ugettext ( ' Mac \r EOF \r ' ) )
self . assertEqual ( ' Catalan Win \n EOF \n ' , ugettext ( ' Win \r \n EOF \r \n ' ) )
2009-12-24 22:23:52 +08:00
2010-01-02 05:38:34 +08:00
def test_to_locale ( self ) :
"""
Tests the to_locale function and the special case of Serbian Latin
( refs #12230 and r11299)
"""
self . assertEqual ( to_locale ( ' en-us ' ) , ' en_US ' )
self . assertEqual ( to_locale ( ' sr-lat ' ) , ' sr_Lat ' )
def test_to_language ( self ) :
"""
Test the to_language function
"""
2012-10-22 20:45:41 +08:00
self . assertEqual ( trans_real . to_language ( ' en_US ' ) , ' en-us ' )
self . assertEqual ( trans_real . to_language ( ' sr_Lat ' ) , ' sr-lat ' )
2010-01-02 05:38:34 +08:00
2015-04-03 18:11:54 +08:00
def test_language_bidi ( self ) :
self . assertEqual ( get_language_bidi ( ) , False )
with translation . override ( None ) :
self . assertEqual ( get_language_bidi ( ) , False )
2015-01-22 00:55:57 +08:00
@override_settings ( LOCALE_PATHS = [ os . path . join ( here , ' other ' , ' locale ' ) ] )
2012-05-29 02:03:34 +08:00
def test_bad_placeholder_1 ( self ) :
2011-09-08 21:24:41 +08:00
"""
Error in translation file should not crash template rendering
( % ( person ) s is translated as % ( personne ) s in fr . po )
2012-05-29 02:03:34 +08:00
Refs #16516.
2011-09-08 21:24:41 +08:00
"""
with translation . override ( ' fr ' ) :
t = Template ( ' { % lo ad i18n % } { % blocktrans % }My name is {{ person }}. { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' person ' : ' James ' } ) )
self . assertEqual ( rendered , ' My name is James. ' )
2015-01-22 00:55:57 +08:00
@override_settings ( LOCALE_PATHS = [ os . path . join ( here , ' other ' , ' locale ' ) ] )
2012-05-29 02:03:34 +08:00
def test_bad_placeholder_2 ( self ) :
"""
Error in translation file should not crash template rendering
( % ( person ) misses a ' s ' in fr . po , causing the string formatting to fail )
Refs #18393.
"""
with translation . override ( ' fr ' ) :
t = Template ( ' { % lo ad i18n % } { % blocktrans % }My other name is {{ person }}. { % e ndblocktrans % } ' )
rendered = t . render ( Context ( { ' person ' : ' James ' } ) )
self . assertEqual ( rendered , ' My other name is James. ' )
2010-01-02 05:38:34 +08:00
2013-05-18 23:36:31 +08:00
class TranslationThreadSafetyTests ( TestCase ) :
2013-05-19 17:44:46 +08:00
2013-05-18 23:36:31 +08:00
def setUp ( self ) :
self . _old_language = get_language ( )
self . _translations = trans_real . _translations
# here we rely on .split() being called inside the _fetch()
# in trans_real.translation()
class sideeffect_str ( str ) :
def split ( self , * args , * * kwargs ) :
res = str . split ( self , * args , * * kwargs )
trans_real . _translations [ ' en-YY ' ] = None
return res
trans_real . _translations = { sideeffect_str ( ' en-XX ' ) : None }
def tearDown ( self ) :
trans_real . _translations = self . _translations
activate ( self . _old_language )
def test_bug14894_translation_activate_thread_safety ( self ) :
translation_count = len ( trans_real . _translations )
try :
translation . activate ( ' pl ' )
except RuntimeError :
self . fail ( ' translation.activate() is not thread-safe ' )
# make sure sideeffect_str actually added a new translation
self . assertLess ( translation_count , len ( trans_real . _translations ) )
2013-02-15 16:36:07 +08:00
@override_settings ( USE_L10N = True )
2014-01-26 22:28:33 +08:00
class FormattingTests ( TestCase ) :
2009-12-24 22:23:52 +08:00
def setUp ( self ) :
2013-05-19 17:44:46 +08:00
super ( FormattingTests , self ) . setUp ( )
2009-12-24 22:23:52 +08:00
self . n = decimal . Decimal ( ' 66666.666 ' )
self . f = 99999.999
self . d = datetime . date ( 2009 , 12 , 31 )
self . dt = datetime . datetime ( 2009 , 12 , 31 , 20 , 50 )
2010-01-02 05:36:36 +08:00
self . t = datetime . time ( 10 , 15 , 48 )
2012-07-20 18:45:19 +08:00
self . l = 10000 if PY3 else long ( 10000 )
2009-12-24 22:23:52 +08:00
self . ctxt = Context ( {
' n ' : self . n ,
2010-01-02 05:36:36 +08:00
' t ' : self . t ,
2009-12-24 22:23:52 +08:00
' d ' : self . d ,
' dt ' : self . dt ,
2010-09-28 00:21:16 +08:00
' f ' : self . f ,
' l ' : self . l ,
2009-12-24 22:23:52 +08:00
} )
2009-12-23 01:58:49 +08:00
2009-12-24 22:23:52 +08:00
def test_locale_independent ( self ) :
2009-12-23 01:58:49 +08:00
"""
2010-01-02 05:36:36 +08:00
Localization of numbers
2009-12-23 01:58:49 +08:00
"""
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 66666.66 ' , nformat ( self . n , decimal_sep = ' . ' , decimal_pos = 2 , grouping = 3 , thousand_sep = ' , ' ) )
self . assertEqual ( ' 66666A6 ' , nformat ( self . n , decimal_sep = ' A ' , decimal_pos = 1 , grouping = 1 , thousand_sep = ' B ' ) )
self . assertEqual ( ' 66666 ' , nformat ( self . n , decimal_sep = ' X ' , decimal_pos = 0 , grouping = 1 , thousand_sep = ' Y ' ) )
2011-05-06 21:29:44 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 66,666.66 ' , nformat ( self . n , decimal_sep = ' . ' , decimal_pos = 2 , grouping = 3 , thousand_sep = ' , ' ) )
self . assertEqual ( ' 6B6B6B6B6A6 ' , nformat ( self . n , decimal_sep = ' A ' , decimal_pos = 1 , grouping = 1 , thousand_sep = ' B ' ) )
self . assertEqual ( ' -66666.6 ' , nformat ( - 66666.666 , decimal_sep = ' . ' , decimal_pos = 1 ) )
self . assertEqual ( ' -66666.0 ' , nformat ( int ( ' -66666 ' ) , decimal_sep = ' . ' , decimal_pos = 1 ) )
self . assertEqual ( ' 10000.0 ' , nformat ( self . l , decimal_sep = ' . ' , decimal_pos = 1 ) )
2011-12-24 19:15:26 +08:00
# This unusual grouping/force_grouping combination may be triggered by the intcomma filter (#17414)
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 10000 ' , nformat ( self . l , decimal_sep = ' . ' , decimal_pos = 0 , grouping = 0 , force_grouping = True ) )
2011-05-06 21:29:44 +08:00
# date filter
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 31.12.2009 в 20:50 ' , Template ( ' {{ dt|date: " d.m.Y в H:i " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' ⌚ 10:15 ' , Template ( ' {{ t|time: " ⌚ H:i " }} ' ) . render ( self . ctxt ) )
2010-01-02 05:38:58 +08:00
2013-02-15 16:36:07 +08:00
@override_settings ( USE_L10N = False )
2009-12-24 22:23:52 +08:00
def test_l10n_disabled ( self ) :
"""
Catalan locale with format i18n disabled translations will be used ,
but not formats
"""
2011-05-06 21:29:44 +08:00
with translation . override ( ' ca ' , deactivate = True ) :
2013-11-01 00:27:21 +08:00
self . maxDiff = 3000
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' N j, Y ' , get_format ( ' DATE_FORMAT ' ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( 0 , get_format ( ' FIRST_DAY_OF_WEEK ' ) )
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' . ' , get_format ( ' DECIMAL_SEPARATOR ' ) )
self . assertEqual ( ' 10:15 a.m. ' , time_format ( self . t ) )
self . assertEqual ( ' des. 31, 2009 ' , date_format ( self . d ) )
self . assertEqual ( ' desembre 2009 ' , date_format ( self . d , ' YEAR_MONTH_FORMAT ' ) )
self . assertEqual ( ' 12/31/2009 8:50 p.m. ' , date_format ( self . dt , ' SHORT_DATETIME_FORMAT ' ) )
self . assertEqual ( ' No localizable ' , localize ( ' No localizable ' ) )
self . assertEqual ( ' 66666.666 ' , localize ( self . n ) )
self . assertEqual ( ' 99999.999 ' , localize ( self . f ) )
self . assertEqual ( ' 10000 ' , localize ( self . l ) )
self . assertEqual ( ' des. 31, 2009 ' , localize ( self . d ) )
self . assertEqual ( ' des. 31, 2009, 8:50 p.m. ' , localize ( self . dt ) )
self . assertEqual ( ' 66666.666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 99999.999 ' , Template ( ' {{ f }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' des. 31, 2009 ' , Template ( ' {{ d }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' des. 31, 2009, 8:50 p.m. ' , Template ( ' {{ dt }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 66666.67 ' , Template ( ' {{ n|floatformat:2 }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 100000.0 ' , Template ( ' {{ f|floatformat }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 10:15 a.m. ' , Template ( ' {{ t|time: " TIME_FORMAT " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 12/31/2009 ' , Template ( ' {{ d|date: " SHORT_DATE_FORMAT " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 12/31/2009 8:50 p.m. ' , Template ( ' {{ dt|date: " SHORT_DATETIME_FORMAT " }} ' ) . render ( self . ctxt ) )
2009-12-24 22:23:52 +08:00
form = I18nForm ( {
2012-06-08 00:08:47 +08:00
' decimal_field ' : ' 66666,666 ' ,
' float_field ' : ' 99999,999 ' ,
' date_field ' : ' 31/12/2009 ' ,
' datetime_field ' : ' 31/12/2009 20:50 ' ,
' time_field ' : ' 20:50 ' ,
' integer_field ' : ' 1.234 ' ,
2009-12-24 22:23:52 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertFalse ( form . is_valid ( ) )
2012-06-08 00:08:47 +08:00
self . assertEqual ( [ ' Introdu \xef u un n \xfa mero. ' ] , form . errors [ ' float_field ' ] )
self . assertEqual ( [ ' Introdu \xef u un n \xfa mero. ' ] , form . errors [ ' decimal_field ' ] )
self . assertEqual ( [ ' Introdu \xef u una data v \xe0 lida. ' ] , form . errors [ ' date_field ' ] )
self . assertEqual ( [ ' Introdu \xef u una data/hora v \xe0 lides. ' ] , form . errors [ ' datetime_field ' ] )
self . assertEqual ( [ ' Introdu \xef u un n \xfa mero sencer. ' ] , form . errors [ ' integer_field ' ] )
2009-12-24 22:23:52 +08:00
form2 = SelectDateForm ( {
2012-06-08 00:08:47 +08:00
' date_field_month ' : ' 12 ' ,
' date_field_day ' : ' 31 ' ,
' date_field_year ' : ' 2009 '
2009-12-24 22:23:52 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form2 . is_valid ( ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form2 . cleaned_data [ ' date_field ' ] )
2012-02-01 04:36:11 +08:00
self . assertHTMLEqual (
2013-11-01 00:27:21 +08:00
' <select name= " mydate_month " id= " id_mydate_month " > \n <option value= " 0 " >---</option> \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= " 0 " >---</option> \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= " 0 " >---</option> \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> ' ,
2015-01-26 11:28:57 +08:00
forms . SelectDateWidget ( years = range ( 2009 , 2019 ) ) . render ( ' mydate ' , datetime . date ( 2009 , 12 , 31 ) )
2009-12-24 22:23:52 +08:00
)
2010-03-20 23:26:41 +08:00
# We shouldn't change the behavior of the floatformat filter re:
# thousand separator and grouping when USE_L10N is False even
# if the USE_THOUSAND_SEPARATOR, NUMBER_GROUPING and
# THOUSAND_SEPARATOR settings are specified
2011-05-06 21:29:44 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ,
NUMBER_GROUPING = 1 , THOUSAND_SEPARATOR = ' ! ' ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 66666.67 ' , Template ( ' {{ n|floatformat:2 }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 100000.0 ' , Template ( ' {{ f|floatformat }} ' ) . render ( self . ctxt ) )
2009-12-24 22:23:52 +08:00
2011-10-20 20:14:06 +08:00
def test_false_like_locale_formats ( self ) :
"""
Ensure that the active locale ' s formats take precedence over the
default settings even if they would be interpreted as False in a
conditional test ( e . g . 0 or empty string ) .
Refs #16938.
"""
2014-03-01 03:40:03 +08:00
with patch_formats ( ' fr ' , THOUSAND_SEPARATOR = ' ' , FIRST_DAY_OF_WEEK = 0 ) :
with translation . override ( ' fr ' ) :
with self . settings ( USE_THOUSAND_SEPARATOR = True , THOUSAND_SEPARATOR = ' ! ' ) :
self . assertEqual ( ' ' , get_format ( ' THOUSAND_SEPARATOR ' ) )
# Even a second time (after the format has been cached)...
self . assertEqual ( ' ' , get_format ( ' THOUSAND_SEPARATOR ' ) )
with self . settings ( FIRST_DAY_OF_WEEK = 1 ) :
self . assertEqual ( 0 , get_format ( ' FIRST_DAY_OF_WEEK ' ) )
# Even a second time (after the format has been cached)...
self . assertEqual ( 0 , get_format ( ' FIRST_DAY_OF_WEEK ' ) )
2011-10-20 20:14:06 +08:00
2009-12-24 22:23:52 +08:00
def test_l10n_enabled ( self ) :
2013-11-01 00:27:21 +08:00
self . maxDiff = 3000
2011-02-04 23:45:52 +08:00
# Catalan locale
2011-05-06 21:29:44 +08:00
with translation . override ( ' ca ' , deactivate = True ) :
2012-02-10 09:13:29 +08:00
self . assertEqual ( ' j \ d \ e F \ d \ e Y ' , get_format ( ' DATE_FORMAT ' ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( 1 , get_format ( ' FIRST_DAY_OF_WEEK ' ) )
self . assertEqual ( ' , ' , get_format ( ' DECIMAL_SEPARATOR ' ) )
2014-09-11 20:43:49 +08:00
self . assertEqual ( ' 10:15 ' , time_format ( self . t ) )
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 31 de desembre de 2009 ' , date_format ( self . d ) )
self . assertEqual ( ' desembre del 2009 ' , date_format ( self . d , ' YEAR_MONTH_FORMAT ' ) )
self . assertEqual ( ' 31/12/2009 20:50 ' , date_format ( self . dt , ' SHORT_DATETIME_FORMAT ' ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( ' No localizable ' , localize ( ' No localizable ' ) )
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( ' 66.666,666 ' , localize ( self . n ) )
self . assertEqual ( ' 99.999,999 ' , localize ( self . f ) )
self . assertEqual ( ' 10.000 ' , localize ( self . l ) )
self . assertEqual ( ' True ' , localize ( True ) )
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
self . assertEqual ( ' 66666,666 ' , localize ( self . n ) )
self . assertEqual ( ' 99999,999 ' , localize ( self . f ) )
self . assertEqual ( ' 10000 ' , localize ( self . l ) )
self . assertEqual ( ' 31 de desembre de 2009 ' , localize ( self . d ) )
self . assertEqual ( ' 31 de desembre de 2009 a les 20:50 ' , localize ( self . dt ) )
2009-12-24 22:23:52 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( ' 66.666,666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 99.999,999 ' , Template ( ' {{ f }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 10.000 ' , Template ( ' {{ l }} ' ) . render ( self . ctxt ) )
2009-12-24 22:23:52 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
form3 = I18nForm ( {
' decimal_field ' : ' 66.666,666 ' ,
' float_field ' : ' 99.999,999 ' ,
' date_field ' : ' 31/12/2009 ' ,
' datetime_field ' : ' 31/12/2009 20:50 ' ,
' time_field ' : ' 20:50 ' ,
' integer_field ' : ' 1.234 ' ,
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form3 . is_valid ( ) )
2013-02-15 16:36:07 +08:00
self . assertEqual ( decimal . Decimal ( ' 66666.666 ' ) , form3 . cleaned_data [ ' decimal_field ' ] )
self . assertEqual ( 99999.999 , form3 . cleaned_data [ ' float_field ' ] )
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form3 . cleaned_data [ ' date_field ' ] )
self . assertEqual ( datetime . datetime ( 2009 , 12 , 31 , 20 , 50 ) , form3 . cleaned_data [ ' datetime_field ' ] )
self . assertEqual ( datetime . time ( 20 , 50 ) , form3 . cleaned_data [ ' time_field ' ] )
self . assertEqual ( 1234 , form3 . cleaned_data [ ' integer_field ' ] )
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
self . assertEqual ( ' 66666,666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 99999,999 ' , Template ( ' {{ f }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 31 de desembre de 2009 ' , Template ( ' {{ d }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 31 de desembre de 2009 a les 20:50 ' , Template ( ' {{ dt }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 66666,67 ' , Template ( ' {{ n|floatformat:2 }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 100000,0 ' , Template ( ' {{ f|floatformat }} ' ) . render ( self . ctxt ) )
2014-09-11 20:43:49 +08:00
self . assertEqual ( ' 10:15 ' , Template ( ' {{ t|time: " TIME_FORMAT " }} ' ) . render ( self . ctxt ) )
2013-02-15 16:36:07 +08:00
self . assertEqual ( ' 31/12/2009 ' , Template ( ' {{ d|date: " SHORT_DATE_FORMAT " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 31/12/2009 20:50 ' , Template ( ' {{ dt|date: " SHORT_DATETIME_FORMAT " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( date_format ( datetime . datetime . now ( ) , " DATE_FORMAT " ) ,
Template ( ' { % now " DATE_FORMAT " % } ' ) . render ( self . ctxt ) )
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
form4 = I18nForm ( {
' decimal_field ' : ' 66666,666 ' ,
' float_field ' : ' 99999,999 ' ,
' date_field ' : ' 31/12/2009 ' ,
' datetime_field ' : ' 31/12/2009 20:50 ' ,
' time_field ' : ' 20:50 ' ,
' integer_field ' : ' 1234 ' ,
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form4 . is_valid ( ) )
2013-02-15 16:36:07 +08:00
self . assertEqual ( decimal . Decimal ( ' 66666.666 ' ) , form4 . cleaned_data [ ' decimal_field ' ] )
self . assertEqual ( 99999.999 , form4 . cleaned_data [ ' float_field ' ] )
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form4 . cleaned_data [ ' date_field ' ] )
self . assertEqual ( datetime . datetime ( 2009 , 12 , 31 , 20 , 50 ) , form4 . cleaned_data [ ' datetime_field ' ] )
self . assertEqual ( datetime . time ( 20 , 50 ) , form4 . cleaned_data [ ' time_field ' ] )
self . assertEqual ( 1234 , form4 . cleaned_data [ ' integer_field ' ] )
2009-12-24 22:23:52 +08:00
2010-03-01 18:19:24 +08:00
form5 = SelectDateForm ( {
2012-06-08 00:08:47 +08:00
' date_field_month ' : ' 12 ' ,
' date_field_day ' : ' 31 ' ,
' date_field_year ' : ' 2009 '
2009-12-24 22:23:52 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form5 . is_valid ( ) )
2010-03-01 18:19:24 +08:00
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form5 . cleaned_data [ ' date_field ' ] )
2012-02-01 04:36:11 +08:00
self . assertHTMLEqual (
2013-11-01 00:27:21 +08:00
' <select name= " mydate_day " id= " id_mydate_day " > \n <option value= " 0 " >---</option> \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= " 0 " >---</option> \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= " 0 " >---</option> \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> ' ,
2015-01-26 11:28:57 +08:00
forms . SelectDateWidget ( years = range ( 2009 , 2019 ) ) . render ( ' mydate ' , datetime . date ( 2009 , 12 , 31 ) )
2009-12-24 22:23:52 +08:00
)
2009-12-23 01:58:49 +08:00
2010-12-22 08:44:54 +08:00
# Russian locale (with E as month)
2011-05-06 21:29:44 +08:00
with translation . override ( ' ru ' , deactivate = True ) :
2012-02-01 04:36:11 +08:00
self . assertHTMLEqual (
2013-11-01 00:27:21 +08:00
' <select name= " mydate_day " id= " id_mydate_day " > \n <option value= " 0 " >---</option> \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= " 0 " >---</option> \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= " 0 " >---</option> \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> ' ,
2015-01-26 11:28:57 +08:00
forms . SelectDateWidget ( years = range ( 2009 , 2019 ) ) . render ( ' mydate ' , datetime . date ( 2009 , 12 , 31 ) )
2011-02-04 23:45:52 +08:00
)
2010-12-22 08:44:54 +08:00
2009-12-23 01:58:49 +08:00
# English locale
2011-05-06 21:29:44 +08:00
with translation . override ( ' en ' , deactivate = True ) :
2009-12-24 22:23:52 +08:00
self . assertEqual ( ' N j, Y ' , get_format ( ' DATE_FORMAT ' ) )
self . assertEqual ( 0 , get_format ( ' FIRST_DAY_OF_WEEK ' ) )
self . assertEqual ( ' . ' , get_format ( ' DECIMAL_SEPARATOR ' ) )
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' Dec. 31, 2009 ' , date_format ( self . d ) )
self . assertEqual ( ' December 2009 ' , date_format ( self . d , ' YEAR_MONTH_FORMAT ' ) )
self . assertEqual ( ' 12/31/2009 8:50 p.m. ' , date_format ( self . dt , ' SHORT_DATETIME_FORMAT ' ) )
self . assertEqual ( ' No localizable ' , localize ( ' No localizable ' ) )
2009-12-24 22:23:52 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( ' 66,666.666 ' , localize ( self . n ) )
self . assertEqual ( ' 99,999.999 ' , localize ( self . f ) )
self . assertEqual ( ' 10,000 ' , localize ( self . l ) )
2009-12-24 22:23:52 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
self . assertEqual ( ' 66666.666 ' , localize ( self . n ) )
self . assertEqual ( ' 99999.999 ' , localize ( self . f ) )
self . assertEqual ( ' 10000 ' , localize ( self . l ) )
self . assertEqual ( ' Dec. 31, 2009 ' , localize ( self . d ) )
self . assertEqual ( ' Dec. 31, 2009, 8:50 p.m. ' , localize ( self . dt ) )
2009-12-24 22:23:52 +08:00
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( ' 66,666.666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 99,999.999 ' , Template ( ' {{ f }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 10,000 ' , Template ( ' {{ l }} ' ) . render ( self . ctxt ) )
with self . settings ( USE_THOUSAND_SEPARATOR = False ) :
self . assertEqual ( ' 66666.666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 99999.999 ' , Template ( ' {{ f }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' Dec. 31, 2009 ' , Template ( ' {{ d }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' Dec. 31, 2009, 8:50 p.m. ' , Template ( ' {{ dt }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 66666.67 ' , Template ( ' {{ n|floatformat:2 }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 100000.0 ' , Template ( ' {{ f|floatformat }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 12/31/2009 ' , Template ( ' {{ d|date: " SHORT_DATE_FORMAT " }} ' ) . render ( self . ctxt ) )
self . assertEqual ( ' 12/31/2009 8:50 p.m. ' , Template ( ' {{ dt|date: " SHORT_DATETIME_FORMAT " }} ' ) . render ( self . ctxt ) )
2009-12-24 22:23:52 +08:00
form5 = I18nForm ( {
2012-06-08 00:08:47 +08:00
' decimal_field ' : ' 66666.666 ' ,
' float_field ' : ' 99999.999 ' ,
' date_field ' : ' 12/31/2009 ' ,
' datetime_field ' : ' 12/31/2009 20:50 ' ,
' time_field ' : ' 20:50 ' ,
' integer_field ' : ' 1234 ' ,
2009-12-24 22:23:52 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form5 . is_valid ( ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( decimal . Decimal ( ' 66666.666 ' ) , form5 . cleaned_data [ ' decimal_field ' ] )
self . assertEqual ( 99999.999 , form5 . cleaned_data [ ' float_field ' ] )
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form5 . cleaned_data [ ' date_field ' ] )
self . assertEqual ( datetime . datetime ( 2009 , 12 , 31 , 20 , 50 ) , form5 . cleaned_data [ ' datetime_field ' ] )
self . assertEqual ( datetime . time ( 20 , 50 ) , form5 . cleaned_data [ ' time_field ' ] )
2010-03-01 18:19:24 +08:00
self . assertEqual ( 1234 , form5 . cleaned_data [ ' integer_field ' ] )
2009-12-24 22:23:52 +08:00
form6 = SelectDateForm ( {
2012-06-08 00:08:47 +08:00
' date_field_month ' : ' 12 ' ,
' date_field_day ' : ' 31 ' ,
' date_field_year ' : ' 2009 '
2009-12-24 22:23:52 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form6 . is_valid ( ) )
2009-12-24 22:23:52 +08:00
self . assertEqual ( datetime . date ( 2009 , 12 , 31 ) , form6 . cleaned_data [ ' date_field ' ] )
2012-02-01 04:36:11 +08:00
self . assertHTMLEqual (
2013-11-01 00:27:21 +08:00
' <select name= " mydate_month " id= " id_mydate_month " > \n <option value= " 0 " >---</option> \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= " 0 " >---</option> \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= " 0 " >---</option> \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> ' ,
2015-01-26 11:28:57 +08:00
forms . SelectDateWidget ( years = range ( 2009 , 2019 ) ) . render ( ' mydate ' , datetime . date ( 2009 , 12 , 31 ) )
2009-12-24 22:23:52 +08:00
)
def test_sub_locales ( self ) :
"""
Check if sublocales fall back to the main locale
"""
2013-02-15 16:36:07 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de-at ' , deactivate = True ) :
2012-06-08 00:08:47 +08:00
self . assertEqual ( ' 66.666,666 ' , Template ( ' {{ n }} ' ) . render ( self . ctxt ) )
2011-05-06 21:29:44 +08:00
with translation . override ( ' es-us ' , deactivate = True ) :
2013-01-18 05:58:53 +08:00
self . assertEqual ( ' 31 de Diciembre de 2009 ' , date_format ( self . d ) )
2009-12-23 01:58:49 +08:00
2009-12-31 06:11:48 +08:00
def test_localized_input ( self ) :
"""
Tests if form input is correctly localized
"""
2013-02-23 16:45:56 +08:00
self . maxDiff = 1200
2011-05-06 21:29:44 +08:00
with translation . override ( ' de-at ' , deactivate = True ) :
2009-12-31 06:11:48 +08:00
form6 = CompanyForm ( {
2012-06-08 00:08:47 +08:00
' name ' : ' acme ' ,
2009-12-31 06:11:48 +08:00
' date_added ' : datetime . datetime ( 2009 , 12 , 31 , 6 , 0 , 0 ) ,
2011-12-04 01:34:52 +08:00
' cents_paid ' : decimal . Decimal ( ' 59.47 ' ) ,
2010-03-01 18:19:24 +08:00
' products_delivered ' : 12000 ,
2009-12-31 06:11:48 +08:00
} )
2015-04-27 22:59:16 +08:00
self . assertTrue ( form6 . is_valid ( ) )
2012-02-01 04:36:11 +08:00
self . assertHTMLEqual (
2009-12-31 06:11:48 +08:00
form6 . as_ul ( ) ,
2012-06-08 00:08:47 +08:00
' <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_paid " >Cents paid:</label> <input type= " text " name= " cents_paid " value= " 59,47 " id= " id_cents_paid " /></li> \n <li><label for= " id_products_delivered " >Products delivered:</label> <input type= " text " name= " products_delivered " value= " 12000 " id= " id_products_delivered " /></li> '
2009-12-31 06:11:48 +08:00
)
self . assertEqual ( localize_input ( datetime . datetime ( 2009 , 12 , 31 , 6 , 0 , 0 ) ) , ' 31.12.2009 06:00:00 ' )
self . assertEqual ( datetime . datetime ( 2009 , 12 , 31 , 6 , 0 , 0 ) , form6 . cleaned_data [ ' date_added ' ] )
2011-05-06 21:29:44 +08:00
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
# Checking for the localized "products_delivered" field
2012-09-28 15:20:01 +08:00
self . assertInHTML ( ' <input type= " text " name= " products_delivered " value= " 12.000 " id= " id_products_delivered " /> ' , form6 . as_ul ( ) )
2009-12-31 06:11:48 +08:00
2013-02-15 23:37:52 +08:00
def test_sanitize_separators ( self ) :
"""
Tests django . utils . formats . sanitize_separators .
"""
# Non-strings are untouched
self . assertEqual ( sanitize_separators ( 123 ) , 123 )
with translation . override ( ' ru ' , deactivate = True ) :
# Russian locale has non-breaking space (\xa0) as thousand separator
# Check that usual space is accepted too when sanitizing inputs
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( sanitize_separators ( ' 1 \xa0 234 \xa0 567 ' ) , ' 1234567 ' )
self . assertEqual ( sanitize_separators ( ' 77 \xa0 777,777 ' ) , ' 77777.777 ' )
self . assertEqual ( sanitize_separators ( ' 12 345 ' ) , ' 12345 ' )
self . assertEqual ( sanitize_separators ( ' 77 777,777 ' ) , ' 77777.777 ' )
with self . settings ( USE_THOUSAND_SEPARATOR = True , USE_L10N = False ) :
self . assertEqual ( sanitize_separators ( ' 12 \xa0 345 ' ) , ' 12 \xa0 345 ' )
2014-08-19 01:57:50 +08:00
with patch_formats ( get_language ( ) , THOUSAND_SEPARATOR = ' . ' , DECIMAL_SEPARATOR = ' , ' ) :
with self . settings ( USE_THOUSAND_SEPARATOR = True ) :
self . assertEqual ( sanitize_separators ( ' 10.234 ' ) , ' 10234 ' )
# Suspicion that user entered dot as decimal separator (#22171)
self . assertEqual ( sanitize_separators ( ' 10.10 ' ) , ' 10.10 ' )
2010-09-27 23:25:08 +08:00
def test_iter_format_modules ( self ) :
"""
Tests the iter_format_modules function .
"""
2014-05-19 13:23:45 +08:00
# Importing some format modules so that we can compare the returned
# modules with these expected modules
default_mod = import_module ( ' django.conf.locale.de.formats ' )
test_mod = import_module ( ' i18n.other.locale.de.formats ' )
test_mod2 = import_module ( ' i18n.other2.locale.de.formats ' )
2011-05-06 21:29:44 +08:00
with translation . override ( ' de-at ' , deactivate = True ) :
2014-05-19 13:23:45 +08:00
# Should return the correct default module when no setting is set
self . assertEqual ( list ( iter_format_modules ( ' de ' ) ) , [ default_mod ] )
# When the setting is a string, should return the given module and
# the default module
self . assertEqual (
list ( iter_format_modules ( ' de ' , ' i18n.other.locale ' ) ) ,
[ test_mod , default_mod ] )
# When setting is a list of strings, should return the given
# modules and the default module
self . assertEqual (
list ( iter_format_modules ( ' de ' , [ ' i18n.other.locale ' , ' i18n.other2.locale ' ] ) ) ,
[ test_mod , test_mod2 , default_mod ] )
2010-09-27 23:25:08 +08:00
2011-01-13 11:02:32 +08:00
def test_iter_format_modules_stability ( self ) :
"""
Tests the iter_format_modules function always yields format modules in
a stable and correct order in presence of both base ll and ll_CC formats .
"""
2011-02-04 23:45:52 +08:00
en_format_mod = import_module ( ' django.conf.locale.en.formats ' )
en_gb_format_mod = import_module ( ' django.conf.locale.en_GB.formats ' )
self . assertEqual ( list ( iter_format_modules ( ' en-gb ' ) ) , [ en_gb_format_mod , en_format_mod ] )
2011-01-13 11:02:32 +08:00
2011-09-22 23:04:27 +08:00
def test_get_format_modules_lang ( self ) :
2013-02-15 16:36:07 +08:00
with translation . override ( ' de ' , deactivate = True ) :
self . assertEqual ( ' . ' , get_format ( ' DECIMAL_SEPARATOR ' , lang = ' en ' ) )
2011-09-22 23:04:27 +08:00
2011-02-03 23:43:50 +08:00
def test_get_format_modules_stability ( self ) :
2013-09-22 19:49:46 +08:00
with self . settings ( FORMAT_MODULE_PATH = ' i18n.other.locale ' ) :
with translation . override ( ' de ' , deactivate = True ) :
old = str ( " %r " ) % get_format_modules ( reverse = True )
2013-11-03 05:02:56 +08:00
new = str ( " %r " ) % get_format_modules ( reverse = True ) # second try
2013-09-22 19:49:46 +08:00
self . assertEqual ( new , old , ' Value returned by get_formats_modules() must be preserved between calls. ' )
2011-02-03 23:43:50 +08:00
2010-10-30 00:48:58 +08:00
def test_localize_templatetag_and_filter ( self ) :
"""
Tests the { % localize % } templatetag
"""
2013-10-15 03:13:14 +08:00
context = Context ( { ' value ' : 3.14 } )
2010-10-30 00:48:58 +08:00
template1 = Template ( " { % lo ad l10n % } { % lo calize % } {{ value }} { % e ndlocalize % }; { % lo calize on % } {{ value }} { % e ndlocalize % } " )
template2 = Template ( " { % lo ad l10n % } {{ value }}; { % lo calize off % } {{ value }}; { % e ndlocalize % } {{ value }} " )
template3 = Template ( ' { % lo ad l10n % } {{ value }}; {{ value|unlocalize }} ' )
template4 = Template ( ' { % lo ad l10n % } {{ value }}; {{ value|localize }} ' )
output1 = ' 3,14;3,14 '
output2 = ' 3,14;3.14;3,14 '
output3 = ' 3,14;3.14 '
output4 = ' 3.14;3,14 '
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
with self . settings ( USE_L10N = False ) :
self . assertEqual ( template1 . render ( context ) , output1 )
self . assertEqual ( template4 . render ( context ) , output4 )
with self . settings ( USE_L10N = True ) :
self . assertEqual ( template1 . render ( context ) , output1 )
self . assertEqual ( template2 . render ( context ) , output2 )
self . assertEqual ( template3 . render ( context ) , output3 )
2010-10-30 00:48:58 +08:00
2013-02-24 21:57:29 +08:00
def test_localized_as_text_as_hidden_input ( self ) :
"""
Tests if form input with ' as_hidden ' or ' as_text ' is correctly localized . Ticket #18777
"""
self . maxDiff = 1200
with translation . override ( ' de-at ' , deactivate = True ) :
template = Template ( ' { % lo ad l10n % } {{ form.date_added }}; {{ form.cents_paid }} ' )
template_as_text = Template ( ' { % lo ad l10n % } {{ form.date_added.as_text }}; {{ form.cents_paid.as_text }} ' )
template_as_hidden = Template ( ' { % lo ad l10n % } {{ form.date_added.as_hidden }}; {{ form.cents_paid.as_hidden }} ' )
form = CompanyForm ( {
' name ' : ' acme ' ,
' date_added ' : datetime . datetime ( 2009 , 12 , 31 , 6 , 0 , 0 ) ,
' cents_paid ' : decimal . Decimal ( ' 59.47 ' ) ,
' products_delivered ' : 12000 ,
2013-10-18 17:02:43 +08:00
} )
2013-10-15 03:13:14 +08:00
context = Context ( { ' form ' : form } )
2013-02-24 21:57:29 +08:00
self . assertTrue ( form . is_valid ( ) )
self . assertHTMLEqual (
template . render ( context ) ,
' <input id= " id_date_added " name= " date_added " type= " text " value= " 31.12.2009 06:00:00 " />; <input id= " id_cents_paid " name= " cents_paid " type= " text " value= " 59,47 " /> '
)
self . assertHTMLEqual (
template_as_text . render ( context ) ,
' <input id= " id_date_added " name= " date_added " type= " text " value= " 31.12.2009 06:00:00 " />; <input id= " id_cents_paid " name= " cents_paid " type= " text " value= " 59,47 " /> '
)
self . assertHTMLEqual (
template_as_hidden . render ( context ) ,
' <input id= " id_date_added " name= " date_added " type= " hidden " value= " 31.12.2009 06:00:00 " />; <input id= " id_cents_paid " name= " cents_paid " type= " hidden " value= " 59,47 " /> '
)
2014-01-26 22:28:33 +08:00
class MiscTests ( TestCase ) :
2009-12-23 01:58:49 +08:00
2011-06-16 01:29:10 +08:00
def setUp ( self ) :
2013-05-19 17:44:46 +08:00
super ( MiscTests , self ) . setUp ( )
2011-06-16 01:29:10 +08:00
self . rf = RequestFactory ( )
2015-02-28 03:17:04 +08:00
@override_settings ( LANGUAGE_CODE = ' de ' )
def test_english_fallback ( self ) :
"""
With a non - English LANGUAGE_CODE and if the active language is English
or one of its variants , the untranslated string should be returned
( instead of falling back to LANGUAGE_CODE ) ( See #24413).
"""
self . assertEqual ( ugettext ( " Image " ) , " Bild " )
with translation . override ( ' en ' ) :
self . assertEqual ( ugettext ( " Image " ) , " Image " )
with translation . override ( ' en-us ' ) :
self . assertEqual ( ugettext ( " Image " ) , " Image " )
with translation . override ( ' en-ca ' ) :
self . assertEqual ( ugettext ( " Image " ) , " Image " )
2009-12-23 01:58:49 +08:00
def test_parse_spec_http_header ( self ) :
"""
Testing HTTP header parsing . First , we test that we can parse the
values according to the spec ( and that we extract all the pieces in
the right order ) .
"""
2012-10-22 20:45:41 +08:00
p = trans_real . parse_accept_lang_header
2009-12-23 01:58:49 +08:00
# Good headers.
self . assertEqual ( [ ( ' de ' , 1.0 ) ] , p ( ' de ' ) )
2013-11-12 14:54:01 +08:00
self . assertEqual ( [ ( ' en-au ' , 1.0 ) ] , p ( ' en-AU ' ) )
2012-10-21 07:25:35 +08:00
self . assertEqual ( [ ( ' es-419 ' , 1.0 ) ] , p ( ' es-419 ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( [ ( ' * ' , 1.0 ) ] , p ( ' *;q=1.00 ' ) )
2013-11-12 14:54:01 +08:00
self . assertEqual ( [ ( ' en-au ' , 0.123 ) ] , p ( ' en-AU;q=0.123 ' ) )
2010-01-10 04:57:32 +08:00
self . assertEqual ( [ ( ' en-au ' , 0.5 ) ] , p ( ' en-au;q=0.5 ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( [ ( ' en-au ' , 1.0 ) ] , p ( ' en-au;q=1.0 ' ) )
self . assertEqual ( [ ( ' da ' , 1.0 ) , ( ' en ' , 0.5 ) , ( ' en-gb ' , 0.25 ) ] , p ( ' da, en-gb;q=0.25, en;q=0.5 ' ) )
self . assertEqual ( [ ( ' en-au-xx ' , 1.0 ) ] , p ( ' en-au-xx ' ) )
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 ' ) )
self . assertEqual ( [ ( ' * ' , 1.0 ) ] , p ( ' * ' ) )
self . assertEqual ( [ ( ' de ' , 1.0 ) ] , p ( ' de;q=0. ' ) )
2011-06-27 00:51:54 +08:00
self . assertEqual ( [ ( ' en ' , 1.0 ) , ( ' * ' , 0.5 ) ] , p ( ' en; q=1.0, * ; q=0.5 ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( [ ] , p ( ' ' ) )
# Bad headers; should always return [].
self . assertEqual ( [ ] , p ( ' en-gb;q=1.0000 ' ) )
self . assertEqual ( [ ] , p ( ' en;q=0.1234 ' ) )
self . assertEqual ( [ ] , p ( ' en;q=.2 ' ) )
self . assertEqual ( [ ] , p ( ' abcdefghi-au ' ) )
self . assertEqual ( [ ] , p ( ' ** ' ) )
self . assertEqual ( [ ] , p ( ' en,,gb ' ) )
self . assertEqual ( [ ] , p ( ' en-au;q=0.1.0 ' ) )
self . assertEqual ( [ ] , p ( ' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en ' ) )
self . assertEqual ( [ ] , p ( ' da, en-gb;q=0.8, en;q=0.7,# ' ) )
self . assertEqual ( [ ] , p ( ' de;q=2.0 ' ) )
self . assertEqual ( [ ] , p ( ' de;q=0.a ' ) )
2012-10-21 07:25:35 +08:00
self . assertEqual ( [ ] , p ( ' 12-345 ' ) )
2009-12-23 01:58:49 +08:00
self . assertEqual ( [ ] , p ( ' ' ) )
2013-09-10 00:48:56 +08:00
self . assertEqual ( [ ] , p ( ' en; q=1, ' ) )
2009-12-23 01:58:49 +08:00
def test_parse_literal_http_header ( self ) :
"""
Now test that we parse a literal HTTP header correctly .
"""
g = get_language_from_request
2011-06-16 01:29:10 +08:00
r = self . rf . get ( ' / ' )
2009-12-23 01:58:49 +08:00
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' pt-br ' }
self . assertEqual ( ' pt-br ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' pt ' }
self . assertEqual ( ' pt ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' es,de ' }
self . assertEqual ( ' es ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' es-ar,de ' }
self . assertEqual ( ' es-ar ' , g ( r ) )
2011-03-28 10:27:43 +08:00
# This test assumes there won't be a Django translation to a US
# variation of the Spanish language, a safe assumption. When the
# user sets it as the preferred language, the main 'es'
# translation should be selected instead.
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' es-us ' }
self . assertEqual ( g ( r ) , ' es ' )
2009-12-23 01:58:49 +08:00
# This tests the following scenario: there isn't a main language (zh)
2015-01-10 04:08:16 +08:00
# translation of Django but there is a translation to variation (zh-hans)
# the user sets zh-hans as the preferred language, it should be selected
2009-12-23 01:58:49 +08:00
# by Django without falling back nor ignoring it.
2015-01-10 04:08:16 +08:00
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-hans,de ' }
self . assertEqual ( g ( r ) , ' zh-hans ' )
2013-11-05 01:31:34 +08:00
2013-11-12 14:54:01 +08:00
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' NL ' }
self . assertEqual ( ' nl ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' fy ' }
self . assertEqual ( ' fy ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' ia ' }
self . assertEqual ( ' ia ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' sr-latn ' }
self . assertEqual ( ' sr-latn ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-hans ' }
self . assertEqual ( ' zh-hans ' , g ( r ) )
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-hant ' }
self . assertEqual ( ' zh-hant ' , g ( r ) )
2013-11-05 01:31:34 +08:00
@override_settings (
2015-01-22 00:55:57 +08:00
LANGUAGES = [
2013-11-05 01:31:34 +08:00
( ' en ' , ' English ' ) ,
( ' zh-hans ' , ' Simplified Chinese ' ) ,
( ' zh-hant ' , ' Traditional Chinese ' ) ,
2015-01-22 00:55:57 +08:00
]
2013-11-05 01:31:34 +08:00
)
def test_support_for_deprecated_chinese_language_codes ( self ) :
"""
Some browsers ( Firefox , IE etc ) use deprecated language codes . As these
language codes will be removed in Django 1.9 , these will be incorrectly
matched . For example zh - tw ( traditional ) will be interpreted as zh - hans
( simplified ) , which is wrong . So we should also accept these deprecated
language codes .
refs #18419 -- this is explicitly for browser compatibility
"""
g = get_language_from_request
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-cn,en ' }
self . assertEqual ( g ( r ) , ' zh-hans ' )
2013-11-05 17:54:23 +08:00
2013-11-05 01:31:34 +08:00
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-tw,en ' }
self . assertEqual ( g ( r ) , ' zh-hant ' )
2013-11-05 17:54:23 +08:00
2014-07-12 03:01:37 +08:00
def test_special_fallback_language ( self ) :
"""
Some languages may have special fallbacks that don ' t follow the simple
' fr-ca ' - > ' fr ' logic ( notably Chinese codes ) .
"""
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' zh-my,en ' }
self . assertEqual ( get_language_from_request ( r ) , ' zh-hans ' )
2010-02-16 20:13:48 +08:00
def test_parse_language_cookie ( self ) :
"""
Now test that we parse language preferences stored in a cookie correctly .
"""
g = get_language_from_request
2011-06-16 01:29:10 +08:00
r = self . rf . get ( ' / ' )
2010-02-16 20:13:48 +08:00
r . COOKIES = { settings . LANGUAGE_COOKIE_NAME : ' pt-br ' }
r . META = { }
self . assertEqual ( ' pt-br ' , g ( r ) )
r . COOKIES = { settings . LANGUAGE_COOKIE_NAME : ' pt ' }
r . META = { }
self . assertEqual ( ' pt ' , g ( r ) )
r . COOKIES = { settings . LANGUAGE_COOKIE_NAME : ' es ' }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' de ' }
self . assertEqual ( ' es ' , g ( r ) )
2011-03-28 10:27:43 +08:00
# This test assumes there won't be a Django translation to a US
# variation of the Spanish language, a safe assumption. When the
# user sets it as the preferred language, the main 'es'
# translation should be selected instead.
r . COOKIES = { settings . LANGUAGE_COOKIE_NAME : ' es-us ' }
r . META = { }
self . assertEqual ( g ( r ) , ' es ' )
2010-02-16 20:13:48 +08:00
# This tests the following scenario: there isn't a main language (zh)
2015-01-10 04:08:16 +08:00
# translation of Django but there is a translation to variation (zh-hans)
# the user sets zh-hans as the preferred language, it should be selected
2010-02-16 20:13:48 +08:00
# by Django without falling back nor ignoring it.
2015-01-10 04:08:16 +08:00
r . COOKIES = { settings . LANGUAGE_COOKIE_NAME : ' zh-hans ' }
2010-02-16 20:13:48 +08:00
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' de ' }
2015-01-10 04:08:16 +08:00
self . assertEqual ( g ( r ) , ' zh-hans ' )
2010-02-16 20:17:17 +08:00
2012-08-23 17:18:41 +08:00
def test_get_language_from_path_real ( self ) :
2012-10-22 20:45:41 +08:00
g = trans_real . get_language_from_path
2012-02-05 02:43:20 +08:00
self . assertEqual ( g ( ' /pl/ ' ) , ' pl ' )
self . assertEqual ( g ( ' /pl ' ) , ' pl ' )
self . assertEqual ( g ( ' /xyz/ ' ) , None )
2012-08-23 17:18:41 +08:00
def test_get_language_from_path_null ( self ) :
2012-02-05 02:43:20 +08:00
from django . utils . translation . trans_null import get_language_from_path as g
self . assertEqual ( g ( ' /pl/ ' ) , None )
self . assertEqual ( g ( ' /pl ' ) , None )
self . assertEqual ( g ( ' /xyz/ ' ) , None )
2012-10-22 20:45:41 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
2011-09-08 21:25:41 +08:00
def test_percent_in_translatable_block ( self ) :
2012-10-22 20:45:41 +08:00
t_sing = Template ( " { % lo ad i18n % } { % blocktrans % }The result was {{ percent }} % { % e ndblocktrans % } " )
t_plur = Template ( " { % lo ad i18n % } { % blocktrans count num as number % } {{ percent }} % r epresents {{ num }} object { % plural % } {{ percent }} % r epresents {{ num }} objects { % e ndblocktrans % } " )
with translation . override ( ' de ' ) :
self . assertEqual ( t_sing . render ( Context ( { ' percent ' : 42 } ) ) , ' Das Ergebnis war 42 % ' )
self . assertEqual ( t_plur . render ( Context ( { ' percent ' : 42 , ' num ' : 1 } ) ) , ' 42 % s tellt 1 Objekt dar ' )
self . assertEqual ( t_plur . render ( Context ( { ' percent ' : 42 , ' num ' : 4 } ) ) , ' 42 % s tellt 4 Objekte dar ' )
2011-09-08 21:25:41 +08:00
2012-10-24 00:48:24 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
def test_percent_formatting_in_blocktrans ( self ) :
"""
Test that using Python ' s %-f ormatting is properly escaped in blocktrans,
singular or plural
"""
t_sing = Template ( " { % lo ad i18n % } { % blocktrans % }There are %(num_comments)s comments { % e ndblocktrans % } " )
t_plur = Template ( " { % lo ad i18n % } { % blocktrans count num as number % } %(percent)s % r epresents {{ num }} object { % plural % } %(percent)s % r epresents {{ num }} objects { % e ndblocktrans % } " )
with translation . override ( ' de ' ) :
# Strings won't get translated as they don't match after escaping %
self . assertEqual ( t_sing . render ( Context ( { ' num_comments ' : 42 } ) ) , ' There are %(num_comments)s comments ' )
self . assertEqual ( t_plur . render ( Context ( { ' percent ' : 42 , ' num ' : 1 } ) ) , ' %(percent)s % r epresents 1 object ' )
self . assertEqual ( t_plur . render ( Context ( { ' percent ' : 42 , ' num ' : 4 } ) ) , ' %(percent)s % r epresents 4 objects ' )
2013-10-28 23:57:56 +08:00
def test_cache_resetting ( self ) :
"""
#14170 after setting LANGUAGE, cache should be cleared and languages
previously valid should not be used .
"""
g = get_language_from_request
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' pt-br ' }
self . assertEqual ( ' pt-br ' , g ( r ) )
2015-01-22 00:55:57 +08:00
with self . settings ( LANGUAGES = [ ( ' en ' , ' English ' ) ] ) :
2013-10-28 23:57:56 +08:00
self . assertNotEqual ( ' pt-br ' , g ( r ) )
2011-09-08 21:25:41 +08:00
2014-01-26 22:28:33 +08:00
class ResolutionOrderI18NTests ( TestCase ) :
2010-02-16 20:17:17 +08:00
def setUp ( self ) :
2013-05-19 17:44:46 +08:00
super ( ResolutionOrderI18NTests , self ) . setUp ( )
2010-02-16 20:17:17 +08:00
activate ( ' de ' )
def tearDown ( self ) :
deactivate ( )
2013-05-19 17:44:46 +08:00
super ( ResolutionOrderI18NTests , self ) . tearDown ( )
2010-02-16 20:17:17 +08:00
def assertUgettext ( self , msgid , msgstr ) :
result = ugettext ( msgid )
2014-10-28 18:02:56 +08:00
self . assertIn ( msgstr , result , ( " The string ' %s ' isn ' t in the "
2010-02-16 20:17:17 +08:00
" translation of ' %s ' ; the actual result is ' %s ' . " % ( msgstr , msgid , result ) ) )
2013-11-03 12:36:09 +08:00
2010-02-16 20:17:17 +08:00
class AppResolutionOrderI18NTests ( ResolutionOrderI18NTests ) :
2014-01-26 22:28:33 +08:00
@override_settings ( LANGUAGE_CODE = ' de ' )
2010-02-16 20:17:17 +08:00
def test_app_translation ( self ) :
2013-12-19 22:57:23 +08:00
# Original translation.
self . assertUgettext ( ' Date/time ' , ' Datum/Zeit ' )
# Different translation.
2013-12-23 17:37:34 +08:00
with self . modify_settings ( INSTALLED_APPS = { ' append ' : ' i18n.resolution ' } ) :
2014-01-26 22:28:33 +08:00
# Force refreshing translations.
2013-12-19 22:57:23 +08:00
activate ( ' de ' )
# Doesn't work because it's added later in the list.
self . assertUgettext ( ' Date/time ' , ' Datum/Zeit ' )
2014-01-25 05:43:00 +08:00
with self . modify_settings ( INSTALLED_APPS = { ' remove ' : ' django.contrib.admin.apps.SimpleAdminConfig ' } ) :
2014-01-26 22:28:33 +08:00
# Force refreshing translations.
2013-12-19 22:57:23 +08:00
activate ( ' de ' )
# Unless the original is removed from the list.
self . assertUgettext ( ' Date/time ' , ' Datum/Zeit (APP) ' )
2010-02-16 20:17:17 +08:00
2013-11-03 12:36:09 +08:00
2012-10-22 20:45:41 +08:00
@override_settings ( LOCALE_PATHS = extended_locale_paths )
2010-02-16 20:17:17 +08:00
class LocalePathsResolutionOrderI18NTests ( ResolutionOrderI18NTests ) :
def test_locale_paths_translation ( self ) :
2011-01-22 03:36:26 +08:00
self . assertUgettext ( ' Time ' , ' LOCALE_PATHS ' )
2010-02-16 20:17:17 +08:00
2011-02-08 02:48:40 +08:00
def test_locale_paths_override_app_translation ( self ) :
2013-12-23 17:37:34 +08:00
with self . settings ( INSTALLED_APPS = [ ' i18n.resolution ' ] ) :
2011-02-08 02:48:40 +08:00
self . assertUgettext ( ' Time ' , ' LOCALE_PATHS ' )
2013-11-03 12:36:09 +08:00
2010-02-16 20:17:17 +08:00
class DjangoFallbackResolutionOrderI18NTests ( ResolutionOrderI18NTests ) :
def test_django_fallback ( self ) :
2011-02-08 02:48:40 +08:00
self . assertEqual ( ugettext ( ' Date/time ' ) , ' Datum/Zeit ' )
2010-09-13 04:03:39 +08:00
class TestModels ( TestCase ) :
def test_lazy ( self ) :
tm = TestModel ( )
tm . save ( )
def test_safestr ( self ) :
2011-12-04 01:34:52 +08:00
c = Company ( cents_paid = 12 , products_delivered = 1 )
2012-08-18 22:04:06 +08:00
c . name = SafeText ( ' Iñtërnâtiônàlizætiøn1 ' )
2010-09-13 04:03:39 +08:00
c . save ( )
2012-08-18 22:04:06 +08:00
c . name = SafeBytes ( ' Iñtërnâtiônàlizætiøn1 ' . encode ( ' utf-8 ' ) )
2010-09-13 04:03:39 +08:00
c . save ( )
2010-12-13 07:02:45 +08:00
class TestLanguageInfo ( TestCase ) :
def test_localized_language_info ( self ) :
li = get_language_info ( ' de ' )
self . assertEqual ( li [ ' code ' ] , ' de ' )
2012-06-08 00:08:47 +08:00
self . assertEqual ( li [ ' name_local ' ] , ' Deutsch ' )
2010-12-13 07:02:45 +08:00
self . assertEqual ( li [ ' name ' ] , ' German ' )
self . assertEqual ( li [ ' bidi ' ] , False )
2011-01-26 23:12:18 +08:00
2013-02-24 00:02:07 +08:00
def test_unknown_language_code ( self ) :
2013-02-24 21:43:45 +08:00
six . assertRaisesRegex ( self , KeyError , r " Unknown language code xx \ . " , get_language_info , ' xx ' )
2013-02-24 00:02:07 +08:00
def test_unknown_only_country_code ( self ) :
li = get_language_info ( ' de-xx ' )
self . assertEqual ( li [ ' code ' ] , ' de ' )
self . assertEqual ( li [ ' name_local ' ] , ' Deutsch ' )
self . assertEqual ( li [ ' name ' ] , ' German ' )
self . assertEqual ( li [ ' bidi ' ] , False )
def test_unknown_language_code_and_country_code ( self ) :
2013-02-24 21:43:45 +08:00
six . assertRaisesRegex ( self , KeyError , r " Unknown language code xx-xx and xx \ . " , get_language_info , ' xx-xx ' )
2013-02-24 00:02:07 +08:00
2014-07-12 03:01:37 +08:00
def test_fallback_language_code ( self ) :
"""
get_language_info return the first fallback language info if the lang_info
struct does not contain the ' name ' key .
"""
li = get_language_info ( ' zh-my ' )
self . assertEqual ( li [ ' code ' ] , ' zh-hans ' )
2015-01-10 04:08:16 +08:00
li = get_language_info ( ' zh-hans ' )
self . assertEqual ( li [ ' code ' ] , ' zh-hans ' )
2014-07-12 03:01:37 +08:00
2011-01-26 23:12:18 +08:00
2014-01-26 22:28:33 +08:00
class MultipleLocaleActivationTests ( TestCase ) :
2011-01-26 23:12:18 +08:00
"""
Tests for template rendering behavior when multiple locales are activated
during the lifetime of the same process .
"""
def setUp ( self ) :
2013-05-19 17:44:46 +08:00
super ( MultipleLocaleActivationTests , self ) . setUp ( )
2011-01-26 23:12:18 +08:00
self . _old_language = get_language ( )
def tearDown ( self ) :
2013-05-19 17:44:46 +08:00
super ( MultipleLocaleActivationTests , self ) . tearDown ( )
2011-01-26 23:12:18 +08:00
activate ( self . _old_language )
def test_single_locale_activation ( self ) :
"""
Simple baseline behavior with one locale for all the supported i18n constructs .
"""
2011-05-06 21:29:44 +08:00
with translation . override ( ' fr ' ) :
self . assertEqual ( Template ( " {{ _( ' Yes ' ) }} " ) . render ( Context ( { } ) ) , ' Oui ' )
self . assertEqual ( Template ( " { % lo ad i18n % } { % trans ' Yes ' % } " ) . render ( Context ( { } ) ) , ' Oui ' )
self . assertEqual ( Template ( " { % lo ad i18n % } { % blocktrans % }Yes { % e ndblocktrans % } " ) . render ( Context ( { } ) ) , ' Oui ' )
2011-01-26 23:12:18 +08:00
# Literal marked up with _() in a filter expression
def test_multiple_locale_filter ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } {{ 0|yesno:_( ' yes,no,maybe ' ) }} " )
2013-08-17 02:12:10 +08:00
with translation . override ( self . _old_language ) , translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_filter_deactivate ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
t = Template ( " { % lo ad i18n % } {{ 0|yesno:_( ' yes,no,maybe ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_filter_direct_switch ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } {{ 0|yesno:_( ' yes,no,maybe ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' nee ' )
2011-01-26 23:12:18 +08:00
# Literal marked up with _()
def test_multiple_locale ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " {{ _( ' No ' ) }} " )
2013-08-17 02:12:10 +08:00
with translation . override ( self . _old_language ) , translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_deactivate ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
t = Template ( " {{ _( ' No ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_direct_switch ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " {{ _( ' No ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
# Literal marked up with _(), loading the i18n template tag library
def test_multiple_locale_loadi18n ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } {{ _( ' No ' ) }} " )
2013-08-17 02:12:10 +08:00
with translation . override ( self . _old_language ) , translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_loadi18n_deactivate ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
t = Template ( " { % lo ad i18n % } {{ _( ' No ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_loadi18n_direct_switch ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } {{ _( ' No ' ) }} " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
# trans i18n tag
def test_multiple_locale_trans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } { % trans ' No ' % } " )
2013-08-17 02:12:10 +08:00
with translation . override ( self . _old_language ) , translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_deactivate_trans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
t = Template ( " { % lo ad i18n % } { % trans ' No ' % } " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_direct_switch_trans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } { % trans ' No ' % } " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
# blocktrans i18n tag
def test_multiple_locale_btrans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } { % blocktrans % }No { % e ndblocktrans % } " )
2013-08-17 02:12:10 +08:00
with translation . override ( self . _old_language ) , translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_deactivate_btrans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' , deactivate = True ) :
t = Template ( " { % lo ad i18n % } { % blocktrans % }No { % e ndblocktrans % } " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2011-01-26 23:12:18 +08:00
def test_multiple_locale_direct_switch_btrans ( self ) :
2011-05-06 21:29:44 +08:00
with translation . override ( ' de ' ) :
t = Template ( " { % lo ad i18n % } { % blocktrans % }No { % e ndblocktrans % } " )
with translation . override ( ' nl ' ) :
self . assertEqual ( t . render ( Context ( { } ) ) , ' Nee ' )
2013-02-28 20:45:21 +08:00
@override_settings (
USE_I18N = True ,
2015-01-22 00:55:57 +08:00
LANGUAGES = [
2013-02-28 20:45:21 +08:00
( ' en ' , ' English ' ) ,
( ' fr ' , ' French ' ) ,
2015-01-22 00:55:57 +08:00
] ,
MIDDLEWARE_CLASSES = [
2013-02-28 20:45:21 +08:00
' django.middleware.locale.LocaleMiddleware ' ,
' django.middleware.common.CommonMiddleware ' ,
2015-01-22 00:55:57 +08:00
] ,
2014-04-05 14:04:46 +08:00
ROOT_URLCONF = ' i18n.urls ' ,
2013-02-28 20:45:21 +08:00
)
2014-01-26 22:28:33 +08:00
class LocaleMiddlewareTests ( TestCase ) :
2013-02-28 20:45:21 +08:00
def test_streaming_response ( self ) :
# Regression test for #5241
response = self . client . get ( ' /fr/streaming/ ' )
self . assertContains ( response , " Oui/Non " )
response = self . client . get ( ' /en/streaming/ ' )
self . assertContains ( response , " Yes/No " )
2013-05-18 20:37:04 +08:00
2013-03-25 22:45:24 +08:00
@override_settings (
2015-01-22 00:55:57 +08:00
MIDDLEWARE_CLASSES = [
2013-03-25 22:45:24 +08:00
' django.contrib.sessions.middleware.SessionMiddleware ' ,
' django.middleware.locale.LocaleMiddleware ' ,
' django.middleware.common.CommonMiddleware ' ,
2015-01-22 00:55:57 +08:00
] ,
2013-03-25 22:45:24 +08:00
)
2013-11-24 01:27:23 +08:00
def test_language_not_saved_to_session ( self ) :
""" Checks that current language is not automatically saved to
session on every request . """
# Regression test for #21473
2013-10-22 21:31:43 +08:00
self . client . get ( ' /fr/simple/ ' )
2014-02-22 21:27:57 +08:00
self . assertNotIn ( LANGUAGE_SESSION_KEY , self . client . session )
2013-03-25 22:45:24 +08:00
2013-05-18 20:37:04 +08:00
@override_settings (
USE_I18N = True ,
2015-01-22 00:55:57 +08:00
LANGUAGES = [
2013-05-18 20:37:04 +08:00
( ' bg ' , ' Bulgarian ' ) ,
( ' en-us ' , ' English ' ) ,
2013-05-19 18:43:34 +08:00
( ' pt-br ' , ' Portugese (Brazil) ' ) ,
2015-01-22 00:55:57 +08:00
] ,
MIDDLEWARE_CLASSES = [
2013-05-18 20:37:04 +08:00
' django.middleware.locale.LocaleMiddleware ' ,
' django.middleware.common.CommonMiddleware ' ,
2015-01-22 00:55:57 +08:00
] ,
2014-04-05 14:04:46 +08:00
ROOT_URLCONF = ' i18n.urls '
2013-05-18 20:37:04 +08:00
)
2014-01-26 22:28:33 +08:00
class CountrySpecificLanguageTests ( TestCase ) :
2013-05-18 20:37:04 +08:00
def setUp ( self ) :
2013-05-19 17:44:46 +08:00
super ( CountrySpecificLanguageTests , self ) . setUp ( )
2013-05-18 20:37:04 +08:00
self . rf = RequestFactory ( )
def test_check_for_language ( self ) :
self . assertTrue ( check_for_language ( ' en ' ) )
self . assertTrue ( check_for_language ( ' en-us ' ) )
self . assertTrue ( check_for_language ( ' en-US ' ) )
2014-12-30 22:41:31 +08:00
self . assertTrue ( check_for_language ( ' be ' ) )
self . assertTrue ( check_for_language ( ' be@latin ' ) )
self . assertTrue ( check_for_language ( ' sr-RS@latin ' ) )
self . assertTrue ( check_for_language ( ' sr-RS@12345 ' ) )
2013-11-20 23:31:53 +08:00
self . assertFalse ( check_for_language ( ' en-ü ' ) )
self . assertFalse ( check_for_language ( ' en \x00 ' ) )
2015-04-03 18:11:54 +08:00
self . assertFalse ( check_for_language ( None ) )
2014-12-30 22:41:31 +08:00
self . assertFalse ( check_for_language ( ' be@ ' ) )
# Specifying encoding is not supported (Django enforces UTF-8)
self . assertFalse ( check_for_language ( ' tr-TR.UTF-8 ' ) )
self . assertFalse ( check_for_language ( ' tr-TR.UTF8 ' ) )
self . assertFalse ( check_for_language ( ' de-DE.utf-8 ' ) )
2013-05-18 20:37:04 +08:00
def test_get_language_from_request ( self ) :
2013-05-19 17:44:46 +08:00
# issue 19919
2013-05-18 20:37:04 +08:00
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' en-US,en;q=0.8,bg;q=0.6,ru;q=0.4 ' }
lang = get_language_from_request ( r )
self . assertEqual ( ' en-us ' , lang )
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4 ' }
lang = get_language_from_request ( r )
self . assertEqual ( ' bg ' , lang )
2013-05-19 18:43:34 +08:00
def test_specific_language_codes ( self ) :
# issue 11915
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' pt,en-US;q=0.8,en;q=0.6,ru;q=0.4 ' }
lang = get_language_from_request ( r )
self . assertEqual ( ' pt-br ' , lang )
r = self . rf . get ( ' / ' )
r . COOKIES = { }
r . META = { ' HTTP_ACCEPT_LANGUAGE ' : ' pt-pt,en-US;q=0.8,en;q=0.6,ru;q=0.4 ' }
lang = get_language_from_request ( r )
self . assertEqual ( ' pt-br ' , lang )
2014-05-01 00:04:30 +08:00
class TranslationFilesMissing ( TestCase ) :
def setUp ( self ) :
super ( TranslationFilesMissing , self ) . setUp ( )
self . gettext_find_builtin = gettext_module . find
def tearDown ( self ) :
gettext_module . find = self . gettext_find_builtin
super ( TranslationFilesMissing , self ) . tearDown ( )
def patchGettextFind ( self ) :
gettext_module . find = lambda * args , * * kw : None
def test_failure_finding_default_mo_files ( self ) :
'''
Ensure IOError is raised if the default language is unparseable .
Refs : #18192
'''
self . patchGettextFind ( )
trans_real . _translations = { }
self . assertRaises ( IOError , activate , ' en ' )