7
from test import support
11
# - Add new tests, for example for "dgettext"
12
# - Remove dummy tests, for example testing for single and double quotes
13
# has no sense, it would have if we were testing a parser (i.e. pygettext)
14
# - Tests should have only one assert.
17
3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
18
AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
19
AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
20
eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
21
aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
22
CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
23
Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
24
ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
25
MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
26
YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
27
SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
28
NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
29
ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
30
d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
31
eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
32
IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
33
ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
37
3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
38
AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
39
ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
40
eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
41
ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
42
bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
43
ZC1CeTogbWFudWFsbHkKAMKkeXoA
47
3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
48
UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
49
IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
50
NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
51
ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
52
cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
53
c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
54
bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
57
LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
58
MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
59
UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
60
MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
62
LANG = os.environ['LANGUAGE']
67
class GettextBaseTest(unittest.TestCase):
69
if not os.path.isdir(LOCALEDIR):
70
os.makedirs(LOCALEDIR)
71
fp = open(MOFILE, 'wb')
72
fp.write(base64.decodestring(GNU_MO_DATA))
74
fp = open(UMOFILE, 'wb')
75
fp.write(base64.decodestring(UMO_DATA))
77
fp = open(MMOFILE, 'wb')
78
fp.write(base64.decodestring(MMO_DATA))
80
os.environ['LANGUAGE'] = 'xx'
83
os.environ['LANGUAGE'] = LANG
84
shutil.rmtree(os.path.split(LOCALEDIR)[0])
87
class GettextTestCase1(GettextBaseTest):
89
GettextBaseTest.setUp(self)
90
self.localedir = os.curdir
92
gettext.install('gettext', self.localedir)
94
def test_some_translations(self):
96
# test some translations
97
eq(_('albatross'), 'albatross')
98
eq(_('mullusk'), 'bacon')
99
eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
100
eq(_(r'nudge nudge'), 'wink wink')
102
def test_double_quotes(self):
103
eq = self.assertEqual
105
eq(_("albatross"), 'albatross')
106
eq(_("mullusk"), 'bacon')
107
eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
108
eq(_(r"nudge nudge"), 'wink wink')
110
def test_triple_single_quotes(self):
111
eq = self.assertEqual
112
# triple single quotes
113
eq(_('''albatross'''), 'albatross')
114
eq(_('''mullusk'''), 'bacon')
115
eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
116
eq(_(r'''nudge nudge'''), 'wink wink')
118
def test_triple_double_quotes(self):
119
eq = self.assertEqual
120
# triple double quotes
121
eq(_("""albatross"""), 'albatross')
122
eq(_("""mullusk"""), 'bacon')
123
eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
124
eq(_(r"""nudge nudge"""), 'wink wink')
126
def test_multiline_strings(self):
127
eq = self.assertEqual
129
eq(_('''This module provides internationalization and localization
130
support for your Python programs by providing an interface to the GNU
131
gettext message catalog library.'''),
132
'''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
133
fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
134
trggrkg zrffntr pngnybt yvoenel.''')
136
def test_the_alternative_interface(self):
137
eq = self.assertEqual
138
# test the alternative interface
139
fp = open(self.mofile, 'rb')
140
t = gettext.GNUTranslations(fp)
142
# Install the translation object
144
eq(_('nudge nudge'), 'wink wink')
145
# Try unicode return type
147
eq(_('mullusk'), 'bacon')
148
# Test installation of other methods
150
t.install(names=["gettext", "lgettext"])
152
eq(builtins.gettext, t.gettext)
153
eq(lgettext, t.lgettext)
155
del builtins.lgettext
158
class GettextTestCase2(GettextBaseTest):
160
GettextBaseTest.setUp(self)
161
self.localedir = os.curdir
162
# Set up the bindings
163
gettext.bindtextdomain('gettext', self.localedir)
164
gettext.textdomain('gettext')
166
self._ = gettext.gettext
168
def test_bindtextdomain(self):
169
self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
171
def test_textdomain(self):
172
self.assertEqual(gettext.textdomain(), 'gettext')
174
def test_some_translations(self):
175
eq = self.assertEqual
176
# test some translations
177
eq(self._('albatross'), 'albatross')
178
eq(self._('mullusk'), 'bacon')
179
eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
180
eq(self._(r'nudge nudge'), 'wink wink')
182
def test_double_quotes(self):
183
eq = self.assertEqual
185
eq(self._("albatross"), 'albatross')
186
eq(self._("mullusk"), 'bacon')
187
eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
188
eq(self._(r"nudge nudge"), 'wink wink')
190
def test_triple_single_quotes(self):
191
eq = self.assertEqual
192
# triple single quotes
193
eq(self._('''albatross'''), 'albatross')
194
eq(self._('''mullusk'''), 'bacon')
195
eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
196
eq(self._(r'''nudge nudge'''), 'wink wink')
198
def test_triple_double_quotes(self):
199
eq = self.assertEqual
200
# triple double quotes
201
eq(self._("""albatross"""), 'albatross')
202
eq(self._("""mullusk"""), 'bacon')
203
eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
204
eq(self._(r"""nudge nudge"""), 'wink wink')
206
def test_multiline_strings(self):
207
eq = self.assertEqual
209
eq(self._('''This module provides internationalization and localization
210
support for your Python programs by providing an interface to the GNU
211
gettext message catalog library.'''),
212
'''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
213
fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
214
trggrkg zrffntr pngnybt yvoenel.''')
217
class PluralFormsTestCase(GettextBaseTest):
219
GettextBaseTest.setUp(self)
222
def test_plural_forms1(self):
223
eq = self.assertEqual
224
x = gettext.ngettext('There is %s file', 'There are %s files', 1)
225
eq(x, 'Hay %s fichero')
226
x = gettext.ngettext('There is %s file', 'There are %s files', 2)
227
eq(x, 'Hay %s ficheros')
229
def test_plural_forms2(self):
230
eq = self.assertEqual
231
fp = open(self.mofile, 'rb')
232
t = gettext.GNUTranslations(fp)
234
x = t.ngettext('There is %s file', 'There are %s files', 1)
235
eq(x, 'Hay %s fichero')
236
x = t.ngettext('There is %s file', 'There are %s files', 2)
237
eq(x, 'Hay %s ficheros')
240
eq = self.assertEqual
241
f = gettext.c2py('0')
242
s = ''.join([ str(f(x)) for x in range(200) ])
243
eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
246
eq = self.assertEqual
247
f = gettext.c2py('n != 1')
248
s = ''.join([ str(f(x)) for x in range(200) ])
249
eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
252
eq = self.assertEqual
253
f = gettext.c2py('n>1')
254
s = ''.join([ str(f(x)) for x in range(200) ])
255
eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
258
eq = self.assertEqual
259
f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
260
s = ''.join([ str(f(x)) for x in range(200) ])
261
eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
264
eq = self.assertEqual
265
# Tests the combination of parentheses and "?:"
266
f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
267
s = ''.join([ str(f(x)) for x in range(200) ])
268
eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
271
eq = self.assertEqual
272
f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
273
s = ''.join([ str(f(x)) for x in range(200) ])
274
eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
277
eq = self.assertEqual
278
f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
279
s = ''.join([ str(f(x)) for x in range(200) ])
280
eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
283
eq = self.assertEqual
284
f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
285
s = ''.join([ str(f(x)) for x in range(200) ])
286
eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
289
eq = self.assertEqual
290
f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
291
s = ''.join([ str(f(x)) for x in range(200) ])
292
eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
294
def test_security(self):
295
raises = self.assertRaises
296
# Test for a dangerous expression
297
raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
300
class UnicodeTranslationsTest(GettextBaseTest):
302
GettextBaseTest.setUp(self)
303
fp = open(UMOFILE, 'rb')
305
self.t = gettext.GNUTranslations(fp)
308
self._ = self.t.gettext
310
def test_unicode_msgid(self):
311
unless = self.failUnless
312
unless(isinstance(self._(''), str))
313
unless(isinstance(self._(''), str))
315
def test_unicode_msgstr(self):
316
eq = self.assertEqual
317
eq(self._('ab\xde'), '\xa4yz')
320
class WeirdMetadataTest(GettextBaseTest):
322
GettextBaseTest.setUp(self)
323
fp = open(MMOFILE, 'rb')
326
self.t = gettext.GNUTranslations(fp)
333
def test_weird_metadata(self):
335
self.assertEqual(len(info), 9)
336
self.assertEqual(info['last-translator'],
337
'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
341
support.run_unittest(__name__)
343
if __name__ == '__main__':
347
# For reference, here's the .po file used to created the GNU_MO_DATA above.
349
# The original version was automatically generated from the sources with
350
# pygettext. Later it was manually modified to add plural forms support.
353
# Dummy translation for the Python test_gettext.py module.
354
# Copyright (C) 2001 Python Software Foundation
355
# Barry Warsaw <barry@python.org>, 2000.
359
"Project-Id-Version: 2.0\n"
360
"PO-Revision-Date: 2003-04-11 14:32-0400\n"
361
"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
362
"Language-Team: XX <python-dev@python.org>\n"
363
"MIME-Version: 1.0\n"
364
"Content-Type: text/plain; charset=iso-8859-1\n"
365
"Content-Transfer-Encoding: 8bit\n"
366
"Generated-By: pygettext.py 1.1\n"
367
"Plural-Forms: nplurals=2; plural=n!=1;\n"
369
#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
370
#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
371
#: test_gettext.py:98
375
#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
376
#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
380
#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
381
#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
382
msgid "Raymond Luxury Yach-t"
383
msgstr "Throatwobbler Mangrove"
385
#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
386
#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
387
#: test_gettext.py:96
391
#: test_gettext.py:40 test_gettext.py:101
393
"This module provides internationalization and localization\n"
394
"support for your Python programs by providing an interface to the GNU\n"
395
"gettext message catalog library."
397
"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
398
"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
399
"trggrkg zrffntr pngnybt yvoenel."
401
# Manually added, as neither pygettext nor xgettext support plural forms
403
msgid "There is %s file"
404
msgid_plural "There are %s files"
405
msgstr[0] "Hay %s fichero"
406
msgstr[1] "Hay %s ficheros"
409
# Here's the second example po file example, used to generate the UMO_DATA
410
# containing utf-8 encoded Unicode strings
413
# Dummy translation for the Python test_gettext.py module.
414
# Copyright (C) 2001 Python Software Foundation
415
# Barry Warsaw <barry@python.org>, 2000.
419
"Project-Id-Version: 2.0\n"
420
"PO-Revision-Date: 2003-04-11 12:42-0400\n"
421
"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
422
"Language-Team: XX <python-dev@python.org>\n"
423
"MIME-Version: 1.0\n"
424
"Content-Type: text/plain; charset=utf-8\n"
425
"Content-Transfer-Encoding: 7bit\n"
426
"Generated-By: manually\n"
433
# Here's the third example po file, used to generate MMO_DATA
438
"Project-Id-Version: No Project 0.0\n"
439
"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
440
"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
441
"Last-Translator: John Doe <jdoe@example.com>\n"
442
"Jane Foobar <jfoobar@example.com>\n"
443
"Language-Team: xx <xx@example.com>\n"
444
"MIME-Version: 1.0\n"
445
"Content-Type: text/plain; charset=iso-8859-15\n"
446
"Content-Transfer-Encoding: quoted-printable\n"
447
"Generated-By: pygettext.py 1.3\n"