fix git support for v1.5.3 (or higher) by setting "--work-tree"
[translate_toolkit.git] / convert / test_pot2po.py
blobdd11943203174298c062b48a7b9c8ab64f67525e
1 #!/usr/bin/env python
3 from translate.convert import pot2po
4 from translate.convert import test_convert
5 from translate.misc import wStringIO
6 from translate.storage import po
7 import warnings
9 class TestPOT2PO:
10 def setup_method(self, method):
11 warnings.resetwarnings()
13 def teardown_method(self, method):
14 warnings.resetwarnings()
16 def convertpot(self, potsource, posource=None):
17 """helper that converts pot source to po source without requiring files"""
18 potfile = wStringIO.StringIO(potsource)
19 if posource:
20 pofile = wStringIO.StringIO(posource)
21 else:
22 pofile = None
23 pooutfile = wStringIO.StringIO()
24 pot2po.convertpot(potfile, pooutfile, pofile)
25 pooutfile.seek(0)
26 return po.pofile(pooutfile.read())
28 def singleunit(self, pofile):
29 """checks that the pofile contains a single non-header unit, and returns it"""
30 assert len(pofile.units) == 2
31 assert pofile.units[0].isheader()
32 print pofile.units[1]
33 return pofile.units[1]
35 def test_convertpot_blank(self):
36 """checks that the convertpot function is working for a simple file initialisation"""
37 potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
38 newpo = self.convertpot(potsource)
39 assert str(self.singleunit(newpo)) == potsource
41 def test_convertpot_blank_plurals(self):
42 """checks that the convertpot function is working for initialising plurals correctly"""
43 potsource = r'''msgid ""
44 msgstr""
46 msgid "%d manual"
47 msgid_plural "%d manuals"
48 msgstr[0] ""
49 msgstr[1] ""
50 '''
51 posource = r'''msgid ""
52 msgstr""
53 "Plural-Forms: nplurals=1; plural=0;\n"
54 '''
56 poexpected = r'''msgid "%d manual"
57 msgid_plural "%d manuals"
58 msgstr[0] ""
59 '''
60 newpo = self.convertpot(potsource, posource)
61 assert str(self.singleunit(newpo)) == poexpected
63 def test_merging_simple(self):
64 """checks that the convertpot function is working for a simple merge"""
65 potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
66 posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
67 newpo = self.convertpot(potsource, posource)
68 assert str(self.singleunit(newpo)) == posource
70 def test_merging_messages_marked_fuzzy(self):
71 """test that when we merge PO files with a fuzzy message that it remains fuzzy"""
72 potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
73 posource = '''#: simple.label%ssimple.accesskey\n#, fuzzy\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
74 newpo = self.convertpot(potsource, posource)
75 assert str(self.singleunit(newpo)) == posource
77 def test_merging_plurals_with_fuzzy_matching(self):
78 """test that when we merge PO files with a fuzzy message that it remains fuzzy"""
79 potsource = r'''#: file.cpp:2
80 msgid "%d manual"
81 msgid_plural "%d manuals"
82 msgstr[0] ""
83 msgstr[1] ""
84 '''
85 posource = r'''#: file.cpp:3
86 #, fuzzy
87 msgid "%d manual"
88 msgid_plural "%d manuals"
89 msgstr[0] "%d handleiding."
90 msgstr[1] "%d handleidings."
91 '''
92 # The #: comment and msgid's are different between the pot and the po
93 poexpected = r'''#: file.cpp:2
94 #, fuzzy
95 msgid "%d manual"
96 msgid_plural "%d manuals"
97 msgstr[0] "%d handleiding."
98 msgstr[1] "%d handleidings."
99 '''
100 newpo = self.convertpot(potsource, posource)
101 assert str(self.singleunit(newpo)) == poexpected
103 def xtest_merging_msgid_change(self):
104 """tests that if the msgid changes but the location stays the same that we merge"""
105 potsource = '''#: simple.label\n#: simple.accesskey\nmsgid "Its &hard coding a newline.\\n"\nmsgstr ""\n'''
106 posource = '''#: simple.label\n#: simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n'''
107 poexpected = '''#: simple.label\n#: simple.accesskey\n#, fuzzy\nmsgid "Its &hard coding a newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n'''
108 newpo = self.convertpot(potsource, posource)
109 print newpo
110 assert str(self.singleunit(newpo)) == poexpected
112 def test_merging_location_change(self):
113 """tests that if the location changes but the msgid stays the same that we merge"""
114 potsource = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
115 posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
116 poexpected = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
117 newpo = self.convertpot(potsource, posource)
118 print newpo
119 assert str(self.singleunit(newpo)) == poexpected
121 def test_merging_location_and_whitespace_change(self):
122 """test that even if the location changes that if the msgid only has whitespace changes we can still merge"""
123 potsource = '''#: singlespace.label%ssinglespace.accesskey\nmsgid "&We have spaces"\nmsgstr ""\n''' % po.lsep
124 posource = '''#: doublespace.label%sdoublespace.accesskey\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep
125 poexpected = '''#: singlespace.label%ssinglespace.accesskey\n#, fuzzy\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep
126 newpo = self.convertpot(potsource, posource)
127 print newpo
128 assert str(self.singleunit(newpo)) == poexpected
130 def test_merging_location_ambiguous_with_disambiguous(self):
131 """test that when we have a PO in ambiguous (Gettext form) and merge with disamabiguous (KDE comment form)
132 that we don't duplicate the location #: comments"""
133 potsource = '''#: location.c:1\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr ""\n\n''' + \
134 '''#: location.c:10\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr ""\n'''
135 posource = '''#: location.c:1\n#: location.c:10\nmsgid "Source"\nmsgstr "Target"\n\n'''
136 poexpected1 = '''#: location.c:1\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr "Target"\n'''
137 poexpected2 = '''#: location.c:10\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr "Target"\n'''
138 newpo = self.convertpot(potsource, posource)
139 print "Expected:\n", poexpected1, "Actual:\n", newpo.units[1]
140 assert str(newpo.units[1]) == poexpected1
141 assert str(newpo.units[2]) == poexpected2
143 def wtest_merging_accelerator_changes(self):
144 """test that a change in the accelerator localtion still allows merging"""
145 potsource = '''#: someline.c\nmsgid "A&bout"\nmsgstr ""\n'''
146 posource = '''#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
147 poexpected = '''#: someline.c\nmsgid "A&bout"\nmsgstr "&Info"\n'''
148 newpo = self.convertpot(potsource, posource)
149 print newpo
150 assert str(self.singleunit(newpo)) == poexpected
152 def xtest_lines_cut_differently(self):
153 """Checks that the correct formatting is preserved when pot an po lines differ."""
154 potsource = '''#: simple.label\nmsgid "Line split "\n"differently"\nmsgstr ""\n'''
155 posource = '''#: simple.label\nmsgid "Line"\n" split differently"\nmsgstr "Lyne verskillend gesny"\n'''
156 newpo = self.convertpot(potsource, posource)
157 newpounit = self.singleunit(newpo)
158 assert str(newpounit) == posource
160 def test_merging_automatic_comments_dont_duplicate(self):
161 """ensure that we can merge #. comments correctly"""
162 potsource = '''#. Row 35\nmsgid "&About"\nmsgstr ""\n'''
163 posource = '''#. Row 35\nmsgid "&About"\nmsgstr "&Info"\n'''
164 newpo = self.convertpot(potsource, posource)
165 newpounit = self.singleunit(newpo)
166 assert str(newpounit) == posource
168 def test_merging_automatic_comments_new_overides_old(self):
169 """ensure that new #. comments override the old comments"""
170 potsource = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr ""\n'''
171 posource = '''#. old comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
172 poexpected = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
173 newpo = self.convertpot(potsource, posource)
174 newpounit = self.singleunit(newpo)
175 assert str(newpounit) == poexpected
177 def test_merging_comments_with_blank_comment_lines(self):
178 """test that when we merge a comment that has a blank line we keep the blank line"""
179 potsource = '''#: someline.c\nmsgid "About"\nmsgstr ""\n'''
180 posource = '''# comment1\n#\n# comment2\n#: someline.c\nmsgid "About"\nmsgstr "Omtrent"\n'''
181 poexpected = posource
182 newpo = self.convertpot(potsource, posource)
183 newpounit = self.singleunit(newpo)
184 assert str(newpounit) == poexpected
186 def test_empty_commentlines(self):
187 potsource = '''#: paneSecurity.title
188 msgid "Security"
189 msgstr ""
191 posource = '''# - Contributor(s):
193 # - Alternatively, the
195 #: paneSecurity.title
196 msgid "Security"
197 msgstr "Sekuriteit"
199 poexpected = posource
200 newpo = self.convertpot(potsource, posource)
201 newpounit = self.singleunit(newpo)
202 print "expected"
203 print poexpected
204 print "got:"
205 print str(newpounit)
206 assert str(newpounit) == poexpected
208 def test_merging_msgidcomments(self):
209 """ensure that we can merge msgidcomments messages"""
210 potsource = r'''#: window.width
211 msgid ""
212 "_: Do not translate this.\n"
213 "36em"
214 msgstr ""
216 posource = r'''#: window.width
217 msgid ""
218 "_: Do not translate this.\n"
219 "36em"
220 msgstr "36em"
222 newpo = self.convertpot(potsource, posource)
223 newpounit = self.singleunit(newpo)
224 assert str(newpounit) == posource
226 def test_merging_msgid_with_msgidcomment(self):
227 """test that we can merge an otherwise identical string that has a different msgid"""
228 potsource = r'''#: pref.certs.title
229 msgid ""
230 "_: pref.certs.title\n"
231 "Certificates"
232 msgstr ""
234 #: certs.label
235 msgid ""
236 "_: certs.label\n"
237 "Certificates"
238 msgstr ""
240 posource = r'''#: pref.certs.title
241 msgid ""
242 "_: pref.certs.title\n"
243 "Certificates"
244 msgstr ""
246 #: certs.label
247 msgid ""
248 "_: certs.label\n"
249 "Certificates"
250 msgstr "Sertifikate"
252 expected = r'''#: pref.certs.title
253 msgid ""
254 "_: pref.certs.title\n"
255 "Certificates"
256 msgstr "Sertifikate"
258 newpo = self.convertpot(potsource, posource)
259 newpounit = newpo.units[1]
260 assert str(newpounit) == expected
262 def test_merging_plurals(self):
263 """ensure that we can merge plural messages"""
264 potsource = '''msgid "One"\nmsgid_plural "Two"\nmsgstr[0] ""\nmsgstr[1] ""\n'''
265 posource = '''msgid "One"\nmsgid_plural "Two"\nmsgstr[0] "Een"\nmsgstr[1] "Twee"\nmsgstr[2] "Drie"\n'''
266 newpo = self.convertpot(potsource, posource)
267 print newpo
268 newpounit = self.singleunit(newpo)
269 assert str(newpounit) == posource
271 def test_merging_obsoleting_messages(self):
272 """check that we obsolete messages no longer present in the new file"""
273 potsource = ''
274 posource = '# Some comment\n#. Extracted comment\n#: obsoleteme:10\nmsgid "One"\nmsgstr "Een"\n'
275 expected = '# Some comment\n#~ msgid "One"\n#~ msgstr "Een"\n'
276 newpo = self.convertpot(potsource, posource)
277 print str(newpo)
278 newpounit = self.singleunit(newpo)
279 assert str(newpounit) == expected
281 def test_not_obsoleting_empty_messages(self):
282 """check that we don't obsolete (and keep) untranslated messages"""
283 potsource = ''
284 posource = '#: obsoleteme:10\nmsgid "One"\nmsgstr ""\n'
285 newpo = self.convertpot(potsource, posource)
286 print str(newpo)
287 # We should only have the header
288 assert len(newpo.units) == 1
290 def test_merging_new_before_obsolete(self):
291 """test to check that we place new blank message before obsolete messages"""
292 potsource = '''#: newline.c\nmsgid "&About"\nmsgstr ""\n'''
293 posource = '''#~ msgid "Old"\n#~ msgstr "Oud"\n'''
294 newpo = self.convertpot(potsource, posource)
295 assert len(newpo.units) == 3
296 assert newpo.units[0].isheader()
297 assert newpo.units[2].isobsolete()
298 assert str(newpo.units[1]) == potsource
299 assert str(newpo.units[2]) == posource
301 # Now test with real units present in posource
302 posource2 = '''msgid "Old"\nmsgstr "Oud"\n'''
303 newpo = self.convertpot(potsource, posource)
304 assert len(newpo.units) == 3
305 assert newpo.units[0].isheader()
306 assert newpo.units[2].isobsolete()
307 assert str(newpo.units[1]) == potsource
308 assert str(newpo.units[2]) == posource
310 def test_merging_resurect_obsolete_messages(self):
311 """check that we can reuse old obsolete messages if the message comes back"""
312 potsource = '''#: resurect.c\nmsgid "&About"\nmsgstr ""\n'''
313 posource = '''#~ msgid "&About"\n#~ msgstr "&Omtrent"\n'''
314 expected = '''#: resurect.c\nmsgid "&About"\nmsgstr "&Omtrent"\n'''
315 newpo = self.convertpot(potsource, posource)
316 print newpo
317 assert len(newpo.units) == 2
318 assert newpo.units[0].isheader()
319 newpounit = self.singleunit(newpo)
320 assert str(newpounit) == expected
322 def test_merging_resurect_obsolete_messages_into_msgidcomment(self):
323 """check that we can reuse old obsolete messages even if the recipient has a msgidcomment"""
324 potsource = '''#: resurect1.c\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr ""\n\n''' + \
325 '''#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr ""\n'''
326 posource = '''#~ msgid "About"\n#~ msgstr "Omtrent"\n'''
327 expected1 = '''#: resurect1.c\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr "Omtrent"\n'''
328 expected2 = '''#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr "Omtrent"\n'''
329 newpo = self.convertpot(potsource, posource)
330 print newpo
331 assert len(newpo.units) == 3
332 assert newpo.units[0].isheader()
333 assert str(newpo.units[1]) == expected1
334 assert str(newpo.units[2]) == expected2
336 def test_header_initialisation(self):
337 """test to check that we initialise the header correctly"""
338 potsource = r'''#, fuzzy
339 msgid ""
340 msgstr ""
341 "Project-Id-Version: PACKAGE VERSION\n"
342 "Report-Msgid-Bugs-To: new@example.com\n"
343 "POT-Creation-Date: 2006-11-11 11:11+0000\n"
344 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
345 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
346 "Language-Team: LANGUAGE <LL@li.org>\n"
347 "MIME-Version: 1.0\n"
348 "Content-Type: text/plain; charset=UTF-8\n"
349 "Content-Transfer-Encoding: 8bit\n"
350 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
351 "X-Generator: Translate Toolkit 0.10rc2\n"
353 posource = r'''msgid ""
354 msgstr ""
355 "Project-Id-Version: Pootle 0.10\n"
356 "Report-Msgid-Bugs-To: old@example.com\n"
357 "POT-Creation-Date: 2006-01-01 01:01+0100\n"
358 "PO-Revision-Date: 2006-09-09 09:09+0900\n"
359 "Last-Translator: Joe Translate <joe@example.com>\n"
360 "Language-Team: Pig Latin <piglatin@example.com>\n"
361 "MIME-Version: 1.0\n"
362 "Content-Type: text/plain; charset=UTF-8\n"
363 "Content-Transfer-Encoding: 8bit\n"
364 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
365 "X-Generator: Translate Toolkit 0.9\n"
367 expected = r'''msgid ""
368 msgstr ""
369 "Project-Id-Version: Pootle 0.10\n"
370 "Report-Msgid-Bugs-To: new@example.com\n"
371 "POT-Creation-Date: 2006-11-11 11:11+0000\n"
372 "PO-Revision-Date: 2006-09-09 09:09+0900\n"
373 "Last-Translator: Joe Translate <joe@example.com>\n"
374 "Language-Team: Pig Latin <piglatin@example.com>\n"
375 "MIME-Version: 1.0\n"
376 "Content-Type: text/plain; charset=UTF-8\n"
377 "Content-Transfer-Encoding: 8bit\n"
378 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
379 "X-Generator: Translate Toolkit 0.10rc2\n"
381 newpo = self.convertpot(potsource, posource)
382 print 'Output Header:\n%s' % newpo
383 print 'Expected Header:\n%s' % expected
384 assert str(newpo) == expected
386 def test_merging_comments(self):
387 """Test that we can merge comments correctly"""
388 potsource = '''#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr ""\n'''
389 posource = '''#. Don't do it!\n#: file.py:2\nmsgid "One"\nmsgstr "Een"\n'''
390 poexpected = '''#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr "Een"\n'''
391 newpo = self.convertpot(potsource, posource)
392 print newpo
393 newpounit = self.singleunit(newpo)
394 assert str(newpounit) == poexpected
396 def test_merging_typecomments(self):
397 """Test that we can merge with typecomments"""
398 potsource = '''#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr ""\n'''
399 posource = '''#: file.c:2\nmsgid "%d pipes"\nmsgstr "%d pype"\n'''
400 poexpected = '''#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr "%d pype"\n'''
401 newpo = self.convertpot(potsource, posource)
402 newpounit = self.singleunit(newpo)
403 print newpounit
404 assert str(newpounit) == poexpected
406 potsource = '''#: file.c:1\n#, c-format\nmsgid "%d computers"\nmsgstr ""\n'''
407 posource = '''#: file.c:2\n#, c-format\nmsgid "%s computers "\nmsgstr "%s-rekenaars"\n'''
408 poexpected = '''#: file.c:1\n#, fuzzy, c-format\nmsgid "%d computers"\nmsgstr "%s-rekenaars"\n'''
409 newpo = self.convertpot(potsource, posource)
410 newpounit = self.singleunit(newpo)
411 assert newpounit.isfuzzy()
412 assert newpounit.hastypecomment("c-format")
414 class TestPOT2POCommand(test_convert.TestConvertCommand, TestPOT2PO):
415 """Tests running actual pot2po commands on files"""
416 convertmodule = pot2po
418 def test_help(self):
419 """tests getting help"""
420 options = test_convert.TestConvertCommand.test_help(self)
421 options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
422 options = self.help_check(options, "-P, --pot")
423 options = self.help_check(options, "--tm")
424 options = self.help_check(options, "-s MIN_SIMILARITY, --similarity=MIN_SIMILARITY")
425 options = self.help_check(options, "--nofuzzymatching", last=True)