blob: b5ed05eab7bbe1443eca406a76e5e1bdb80affef [file] [log] [blame]
Barry Warsaw9e035922000-08-25 19:14:25 +00001import os
Barry Warsawff6d8132000-08-25 19:50:38 +00002import base64
Barry Warsaw9e035922000-08-25 19:14:25 +00003import gettext
Serhiy Storchaka26cb4652017-06-20 17:13:29 +03004import locale
Martin v. Löwisd8996052002-11-21 21:45:32 +00005import unittest
Barry Warsawa1ce93f2003-04-11 18:36:43 +00006
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import 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
Guido van Rossum39478e82007-08-27 17:23:59 +000016GNU_MO_DATA = b'''\
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
Antoine Pitroube8d06f2014-10-28 20:17:51 +010036# This data contains an invalid major version number (5)
37# An unexpected major version number should be treated as an error when
38# parsing a .mo file
39
40GNU_MO_DATA_BAD_MAJOR_VERSION = b'''\
413hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
42AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
43AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
44eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
45aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
46CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
47Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
48ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
49MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
50YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
51SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
52NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
53ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
54d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
55eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
56IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
57ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
58'''
59
60# This data contains an invalid minor version number (7)
61# An unexpected minor version number only indicates that some of the file's
62# contents may not be able to be read. It does not indicate an error.
63
64GNU_MO_DATA_BAD_MINOR_VERSION = b'''\
653hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
66AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
67AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
68eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
69aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
70CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
71Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
72ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
73MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
74YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
75SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
76NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
77ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
78d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
79eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
80IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
81ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
82'''
83
84
Guido van Rossum39478e82007-08-27 17:23:59 +000085UMO_DATA = b'''\
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000863hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
87AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
88ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
89eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
90ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
91bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
92ZC1CeTogbWFudWFsbHkKAMKkeXoA
93'''
Fred Drake004d5e62000-10-23 17:22:08 +000094
Guido van Rossum39478e82007-08-27 17:23:59 +000095MMO_DATA = b'''\
Barry Warsawe960e222003-05-20 17:28:54 +0000963hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
97UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
98IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
99NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
100ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
101cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
102c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
103bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
104'''
105
Barry Warsawff6d8132000-08-25 19:50:38 +0000106LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
107MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100108MOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo')
109MOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000110UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
Barry Warsawe960e222003-05-20 17:28:54 +0000111MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
Barry Warsawff6d8132000-08-25 19:50:38 +0000112
113
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000114class GettextBaseTest(unittest.TestCase):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000115 def setUp(self):
Neal Norwitza0e0cd32004-07-19 00:08:59 +0000116 if not os.path.isdir(LOCALEDIR):
117 os.makedirs(LOCALEDIR)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000118 with open(MOFILE, 'wb') as fp:
119 fp.write(base64.decodebytes(GNU_MO_DATA))
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100120 with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp:
121 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION))
122 with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp:
123 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION))
Éric Araujo7fa886d2010-11-06 04:11:59 +0000124 with open(UMOFILE, 'wb') as fp:
125 fp.write(base64.decodebytes(UMO_DATA))
126 with open(MMOFILE, 'wb') as fp:
127 fp.write(base64.decodebytes(MMO_DATA))
Walter Dörwald155374d2009-05-01 19:58:58 +0000128 self.env = support.EnvironmentVarGuard()
129 self.env['LANGUAGE'] = 'xx'
Éric Araujo37a89332010-11-06 04:09:29 +0000130 gettext._translations.clear()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000131
132 def tearDown(self):
Walter Dörwald155374d2009-05-01 19:58:58 +0000133 self.env.__exit__()
134 del self.env
Victor Stinnercdb2c602014-07-24 12:07:45 +0200135 support.rmtree(os.path.split(LOCALEDIR)[0])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000136
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400137GNU_MO_DATA_ISSUE_17898 = b'''\
1383hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z
139OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk
140WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU
141Ri04CgA=
142'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000143
144class GettextTestCase1(GettextBaseTest):
145 def setUp(self):
146 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000147 self.localedir = os.curdir
148 self.mofile = MOFILE
Martin v. Löwisd8996052002-11-21 21:45:32 +0000149 gettext.install('gettext', self.localedir)
150
Martin v. Löwisd8996052002-11-21 21:45:32 +0000151 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000152 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000153 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000154 eq(_('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000155 eq(_('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000156 eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000157 eq(_(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000158
159 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000160 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000161 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000162 eq(_("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000163 eq(_("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000164 eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000165 eq(_(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000166
167 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000168 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000169 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000170 eq(_('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000171 eq(_('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000172 eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000173 eq(_(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000174
175 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000176 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000177 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000178 eq(_("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000179 eq(_("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000180 eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000181 eq(_(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000182
183 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000184 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000185 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000186 eq(_('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000187support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000188gettext message catalog library.'''),
189 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000190fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000191trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000192
193 def test_the_alternative_interface(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000194 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000195 # test the alternative interface
Éric Araujo7fa886d2010-11-06 04:11:59 +0000196 with open(self.mofile, 'rb') as fp:
197 t = gettext.GNUTranslations(fp)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000198 # Install the translation object
Martin v. Löwisd8996052002-11-21 21:45:32 +0000199 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000200 eq(_('nudge nudge'), 'wink wink')
201 # Try unicode return type
Benjamin Peterson801844d2008-07-14 14:32:15 +0000202 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000203 eq(_('mullusk'), 'bacon')
Georg Brandl602b9ba2006-02-19 13:26:36 +0000204 # Test installation of other methods
Georg Brandl1a3284e2007-12-02 09:40:06 +0000205 import builtins
Benjamin Peterson801844d2008-07-14 14:32:15 +0000206 t.install(names=["gettext", "lgettext"])
207 eq(_, t.gettext)
208 eq(builtins.gettext, t.gettext)
Georg Brandl602b9ba2006-02-19 13:26:36 +0000209 eq(lgettext, t.lgettext)
Georg Brandl1a3284e2007-12-02 09:40:06 +0000210 del builtins.gettext
211 del builtins.lgettext
Martin v. Löwisd8996052002-11-21 21:45:32 +0000212
213
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000214class GettextTestCase2(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000215 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000216 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000217 self.localedir = os.curdir
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000218 # Set up the bindings
Martin v. Löwisd8996052002-11-21 21:45:32 +0000219 gettext.bindtextdomain('gettext', self.localedir)
220 gettext.textdomain('gettext')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000221 # For convenience
Martin v. Löwisd8996052002-11-21 21:45:32 +0000222 self._ = gettext.gettext
223
Martin v. Löwisd8996052002-11-21 21:45:32 +0000224 def test_bindtextdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000225 self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000226
227 def test_textdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000228 self.assertEqual(gettext.textdomain(), 'gettext')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000229
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100230 def test_bad_major_version(self):
231 with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp:
232 with self.assertRaises(OSError) as cm:
233 gettext.GNUTranslations(fp)
234
235 exception = cm.exception
236 self.assertEqual(exception.errno, 0)
237 self.assertEqual(exception.strerror, "Bad version number 5")
238 self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION)
239
240 def test_bad_minor_version(self):
241 with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp:
242 # Check that no error is thrown with a bad minor version number
243 gettext.GNUTranslations(fp)
244
Martin v. Löwisd8996052002-11-21 21:45:32 +0000245 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000246 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000247 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000248 eq(self._('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000249 eq(self._('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000250 eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000251 eq(self._(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000252
253 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000254 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000255 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000256 eq(self._("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000257 eq(self._("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000258 eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000259 eq(self._(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000260
261 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000262 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000263 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000264 eq(self._('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000265 eq(self._('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000266 eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000267 eq(self._(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000268
269 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000270 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000271 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000272 eq(self._("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000273 eq(self._("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000274 eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000275 eq(self._(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000276
277 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000278 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000279 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000280 eq(self._('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000281support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000282gettext message catalog library.'''),
283 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000284fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000285trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000286
287
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000288class PluralFormsTestCase(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000289 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000290 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000291 self.mofile = MOFILE
292
293 def test_plural_forms1(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000294 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000295 x = gettext.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000296 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000297 x = gettext.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000298 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000299
300 def test_plural_forms2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000301 eq = self.assertEqual
Éric Araujo7fa886d2010-11-06 04:11:59 +0000302 with open(self.mofile, 'rb') as fp:
303 t = gettext.GNUTranslations(fp)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000304 x = t.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000305 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000306 x = t.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000307 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000308
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200309 # Examples from http://www.gnu.org/software/gettext/manual/gettext.html
310
311 def test_ja(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000312 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000313 f = gettext.c2py('0')
314 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000315 eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000316
317 def test_de(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000318 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000319 f = gettext.c2py('n != 1')
320 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000321 eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000322
323 def test_fr(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000324 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000325 f = gettext.c2py('n>1')
326 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000327 eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000328
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200329 def test_lv(self):
330 eq = self.assertEqual
331 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2')
332 s = ''.join([ str(f(x)) for x in range(200) ])
333 eq(s, "20111111111111111111101111111110111111111011111111101111111110111111111011111111101111111110111111111011111111111111111110111111111011111111101111111110111111111011111111101111111110111111111011111111")
334
Martin v. Löwisd8996052002-11-21 21:45:32 +0000335 def test_gd(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000336 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000337 f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
338 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000339 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000340
341 def test_gd2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000342 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000343 # Tests the combination of parentheses and "?:"
344 f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
345 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000346 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000347
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200348 def test_ro(self):
349 eq = self.assertEqual
350 f = gettext.c2py('n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2')
351 s = ''.join([ str(f(x)) for x in range(200) ])
352 eq(s, "10111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222")
353
Martin v. Löwisd8996052002-11-21 21:45:32 +0000354 def test_lt(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000355 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000356 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
357 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000358 eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000359
360 def test_ru(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000361 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000362 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
363 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000364 eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000365
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200366 def test_cs(self):
367 eq = self.assertEqual
368 f = gettext.c2py('(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2')
369 s = ''.join([ str(f(x)) for x in range(200) ])
370 eq(s, "20111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
371
Martin v. Löwisd8996052002-11-21 21:45:32 +0000372 def test_pl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000373 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000374 f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
375 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000376 eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000377
378 def test_sl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000379 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000380 f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
381 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000382 eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000383
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200384 def test_ar(self):
385 eq = self.assertEqual
386 f = gettext.c2py('n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5')
387 s = ''.join([ str(f(x)) for x in range(200) ])
388 eq(s, "01233333333444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445553333333344444444444444444444444444444444444444444444444444444444444444444444444444444444444444444")
389
Martin v. Löwisd8996052002-11-21 21:45:32 +0000390 def test_security(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000391 raises = self.assertRaises
Martin v. Löwisd8996052002-11-21 21:45:32 +0000392 # Test for a dangerous expression
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000393 raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200394 # issue28563
395 raises(ValueError, gettext.c2py, '"(eval(foo) && ""')
396 raises(ValueError, gettext.c2py, 'f"{os.system(\'sh\')}"')
397 # Maximum recursion depth exceeded during compilation
398 raises(ValueError, gettext.c2py, 'n+'*10000 + 'n')
399 self.assertEqual(gettext.c2py('n+'*100 + 'n')(1), 101)
400 # MemoryError during compilation
401 raises(ValueError, gettext.c2py, '('*100 + 'n' + ')'*100)
402 # Maximum recursion depth exceeded in C to Python translator
403 raises(ValueError, gettext.c2py, '('*10000 + 'n' + ')'*10000)
404 self.assertEqual(gettext.c2py('('*20 + 'n' + ')'*20)(1), 1)
405
406 def test_chained_comparison(self):
407 # C doesn't chain comparison as Python so 2 == 2 == 2 gets different results
408 f = gettext.c2py('n == n == n')
409 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
410 f = gettext.c2py('1 < n == n')
411 self.assertEqual(''.join(str(f(x)) for x in range(3)), '100')
412 f = gettext.c2py('n == n < 2')
413 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
414 f = gettext.c2py('0 < n < 2')
415 self.assertEqual(''.join(str(f(x)) for x in range(3)), '111')
416
417 def test_decimal_number(self):
418 self.assertEqual(gettext.c2py('0123')(1), 123)
419
420 def test_invalid_syntax(self):
421 invalid_expressions = [
422 'x>1', '(n>1', 'n>1)', '42**42**42', '0xa', '1.0', '1e2',
423 'n>0x1', '+n', '-n', 'n()', 'n(1)', '1+', 'nn', 'n n',
424 ]
425 for expr in invalid_expressions:
426 with self.assertRaises(ValueError):
427 gettext.c2py(expr)
428
429 def test_nested_condition_operator(self):
430 self.assertEqual(gettext.c2py('n?1?2:3:4')(0), 4)
431 self.assertEqual(gettext.c2py('n?1?2:3:4')(1), 2)
432 self.assertEqual(gettext.c2py('n?1:3?4:5')(0), 4)
433 self.assertEqual(gettext.c2py('n?1:3?4:5')(1), 1)
434
435 def test_division(self):
436 f = gettext.c2py('2/n*3')
437 self.assertEqual(f(1), 6)
438 self.assertEqual(f(2), 3)
439 self.assertEqual(f(3), 0)
440 self.assertEqual(f(-1), -6)
441 self.assertRaises(ZeroDivisionError, f, 0)
442
443 def test_plural_number(self):
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200444 f = gettext.c2py('n != 1')
445 self.assertEqual(f(1), 0)
446 self.assertEqual(f(2), 1)
Serhiy Storchakaf6595982017-03-12 13:15:01 +0200447 with self.assertWarns(DeprecationWarning):
448 self.assertEqual(f(1.0), 0)
449 with self.assertWarns(DeprecationWarning):
450 self.assertEqual(f(2.0), 1)
451 with self.assertWarns(DeprecationWarning):
452 self.assertEqual(f(1.1), 1)
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200453 self.assertRaises(TypeError, f, '2')
454 self.assertRaises(TypeError, f, b'2')
455 self.assertRaises(TypeError, f, [])
456 self.assertRaises(TypeError, f, object())
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200457
Martin v. Löwisd8996052002-11-21 21:45:32 +0000458
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300459class LGettextTestCase(GettextBaseTest):
460 def setUp(self):
461 GettextBaseTest.setUp(self)
462 self.mofile = MOFILE
463
464 def test_lgettext(self):
465 lgettext = gettext.lgettext
466 ldgettext = gettext.ldgettext
467 self.assertEqual(lgettext('mullusk'), b'bacon')
468 self.assertEqual(lgettext('spam'), b'spam')
469 self.assertEqual(ldgettext('gettext', 'mullusk'), b'bacon')
470 self.assertEqual(ldgettext('gettext', 'spam'), b'spam')
471
472 def test_lgettext_2(self):
473 with open(self.mofile, 'rb') as fp:
474 t = gettext.GNUTranslations(fp)
475 lgettext = t.lgettext
476 self.assertEqual(lgettext('mullusk'), b'bacon')
477 self.assertEqual(lgettext('spam'), b'spam')
478
479 def test_lgettext_bind_textdomain_codeset(self):
480 lgettext = gettext.lgettext
481 ldgettext = gettext.ldgettext
482 saved_codeset = gettext.bind_textdomain_codeset('gettext')
483 try:
484 gettext.bind_textdomain_codeset('gettext', 'utf-16')
485 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
486 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
487 self.assertEqual(ldgettext('gettext', 'mullusk'), 'bacon'.encode('utf-16'))
488 self.assertEqual(ldgettext('gettext', 'spam'), 'spam'.encode('utf-16'))
489 finally:
490 del gettext._localecodesets['gettext']
491 gettext.bind_textdomain_codeset('gettext', saved_codeset)
492
493 def test_lgettext_output_encoding(self):
494 with open(self.mofile, 'rb') as fp:
495 t = gettext.GNUTranslations(fp)
496 lgettext = t.lgettext
497 t.set_output_charset('utf-16')
498 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
499 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
500
501 def test_lngettext(self):
502 lngettext = gettext.lngettext
503 ldngettext = gettext.ldngettext
504 x = lngettext('There is %s file', 'There are %s files', 1)
505 self.assertEqual(x, b'Hay %s fichero')
506 x = lngettext('There is %s file', 'There are %s files', 2)
507 self.assertEqual(x, b'Hay %s ficheros')
508 x = lngettext('There is %s directory', 'There are %s directories', 1)
509 self.assertEqual(x, b'There is %s directory')
510 x = lngettext('There is %s directory', 'There are %s directories', 2)
511 self.assertEqual(x, b'There are %s directories')
512 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
513 self.assertEqual(x, b'Hay %s fichero')
514 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
515 self.assertEqual(x, b'Hay %s ficheros')
516 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
517 self.assertEqual(x, b'There is %s directory')
518 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
519 self.assertEqual(x, b'There are %s directories')
520
521 def test_lngettext_2(self):
522 with open(self.mofile, 'rb') as fp:
523 t = gettext.GNUTranslations(fp)
524 lngettext = t.lngettext
525 x = lngettext('There is %s file', 'There are %s files', 1)
526 self.assertEqual(x, b'Hay %s fichero')
527 x = lngettext('There is %s file', 'There are %s files', 2)
528 self.assertEqual(x, b'Hay %s ficheros')
529 x = lngettext('There is %s directory', 'There are %s directories', 1)
530 self.assertEqual(x, b'There is %s directory')
531 x = lngettext('There is %s directory', 'There are %s directories', 2)
532 self.assertEqual(x, b'There are %s directories')
533
534 def test_lngettext_bind_textdomain_codeset(self):
535 lngettext = gettext.lngettext
536 ldngettext = gettext.ldngettext
537 saved_codeset = gettext.bind_textdomain_codeset('gettext')
538 try:
539 gettext.bind_textdomain_codeset('gettext', 'utf-16')
540 x = lngettext('There is %s file', 'There are %s files', 1)
541 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
542 x = lngettext('There is %s file', 'There are %s files', 2)
543 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
544 x = lngettext('There is %s directory', 'There are %s directories', 1)
545 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
546 x = lngettext('There is %s directory', 'There are %s directories', 2)
547 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
548 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
549 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
550 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
551 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
552 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
553 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
554 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
555 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
556 finally:
557 del gettext._localecodesets['gettext']
558 gettext.bind_textdomain_codeset('gettext', saved_codeset)
559
560 def test_lngettext_output_encoding(self):
561 with open(self.mofile, 'rb') as fp:
562 t = gettext.GNUTranslations(fp)
563 lngettext = t.lngettext
564 t.set_output_charset('utf-16')
565 x = lngettext('There is %s file', 'There are %s files', 1)
566 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
567 x = lngettext('There is %s file', 'There are %s files', 2)
568 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
569 x = lngettext('There is %s directory', 'There are %s directories', 1)
570 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
571 x = lngettext('There is %s directory', 'There are %s directories', 2)
572 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
573
574
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400575class GNUTranslationParsingTest(GettextBaseTest):
576 def test_plural_form_error_issue17898(self):
577 with open(MOFILE, 'wb') as fp:
578 fp.write(base64.decodebytes(GNU_MO_DATA_ISSUE_17898))
579 with open(MOFILE, 'rb') as fp:
580 # If this runs cleanly, the bug is fixed.
581 t = gettext.GNUTranslations(fp)
582
Martin v. Löwisd8996052002-11-21 21:45:32 +0000583
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000584class UnicodeTranslationsTest(GettextBaseTest):
585 def setUp(self):
586 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000587 with open(UMOFILE, 'rb') as fp:
Barry Warsawedb155f2003-04-24 18:08:13 +0000588 self.t = gettext.GNUTranslations(fp)
Benjamin Peterson801844d2008-07-14 14:32:15 +0000589 self._ = self.t.gettext
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000590
591 def test_unicode_msgid(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300592 self.assertIsInstance(self._(''), str)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000593
594 def test_unicode_msgstr(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300595 self.assertEqual(self._('ab\xde'), '\xa4yz')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000596
597
Barry Warsawe960e222003-05-20 17:28:54 +0000598class WeirdMetadataTest(GettextBaseTest):
599 def setUp(self):
600 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000601 with open(MMOFILE, 'rb') as fp:
Barry Warsawe960e222003-05-20 17:28:54 +0000602 try:
603 self.t = gettext.GNUTranslations(fp)
604 except:
605 self.tearDown()
606 raise
Barry Warsawe960e222003-05-20 17:28:54 +0000607
608 def test_weird_metadata(self):
609 info = self.t.info()
Christian Heimes6ae5d7f2007-10-31 18:53:44 +0000610 self.assertEqual(len(info), 9)
Barry Warsawe960e222003-05-20 17:28:54 +0000611 self.assertEqual(info['last-translator'],
612 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
613
614
Éric Araujo6108bf52010-10-04 23:52:37 +0000615class DummyGNUTranslations(gettext.GNUTranslations):
616 def foo(self):
617 return 'foo'
618
619
620class GettextCacheTestCase(GettextBaseTest):
621 def test_cache(self):
622 self.localedir = os.curdir
623 self.mofile = MOFILE
624
625 self.assertEqual(len(gettext._translations), 0)
626
627 t = gettext.translation('gettext', self.localedir)
628
629 self.assertEqual(len(gettext._translations), 1)
630
631 t = gettext.translation('gettext', self.localedir,
632 class_=DummyGNUTranslations)
633
634 self.assertEqual(len(gettext._translations), 2)
635 self.assertEqual(t.__class__, DummyGNUTranslations)
636
637 # Calling it again doesn't add to the cache
638
639 t = gettext.translation('gettext', self.localedir,
640 class_=DummyGNUTranslations)
641
642 self.assertEqual(len(gettext._translations), 2)
643 self.assertEqual(t.__class__, DummyGNUTranslations)
644
645
Martin Panterd226d302015-11-14 11:47:00 +0000646class MiscTestCase(unittest.TestCase):
647 def test__all__(self):
648 blacklist = {'c2py', 'ENOENT'}
649 support.check__all__(self, gettext, blacklist=blacklist)
650
651
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000652def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000653 support.run_unittest(__name__)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000654
655if __name__ == '__main__':
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000656 test_main()
Martin v. Löwisd8996052002-11-21 21:45:32 +0000657
Barry Warsawff6d8132000-08-25 19:50:38 +0000658
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000659# For reference, here's the .po file used to created the GNU_MO_DATA above.
Martin v. Löwisd8996052002-11-21 21:45:32 +0000660#
661# The original version was automatically generated from the sources with
662# pygettext. Later it was manually modified to add plural forms support.
Barry Warsawff6d8132000-08-25 19:50:38 +0000663
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300664b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000665# Dummy translation for the Python test_gettext.py module.
Barry Warsaw19148732001-08-24 19:11:57 +0000666# Copyright (C) 2001 Python Software Foundation
667# Barry Warsaw <barry@python.org>, 2000.
Barry Warsaw64dab462000-08-30 03:32:07 +0000668#
669msgid ""
670msgstr ""
671"Project-Id-Version: 2.0\n"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000672"PO-Revision-Date: 2003-04-11 14:32-0400\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000673"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000674"Language-Team: XX <python-dev@python.org>\n"
675"MIME-Version: 1.0\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000676"Content-Type: text/plain; charset=iso-8859-1\n"
677"Content-Transfer-Encoding: 8bit\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000678"Generated-By: pygettext.py 1.1\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000679"Plural-Forms: nplurals=2; plural=n!=1;\n"
Barry Warsawff6d8132000-08-25 19:50:38 +0000680
Barry Warsaw64dab462000-08-30 03:32:07 +0000681#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
682#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
683#: test_gettext.py:98
684msgid "nudge nudge"
685msgstr "wink wink"
Barry Warsawff6d8132000-08-25 19:50:38 +0000686
Barry Warsaw64dab462000-08-30 03:32:07 +0000687#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
688#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
689msgid "albatross"
690msgstr ""
Barry Warsawff6d8132000-08-25 19:50:38 +0000691
Barry Warsaw64dab462000-08-30 03:32:07 +0000692#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
693#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
694msgid "Raymond Luxury Yach-t"
695msgstr "Throatwobbler Mangrove"
Barry Warsawff6d8132000-08-25 19:50:38 +0000696
Barry Warsaw64dab462000-08-30 03:32:07 +0000697#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
698#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
699#: test_gettext.py:96
700msgid "mullusk"
701msgstr "bacon"
Barry Warsawff6d8132000-08-25 19:50:38 +0000702
Barry Warsaw64dab462000-08-30 03:32:07 +0000703#: test_gettext.py:40 test_gettext.py:101
704msgid ""
705"This module provides internationalization and localization\n"
706"support for your Python programs by providing an interface to the GNU\n"
707"gettext message catalog library."
708msgstr ""
709"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
710"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
711"trggrkg zrffntr pngnybt yvoenel."
Martin v. Löwisd8996052002-11-21 21:45:32 +0000712
713# Manually added, as neither pygettext nor xgettext support plural forms
714# in Python.
715msgid "There is %s file"
716msgid_plural "There are %s files"
717msgstr[0] "Hay %s fichero"
718msgstr[1] "Hay %s ficheros"
Barry Warsaw64dab462000-08-30 03:32:07 +0000719'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000720
721# Here's the second example po file example, used to generate the UMO_DATA
722# containing utf-8 encoded Unicode strings
723
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300724b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000725# Dummy translation for the Python test_gettext.py module.
726# Copyright (C) 2001 Python Software Foundation
727# Barry Warsaw <barry@python.org>, 2000.
728#
729msgid ""
730msgstr ""
731"Project-Id-Version: 2.0\n"
732"PO-Revision-Date: 2003-04-11 12:42-0400\n"
733"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
734"Language-Team: XX <python-dev@python.org>\n"
735"MIME-Version: 1.0\n"
736"Content-Type: text/plain; charset=utf-8\n"
737"Content-Transfer-Encoding: 7bit\n"
738"Generated-By: manually\n"
739
740#: nofile:0
741msgid "ab\xc3\x9e"
742msgstr "\xc2\xa4yz"
743'''
Barry Warsawe960e222003-05-20 17:28:54 +0000744
745# Here's the third example po file, used to generate MMO_DATA
746
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300747b'''
Barry Warsawe960e222003-05-20 17:28:54 +0000748msgid ""
749msgstr ""
750"Project-Id-Version: No Project 0.0\n"
751"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
752"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
753"Last-Translator: John Doe <jdoe@example.com>\n"
754"Jane Foobar <jfoobar@example.com>\n"
755"Language-Team: xx <xx@example.com>\n"
756"MIME-Version: 1.0\n"
757"Content-Type: text/plain; charset=iso-8859-15\n"
758"Content-Transfer-Encoding: quoted-printable\n"
759"Generated-By: pygettext.py 1.3\n"
760'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400761
762#
763# messages.po, used for bug 17898
764#
765
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300766b'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400767# test file for http://bugs.python.org/issue17898
768msgid ""
769msgstr ""
770"Plural-Forms: nplurals=2; plural=(n != 1);\n"
771"#-#-#-#-# messages.po (EdX Studio) #-#-#-#-#\n"
772"Content-Type: text/plain; charset=UTF-8\n"
773'''