#!/usr/bin/env python
# -*- coding: utf-8 -*-
from translate.tools import pomerge
from translate.storage import po
from translate.storage import xliff
from translate.misc import wStringIO
class TestPOMerge:
xliffskeleton = '''
%s
'''
def mergepo(self, templatesource, inputsource):
"""merges the sources of the given files and returns a new pofile object"""
templatefile = wStringIO.StringIO(templatesource)
inputfile = wStringIO.StringIO(inputsource)
outputfile = wStringIO.StringIO()
assert pomerge.mergepo(inputfile, outputfile, templatefile)
outputpostring = outputfile.getvalue()
outputpofile = po.pofile(outputpostring)
return outputpofile
def mergexliff(self, templatesource, inputsource):
"""merges the sources of the given files and returns a new xlifffile object"""
templatefile = wStringIO.StringIO(templatesource)
inputfile = wStringIO.StringIO(inputsource)
outputfile = wStringIO.StringIO()
assert pomerge.mergexliff(inputfile, outputfile, templatefile)
outputxliffstring = outputfile.getvalue()
print "Generated XML:"
print outputxliffstring
outputxlifffile = xliff.xlifffile(outputxliffstring)
return outputxlifffile
def countunits(self, pofile):
"""returns the number of non-header items"""
if pofile.units[0].isheader():
return len(pofile.units) - 1
else:
return len(pofile.units)
def singleunit(self, pofile):
"""checks that the pofile contains a single non-header unit, and returns it"""
assert self.countunits(pofile) == 1
return pofile.units[-1]
def test_simplemerge(self):
"""checks that a simple po entry merges OK"""
templatepo = '''#: simple.test\nmsgid "Simple String"\nmsgstr ""\n'''
inputpo = '''#: simple.test\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
pofile = self.mergepo(templatepo, inputpo)
pounit = self.singleunit(pofile)
assert po.unquotefrompo(pounit.msgid) == "Simple String"
assert po.unquotefrompo(pounit.msgstr) == "Dimpled Ring"
def test_replacemerge(self):
"""checks that a simple po entry merges OK"""
templatepo = '''#: simple.test\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
inputpo = '''#: simple.test\nmsgid "Simple String"\nmsgstr "Dimpled King"\n'''
pofile = self.mergepo(templatepo, inputpo)
pounit = self.singleunit(pofile)
assert po.unquotefrompo(pounit.msgid) == "Simple String"
assert po.unquotefrompo(pounit.msgstr) == "Dimpled King"
def test_reflowed_source_comments(self):
"""ensure that we don't duplicate source comments (locations) if they have been reflowed"""
templatepo = '''#: newMenu.label\n#: newMenu.accesskey\nmsgid "&New"\nmsgstr ""\n'''
newpo = '''#: newMenu.label newMenu.accesskey\nmsgid "&New"\nmsgstr "&Nuwe"\n'''
expectedpo = '''#: newMenu.label\n#: newMenu.accesskey\nmsgid "&New"\nmsgstr "&Nuwe"\n'''
pofile = self.mergepo(templatepo, newpo)
pounit = self.singleunit(pofile)
print pofile
assert pofile.getoutput() == expectedpo
def test_comments_with_blank_lines(self):
"""ensure that we don't loose empty newlines in comments"""
templatepo = '''# # ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# bla bla
msgid "bla"
msgstr "blabla"
'''
newpo = templatepo
expectedpo = templatepo
pofile = self.mergepo(templatepo, newpo)
pounit = self.singleunit(pofile)
print pofile
assert pofile.getoutput() == expectedpo
def test_merge_dont_delete_unassociated_comments(self):
"""ensure that we do not delete comments in the PO file that are not assocaited with a message block"""
templatepo = '''# Lonely comment\n\n# Translation comment\nmsgid "Bob"\nmsgstr "Toolmaker"\n'''
mergepo = '''# Translation comment\nmsgid "Bob"\nmsgstr "Builder"\n'''
expectedpo = '''# Lonely comment\n\n# Translation comment\nmsgid "Bob"\nmsgstr "Builder"\n'''
pofile = self.mergepo(templatepo, mergepo)
# pounit = self.singleunit(pofile)
print pofile
assert pofile.getoutput() == expectedpo
def test_preserve_format_trailing_newlines(self):
"""Test that we can merge messages correctly that end with a newline"""
templatepo = '''msgid "Simple string\\n"\nmsgstr ""\n'''
mergepo = '''msgid "Simple string\\n"\nmsgstr "Dimpled ring\\n"\n'''
expectedpo = '''msgid "Simple string\\n"\nmsgstr "Dimpled ring\\n"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
templatepo = '''msgid ""\n"Simple string\\n"\nmsgstr ""\n'''
mergepo = '''msgid ""\n"Simple string\\n"\nmsgstr ""\n"Dimpled ring\\n"\n'''
expectedpo = '''msgid ""\n"Simple string\\n"\nmsgstr "Dimpled ring\\n"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_preserve_format_minor_start_and_end_of_sentence_changes(self):
"""Test that we are not too fussy about large diffs for simple changes at the start or end of a sentence"""
templatepo = '''msgid "Target type:"\nmsgstr "Doelsoort"\n\n'''
mergepo = '''msgid "Target type:"\nmsgstr "Doelsoort:"\n'''
expectedpo = mergepo
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
templatepo = '''msgid "&Select"\nmsgstr "Kies"\n\n'''
mergepo = '''msgid "&Select"\nmsgstr "&Kies"\n'''
expectedpo = mergepo
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
templatepo = '''msgid "en-us, en"\nmsgstr "en-us, en"\n'''
mergepo = '''msgid "en-us, en"\nmsgstr "af-za, af, en-za, en-gb, en-us, en"\n'''
expectedpo = mergepo
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_preserve_format_last_entry_in_a_file(self):
"""The last entry in a PO file is usualy not followed by an empty line. Test that we preserve this"""
templatepo = '''msgid "First"\nmsgstr ""\n\nmsgid "Second"\nmsgstr ""\n'''
mergepo = '''msgid "First"\nmsgstr "Eerste"\n\nmsgid "Second"\nmsgstr "Tweede"\n'''
expectedpo = '''msgid "First"\nmsgstr "Eerste"\n\nmsgid "Second"\nmsgstr "Tweede"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
templatepo = '''msgid "First"\nmsgstr ""\n\nmsgid "Second"\nmsgstr ""\n\n'''
mergepo = '''msgid "First"\nmsgstr "Eerste"\n\nmsgid "Second"\nmsgstr "Tweede"\n'''
expectedpo = '''msgid "First"\nmsgstr "Eerste"\n\nmsgid "Second"\nmsgstr "Tweede"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def xtest_escape_tabs(self):
"""Ensure that input tabs are escaped in the output, like gettext does."""
# The strings below contains the tab character, not spaces.
templatepo = '''msgid "First Second"\nmsgstr ""\n\n'''
mergepo = '''msgid "First Second"\nmsgstr "Eerste Tweede"\n'''
expectedpo = r'''imsgid "First\tSecond"
msgstr "Eerste\tTweede"
'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_preserve_comments_layout(self):
"""Ensure that when we merge with new '# (poconflict)' or other comments that we don't mess formating"""
templatepo = '''#: filename\nmsgid "Desktop Background.bmp"\nmsgstr "Desktop Background.bmp"\n\n'''
mergepo = '''# (pofilter) unchanged: please translate\n#: filename\nmsgid "Desktop Background.bmp"\nmsgstr "Desktop Background.bmp"\n'''
expectedpo = mergepo
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_merge_dos2unix(self):
"""Test that merging a comment line with dos newlines doesn't add a new line"""
templatepo = '''# User comment\n# (pofilter) Translate Toolkit comment\n#. Automatic comment\n#: location_comment.c:110\nmsgid "File"\nmsgstr "File"\n\n'''
mergepo = '''# User comment\r\n# (pofilter) Translate Toolkit comment\r\n#. Automatic comment\r\n#: location_comment.c:110\r\nmsgid "File"\r\nmsgstr "Ifayile"\r\n\r\n'''
expectedpo = '''# User comment\n# (pofilter) Translate Toolkit comment\n#. Automatic comment\n#: location_comment.c:110\nmsgid "File"\nmsgstr "Ifayile"\n'''
pofile = self.mergepo(templatepo, mergepo)
assert str(pofile) == expectedpo
# Unassociated comment
templatepo = '''# Lonely comment\n\n#: location_comment.c:110\nmsgid "Bob"\nmsgstr "Toolmaker"\n'''
mergepo = '''# Lonely comment\r\n\r\n#: location_comment.c:110\r\nmsgid "Bob"\r\nmsgstr "Builder"\r\n\r\n'''
expectedpo = '''# Lonely comment\n\n#: location_comment.c:110\nmsgid "Bob"\nmsgstr "Builder"\n'''
pofile = self.mergepo(templatepo, mergepo)
assert str(pofile) == expectedpo
# New comment
templatepo = '''#: location_comment.c:110\nmsgid "File"\nmsgstr "File"\n\n'''
mergepo = '''# User comment\r\n# (pofilter) Translate Toolkit comment\r\n#: location_comment.c:110\r\nmsgid "File"\r\nmsgstr "Ifayile"\r\n\r\n'''
expectedpo = '''# User comment\n# (pofilter) Translate Toolkit comment\n#: location_comment.c:110\nmsgid "File"\nmsgstr "Ifayile"\n'''
pofile = self.mergepo(templatepo, mergepo)
assert str(pofile) == expectedpo
def test_xliff_into_xliff(self):
templatexliff = self.xliffskeleton % '''
red
'''
mergexliff = self.xliffskeleton % '''
red
rooi
'''
xlifffile = self.mergexliff(templatexliff, mergexliff)
assert len(xlifffile.units) == 1
unit = xlifffile.units[0]
assert unit.source == "red"
assert unit.target== "rooi"
def test_po_into_xliff(self):
templatexliff = self.xliffskeleton % '''
red
'''
mergepo = 'msgid "red"\nmsgstr "rooi"'
xlifffile = self.mergexliff(templatexliff, mergepo)
assert len(xlifffile.units) == 1
unit = xlifffile.units[0]
assert unit.source == "red"
assert unit.target== "rooi"
def test_xliff_into_po(self):
templatepo = '# my comment\nmsgid "red"\nmsgstr ""'
mergexliff = self.xliffskeleton % '''
red
rooi
'''
expectedpo = '# my comment\nmsgid "red"\nmsgstr "rooi"\n'
pofile = self.mergepo(templatepo, mergexliff)
assert str(pofile) == expectedpo
def test_merging_dont_merge_kde_comments_found_in_translation(self):
"""If we find a KDE comment in the translation (target) then do not merge it."""
templatepo = '''msgid "_: KDE comment\\n"\n"File"\nmsgstr "File"\n\n'''
mergepo = '''msgid "_: KDE comment\\n"\n"File"\nmsgstr "_: KDE comment\\n"\n"Ifayile"\n\n'''
expectedpo = '''msgid ""\n"_: KDE comment\\n"\n"File"\nmsgstr "Ifayile"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
# Translated kde comment.
mergepo = '''msgid "_: KDE comment\\n"\n"File"\nmsgstr "_: KDE kommentaar\\n"\n"Ifayile"\n\n'''
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
# multiline KDE comment
templatepo = '''msgid "_: KDE "\n"comment\\n"\n"File"\nmsgstr "File"\n\n'''
mergepo = '''msgid "_: KDE "\n"comment\\n"\n"File"\nmsgstr "_: KDE "\n"comment\\n"\n"Ifayile"\n\n'''
expectedpo = '''msgid ""\n"_: KDE comment\\n"\n"File"\nmsgstr "Ifayile"\n'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n\nMerged:\n%s" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_merging_untranslated_with_kde_disambiguation(self):
"""test merging untranslated messages that are the same except for KDE disambiguation"""
templatepo = r'''#: sendMsgTitle
#: sendMsgTitle.accesskey
msgid "_: sendMsgTitle sendMsgTitle.accesskey\n"
"Send Message"
msgstr ""
#: sendMessageCheckWindowTitle
#: sendMessageCheckWindowTitle.accesskey
msgid "_: sendMessageCheckWindowTitle sendMessageCheckWindowTitle.accesskey\n"
"Send Message"
msgstr ""
'''
mergepo = r'''#: sendMsgTitle
#: sendMsgTitle.accesskey
msgid ""
"_: sendMsgTitle sendMsgTitle.accesskey\n"
"Send Message"
msgstr "Stuur"
#: sendMessageCheckWindowTitle
#: sendMessageCheckWindowTitle.accesskey
msgid ""
"_: sendMessageCheckWindowTitle sendMessageCheckWindowTitle.accesskey\n"
"Send Message"
msgstr "Stuur"
'''
expectedpo = mergepo
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n---\nMerged:\n%s\n---" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo
def test_merging_header_entries(self):
"""Check that we do the right thing if we have header entries in the input PO."""
templatepo = r'''#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: new@example.com\n"
"POT-Creation-Date: 2006-11-11 11:11+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
"X-Generator: Translate Toolkit 0.10rc2\n"
#: simple.test
msgid "Simple String"
msgstr ""
'''
mergepo = r'''msgid ""
msgstr ""
"Project-Id-Version: Pootle 0.10\n"
"Report-Msgid-Bugs-To: old@example.com\n"
"POT-Creation-Date: 2006-01-01 01:01+0100\n"
"PO-Revision-Date: 2006-09-09 09:09+0900\n"
"Last-Translator: Joe Translate \n"
"Language-Team: Pig Latin \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Translate Toolkit 0.9\n"
#: simple.test
msgid "Simple String"
msgstr "Dimpled Ring"
'''
expectedpo = r'''msgid ""
msgstr ""
"Project-Id-Version: Pootle 0.10\n"
"Report-Msgid-Bugs-To: new@example.com\n"
"POT-Creation-Date: 2006-11-11 11:11+0000\n"
"PO-Revision-Date: 2006-09-09 09:09+0900\n"
"Last-Translator: Joe Translate \n"
"Language-Team: Pig Latin \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Translate Toolkit 0.10rc2\n"
#: simple.test
msgid "Simple String"
msgstr "Dimpled Ring"
'''
pofile = self.mergepo(templatepo, mergepo)
print "Expected:\n%s\n---\nMerged:\n%s\n---" % (expectedpo, str(pofile))
assert str(pofile) == expectedpo