1import warnings 2from io import BytesIO 3 4from pytest import mark 5 6from translate.convert import pot2po, test_convert 7from translate.storage import po 8 9 10class TestPOT2PO: 11 def setup_method(self, method): 12 warnings.resetwarnings() 13 14 def teardown_method(self, method): 15 warnings.resetwarnings() 16 17 def convertpot(self, potsource, posource=None): 18 """helper that converts pot source to po source without requiring files""" 19 potfile = BytesIO(potsource.encode()) 20 if posource: 21 pofile = BytesIO(posource.encode()) 22 else: 23 pofile = None 24 pooutfile = BytesIO() 25 pot2po.convertpot(potfile, pooutfile, pofile) 26 pooutfile.seek(0) 27 return po.pofile(pooutfile.read()) 28 29 def singleunit(self, pofile): 30 """checks that the pofile contains a single non-header unit, and returns it""" 31 assert len(pofile.units) == 2 32 assert pofile.units[0].isheader() 33 print(pofile.units[1]) 34 return pofile.units[1] 35 36 def test_convertpot_blank(self): 37 """checks that the convertpot function is working for a simple file initialisation""" 38 potsource = ( 39 """#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n""" 40 % po.lsep 41 ) 42 newpo = self.convertpot(potsource) 43 assert str(self.singleunit(newpo)) == potsource 44 45 def test_convertpot_blank_plurals(self): 46 """checks that the convertpot function is working for initialising plurals correctly""" 47 potsource = r"""msgid "" 48msgstr"" 49 50msgid "%d manual" 51msgid_plural "%d manuals" 52msgstr[0] "" 53msgstr[1] "" 54""" 55 posource = r"""msgid "" 56msgstr"" 57"Plural-Forms: nplurals=1; plural=0;\n" 58""" 59 60 poexpected = r"""msgid "%d manual" 61msgid_plural "%d manuals" 62msgstr[0] "" 63""" 64 newpo = self.convertpot(potsource, posource) 65 assert str(self.singleunit(newpo)) == poexpected 66 67 def test_merging_simple(self): 68 """checks that the convertpot function is working for a simple merge""" 69 potsource = ( 70 """#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n""" 71 % po.lsep 72 ) 73 posource = ( 74 """#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 75 % po.lsep 76 ) 77 newpo = self.convertpot(potsource, posource) 78 assert str(self.singleunit(newpo)) == posource 79 80 def test_merging_messages_marked_fuzzy(self): 81 """test that when we merge PO files with a fuzzy message that it remains fuzzy""" 82 potsource = ( 83 """#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n""" 84 % po.lsep 85 ) 86 posource = ( 87 """#: simple.label%ssimple.accesskey\n#, fuzzy\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 88 % po.lsep 89 ) 90 newpo = self.convertpot(potsource, posource) 91 assert str(self.singleunit(newpo)) == posource 92 93 def test_merging_plurals_with_fuzzy_matching(self): 94 """test that when we merge PO files with a fuzzy message that it remains fuzzy""" 95 potsource = r"""#: file.cpp:2 96msgid "%d manual" 97msgid_plural "%d manuals" 98msgstr[0] "" 99msgstr[1] "" 100""" 101 posource = r"""#: file.cpp:3 102#, fuzzy 103msgid "%d manual" 104msgid_plural "%d manuals" 105msgstr[0] "%d handleiding." 106msgstr[1] "%d handleidings." 107""" 108 # The #: comment and msgid's are different between the pot and the po 109 poexpected = r"""#: file.cpp:2 110#, fuzzy 111msgid "%d manual" 112msgid_plural "%d manuals" 113msgstr[0] "%d handleiding." 114msgstr[1] "%d handleidings." 115""" 116 newpo = self.convertpot(potsource, posource) 117 assert str(self.singleunit(newpo)) == poexpected 118 119 @mark.xfail(reason="Not implemented - review if this is even correct") 120 def test_merging_msgid_change(self): 121 """tests that if the msgid changes but the location stays the same that we merge""" 122 potsource = """#: simple.label\n#: simple.accesskey\nmsgid "Its &hard coding a newline.\\n"\nmsgstr ""\n""" 123 posource = """#: simple.label\n#: simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 124 poexpected = """#: simple.label\n#: simple.accesskey\n#, fuzzy\nmsgid "Its &hard coding a newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 125 newpo = self.convertpot(potsource, posource) 126 print(newpo) 127 assert str(self.singleunit(newpo)) == poexpected 128 129 def test_merging_location_change(self): 130 """tests that if the location changes but the msgid stays the same that we merge""" 131 potsource = ( 132 """#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n""" 133 % po.lsep 134 ) 135 posource = ( 136 """#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 137 % po.lsep 138 ) 139 poexpected = ( 140 """#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n""" 141 % po.lsep 142 ) 143 newpo = self.convertpot(potsource, posource) 144 print(newpo) 145 assert str(self.singleunit(newpo)) == poexpected 146 147 def test_merging_location_and_whitespace_change(self): 148 """ 149 test that even if the location changes that if the msgid 150 only has whitespace changes we can still merge 151 """ 152 153 potsource = ( 154 """#: singlespace.label%ssinglespace.accesskey\nmsgid "&We have spaces"\nmsgstr ""\n""" 155 % po.lsep 156 ) 157 posource = ( 158 """#: doublespace.label%sdoublespace.accesskey\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n""" 159 % po.lsep 160 ) 161 poexpected = ( 162 """#: singlespace.label%ssinglespace.accesskey\n#, fuzzy\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n""" 163 % po.lsep 164 ) 165 newpo = self.convertpot(potsource, posource) 166 print(newpo) 167 assert str(self.singleunit(newpo)) == poexpected 168 169 def test_merging_location_ambiguous_with_disambiguous(self): 170 """ 171 test that when we have a PO in ambiguous (Gettext form) and merge with 172 disamabiguous (KDE comment form) that we don't duplicate the 173 location #: comments 174 """ 175 potsource = ( 176 """#: location.c:1\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr ""\n\n""" 177 + """#: location.c:10\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr ""\n""" 178 ) 179 posource = ( 180 """#: location.c:1\n#: location.c:10\nmsgid "Source"\nmsgstr "Target"\n\n""" 181 ) 182 poexpected1 = """#: location.c:1\n#, fuzzy\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr "Target"\n""" 183 poexpected2 = """#: location.c:10\n#, fuzzy\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr "Target"\n""" 184 newpo = self.convertpot(potsource, posource) 185 print("Expected:\n", poexpected1, "Actual:\n", newpo.units[1]) 186 assert str(newpo.units[1]) == poexpected1 187 assert str(newpo.units[2]) == poexpected2 188 189 @mark.xfail(reason="Not Implemented - needs review") 190 def test_merging_accelerator_changes(self): 191 """test that a change in the accelerator localtion still allows merging""" 192 potsource = """#: someline.c\nmsgid "A&bout"\nmsgstr ""\n""" 193 posource = """#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n""" 194 poexpected = """#: someline.c\nmsgid "A&bout"\nmsgstr "&Info"\n""" 195 newpo = self.convertpot(potsource, posource) 196 print(newpo) 197 assert str(self.singleunit(newpo)) == poexpected 198 199 @mark.xfail(reason="Not Implemented - review if this is even correct") 200 def test_lines_cut_differently(self): 201 """Checks that the correct formatting is preserved when pot an po lines differ.""" 202 potsource = ( 203 """#: simple.label\nmsgid "Line split "\n"differently"\nmsgstr ""\n""" 204 ) 205 posource = """#: simple.label\nmsgid "Line"\n" split differently"\nmsgstr "Lyne verskillend gesny"\n""" 206 newpo = self.convertpot(potsource, posource) 207 newpounit = self.singleunit(newpo) 208 assert str(newpounit) == posource 209 210 def test_merging_automatic_comments_dont_duplicate(self): 211 """ensure that we can merge #. comments correctly""" 212 potsource = """#. Row 35\nmsgid "&About"\nmsgstr ""\n""" 213 posource = """#. Row 35\nmsgid "&About"\nmsgstr "&Info"\n""" 214 newpo = self.convertpot(potsource, posource) 215 newpounit = self.singleunit(newpo) 216 assert str(newpounit) == posource 217 218 def test_merging_automatic_comments_new_overides_old(self): 219 """ensure that new #. comments override the old comments""" 220 potsource = """#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr ""\n""" 221 posource = """#. old comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n""" 222 poexpected = ( 223 """#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n""" 224 ) 225 newpo = self.convertpot(potsource, posource) 226 newpounit = self.singleunit(newpo) 227 assert str(newpounit) == poexpected 228 229 def test_merging_comments_with_blank_comment_lines(self): 230 """test that when we merge a comment that has a blank line we keep the blank line""" 231 potsource = """#: someline.c\nmsgid "About"\nmsgstr ""\n""" 232 posource = """# comment1\n#\n# comment2\n#: someline.c\nmsgid "About"\nmsgstr "Omtrent"\n""" 233 poexpected = posource 234 newpo = self.convertpot(potsource, posource) 235 newpounit = self.singleunit(newpo) 236 assert str(newpounit) == poexpected 237 238 def test_empty_commentlines(self): 239 potsource = """#: paneSecurity.title 240msgid "Security" 241msgstr "" 242""" 243 posource = """# - Contributor(s): 244# - 245# - Alternatively, the 246# - 247#: paneSecurity.title 248msgid "Security" 249msgstr "Sekuriteit" 250""" 251 poexpected = posource 252 newpo = self.convertpot(potsource, posource) 253 newpounit = self.singleunit(newpo) 254 print("expected") 255 print(poexpected) 256 print("got:") 257 print(str(newpounit)) 258 assert str(newpounit) == poexpected 259 260 def test_merging_msgidcomments(self): 261 """ensure that we can merge msgidcomments messages""" 262 potsource = r"""#: window.width 263msgid "" 264"_: Do not translate this.\n" 265"36em" 266msgstr "" 267""" 268 posource = r"""#: window.width 269msgid "" 270"_: Do not translate this.\n" 271"36em" 272msgstr "36em" 273""" 274 newpo = self.convertpot(potsource, posource) 275 newpounit = self.singleunit(newpo) 276 assert str(newpounit) == posource 277 278 def test_merging_msgid_with_msgidcomment(self): 279 """test that we can merge an otherwise identical string that has a different msgid""" 280 potsource = r"""#: pref.certs.title 281msgid "" 282"_: pref.certs.title\n" 283"Certificates" 284msgstr "" 285 286#: certs.label 287msgid "" 288"_: certs.label\n" 289"Certificates" 290msgstr "" 291""" 292 posource = r"""#: pref.certs.title 293msgid "" 294"_: pref.certs.title\n" 295"Certificates" 296msgstr "" 297 298#: certs.label 299msgid "" 300"_: certs.label\n" 301"Certificates" 302msgstr "Sertifikate" 303""" 304 expected = r"""#: pref.certs.title 305#, fuzzy 306msgid "" 307"_: pref.certs.title\n" 308"Certificates" 309msgstr "Sertifikate" 310""" 311 newpo = self.convertpot(potsource, posource) 312 newpounit = newpo.units[1] 313 assert str(newpounit) == expected 314 315 def test_merging_plurals(self): 316 """ensure that we can merge plural messages""" 317 potsource = """msgid "One"\nmsgid_plural "Two"\nmsgstr[0] ""\nmsgstr[1] ""\n""" 318 posource = """msgid "One"\nmsgid_plural "Two"\nmsgstr[0] "Een"\nmsgstr[1] "Twee"\nmsgstr[2] "Drie"\n""" 319 newpo = self.convertpot(potsource, posource) 320 print(newpo) 321 newpounit = self.singleunit(newpo) 322 assert str(newpounit) == posource 323 324 def test_merging_obsoleting_messages(self): 325 """check that we obsolete messages no longer present in the new file""" 326 # add emtpy msgid line to help factory identify format 327 potsource = 'msgid ""\nmsgstr ""\n' 328 posource = '# Some comment\n#. Extracted comment\n#: obsoleteme:10\nmsgid "One"\nmsgstr "Een"\n' 329 expected = '# Some comment\n#~ msgid "One"\n#~ msgstr "Een"\n' 330 newpo = self.convertpot(potsource, posource) 331 print(bytes(newpo)) 332 newpounit = self.singleunit(newpo) 333 assert str(newpounit) == expected 334 335 def test_not_obsoleting_empty_messages(self): 336 """check that we don't obsolete (and keep) untranslated messages""" 337 # add emtpy msgid line to help factory identify format 338 potsource = 'msgid ""\nmsgstr ""\n' 339 posource = '#: obsoleteme:10\nmsgid "One"\nmsgstr ""\n' 340 newpo = self.convertpot(potsource, posource) 341 print(bytes(newpo)) 342 # We should only have the header 343 assert len(newpo.units) == 1 344 345 def test_merging_new_before_obsolete(self): 346 """test to check that we place new blank message before obsolete messages""" 347 potsource = """#: newline.c\nmsgid "&About"\nmsgstr ""\n""" 348 posource = """#~ msgid "Old"\n#~ msgstr "Oud"\n""" 349 newpo = self.convertpot(potsource, posource) 350 assert len(newpo.units) == 3 351 assert newpo.units[0].isheader() 352 assert newpo.units[2].isobsolete() 353 assert str(newpo.units[1]) == potsource 354 assert str(newpo.units[2]) == posource 355 356 # Now test with real units present in posource 357 posource2 = """msgid "Old"\nmsgstr "Oud"\n""" 358 newpo = self.convertpot(potsource, posource2) 359 assert len(newpo.units) == 3 360 assert newpo.units[0].isheader() 361 assert newpo.units[2].isobsolete() 362 assert str(newpo.units[1]) == potsource 363 assert str(newpo.units[2]) == posource 364 365 def test_merging_resurect_obsolete_messages(self): 366 """check that we can reuse old obsolete messages if the message comes back""" 367 potsource = """#: resurect.c\nmsgid "&About"\nmsgstr ""\n""" 368 posource = """#~ msgid "&About"\n#~ msgstr "&Omtrent"\n""" 369 expected = """#: resurect.c\nmsgid "&About"\nmsgstr "&Omtrent"\n""" 370 newpo = self.convertpot(potsource, posource) 371 print(newpo) 372 assert len(newpo.units) == 2 373 assert newpo.units[0].isheader() 374 newpounit = self.singleunit(newpo) 375 assert str(newpounit) == expected 376 377 def test_merging_resurect_obsolete_messages_into_msgidcomment(self): 378 """check that we can reuse old obsolete messages even if the recipient has a msgidcomment""" 379 potsource = ( 380 """#: resurect1.c\nmsgid "About"\nmsgstr ""\n\n""" 381 + """#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr ""\n""" 382 ) 383 posource = """#~ msgid "About"\n#~ msgstr "Omtrent"\n""" 384 expected1 = """#: resurect1.c\nmsgid "About"\nmsgstr "Omtrent"\n""" 385 expected2 = """#: resurect2.c\n#, fuzzy\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr "Omtrent"\n""" 386 newpo = self.convertpot(potsource, posource) 387 print(newpo) 388 assert len(newpo.units) == 3 389 assert newpo.units[0].isheader() 390 assert str(newpo.units[1]) == expected1 391 assert str(newpo.units[2]) == expected2 392 393 def test_header_initialisation(self): 394 """test to check that we initialise the header correctly""" 395 potsource = r"""#, fuzzy 396msgid "" 397msgstr "" 398"Project-Id-Version: PACKAGE VERSION\n" 399"Report-Msgid-Bugs-To: new@example.com\n" 400"POT-Creation-Date: 2006-11-11 11:11+0000\n" 401"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 402"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 403"Language-Team: LANGUAGE <LL@li.org>\n" 404"MIME-Version: 1.0\n" 405"Content-Type: text/plain; charset=UTF-8\n" 406"Content-Transfer-Encoding: 8bit\n" 407"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" 408"X-Generator: Translate Toolkit 0.10rc2\n" 409""" 410 posource = r"""msgid "" 411msgstr "" 412"Project-Id-Version: Pootle 0.10\n" 413"Report-Msgid-Bugs-To: old@example.com\n" 414"POT-Creation-Date: 2006-01-01 01:01+0100\n" 415"PO-Revision-Date: 2006-09-09 09:09+0900\n" 416"Last-Translator: Joe Translate <joe@example.com>\n" 417"Language-Team: Pig Latin <piglatin@example.com>\n" 418"MIME-Version: 1.0\n" 419"Content-Type: text/plain; charset=UTF-8\n" 420"Content-Transfer-Encoding: 8bit\n" 421"Plural-Forms: nplurals=2; plural=(n != 1);\n" 422"X-Generator: Translate Toolkit 0.9\n" 423""" 424 expected = r"""msgid "" 425msgstr "" 426"Project-Id-Version: Pootle 0.10\n" 427"Report-Msgid-Bugs-To: new@example.com\n" 428"POT-Creation-Date: 2006-11-11 11:11+0000\n" 429"PO-Revision-Date: 2006-09-09 09:09+0900\n" 430"Last-Translator: Joe Translate <joe@example.com>\n" 431"Language-Team: Pig Latin <piglatin@example.com>\n" 432"MIME-Version: 1.0\n" 433"Content-Type: text/plain; charset=UTF-8\n" 434"Content-Transfer-Encoding: 8bit\n" 435"Plural-Forms: nplurals=2; plural=(n != 1);\n" 436"X-Generator: Translate Toolkit 0.10rc2\n" 437""" 438 newpo = self.convertpot(potsource, posource) 439 print("Output Header:\n%s" % newpo) 440 print("Expected Header:\n%s" % expected) 441 assert bytes(newpo).decode("utf-8") == expected 442 443 def test_merging_comments(self): 444 """Test that we can merge comments correctly""" 445 potsource = """#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr ""\n""" 446 posource = """#. Don't do it!\n#: file.py:2\nmsgid "One"\nmsgstr "Een"\n""" 447 poexpected = """#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr "Een"\n""" 448 newpo = self.convertpot(potsource, posource) 449 print(newpo) 450 newpounit = self.singleunit(newpo) 451 assert str(newpounit) == poexpected 452 453 def test_merging_typecomments(self): 454 """Test that we can merge with typecomments""" 455 potsource = """#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr ""\n""" 456 posource = """#: file.c:2\nmsgid "%d pipes"\nmsgstr "%d pype"\n""" 457 poexpected = ( 458 """#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr "%d pype"\n""" 459 ) 460 newpo = self.convertpot(potsource, posource) 461 newpounit = self.singleunit(newpo) 462 print(newpounit) 463 assert str(newpounit) == poexpected 464 465 potsource = """#: file.c:1\n#, c-format\nmsgid "%d computers"\nmsgstr ""\n""" 466 posource = """#: file.c:2\n#, c-format\nmsgid "%s computers "\nmsgstr "%s-rekenaars"\n""" 467 poexpected = """#: file.c:1\n#, fuzzy, c-format\nmsgid "%d computers"\nmsgstr "%s-rekenaars"\n""" 468 newpo = self.convertpot(potsource, posource) 469 newpounit = self.singleunit(newpo) 470 assert newpounit.isfuzzy() 471 assert newpounit.hastypecomment("c-format") 472 473 def test_msgctxt(self): 474 """Test that msgctxt is migrated correctly""" 475 potsource = """ 476#: something.h:5 477msgctxt "context1" 478msgid "text" 479msgstr "" 480 481#: something.h:6 482msgctxt "context2" 483msgid "text" 484msgstr "" 485""" 486 posource = """ 487#: something.h:3 488msgctxt "context0" 489msgid "text" 490msgstr "teks" 491 492#: something.h:4 493msgctxt "context1" 494msgid "text" 495msgstr "sms" 496""" 497 poexpected = """ 498#: something.h:5 499msgctxt "context1" 500msgid "text" 501msgstr "sms" 502 503#: something.h:6 504#, fuzzy 505msgctxt "context2" 506msgid "text" 507msgstr "teks" 508""" 509 newpo = self.convertpot(potsource, posource) 510 print(newpo) 511 assert poexpected in bytes(newpo).decode("utf-8") 512 513 def test_msgctxt_multiline(self): 514 """Test multiline msgctxt fields.""" 515 pot_source = r"""#. |1MV 516#: ActionTe.ulf 517msgctxt "" 518"ActionTe.ulf\n" 519"OOO_ACTIONTEXT_21\n" 520"LngText.text" 521msgid "Computing space requirements" 522msgstr "" 523""" 524 525 po_source = r"""#. |1MV 526#: ActionTe.ulf 527msgctxt "" 528"ActionTe.ulf\n" 529"OOO_ACTIONTEXT_21\n" 530"LngText.text" 531msgid "Computing space requirements" 532msgstr "A szükséges lemezterület kiszámítása" 533""" 534 535 new_po = self.convertpot(pot_source, po_source) 536 assert new_po.units[0].isheader() 537 unit = new_po.units[1] 538 assert not unit.isfuzzy() 539 assert po_source == str(unit) 540 541 def test_msgid_merge_on_location(self): 542 """Tests that unit merges rely on location-based matching.""" 543 pot_source = r""" 544msgid "" 545msgstr "" 546"X-Merge-On: location\n" 547 548#. $:am 549#: ActionTe.ulf 550msgctxt "" 551"ActionTe.ulf\n" 552"OOO_ACTIONTEXT_11\n" 553"LngText.text" 554msgid "Computing space requirements" 555msgstr "" 556 557#. NjJ3 558#: ActionTe.ulf 559msgctxt "" 560"ActionTe.ulf\n" 561"OOO_ACTIONTEXT_12\n" 562"LngText.text" 563msgid "Computing space requirements" 564msgstr "" 565""" 566 567 po_source = r""" 568#. $:am 569#: ActionTe.ulf 570msgctxt "" 571"ActionTe.ulf\n" 572"OOO_ACTIONTEXT_11\n" 573"LngText.text" 574msgid "Computing space requirements" 575msgstr "A szükséges lemezterület kiszámítása" 576 577#. NjJ3 578#: ActionTe.ulf 579msgctxt "" 580"ActionTe.ulf\n" 581"OOO_ACTIONTEXT_12\n" 582"LngText.text" 583msgid "Computing space requirements" 584msgstr "A szükséges lemezterület kiszámítása" 585""" 586 587 new_po = self.convertpot(pot_source, po_source) 588 589 assert len(new_po.units) == 3 590 assert new_po.units[0].isheader() 591 592 assert not new_po.units[1].isfuzzy() 593 assert new_po.units[2].isfuzzy() 594 595 def test_msgid_merge_on_id(self): 596 """Tests that unit merges rely on location-based matching.""" 597 pot_source = r""" 598msgid "" 599msgstr "" 600"X-Merge-On: id\n" 601 602#. $:am 603#: ActionTe.ulf 604msgctxt "" 605"ActionTe.ulf\n" 606"OOO_ACTIONTEXT_11\n" 607"LngText.text" 608msgid "Computing space requirements" 609msgstr "" 610 611#. NjJ3 612#: ActionTe.ulf 613msgctxt "" 614"ActionTe.ulf\n" 615"OOO_ACTIONTEXT_12\n" 616"LngText.text" 617msgid "Computing space requirements" 618msgstr "" 619""" 620 pot_source_noheader = r""" 621#. $:am 622#: ActionTe.ulf 623msgctxt "" 624"ActionTe.ulf\n" 625"OOO_ACTIONTEXT_11\n" 626"LngText.text" 627msgid "Computing space requirements" 628msgstr "" 629 630#. NjJ3 631#: ActionTe.ulf 632msgctxt "" 633"ActionTe.ulf\n" 634"OOO_ACTIONTEXT_12\n" 635"LngText.text" 636msgid "Computing space requirements" 637msgstr "" 638""" 639 640 po_source = r""" 641#. $:am 642#: ActionTe.ulf 643msgctxt "" 644"ActionTe.ulf\n" 645"OOO_ACTIONTEXT_11\n" 646"LngText.text" 647msgid "Computing space requirements" 648msgstr "A szükséges lemezterület kiszámítása" 649 650#. NjJ3 651#: ActionTe.ulf 652msgctxt "" 653"ActionTe.ulf\n" 654"OOO_ACTIONTEXT_12\n" 655"LngText.text" 656msgid "Computing space requirements" 657msgstr "A szükséges lemezterület kiszámítása" 658""" 659 660 for pot in (pot_source, pot_source_noheader): 661 new_po = self.convertpot(pot, po_source) 662 663 assert len(new_po.units) == 3 664 assert new_po.units[0].isheader() 665 666 assert not new_po.units[1].isfuzzy() 667 assert not new_po.units[2].isfuzzy() 668 669 def test_empty_msgid(self): 670 """Test that we handle empty msgids correctly.""" 671 # TODO: this test will fail if we don't have the gettext location 672 # comment in the pot file 673 potsource = '#: file:1\nmsgctxt "bla"\nmsgid ""\nmsgstr ""\n' 674 posource = r""" 675msgid "" 676"Project-Id-Version: Pootle 0.10\n" 677msgstr "" 678 679msgctxt "bla" 680msgid "" 681msgstr "trans" 682""" 683 newpo = self.convertpot(potsource, posource) 684 print(newpo) 685 assert len(newpo.units) == 2 686 assert newpo.units[0].isheader() 687 unit = newpo.units[1] 688 assert unit.source == "" 689 assert unit.getid() == "bla\04" 690 assert unit.target == "trans" 691 assert not unit.isfuzzy() 692 693 def test_migrate_msgidcomment_to_msgctxt(self): 694 """ 695 Test that we migrate correctly from msgidcomments to msgctxt. 696 697 This is needed for our move away from using msgidcomments for mozilla. 698 """ 699 potsource = r""" 700msgid "" 701msgstr "" 702"X-Accelerator-Marker: &\n" 703"X-Merge-On: location\n" 704 705 706#: bla 707msgctxt "bla" 708msgid "" 709msgstr "" 710""" 711 posource = r""" 712msgid "" 713msgstr "" 714"Project-Id-Version: Pootle 0.10\n" 715"X-Accelerator-Marker: &\n" 716 717 718#: bla 719msgid "" 720"_: bla\n" 721msgstr "trans" 722""" 723 newpo = self.convertpot(potsource, posource) 724 print(newpo) 725 assert len(newpo.units) == 2 726 assert newpo.units[0].isheader() 727 unit = newpo.units[1] 728 assert unit.source == "" 729 assert unit.getid() == "bla\04" 730 assert unit.target == "trans" 731 assert not unit.isfuzzy() 732 733 def test_obsolete_msgctxt(self): 734 """Test that obsolete units' msgctxt is preserved.""" 735 potsource = 'msgctxt "newContext"\nmsgid "First unit"\nmsgstr ""' 736 posource = """ 737msgctxt "newContext" 738msgid "First unit" 739msgstr "Eerste eenheid" 740 741#~ msgctxt "context" 742#~ msgid "Old unit" 743#~ msgstr "Ou eenheid1" 744 745#~ msgctxt "context2" 746#~ msgid "Old unit" 747#~ msgstr "Ou eenheid2" 748 749#~ msgid "Old unit" 750#~ msgstr "Ou eenheid3" 751""" 752 newpo = self.convertpot(potsource, posource) 753 print(newpo) 754 assert len(newpo.units) == 5 755 assert newpo.units[1].getcontext() == "newContext" 756 # Search in unit string, because obsolete units can't return a context 757 assert 'msgctxt "context"' in str(newpo.units[2]) 758 assert 'msgctxt "context2"' in str(newpo.units[3]) 759 760 def test_small_strings(self): 761 """ 762 Test that units with small source strings are not incorrectly 763 populated by means of fuzzy matching. 764 """ 765 potsource = r"""#, fuzzy 766msgid "" 767msgstr "" 768"Project-Id-Version: PACKAGE VERSION\n" 769"Report-Msgid-Bugs-To: new@example.com\n" 770"POT-Creation-Date: 2006-11-11 11:11+0000\n" 771"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 772"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 773"Language-Team: LANGUAGE <LL@li.org>\n" 774"MIME-Version: 1.0\n" 775"Content-Type: text/plain; charset=UTF-8\n" 776"Content-Transfer-Encoding: 8bit\n" 777"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" 778"X-Accelerator-Marker: &\n" 779"X-Generator: Translate Toolkit 0.10rc2\n" 780"X-Merge-On: location\n" 781 782#: new_disassociated_mozilla_accesskey 783msgid "R" 784msgstr "" 785""" 786 posource = r"""msgid "" 787msgstr "" 788"Project-Id-Version: Pootle 0.10\n" 789"Report-Msgid-Bugs-To: old@example.com\n" 790"POT-Creation-Date: 2006-01-01 01:01+0100\n" 791"PO-Revision-Date: 2006-09-09 09:09+0900\n" 792"Last-Translator: Joe Translate <joe@example.com>\n" 793"Language-Team: Pig Latin <piglatin@example.com>\n" 794"MIME-Version: 1.0\n" 795"Content-Type: text/plain; charset=UTF-8\n" 796"Content-Transfer-Encoding: 8bit\n" 797"Plural-Forms: nplurals=2; plural=(n != 1);\n" 798"X-Generator: Translate Toolkit 0.9\n" 799"X-Accelerator-Marker: &\n" 800 801#: old_disassociated_mozilla_accesskey 802msgid "R" 803msgstr "S" 804""" 805 expected = r"""msgid "" 806msgstr "" 807"Project-Id-Version: Pootle 0.10\n" 808"Report-Msgid-Bugs-To: new@example.com\n" 809"POT-Creation-Date: 2006-11-11 11:11+0000\n" 810"PO-Revision-Date: 2006-09-09 09:09+0900\n" 811"Last-Translator: Joe Translate <joe@example.com>\n" 812"Language-Team: Pig Latin <piglatin@example.com>\n" 813"MIME-Version: 1.0\n" 814"Content-Type: text/plain; charset=UTF-8\n" 815"Content-Transfer-Encoding: 8bit\n" 816"Plural-Forms: nplurals=2; plural=(n != 1);\n" 817"X-Accelerator-Marker: &\n" 818"X-Generator: Translate Toolkit 0.10rc2\n" 819"X-Merge-On: location\n" 820 821#: new_disassociated_mozilla_accesskey 822msgid "R" 823msgstr "" 824""" 825 newpo = self.convertpot(potsource, posource) 826 print("Output:\n%s" % newpo) 827 print("Expected:\n%s" % expected) 828 assert bytes(newpo).decode("utf-8") == expected 829 830 831class TestPOT2POCommand(test_convert.TestConvertCommand, TestPOT2PO): 832 """Tests running actual pot2po commands on files""" 833 834 convertmodule = pot2po 835 836 def test_help(self, capsys): 837 """tests getting help""" 838 options = super().test_help(capsys) 839 options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE") 840 options = self.help_check(options, "-P, --pot") 841 options = self.help_check(options, "--tm") 842 options = self.help_check( 843 options, "-s MIN_SIMILARITY, --similarity=MIN_SIMILARITY" 844 ) 845 options = self.help_check(options, "--nofuzzymatching", last=True) 846