1# -*- coding: utf-8 -*- 2from __future__ import with_statement 3 4import sys 5import os 6sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) 7 8import pickle 9from threading import Thread, Semaphore 10 11import unittest 12from decimal import Decimal 13import flask 14from datetime import datetime, timedelta 15import flask_babel as babel 16from flask_babel import gettext, ngettext, lazy_gettext, lazy_ngettext, get_translations 17from babel.support import NullTranslations 18from flask_babel._compat import text_type 19 20 21class IntegrationTestCase(unittest.TestCase): 22 def test_no_request_context(self): 23 b = babel.Babel() 24 app = flask.Flask(__name__) 25 b.init_app(app) 26 27 with app.app_context(): 28 assert isinstance(get_translations(), NullTranslations) 29 30 def test_multiple_directories(self): 31 """ 32 Ensure we can load translations from multiple directories. 33 """ 34 b = babel.Babel() 35 app = flask.Flask(__name__) 36 37 app.config.update({ 38 'BABEL_TRANSLATION_DIRECTORIES': ';'.join(( 39 'translations', 40 'renamed_translations' 41 )), 42 'BABEL_DEFAULT_LOCALE': 'de_DE' 43 }) 44 45 b.init_app(app) 46 47 with app.test_request_context(): 48 translations = b.list_translations() 49 50 assert(len(translations) == 2) 51 assert(str(translations[0]) == 'de') 52 assert(str(translations[1]) == 'de') 53 54 assert gettext( 55 u'Hello %(name)s!', 56 name='Peter' 57 ) == 'Hallo Peter!' 58 59 def test_different_domain(self): 60 """ 61 Ensure we can load translations from multiple directories. 62 """ 63 b = babel.Babel() 64 app = flask.Flask(__name__) 65 66 app.config.update({ 67 'BABEL_TRANSLATION_DIRECTORIES': 'translations_different_domain', 68 'BABEL_DEFAULT_LOCALE': 'de_DE', 69 'BABEL_DOMAIN': 'myapp' 70 }) 71 72 b.init_app(app) 73 74 with app.test_request_context(): 75 translations = b.list_translations() 76 77 assert(len(translations) == 1) 78 assert(str(translations[0]) == 'de') 79 80 assert gettext(u'Good bye') == 'Auf Wiedersehen' 81 82 def test_lazy_old_style_formatting(self): 83 lazy_string = lazy_gettext(u'Hello %(name)s') 84 assert lazy_string % {u'name': u'test'} == u'Hello test' 85 86 lazy_string = lazy_gettext(u'test') 87 assert u'Hello %s' % lazy_string == u'Hello test' 88 89 def test_lazy_pickling(self): 90 lazy_string = lazy_gettext(u'Foo') 91 pickled = pickle.dumps(lazy_string) 92 unpickled = pickle.loads(pickled) 93 94 assert unpickled == lazy_string 95 96 97class DateFormattingTestCase(unittest.TestCase): 98 99 def test_basics(self): 100 app = flask.Flask(__name__) 101 babel.Babel(app) 102 d = datetime(2010, 4, 12, 13, 46) 103 delta = timedelta(days=6) 104 105 with app.test_request_context(): 106 assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM' 107 assert babel.format_date(d) == 'Apr 12, 2010' 108 assert babel.format_time(d) == '1:46:00 PM' 109 assert babel.format_timedelta(delta) == '1 week' 110 assert babel.format_timedelta(delta, threshold=1) == '6 days' 111 112 with app.test_request_context(): 113 app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna' 114 assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM' 115 assert babel.format_date(d) == 'Apr 12, 2010' 116 assert babel.format_time(d) == '3:46:00 PM' 117 118 with app.test_request_context(): 119 app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE' 120 assert babel.format_datetime(d, 'long') == \ 121 '12. April 2010 um 15:46:00 MESZ' 122 123 def test_init_app(self): 124 b = babel.Babel() 125 app = flask.Flask(__name__) 126 b.init_app(app) 127 d = datetime(2010, 4, 12, 13, 46) 128 129 with app.test_request_context(): 130 assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM' 131 assert babel.format_date(d) == 'Apr 12, 2010' 132 assert babel.format_time(d) == '1:46:00 PM' 133 134 with app.test_request_context(): 135 app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna' 136 assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM' 137 assert babel.format_date(d) == 'Apr 12, 2010' 138 assert babel.format_time(d) == '3:46:00 PM' 139 140 with app.test_request_context(): 141 app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE' 142 assert babel.format_datetime(d, 'long') == \ 143 '12. April 2010 um 15:46:00 MESZ' 144 145 def test_custom_formats(self): 146 app = flask.Flask(__name__) 147 app.config.update( 148 BABEL_DEFAULT_LOCALE='en_US', 149 BABEL_DEFAULT_TIMEZONE='Pacific/Johnston' 150 ) 151 b = babel.Babel(app) 152 b.date_formats['datetime'] = 'long' 153 b.date_formats['datetime.long'] = 'MMMM d, yyyy h:mm:ss a' 154 d = datetime(2010, 4, 12, 13, 46) 155 156 with app.test_request_context(): 157 assert babel.format_datetime(d) == 'April 12, 2010 3:46:00 AM' 158 159 def test_custom_locale_selector(self): 160 app = flask.Flask(__name__) 161 b = babel.Babel(app) 162 d = datetime(2010, 4, 12, 13, 46) 163 164 the_timezone = 'UTC' 165 the_locale = 'en_US' 166 167 @b.localeselector 168 def select_locale(): 169 return the_locale 170 171 @b.timezoneselector 172 def select_timezone(): 173 return the_timezone 174 175 with app.test_request_context(): 176 assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM' 177 178 the_locale = 'de_DE' 179 the_timezone = 'Europe/Vienna' 180 181 with app.test_request_context(): 182 assert babel.format_datetime(d) == '12.04.2010, 15:46:00' 183 184 def test_refreshing(self): 185 app = flask.Flask(__name__) 186 babel.Babel(app) 187 d = datetime(2010, 4, 12, 13, 46) 188 with app.test_request_context(): 189 assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM' 190 app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna' 191 babel.refresh() 192 assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM' 193 194 def test_force_locale(self): 195 app = flask.Flask(__name__) 196 b = babel.Babel(app) 197 198 @b.localeselector 199 def select_locale(): 200 return 'de_DE' 201 202 with app.test_request_context(): 203 assert str(babel.get_locale()) == 'de_DE' 204 with babel.force_locale('en_US'): 205 assert str(babel.get_locale()) == 'en_US' 206 assert str(babel.get_locale()) == 'de_DE' 207 208 def test_force_locale_with_threading(self): 209 app = flask.Flask(__name__) 210 b = babel.Babel(app) 211 212 @b.localeselector 213 def select_locale(): 214 return 'de_DE' 215 216 semaphore = Semaphore(value=0) 217 218 def first_request(): 219 with app.test_request_context(): 220 with babel.force_locale('en_US'): 221 assert str(babel.get_locale()) == 'en_US' 222 semaphore.acquire() 223 224 thread = Thread(target=first_request) 225 thread.start() 226 227 try: 228 with app.test_request_context(): 229 assert str(babel.get_locale()) == 'de_DE' 230 finally: 231 semaphore.release() 232 thread.join() 233 234 def test_refresh_during_force_locale(self): 235 app = flask.Flask(__name__) 236 b = babel.Babel(app) 237 238 @b.localeselector 239 def select_locale(): 240 return 'de_DE' 241 242 with app.test_request_context(): 243 with babel.force_locale('en_US'): 244 assert str(babel.get_locale()) == 'en_US' 245 babel.refresh() 246 assert str(babel.get_locale()) == 'en_US' 247 248 249class NumberFormattingTestCase(unittest.TestCase): 250 251 def test_basics(self): 252 app = flask.Flask(__name__) 253 babel.Babel(app) 254 n = 1099 255 256 with app.test_request_context(): 257 assert babel.format_number(n) == u'1,099' 258 assert babel.format_decimal(Decimal('1010.99')) == u'1,010.99' 259 assert babel.format_currency(n, 'USD') == '$1,099.00' 260 assert babel.format_percent(0.19) == '19%' 261 assert babel.format_scientific(10000) == u'1E4' 262 263 264class GettextTestCase(unittest.TestCase): 265 266 def test_basics(self): 267 app = flask.Flask(__name__) 268 babel.Babel(app, default_locale='de_DE') 269 270 with app.test_request_context(): 271 assert gettext(u'Hello %(name)s!', name='Peter') == 'Hallo Peter!' 272 assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 3) == \ 273 u'3 Äpfel' 274 assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 1) == \ 275 u'1 Apfel' 276 277 def test_template_basics(self): 278 app = flask.Flask(__name__) 279 babel.Babel(app, default_locale='de_DE') 280 281 t = lambda x: flask.render_template_string('{{ %s }}' % x) 282 283 with app.test_request_context(): 284 assert t("gettext('Hello %(name)s!', name='Peter')") == \ 285 u'Hallo Peter!' 286 assert t("ngettext('%(num)s Apple', '%(num)s Apples', 3)") == \ 287 u'3 Äpfel' 288 assert t("ngettext('%(num)s Apple', '%(num)s Apples', 1)") == \ 289 u'1 Apfel' 290 assert flask.render_template_string(''' 291 {% trans %}Hello {{ name }}!{% endtrans %} 292 ''', name='Peter').strip() == 'Hallo Peter!' 293 assert flask.render_template_string(''' 294 {% trans num=3 %}{{ num }} Apple 295 {%- pluralize %}{{ num }} Apples{% endtrans %} 296 ''', name='Peter').strip() == u'3 Äpfel' 297 298 def test_lazy_gettext(self): 299 app = flask.Flask(__name__) 300 babel.Babel(app, default_locale='de_DE') 301 yes = lazy_gettext(u'Yes') 302 with app.test_request_context(): 303 assert text_type(yes) == 'Ja' 304 assert yes.__html__() == 'Ja' 305 app.config['BABEL_DEFAULT_LOCALE'] = 'en_US' 306 with app.test_request_context(): 307 assert text_type(yes) == 'Yes' 308 assert yes.__html__() == 'Yes' 309 310 def test_lazy_ngettext(self): 311 app = flask.Flask(__name__) 312 babel.Babel(app, default_locale='de_DE') 313 one_apple = lazy_ngettext(u'%(num)s Apple', u'%(num)s Apples', 1) 314 with app.test_request_context(): 315 assert text_type(one_apple) == '1 Apfel' 316 assert one_apple.__html__() == '1 Apfel' 317 two_apples = lazy_ngettext(u'%(num)s Apple', u'%(num)s Apples', 2) 318 with app.test_request_context(): 319 assert text_type(two_apples) == u'2 Äpfel' 320 assert two_apples.__html__() == u'2 Äpfel' 321 322 def test_list_translations(self): 323 app = flask.Flask(__name__) 324 b = babel.Babel(app, default_locale='de_DE') 325 translations = b.list_translations() 326 assert len(translations) == 1 327 assert str(translations[0]) == 'de' 328 329 def test_no_formatting(self): 330 """ 331 Ensure we don't format strings unless a variable is passed. 332 """ 333 app = flask.Flask(__name__) 334 babel.Babel(app) 335 336 with app.test_request_context(): 337 assert gettext(u'Test %s') == u'Test %s' 338 assert gettext(u'Test %(name)s', name=u'test') == u'Test test' 339 assert gettext(u'Test %s') % 'test' == u'Test test' 340 341 342if __name__ == '__main__': 343 unittest.main() 344