blob: 4d1e0a35e7ade4e4e2f658d502c70aea709d2911 [file] [log] [blame]
Barry Warsaw9e035922000-08-25 19:14:25 +00001import os
Barry Warsawff6d8132000-08-25 19:50:38 +00002import base64
Barry Warsawa1ce93f2003-04-11 18:36:43 +00003import shutil
Barry Warsaw9e035922000-08-25 19:14:25 +00004import gettext
Martin v. Löwisd8996052002-11-21 21:45:32 +00005import unittest
Barry Warsawa1ce93f2003-04-11 18:36:43 +00006
Collin Winterc2898c52007-04-25 17:29:52 +00007from test import test_support
Barry Warsawa1ce93f2003-04-11 18:36:43 +00008
Fred Drake004d5e62000-10-23 17:22:08 +00009
Martin v. Löwisd8996052002-11-21 21:45:32 +000010# TODO:
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.
Barry Warsaw64dab462000-08-30 03:32:07 +000015
Barry Warsawff6d8132000-08-25 19:50:38 +000016GNU_MO_DATA = '''\
Martin v. Löwisd8996052002-11-21 21:45:32 +0000173hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
18AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
19AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
20eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
21aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
22CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
23Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
24ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
25MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
26YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
27SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
28NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
29ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
30d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
31eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
32IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
33ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
Barry Warsawff6d8132000-08-25 19:50:38 +000034'''
35
Barry Warsawa1ce93f2003-04-11 18:36:43 +000036UMO_DATA = '''\
373hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
38AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
39ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
40eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
41ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
42bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
43ZC1CeTogbWFudWFsbHkKAMKkeXoA
44'''
Fred Drake004d5e62000-10-23 17:22:08 +000045
Barry Warsawe960e222003-05-20 17:28:54 +000046MMO_DATA = '''\
473hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
48UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
49IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
50NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
51ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
52cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
53c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
54bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
55'''
56
Barry Warsawff6d8132000-08-25 19:50:38 +000057LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
58MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
Barry Warsawa1ce93f2003-04-11 18:36:43 +000059UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
Barry Warsawe960e222003-05-20 17:28:54 +000060MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
Barry Warsawff6d8132000-08-25 19:50:38 +000061
62
Barry Warsawa1ce93f2003-04-11 18:36:43 +000063class GettextBaseTest(unittest.TestCase):
Martin v. Löwisd8996052002-11-21 21:45:32 +000064 def setUp(self):
Neal Norwitza0e0cd32004-07-19 00:08:59 +000065 if not os.path.isdir(LOCALEDIR):
66 os.makedirs(LOCALEDIR)
Éric Araujo54274ad2011-02-03 00:12:18 +000067 with open(MOFILE, 'wb') as fp:
68 fp.write(base64.decodestring(GNU_MO_DATA))
69 with open(UMOFILE, 'wb') as fp:
70 fp.write(base64.decodestring(UMO_DATA))
71 with open(MMOFILE, 'wb') as fp:
72 fp.write(base64.decodestring(MMO_DATA))
73
Walter Dörwald6733bed2009-05-01 17:35:37 +000074 self.env = test_support.EnvironmentVarGuard()
75 self.env['LANGUAGE'] = 'xx'
Éric Araujoe28665a2010-11-06 04:36:28 +000076 gettext._translations.clear()
Barry Warsawa1ce93f2003-04-11 18:36:43 +000077
78 def tearDown(self):
Walter Dörwald6733bed2009-05-01 17:35:37 +000079 self.env.__exit__()
80 del self.env
Brett Cannon4aebbb02003-04-27 19:42:41 +000081 shutil.rmtree(os.path.split(LOCALEDIR)[0])
Barry Warsawa1ce93f2003-04-11 18:36:43 +000082
Andrew Kuchling270b0582015-04-14 10:03:35 -040083GNU_MO_DATA_ISSUE_17898 = b'''\
843hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z
85OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk
86WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU
87Ri04CgA=
88'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +000089
90class GettextTestCase1(GettextBaseTest):
91 def setUp(self):
92 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +000093 self.localedir = os.curdir
94 self.mofile = MOFILE
Martin v. Löwisd8996052002-11-21 21:45:32 +000095 gettext.install('gettext', self.localedir)
96
Martin v. Löwisd8996052002-11-21 21:45:32 +000097 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +000098 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +000099 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000100 eq(_('albatross'), 'albatross')
101 eq(_(u'mullusk'), 'bacon')
102 eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
103 eq(_(ur'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000104
105 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000106 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000107 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000108 eq(_("albatross"), 'albatross')
109 eq(_(u"mullusk"), 'bacon')
110 eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
111 eq(_(ur"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000112
113 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000114 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000115 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000116 eq(_('''albatross'''), 'albatross')
117 eq(_(u'''mullusk'''), 'bacon')
118 eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
119 eq(_(ur'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000120
121 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000122 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000123 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000124 eq(_("""albatross"""), 'albatross')
125 eq(_(u"""mullusk"""), 'bacon')
126 eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
127 eq(_(ur"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000128
129 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000130 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000131 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000132 eq(_('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000133support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000134gettext message catalog library.'''),
135 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000136fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000137trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000138
139 def test_the_alternative_interface(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000140 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000141 # test the alternative interface
Éric Araujo54274ad2011-02-03 00:12:18 +0000142 with open(self.mofile, 'rb') as fp:
143 t = gettext.GNUTranslations(fp)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000144 # Install the translation object
Martin v. Löwisd8996052002-11-21 21:45:32 +0000145 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000146 eq(_('nudge nudge'), 'wink wink')
147 # Try unicode return type
148 t.install(unicode=True)
149 eq(_('mullusk'), 'bacon')
Georg Brandl602b9ba2006-02-19 13:26:36 +0000150 # Test installation of other methods
151 import __builtin__
152 t.install(unicode=True, names=["gettext", "lgettext"])
153 eq(_, t.ugettext)
154 eq(__builtin__.gettext, t.ugettext)
155 eq(lgettext, t.lgettext)
156 del __builtin__.gettext
157 del __builtin__.lgettext
Martin v. Löwisd8996052002-11-21 21:45:32 +0000158
159
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000160class GettextTestCase2(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000161 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000162 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000163 self.localedir = os.curdir
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000164 # Set up the bindings
Martin v. Löwisd8996052002-11-21 21:45:32 +0000165 gettext.bindtextdomain('gettext', self.localedir)
166 gettext.textdomain('gettext')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000167 # For convenience
Martin v. Löwisd8996052002-11-21 21:45:32 +0000168 self._ = gettext.gettext
169
Martin v. Löwisd8996052002-11-21 21:45:32 +0000170 def test_bindtextdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000171 self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000172
173 def test_textdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000174 self.assertEqual(gettext.textdomain(), 'gettext')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000175
176 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000177 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000178 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000179 eq(self._('albatross'), 'albatross')
180 eq(self._(u'mullusk'), 'bacon')
181 eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
182 eq(self._(ur'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000183
184 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000185 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000186 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000187 eq(self._("albatross"), 'albatross')
188 eq(self._(u"mullusk"), 'bacon')
189 eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
190 eq(self._(ur"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000191
192 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000193 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000194 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000195 eq(self._('''albatross'''), 'albatross')
196 eq(self._(u'''mullusk'''), 'bacon')
197 eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
198 eq(self._(ur'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000199
200 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000201 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000202 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000203 eq(self._("""albatross"""), 'albatross')
204 eq(self._(u"""mullusk"""), 'bacon')
205 eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
206 eq(self._(ur"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000207
208 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000209 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000210 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000211 eq(self._('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000212support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000213gettext message catalog library.'''),
214 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000215fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000216trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000217
218
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000219class PluralFormsTestCase(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000220 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000221 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000222 self.mofile = MOFILE
223
224 def test_plural_forms1(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000225 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000226 x = gettext.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000227 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000228 x = gettext.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000229 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000230
231 def test_plural_forms2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000232 eq = self.assertEqual
Éric Araujo54274ad2011-02-03 00:12:18 +0000233 with open(self.mofile, 'rb') as fp:
234 t = gettext.GNUTranslations(fp)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000235 x = t.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000236 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000237 x = t.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000238 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000239
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200240 # Examples from http://www.gnu.org/software/gettext/manual/gettext.html
241
242 def test_ja(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000243 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000244 f = gettext.c2py('0')
245 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000246 eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000247
248 def test_de(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000249 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000250 f = gettext.c2py('n != 1')
251 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000252 eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000253
254 def test_fr(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000255 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000256 f = gettext.c2py('n>1')
257 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000258 eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000259
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200260 def test_lv(self):
261 eq = self.assertEqual
262 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2')
263 s = ''.join([ str(f(x)) for x in range(200) ])
264 eq(s, "20111111111111111111101111111110111111111011111111101111111110111111111011111111101111111110111111111011111111111111111110111111111011111111101111111110111111111011111111101111111110111111111011111111")
265
Martin v. Löwisd8996052002-11-21 21:45:32 +0000266 def test_gd(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000267 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000268 f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
269 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000270 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000271
272 def test_gd2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000273 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000274 # Tests the combination of parentheses and "?:"
275 f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
276 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000277 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000278
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200279 def test_ro(self):
280 eq = self.assertEqual
281 f = gettext.c2py('n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2')
282 s = ''.join([ str(f(x)) for x in range(200) ])
283 eq(s, "10111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222")
284
Martin v. Löwisd8996052002-11-21 21:45:32 +0000285 def test_lt(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000286 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000287 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
288 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000289 eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000290
291 def test_ru(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000292 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000293 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
294 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000295 eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000296
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200297 def test_cs(self):
298 eq = self.assertEqual
299 f = gettext.c2py('(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2')
300 s = ''.join([ str(f(x)) for x in range(200) ])
301 eq(s, "20111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
302
Martin v. Löwisd8996052002-11-21 21:45:32 +0000303 def test_pl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000304 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000305 f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
306 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000307 eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000308
309 def test_sl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000310 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000311 f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
312 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000313 eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000314
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200315 def test_ar(self):
316 eq = self.assertEqual
317 f = gettext.c2py('n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5')
318 s = ''.join([ str(f(x)) for x in range(200) ])
319 eq(s, "01233333333444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445553333333344444444444444444444444444444444444444444444444444444444444444444444444444444444444444444")
320
Martin v. Löwisd8996052002-11-21 21:45:32 +0000321 def test_security(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000322 raises = self.assertRaises
Martin v. Löwisd8996052002-11-21 21:45:32 +0000323 # Test for a dangerous expression
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000324 raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200325 # issue28563
326 raises(ValueError, gettext.c2py, '"(eval(foo) && ""')
327 raises(ValueError, gettext.c2py, 'f"{os.system(\'sh\')}"')
328 # Maximum recursion depth exceeded during compilation
329 raises(ValueError, gettext.c2py, 'n+'*10000 + 'n')
330 self.assertEqual(gettext.c2py('n+'*100 + 'n')(1), 101)
331 # MemoryError during compilation
332 raises(ValueError, gettext.c2py, '('*100 + 'n' + ')'*100)
333 # Maximum recursion depth exceeded in C to Python translator
334 raises(ValueError, gettext.c2py, '('*10000 + 'n' + ')'*10000)
335 self.assertEqual(gettext.c2py('('*20 + 'n' + ')'*20)(1), 1)
336
337 def test_chained_comparison(self):
338 # C doesn't chain comparison as Python so 2 == 2 == 2 gets different results
339 f = gettext.c2py('n == n == n')
340 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
341 f = gettext.c2py('1 < n == n')
342 self.assertEqual(''.join(str(f(x)) for x in range(3)), '100')
343 f = gettext.c2py('n == n < 2')
344 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
345 f = gettext.c2py('0 < n < 2')
346 self.assertEqual(''.join(str(f(x)) for x in range(3)), '111')
347
348 def test_decimal_number(self):
349 self.assertEqual(gettext.c2py('0123')(1), 123)
350
351 def test_invalid_syntax(self):
352 invalid_expressions = [
353 'x>1', '(n>1', 'n>1)', '42**42**42', '0xa', '1.0', '1e2',
354 'n>0x1', '+n', '-n', 'n()', 'n(1)', '1+', 'nn', 'n n',
355 ]
356 for expr in invalid_expressions:
357 with self.assertRaises(ValueError):
358 gettext.c2py(expr)
359
360 def test_nested_condition_operator(self):
361 self.assertEqual(gettext.c2py('n?1?2:3:4')(0), 4)
362 self.assertEqual(gettext.c2py('n?1?2:3:4')(1), 2)
363 self.assertEqual(gettext.c2py('n?1:3?4:5')(0), 4)
364 self.assertEqual(gettext.c2py('n?1:3?4:5')(1), 1)
365
366 def test_division(self):
367 f = gettext.c2py('2/n*3')
368 self.assertEqual(f(1), 6)
369 self.assertEqual(f(2), 3)
370 self.assertEqual(f(3), 0)
371 self.assertEqual(f(-1), -6)
372 self.assertRaises(ZeroDivisionError, f, 0)
373
374 def test_plural_number(self):
Serhiy Storchakad3e6c9e2016-11-14 19:25:44 +0200375 f = gettext.c2py('n != 1')
376 self.assertEqual(f(1), 0)
377 self.assertEqual(f(2), 1)
378 self.assertEqual(f(1.0), 0)
379 self.assertEqual(f(2.0), 1)
380 self.assertEqual(f(1.1), 1)
381 self.assertRaises(TypeError, f, '2')
382 self.assertRaises(TypeError, f, b'2')
383 self.assertRaises(TypeError, f, [])
384 self.assertRaises(TypeError, f, object())
Serhiy Storchakaa8760272016-11-08 21:15:55 +0200385
Martin v. Löwisd8996052002-11-21 21:45:32 +0000386
Andrew Kuchling270b0582015-04-14 10:03:35 -0400387class GNUTranslationParsingTest(GettextBaseTest):
388 def test_plural_form_error_issue17898(self):
389 with open(MOFILE, 'wb') as fp:
390 fp.write(base64.decodestring(GNU_MO_DATA_ISSUE_17898))
391 with open(MOFILE, 'rb') as fp:
392 # If this runs cleanly, the bug is fixed.
393 t = gettext.GNUTranslations(fp)
394
Martin v. Löwisd8996052002-11-21 21:45:32 +0000395
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000396class UnicodeTranslationsTest(GettextBaseTest):
397 def setUp(self):
398 GettextBaseTest.setUp(self)
Éric Araujo54274ad2011-02-03 00:12:18 +0000399 with open(UMOFILE, 'rb') as fp:
Barry Warsawedb155f2003-04-24 18:08:13 +0000400 self.t = gettext.GNUTranslations(fp)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000401 self._ = self.t.ugettext
402
403 def test_unicode_msgid(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000404 unless = self.assertTrue
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000405 unless(isinstance(self._(''), unicode))
406 unless(isinstance(self._(u''), unicode))
407
408 def test_unicode_msgstr(self):
409 eq = self.assertEqual
410 eq(self._(u'ab\xde'), u'\xa4yz')
411
412
Barry Warsawe960e222003-05-20 17:28:54 +0000413class WeirdMetadataTest(GettextBaseTest):
414 def setUp(self):
415 GettextBaseTest.setUp(self)
Éric Araujo54274ad2011-02-03 00:12:18 +0000416 with open(MMOFILE, 'rb') as fp:
Barry Warsawe960e222003-05-20 17:28:54 +0000417 try:
418 self.t = gettext.GNUTranslations(fp)
419 except:
420 self.tearDown()
421 raise
Barry Warsawe960e222003-05-20 17:28:54 +0000422
423 def test_weird_metadata(self):
424 info = self.t.info()
425 self.assertEqual(info['last-translator'],
426 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
427
428
Éric Araujoc17776f2010-10-04 23:59:35 +0000429class DummyGNUTranslations(gettext.GNUTranslations):
430 def foo(self):
431 return 'foo'
432
433
434class GettextCacheTestCase(GettextBaseTest):
435 def test_cache(self):
436 self.localedir = os.curdir
437 self.mofile = MOFILE
438
439 self.assertEqual(len(gettext._translations), 0)
440
441 t = gettext.translation('gettext', self.localedir)
442
443 self.assertEqual(len(gettext._translations), 1)
444
445 t = gettext.translation('gettext', self.localedir,
446 class_=DummyGNUTranslations)
447
448 self.assertEqual(len(gettext._translations), 2)
449 self.assertEqual(t.__class__, DummyGNUTranslations)
450
451 # Calling it again doesn't add to the cache
452
453 t = gettext.translation('gettext', self.localedir,
454 class_=DummyGNUTranslations)
455
456 self.assertEqual(len(gettext._translations), 2)
457 self.assertEqual(t.__class__, DummyGNUTranslations)
458
459
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000460def test_main():
Collin Winterc2898c52007-04-25 17:29:52 +0000461 test_support.run_unittest(__name__)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000462
463if __name__ == '__main__':
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000464 test_main()
Martin v. Löwisd8996052002-11-21 21:45:32 +0000465
Barry Warsawff6d8132000-08-25 19:50:38 +0000466
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000467# For reference, here's the .po file used to created the GNU_MO_DATA above.
Martin v. Löwisd8996052002-11-21 21:45:32 +0000468#
469# The original version was automatically generated from the sources with
470# pygettext. Later it was manually modified to add plural forms support.
Barry Warsawff6d8132000-08-25 19:50:38 +0000471
Barry Warsaw64dab462000-08-30 03:32:07 +0000472'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000473# Dummy translation for the Python test_gettext.py module.
Barry Warsaw19148732001-08-24 19:11:57 +0000474# Copyright (C) 2001 Python Software Foundation
475# Barry Warsaw <barry@python.org>, 2000.
Barry Warsaw64dab462000-08-30 03:32:07 +0000476#
477msgid ""
478msgstr ""
479"Project-Id-Version: 2.0\n"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000480"PO-Revision-Date: 2003-04-11 14:32-0400\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000481"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000482"Language-Team: XX <python-dev@python.org>\n"
483"MIME-Version: 1.0\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000484"Content-Type: text/plain; charset=iso-8859-1\n"
485"Content-Transfer-Encoding: 8bit\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000486"Generated-By: pygettext.py 1.1\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000487"Plural-Forms: nplurals=2; plural=n!=1;\n"
Barry Warsawff6d8132000-08-25 19:50:38 +0000488
Barry Warsaw64dab462000-08-30 03:32:07 +0000489#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
490#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
491#: test_gettext.py:98
492msgid "nudge nudge"
493msgstr "wink wink"
Barry Warsawff6d8132000-08-25 19:50:38 +0000494
Barry Warsaw64dab462000-08-30 03:32:07 +0000495#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
496#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
497msgid "albatross"
498msgstr ""
Barry Warsawff6d8132000-08-25 19:50:38 +0000499
Barry Warsaw64dab462000-08-30 03:32:07 +0000500#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
501#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
502msgid "Raymond Luxury Yach-t"
503msgstr "Throatwobbler Mangrove"
Barry Warsawff6d8132000-08-25 19:50:38 +0000504
Barry Warsaw64dab462000-08-30 03:32:07 +0000505#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
506#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
507#: test_gettext.py:96
508msgid "mullusk"
509msgstr "bacon"
Barry Warsawff6d8132000-08-25 19:50:38 +0000510
Barry Warsaw64dab462000-08-30 03:32:07 +0000511#: test_gettext.py:40 test_gettext.py:101
512msgid ""
513"This module provides internationalization and localization\n"
514"support for your Python programs by providing an interface to the GNU\n"
515"gettext message catalog library."
516msgstr ""
517"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
518"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
519"trggrkg zrffntr pngnybt yvoenel."
Martin v. Löwisd8996052002-11-21 21:45:32 +0000520
521# Manually added, as neither pygettext nor xgettext support plural forms
522# in Python.
523msgid "There is %s file"
524msgid_plural "There are %s files"
525msgstr[0] "Hay %s fichero"
526msgstr[1] "Hay %s ficheros"
Barry Warsaw64dab462000-08-30 03:32:07 +0000527'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000528
529# Here's the second example po file example, used to generate the UMO_DATA
530# containing utf-8 encoded Unicode strings
531
532'''
533# Dummy translation for the Python test_gettext.py module.
534# Copyright (C) 2001 Python Software Foundation
535# Barry Warsaw <barry@python.org>, 2000.
536#
537msgid ""
538msgstr ""
539"Project-Id-Version: 2.0\n"
540"PO-Revision-Date: 2003-04-11 12:42-0400\n"
541"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
542"Language-Team: XX <python-dev@python.org>\n"
543"MIME-Version: 1.0\n"
544"Content-Type: text/plain; charset=utf-8\n"
545"Content-Transfer-Encoding: 7bit\n"
546"Generated-By: manually\n"
547
548#: nofile:0
549msgid "ab\xc3\x9e"
550msgstr "\xc2\xa4yz"
551'''
Barry Warsawe960e222003-05-20 17:28:54 +0000552
553# Here's the third example po file, used to generate MMO_DATA
554
555'''
556msgid ""
557msgstr ""
558"Project-Id-Version: No Project 0.0\n"
559"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
560"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
561"Last-Translator: John Doe <jdoe@example.com>\n"
562"Jane Foobar <jfoobar@example.com>\n"
563"Language-Team: xx <xx@example.com>\n"
564"MIME-Version: 1.0\n"
565"Content-Type: text/plain; charset=iso-8859-15\n"
566"Content-Transfer-Encoding: quoted-printable\n"
567"Generated-By: pygettext.py 1.3\n"
568'''
Andrew Kuchling270b0582015-04-14 10:03:35 -0400569
570#
571# messages.po, used for bug 17898
572#
573
574'''
575# test file for http://bugs.python.org/issue17898
576msgid ""
577msgstr ""
578"Plural-Forms: nplurals=2; plural=(n != 1);\n"
579"#-#-#-#-# messages.po (EdX Studio) #-#-#-#-#\n"
580"Content-Type: text/plain; charset=UTF-8\n"
581'''