1from io import BytesIO
2
3from translate.convert import po2tmx, test_convert
4from translate.misc.xml_helpers import XML_NS
5from translate.storage import tmx
6
7
8class TestPO2TMX:
9    def po2tmx(self, posource, sourcelanguage="en", targetlanguage="af", comment=None):
10        """helper that converts po source to tmx source without requiring files"""
11        inputfile = BytesIO(posource.encode("utf-8"))
12        outputfile = BytesIO()
13        outputfile.tmxfile = tmx.tmxfile(inputfile=None, sourcelanguage=sourcelanguage)
14        po2tmx.convertpo(
15            inputfile,
16            outputfile,
17            templatefile=None,
18            sourcelanguage=sourcelanguage,
19            targetlanguage=targetlanguage,
20            comment=comment,
21        )
22        return outputfile.tmxfile
23
24    def test_basic(self):
25        minipo = r"""# Afrikaans translation of program ABC
26#
27msgid ""
28msgstr ""
29"Project-Id-Version: program 2.1-branch\n"
30"Report-Msgid-Bugs-To: \n"
31"POT-Creation-Date: 2006-01-09 07:15+0100\n"
32"PO-Revision-Date: 2004-03-30 17:02+0200\n"
33"Last-Translator: Zuza Software Foundation <xxx@translate.org.za>\n"
34"Language-Team: Afrikaans <translate-discuss-xxx@lists.sourceforge.net>\n"
35"MIME-Version: 1.0\n"
36"Content-Type: text/plain; charset=UTF-8\n"
37"Content-Transfer-Encoding: 8bit\n"
38
39# Please remember to do something
40#: ../dir/file.xml.in.h:1 ../dir/file2.xml.in.h:4
41msgid "Applications"
42msgstr "Toepassings"
43"""
44        tmx = self.po2tmx(minipo)
45        print("The generated xml:")
46        print(bytes(tmx))
47        assert tmx.translate("Applications") == "Toepassings"
48        assert tmx.translate("bla") is None
49        xmltext = bytes(tmx).decode("utf-8")
50        assert xmltext.index('creationtool="Translate Toolkit"')
51        assert xmltext.index("adminlang")
52        assert xmltext.index("creationtoolversion")
53        assert xmltext.index("datatype")
54        assert xmltext.index("o-tmf")
55        assert xmltext.index("segtype")
56        assert xmltext.index("srclang")
57
58    def test_sourcelanguage(self):
59        minipo = 'msgid "String"\nmsgstr "String"\n'
60        tmx = self.po2tmx(minipo, sourcelanguage="xh")
61        print("The generated xml:")
62        print(bytes(tmx))
63        header = tmx.document.find("header")
64        assert header.get("srclang") == "xh"
65
66    def test_targetlanguage(self):
67        minipo = 'msgid "String"\nmsgstr "String"\n'
68        tmx = self.po2tmx(minipo, targetlanguage="xh")
69        print("The generated xml:")
70        print(bytes(tmx))
71        tuv = tmx.document.findall(".//%s" % tmx.namespaced("tuv"))[1]
72        # tag[0] will be the source, we want the target tuv
73        assert tuv.get("{%s}lang" % XML_NS) == "xh"
74
75    def test_multiline(self):
76        """Test multiline po entry"""
77        minipo = r'''msgid "First part "
78"and extra"
79msgstr "Eerste deel "
80"en ekstra"'''
81        tmx = self.po2tmx(minipo)
82        print("The generated xml:")
83        print(bytes(tmx))
84        assert tmx.translate("First part and extra") == "Eerste deel en ekstra"
85
86    def test_escapednewlines(self):
87        """Test the escaping of newlines"""
88        minipo = r"""msgid "First line\nSecond line"
89msgstr "Eerste lyn\nTweede lyn"
90"""
91        tmx = self.po2tmx(minipo)
92        print("The generated xml:")
93        print(bytes(tmx))
94        assert tmx.translate("First line\nSecond line") == "Eerste lyn\nTweede lyn"
95
96    def test_escapedtabs(self):
97        """Test the escaping of tabs"""
98        minipo = r"""msgid "First column\tSecond column"
99msgstr "Eerste kolom\tTweede kolom"
100"""
101        tmx = self.po2tmx(minipo)
102        print("The generated xml:")
103        print(bytes(tmx))
104        assert (
105            tmx.translate("First column\tSecond column") == "Eerste kolom\tTweede kolom"
106        )
107
108    def test_escapedquotes(self):
109        """Test the escaping of quotes (and slash)"""
110        minipo = r"""msgid "Hello \"Everyone\""
111msgstr "Good day \"All\""
112
113msgid "Use \\\"."
114msgstr "Gebruik \\\"."
115"""
116        tmx = self.po2tmx(minipo)
117        print("The generated xml:")
118        print(bytes(tmx))
119        assert tmx.translate('Hello "Everyone"') == 'Good day "All"'
120        assert tmx.translate(r"Use \".") == r"Gebruik \"."
121
122    def test_exclusions(self):
123        """Test that empty and fuzzy messages are excluded"""
124        minipo = r"""#, fuzzy
125msgid "One"
126msgstr "Een"
127
128msgid "Two"
129msgstr ""
130
131msgid ""
132msgstr "Drie"
133"""
134        tmx = self.po2tmx(minipo)
135        print("The generated xml:")
136        print(bytes(tmx))
137        assert b"<tu" not in bytes(tmx)
138        assert len(tmx.units) == 0
139
140    def test_nonascii(self):
141        """Tests that non-ascii conversion works."""
142        minipo = """msgid "Bézier curve"
143msgstr "Bézier-kurwe"
144"""
145        tmx = self.po2tmx(minipo)
146        print(bytes(tmx))
147        assert tmx.translate("Bézier curve") == "Bézier-kurwe"
148
149    def test_nonecomments(self):
150        """Tests that none comments are imported."""
151        minipo = """#My comment rules
152msgid "Bézier curve"
153msgstr "Bézier-kurwe"
154"""
155        tmx = self.po2tmx(minipo)
156        print(bytes(tmx))
157        unit = tmx.findunits("Bézier curve")
158        assert len(unit[0].getnotes()) == 0
159
160    def test_otherscomments(self):
161        """Tests that others comments are imported."""
162        minipo = """#My comment rules
163msgid "Bézier curve"
164msgstr "Bézier-kurwe"
165"""
166        tmx = self.po2tmx(minipo, comment="others")
167        print(bytes(tmx))
168        unit = tmx.findunits("Bézier curve")
169        assert unit[0].getnotes() == "My comment rules"
170
171    def test_sourcecomments(self):
172        """Tests that source comments are imported."""
173        minipo = """#: ../PuzzleFourSided.h:45
174msgid "Bézier curve"
175msgstr "Bézier-kurwe"
176"""
177        tmx = self.po2tmx(minipo, comment="source")
178        print(bytes(tmx))
179        unit = tmx.findunits("Bézier curve")
180        assert unit[0].getnotes() == "../PuzzleFourSided.h:45"
181
182    def test_typecomments(self):
183        """Tests that others comments are imported."""
184        minipo = """#, csharp-format
185msgid "Bézier curve"
186msgstr "Bézier-kurwe"
187"""
188        tmx = self.po2tmx(minipo, comment="type")
189        print(bytes(tmx))
190        unit = tmx.findunits("Bézier curve")
191        assert unit[0].getnotes() == "csharp-format"
192
193
194class TestPO2TMXCommand(test_convert.TestConvertCommand, TestPO2TMX):
195    """Tests running actual po2tmx commands on files"""
196
197    convertmodule = po2tmx
198
199    def test_help(self, capsys):
200        """tests getting help"""
201        options = super().test_help(capsys)
202        options = self.help_check(options, "-l LANG, --language=LANG")
203        options = self.help_check(options, "--source-language=LANG")
204        options = self.help_check(options, "--comments", last=True)
205