1 import os 2 import base64 3 import shutil 4 import gettext 5 import unittest 6 7 from test import test_support 8 9 10 # 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. 15 16 GNU_MO_DATA = '''\ 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== 34 ''' 35 36 UMO_DATA = '''\ 37 3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm 38 AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S 39 ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy 40 eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t 41 ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp 42 bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl 43 ZC1CeTogbWFudWFsbHkKAMKkeXoA 44 ''' 45 46 MMO_DATA = '''\ 47 3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA 48 UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk 49 IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6 50 NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu 51 ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt 52 cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy 53 c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi 54 bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA= 55 ''' 56 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') 61 62 63 class GettextBaseTest(unittest.TestCase): 64 def setUp(self): 65 if not os.path.isdir(LOCALEDIR): 66 os.makedirs(LOCALEDIR) 67 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 74 self.env = test_support.EnvironmentVarGuard() 75 self.env['LANGUAGE'] = 'xx' 76 gettext._translations.clear() 77 78 def tearDown(self): 79 self.env.__exit__() 80 del self.env 81 shutil.rmtree(os.path.split(LOCALEDIR)[0]) 82 83 GNU_MO_DATA_ISSUE_17898 = b'''\ 84 3hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z 85 OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk 86 WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU 87 Ri04CgA= 88 ''' 89 90 class GettextTestCase1(GettextBaseTest): 91 def setUp(self): 92 GettextBaseTest.setUp(self) 93 self.localedir = os.curdir 94 self.mofile = MOFILE 95 gettext.install('gettext', self.localedir) 96 97 def test_some_translations(self): 98 eq = self.assertEqual 99 # test some translations 100 eq(_('albatross'), 'albatross') 101 eq(_(u'mullusk'), 'bacon') 102 eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove') 103 eq(_(ur'nudge nudge'), 'wink wink') 104 105 def test_double_quotes(self): 106 eq = self.assertEqual 107 # double quotes 108 eq(_("albatross"), 'albatross') 109 eq(_(u"mullusk"), 'bacon') 110 eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove') 111 eq(_(ur"nudge nudge"), 'wink wink') 112 113 def test_triple_single_quotes(self): 114 eq = self.assertEqual 115 # triple single quotes 116 eq(_('''albatross'''), 'albatross') 117 eq(_(u'''mullusk'''), 'bacon') 118 eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove') 119 eq(_(ur'''nudge nudge'''), 'wink wink') 120 121 def test_triple_double_quotes(self): 122 eq = self.assertEqual 123 # triple double quotes 124 eq(_("""albatross"""), 'albatross') 125 eq(_(u"""mullusk"""), 'bacon') 126 eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove') 127 eq(_(ur"""nudge nudge"""), 'wink wink') 128 129 def test_multiline_strings(self): 130 eq = self.assertEqual 131 # multiline strings 132 eq(_('''This module provides internationalization and localization 133 support for your Python programs by providing an interface to the GNU 134 gettext message catalog library.'''), 135 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba 136 fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH 137 trggrkg zrffntr pngnybt yvoenel.''') 138 139 def test_the_alternative_interface(self): 140 eq = self.assertEqual 141 # test the alternative interface 142 with open(self.mofile, 'rb') as fp: 143 t = gettext.GNUTranslations(fp) 144 # Install the translation object 145 t.install() 146 eq(_('nudge nudge'), 'wink wink') 147 # Try unicode return type 148 t.install(unicode=True) 149 eq(_('mullusk'), 'bacon') 150 # 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 158 159 160 class GettextTestCase2(GettextBaseTest): 161 def setUp(self): 162 GettextBaseTest.setUp(self) 163 self.localedir = os.curdir 164 # Set up the bindings 165 gettext.bindtextdomain('gettext', self.localedir) 166 gettext.textdomain('gettext') 167 # For convenience 168 self._ = gettext.gettext 169 170 def test_bindtextdomain(self): 171 self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir) 172 173 def test_textdomain(self): 174 self.assertEqual(gettext.textdomain(), 'gettext') 175 176 def test_some_translations(self): 177 eq = self.assertEqual 178 # test some translations 179 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') 183 184 def test_double_quotes(self): 185 eq = self.assertEqual 186 # double quotes 187 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') 191 192 def test_triple_single_quotes(self): 193 eq = self.assertEqual 194 # triple single quotes 195 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') 199 200 def test_triple_double_quotes(self): 201 eq = self.assertEqual 202 # triple double quotes 203 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') 207 208 def test_multiline_strings(self): 209 eq = self.assertEqual 210 # multiline strings 211 eq(self._('''This module provides internationalization and localization 212 support for your Python programs by providing an interface to the GNU 213 gettext message catalog library.'''), 214 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba 215 fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH 216 trggrkg zrffntr pngnybt yvoenel.''') 217 218 219 class PluralFormsTestCase(GettextBaseTest): 220 def setUp(self): 221 GettextBaseTest.setUp(self) 222 self.mofile = MOFILE 223 224 def test_plural_forms1(self): 225 eq = self.assertEqual 226 x = gettext.ngettext('There is %s file', 'There are %s files', 1) 227 eq(x, 'Hay %s fichero') 228 x = gettext.ngettext('There is %s file', 'There are %s files', 2) 229 eq(x, 'Hay %s ficheros') 230 231 def test_plural_forms2(self): 232 eq = self.assertEqual 233 with open(self.mofile, 'rb') as fp: 234 t = gettext.GNUTranslations(fp) 235 x = t.ngettext('There is %s file', 'There are %s files', 1) 236 eq(x, 'Hay %s fichero') 237 x = t.ngettext('There is %s file', 'There are %s files', 2) 238 eq(x, 'Hay %s ficheros') 239 240 # Examples from http://www.gnu.org/software/gettext/manual/gettext.html 241 242 def test_ja(self): 243 eq = self.assertEqual 244 f = gettext.c2py('0') 245 s = ''.join([ str(f(x)) for x in range(200) ]) 246 eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") 247 248 def test_de(self): 249 eq = self.assertEqual 250 f = gettext.c2py('n != 1') 251 s = ''.join([ str(f(x)) for x in range(200) ]) 252 eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") 253 254 def test_fr(self): 255 eq = self.assertEqual 256 f = gettext.c2py('n>1') 257 s = ''.join([ str(f(x)) for x in range(200) ]) 258 eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") 259 260 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 266 def test_gd(self): 267 eq = self.assertEqual 268 f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2') 269 s = ''.join([ str(f(x)) for x in range(200) ]) 270 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222") 271 272 def test_gd2(self): 273 eq = self.assertEqual 274 # 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) ]) 277 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222") 278 279 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 285 def test_lt(self): 286 eq = self.assertEqual 287 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) ]) 289 eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111") 290 291 def test_ru(self): 292 eq = self.assertEqual 293 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) ]) 295 eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222") 296 297 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 303 def test_pl(self): 304 eq = self.assertEqual 305 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) ]) 307 eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222") 308 309 def test_sl(self): 310 eq = self.assertEqual 311 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) ]) 313 eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333") 314 315 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 321 def test_security(self): 322 raises = self.assertRaises 323 # Test for a dangerous expression 324 raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)") 325 # 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): 375 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()) 385 386 387 class 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 395 396 class UnicodeTranslationsTest(GettextBaseTest): 397 def setUp(self): 398 GettextBaseTest.setUp(self) 399 with open(UMOFILE, 'rb') as fp: 400 self.t = gettext.GNUTranslations(fp) 401 self._ = self.t.ugettext 402 403 def test_unicode_msgid(self): 404 unless = self.assertTrue 405 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 413 class WeirdMetadataTest(GettextBaseTest): 414 def setUp(self): 415 GettextBaseTest.setUp(self) 416 with open(MMOFILE, 'rb') as fp: 417 try: 418 self.t = gettext.GNUTranslations(fp) 419 except: 420 self.tearDown() 421 raise 422 423 def test_weird_metadata(self): 424 info = self.t.info() 425 self.assertEqual(info['last-translator'], 426 'John Doe <jdoe (at] example.com>\nJane Foobar <jfoobar (at] example.com>') 427 428 429 class DummyGNUTranslations(gettext.GNUTranslations): 430 def foo(self): 431 return 'foo' 432 433 434 class 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 460 def test_main(): 461 test_support.run_unittest(__name__) 462 463 if __name__ == '__main__': 464 test_main() 465 466 467 # For reference, here's the .po file used to created the GNU_MO_DATA above. 468 # 469 # The original version was automatically generated from the sources with 470 # pygettext. Later it was manually modified to add plural forms support. 471 472 ''' 473 # Dummy translation for the Python test_gettext.py module. 474 # Copyright (C) 2001 Python Software Foundation 475 # Barry Warsaw <barry (at] python.org>, 2000. 476 # 477 msgid "" 478 msgstr "" 479 "Project-Id-Version: 2.0\n" 480 "PO-Revision-Date: 2003-04-11 14:32-0400\n" 481 "Last-Translator: J. David Ibanez <j-david (at] noos.fr>\n" 482 "Language-Team: XX <python-dev (at] python.org>\n" 483 "MIME-Version: 1.0\n" 484 "Content-Type: text/plain; charset=iso-8859-1\n" 485 "Content-Transfer-Encoding: 8bit\n" 486 "Generated-By: pygettext.py 1.1\n" 487 "Plural-Forms: nplurals=2; plural=n!=1;\n" 488 489 #: 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 492 msgid "nudge nudge" 493 msgstr "wink wink" 494 495 #: 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 497 msgid "albatross" 498 msgstr "" 499 500 #: 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 502 msgid "Raymond Luxury Yach-t" 503 msgstr "Throatwobbler Mangrove" 504 505 #: 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 508 msgid "mullusk" 509 msgstr "bacon" 510 511 #: test_gettext.py:40 test_gettext.py:101 512 msgid "" 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." 516 msgstr "" 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." 520 521 # Manually added, as neither pygettext nor xgettext support plural forms 522 # in Python. 523 msgid "There is %s file" 524 msgid_plural "There are %s files" 525 msgstr[0] "Hay %s fichero" 526 msgstr[1] "Hay %s ficheros" 527 ''' 528 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 (at] python.org>, 2000. 536 # 537 msgid "" 538 msgstr "" 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 (at] python.org>\n" 542 "Language-Team: XX <python-dev (at] 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 549 msgid "ab\xc3\x9e" 550 msgstr "\xc2\xa4yz" 551 ''' 552 553 # Here's the third example po file, used to generate MMO_DATA 554 555 ''' 556 msgid "" 557 msgstr "" 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 (at] example.com>\n" 562 "Jane Foobar <jfoobar (at] example.com>\n" 563 "Language-Team: xx <xx (at] 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 ''' 569 570 # 571 # messages.po, used for bug 17898 572 # 573 574 ''' 575 # test file for http://bugs.python.org/issue17898 576 msgid "" 577 msgstr "" 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 ''' 582