fix git support for v1.5.3 (or higher) by setting "--work-tree"
[translate_toolkit.git] / storage / test_pypo.py
blob3f7d60f63a719c5ee1dcf1360bda0ab32e022496
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 from translate.storage import test_po
5 from translate.storage import pypo
6 from translate.misc.multistring import multistring
7 from translate.misc import wStringIO
8 from py.test import raises
10 class TestPYPOUnit(test_po.TestPOUnit):
11 UnitClass = pypo.pounit
13 def test_plurals(self):
14 """Tests that plurals are handled correctly."""
15 unit = self.UnitClass("Cow")
16 unit.msgid_plural = ['"Cows"']
17 assert isinstance(unit.source, multistring)
18 assert unit.source.strings == ["Cow", "Cows"]
19 assert unit.source == "Cow"
21 unit.target = ["Koei", "Koeie"]
22 assert isinstance(unit.target, multistring)
23 assert unit.target.strings == ["Koei", "Koeie"]
24 assert unit.target == "Koei"
26 unit.target = {0:"Koei", 3:"Koeie"}
27 assert isinstance(unit.target, multistring)
28 assert unit.target.strings == ["Koei", "Koeie"]
29 assert unit.target == "Koei"
31 unit.target = [u"Sk\u00ear", u"Sk\u00eare"]
32 assert isinstance(unit.target, multistring)
33 assert unit.target.strings == [u"Sk\u00ear", u"Sk\u00eare"]
34 assert unit.target.strings == [u"Sk\u00ear", u"Sk\u00eare"]
35 assert unit.target == u"Sk\u00ear"
37 def test_plural_reduction(self):
38 """checks that reducing the number of plurals supplied works"""
39 unit = self.UnitClass("Tree")
40 unit.msgid_plural = ['"Trees"']
41 assert isinstance(unit.source, multistring)
42 assert unit.source.strings == ["Tree", "Trees"]
43 unit.target = multistring(["Boom", "Bome", "Baie Bome"])
44 assert isinstance(unit.source, multistring)
45 assert unit.target.strings == ["Boom", "Bome", "Baie Bome"]
46 unit.target = multistring(["Boom", "Bome"])
47 assert unit.target.strings == ["Boom", "Bome"]
48 unit.target = "Boom"
49 # FIXME: currently assigning the target to the same as the first string won't change anything
50 # we need to verify that this is the desired behaviour...
51 assert unit.target.strings == ["Boom", "Bome"]
52 unit.target = "Een Boom"
53 assert unit.target.strings == ["Een Boom"]
55 def test_notes(self):
56 """tests that the generic notes API works"""
57 unit = self.UnitClass("File")
58 unit.addnote("Which meaning of file?")
59 assert str(unit) == '# Which meaning of file?\nmsgid "File"\nmsgstr ""\n'
60 unit.addnote("Verb", origin="programmer")
61 assert str(unit) == '# Which meaning of file?\n#. Verb\nmsgid "File"\nmsgstr ""\n'
62 unit.addnote("Thank you", origin="translator")
63 assert str(unit) == '# Which meaning of file?\n# Thank you\n#. Verb\nmsgid "File"\nmsgstr ""\n'
65 assert unit.getnotes("developer") == "Verb"
66 assert unit.getnotes("translator") == "Which meaning of file?\nThank you"
67 assert unit.getnotes() == "Which meaning of file?\nThank you\nVerb"
68 assert raises(ValueError, unit.getnotes, "devteam")
70 def test_notes_withcomments(self):
71 """tests that when we add notes that look like comments that we treat them properly"""
72 unit = self.UnitClass("File")
73 unit.addnote("# Double commented comment")
74 assert str(unit) == '# # Double commented comment\nmsgid "File"\nmsgstr ""\n'
75 assert unit.getnotes() == "# Double commented comment"
77 def test_wrap_firstlines(self):
78 '''tests that we wrap the first line correctly a first line if longer then 71 chars
79 as at 71 chars we should align the text on the left and preceed with with a msgid ""'''
80 # longest before we wrap text
81 str_max = "123456789 123456789 123456789 123456789 123456789 123456789 123456789 1"
82 unit = self.UnitClass(str_max)
83 expected = 'msgid "%s"\nmsgstr ""\n' % str_max
84 print expected, str(unit)
85 assert str(unit) == expected
86 # at this length we wrap
87 str_wrap = str_max + '2'
88 unit = self.UnitClass(str_wrap)
89 expected = 'msgid ""\n"%s"\nmsgstr ""\n' % str_wrap
90 print expected, str(unit)
91 assert str(unit) == expected
93 def test_wrap_on_newlines(self):
94 """test that we wrap newlines on a real \n"""
95 string = "123456789\n" * 3
96 postring = ('"123456789\\n"\n' * 3)[:-1]
97 unit = self.UnitClass(string)
98 expected = 'msgid ""\n%s\nmsgstr ""\n' % postring
99 print expected, str(unit)
100 assert str(unit) == expected
102 # Now check for long newlines segments
103 longstring = ("123456789 " * 10 + "\n") * 3
104 expected = r'''msgid ""
105 "123456789 123456789 123456789 123456789 123456789 123456789 123456789 "
106 "123456789 123456789 123456789 \n"
107 "123456789 123456789 123456789 123456789 123456789 123456789 123456789 "
108 "123456789 123456789 123456789 \n"
109 "123456789 123456789 123456789 123456789 123456789 123456789 123456789 "
110 "123456789 123456789 123456789 \n"
111 msgstr ""
113 unit = self.UnitClass(longstring)
114 print expected, str(unit)
115 assert str(unit) == expected
117 def test_wrap_on_max_line_length(self):
118 """test that we wrap all lines on the maximum line length"""
119 string = "1 3 5 7 N " * 11
120 expected = 'msgid ""\n%s\nmsgstr ""\n' % '"1 3 5 7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 "\n"7 N 1 3 5 7 N 1 3 5 7 N 1 3 5 7 N "'
121 unit = self.UnitClass(string)
122 print "Expected:"
123 print expected
124 print "Actual:"
125 print str(unit)
126 assert str(unit) == expected
128 def test_spacing_max_line(self):
129 """Test that the spacing of text is done the same as msgcat."""
130 idstring = "Creates a new document using an existing template iiiiiiiiiiiiiiiiiiiiiii or "
131 idstring += "opens a sample document."
132 expected = '''msgid ""
133 "Creates a new document using an existing template iiiiiiiiiiiiiiiiiiiiiii or "
134 "opens a sample document."
135 msgstr ""
137 unit = self.UnitClass(idstring)
138 print "Expected:"
139 print expected
140 print "Actual:"
141 print str(unit)
142 assert str(unit) == expected
144 class TestPYPOFile(test_po.TestPOFile):
145 StoreClass = pypo.pofile
146 def test_combine_msgidcomments(self):
147 """checks that we don't get duplicate msgid comments"""
148 posource = 'msgid "test me"\nmsgstr ""'
149 pofile = self.poparse(posource)
150 thepo = pofile.units[0]
151 thepo.msgidcomments.append('"_: first comment\\n"')
152 thepo.msgidcomments.append('"_: second comment\\n"')
153 regenposource = str(pofile)
154 assert regenposource.count("_:") == 1
156 def test_merge_duplicates_msgctxt(self):
157 """checks that merging duplicates works for msgctxt"""
158 posource = '#: source1\nmsgid "test me"\nmsgstr ""\n\n#: source2\nmsgid "test me"\nmsgstr ""\n'
159 pofile = self.poparse(posource)
160 assert len(pofile.units) == 2
161 pofile.removeduplicates("msgctxt")
162 print pofile
163 assert len(pofile.units) == 2
164 assert str(pofile.units[0]).count("source1") == 2
165 assert str(pofile.units[1]).count("source2") == 2
167 def test_merge_blanks(self):
168 """checks that merging adds msgid_comments to blanks"""
169 posource = '#: source1\nmsgid ""\nmsgstr ""\n\n#: source2\nmsgid ""\nmsgstr ""\n'
170 pofile = self.poparse(posource)
171 assert len(pofile.units) == 2
172 pofile.removeduplicates("merge")
173 assert len(pofile.units) == 2
174 print pofile.units[0].msgidcomments
175 print pofile.units[1].msgidcomments
176 assert pypo.unquotefrompo(pofile.units[0].msgidcomments) == "_: source1\n"
177 assert pypo.unquotefrompo(pofile.units[1].msgidcomments) == "_: source2\n"
179 def test_msgid_comment(self):
180 """checks that when adding msgid_comments we place them on a newline"""
181 posource = '#: source0\nmsgid "Same"\nmsgstr ""\n\n#: source1\nmsgid "Same"\nmsgstr ""\n'
182 pofile = self.poparse(posource)
183 assert len(pofile.units) == 2
184 pofile.removeduplicates("msgid_comment")
185 assert len(pofile.units) == 2
186 assert pypo.unquotefrompo(pofile.units[0].msgidcomments) == "_: source0\n"
187 assert pypo.unquotefrompo(pofile.units[1].msgidcomments) == "_: source1\n"
188 # Now lets check for formating
189 for i in (0, 1):
190 expected = '''#: source%d\nmsgid ""\n"_: source%d\\n"\n"Same"\nmsgstr ""\n''' % (i, i)
191 assert pofile.units[i].__str__() == expected
193 def test_keep_blanks(self):
194 """checks that keeping keeps blanks and doesn't add msgid_comments"""
195 posource = '#: source1\nmsgid ""\nmsgstr ""\n\n#: source2\nmsgid ""\nmsgstr ""\n'
196 pofile = self.poparse(posource)
197 assert len(pofile.units) == 2
198 pofile.removeduplicates("keep")
199 assert len(pofile.units) == 2
200 # check we don't add msgidcomments
201 assert pypo.unquotefrompo(pofile.units[0].msgidcomments) == ""
202 assert pypo.unquotefrompo(pofile.units[1].msgidcomments) == ""
204 def test_output_str_unicode(self):
205 """checks that we can str(element) which is in unicode"""
206 posource = u'''#: nb\nmsgid "Norwegian Bokm\xe5l"\nmsgstr ""\n'''
207 pofile = self.StoreClass(wStringIO.StringIO(posource.encode("UTF-8")), encoding="UTF-8")
208 assert len(pofile.units) == 1
209 print str(pofile)
210 thepo = pofile.units[0]
211 assert str(thepo) == posource.encode("UTF-8")
212 # extra test: what if we set the msgid to a unicode? this happens in prop2po etc
213 thepo.source = u"Norwegian Bokm\xe5l"
214 assert str(thepo) == posource.encode("UTF-8")
215 # Now if we set the msgstr to Unicode
216 # this is an escaped half character (1/2)
217 halfstr = "\xbd ...".decode("latin-1")
218 thepo.target = halfstr
219 assert halfstr in str(thepo).decode("UTF-8")
220 thepo.target = halfstr.encode("UTF-8")
221 assert halfstr.encode("UTF-8") in str(thepo)
223 def test_posections(self):
224 """checks the content of all the expected sections of a PO message"""
225 posource = '# other comment\n#. automatic comment\n#: source comment\n#, fuzzy\nmsgid "One"\nmsgstr "Een"\n'
226 pofile = self.poparse(posource)
227 print pofile
228 assert len(pofile.units) == 1
229 assert str(pofile) == posource
230 assert pofile.units[0].othercomments == ["# other comment\n"]
231 assert pofile.units[0].automaticcomments == ["#. automatic comment\n"]
232 assert pofile.units[0].sourcecomments == ["#: source comment\n"]
233 assert pofile.units[0].typecomments == ["#, fuzzy\n"]
235 def test_unassociated_comments(self):
236 """tests behaviour of unassociated comments."""
237 oldsource = '# old lonesome comment\n\nmsgid "one"\nmsgstr "een"\n'
238 oldfile = self.poparse(oldsource)
239 print "__str__", str(oldfile)
240 assert len(oldfile.units) == 2
241 assert str(oldfile).find("# old lonesome comment\n\n") >= 0