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