Package translate :: Package convert :: Module test_po2dtd
[hide private]
[frames] | no frames]

Source Code for Module translate.convert.test_po2dtd

  1  #!/usr/bin/env python 
  2   
  3  from translate.convert import po2dtd 
  4  from translate.convert import dtd2po 
  5  from translate.convert import test_convert 
  6  from translate.misc import wStringIO 
  7  from translate.storage import po 
  8  from translate.storage import dtd 
  9  from py import test 
 10  import warnings 
 11   
12 -class TestPO2DTD:
13 - def setup_method(self, method):
14 warnings.resetwarnings()
15
16 - def teardown_method(self, method):
17 warnings.resetwarnings()
18
19 - def po2dtd(self, posource):
20 """helper that converts po source to dtd source without requiring files""" 21 inputfile = wStringIO.StringIO(posource) 22 inputpo = po.pofile(inputfile) 23 convertor = po2dtd.po2dtd() 24 outputdtd = convertor.convertstore(inputpo) 25 return outputdtd
26
27 - def merge2dtd(self, dtdsource, posource):
28 """helper that merges po translations to dtd source without requiring files""" 29 inputfile = wStringIO.StringIO(posource) 30 inputpo = po.pofile(inputfile) 31 templatefile = wStringIO.StringIO(dtdsource) 32 templatedtd = dtd.dtdfile(templatefile) 33 convertor = po2dtd.redtd(templatedtd) 34 outputdtd = convertor.convertstore(inputpo) 35 return outputdtd
36
37 - def convertdtd(self, posource, dtdtemplate):
38 """helper to exercise the command line function""" 39 inputfile = wStringIO.StringIO(posource) 40 outputfile = wStringIO.StringIO() 41 templatefile = wStringIO.StringIO(dtdtemplate) 42 assert po2dtd.convertdtd(inputfile, outputfile, templatefile) 43 return outputfile.getvalue()
44
45 - def roundtripsource(self, dtdsource):
46 """converts dtd source to po and back again, returning the resulting source""" 47 dtdinputfile = wStringIO.StringIO(dtdsource) 48 dtdinputfile2 = wStringIO.StringIO(dtdsource) 49 pooutputfile = wStringIO.StringIO() 50 dtd2po.convertdtd(dtdinputfile, pooutputfile, dtdinputfile2) 51 posource = pooutputfile.getvalue() 52 poinputfile = wStringIO.StringIO(posource) 53 dtdtemplatefile = wStringIO.StringIO(dtdsource) 54 dtdoutputfile = wStringIO.StringIO() 55 po2dtd.convertdtd(poinputfile, dtdoutputfile, dtdtemplatefile) 56 dtdresult = dtdoutputfile.getvalue() 57 print "original dtd:\n", dtdsource, "po version:\n", posource, "output dtd:\n", dtdresult 58 return dtdresult
59
60 - def roundtripstring(self, entitystring):
61 """Just takes the contents of a ENTITY definition (with quotes) and does a roundtrip on that""" 62 dtdintro, dtdoutro = '<!ENTITY Test.RoundTrip ', '>\n' 63 dtdsource = dtdintro + entitystring + dtdoutro 64 dtdresult = self.roundtripsource(dtdsource) 65 assert dtdresult.startswith(dtdintro) and dtdresult.endswith(dtdoutro) 66 return dtdresult[len(dtdintro):-len(dtdoutro)]
67
68 - def check_roundtrip(self, dtdsource):
69 """Checks that the round-tripped string is the same as the original""" 70 assert self.roundtripstring(dtdsource) == dtdsource
71
72 - def test_joinlines(self):
73 """tests that po lines are joined seamlessly (bug 16)""" 74 multilinepo = '''#: pref.menuPath\nmsgid ""\n"<span>Tools &gt; Options</"\n"span>"\nmsgstr ""\n''' 75 dtdfile = self.po2dtd(multilinepo) 76 dtdsource = str(dtdfile) 77 assert "</span>" in dtdsource
78
79 - def test_escapedstr(self):
80 """tests that \n in msgstr is escaped correctly in dtd""" 81 multilinepo = '''#: pref.menuPath\nmsgid "Hello\\nEveryone"\nmsgstr "Good day\\nAll"\n''' 82 dtdfile = self.po2dtd(multilinepo) 83 dtdsource = str(dtdfile) 84 assert "Good day\nAll" in dtdsource
85
86 - def test_ampersandwarning(self):
87 """tests that proper warnings are given if invalid ampersands occur""" 88 simplestring = '''#: simple.warningtest\nmsgid "Simple String"\nmsgstr "Dimpled &Ring"\n''' 89 warnings.simplefilter("error") 90 assert test.raises(Warning, po2dtd.removeinvalidamps, "simple.warningtest", "Dimpled &Ring")
91
92 - def test_missingaccesskey(self):
93 """tests that proper warnings are given if access key is missing""" 94 simplepo = '''#: simple.label\n#: simple.accesskey\nmsgid "Simple &String"\nmsgstr "Dimpled Ring"\n''' 95 simpledtd = '''<!ENTITY simple.label "Simple String">\n<!ENTITY simple.accesskey "S">''' 96 warnings.simplefilter("error") 97 assert test.raises(Warning, self.merge2dtd, simpledtd, simplepo)
98
99 - def test_accesskeycase(self):
100 """tests that access keys come out with the same case as the original, regardless""" 101 simplepo_template = '''#: simple.label\n#: simple.accesskey\nmsgid "Simple &%s"\nmsgstr "Dimpled &%s"\n''' 102 simpledtd_template = '''<!ENTITY simple.label "Simple %s">\n<!ENTITY simple.accesskey "%s">''' 103 # we test each combination of label case and accelerator case 104 for srcword in ("String", "string"): 105 for destword in ("Ring", "ring"): 106 for srcaccel, destaccel in ("SR", "sr"): 107 simplepo = simplepo_template % (srcword, destword) 108 simpledtd = simpledtd_template % (srcword, srcaccel) 109 dtdfile = self.merge2dtd(simpledtd, simplepo) 110 dtdfile.makeindex() 111 accel = dtd.unquotefromdtd(dtdfile.index["simple.accesskey"].definition) 112 assert accel == destaccel
113
114 - def test_accesskey_types(self):
115 """tests that we can detect the various styles of accesskey""" 116 simplepo_template = '''#: simple.%s\n#: simple.%s\nmsgid "&File"\nmsgstr "F&aele"\n''' 117 simpledtd_template = '''<!ENTITY simple.%s "File">\n<!ENTITY simple.%s "a">''' 118 for label in ("label", "title"): 119 for accesskey in ("accesskey", "accessKey", "akey"): 120 simplepo = simplepo_template % (label, accesskey) 121 simpledtd = simpledtd_template % (label, accesskey) 122 dtdfile = self.merge2dtd(simpledtd, simplepo) 123 dtdfile.makeindex() 124 assert dtd.unquotefromdtd(dtdfile.index["simple.%s" % accesskey].definition) == "a"
125
126 - def test_ampersandfix(self):
127 """tests that invalid ampersands are fixed in the dtd""" 128 simplestring = '''#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled &Ring"\n''' 129 dtdfile = self.po2dtd(simplestring) 130 dtdsource = str(dtdfile) 131 assert "Dimpled Ring" in dtdsource
132
133 - def test_entities_two(self):
134 """test the error ouput when we find two entities""" 135 simplestring = '''#: simple.string second.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n''' 136 dtdfile = self.po2dtd(simplestring) 137 dtdsource = str(dtdfile) 138 assert "CONVERSION NOTE - multiple entities" in dtdsource
139
140 - def test_entities(self):
141 """tests that entities are correctly idnetified in the dtd""" 142 simplestring = '''#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n''' 143 dtdfile = self.po2dtd(simplestring) 144 dtdsource = str(dtdfile) 145 assert dtdsource.startswith("<!ENTITY simple.string")
146
147 - def test_comments_translator(self):
148 """tests for translator comments""" 149 simplestring = '''# Comment1\n# Comment2\n#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n''' 150 dtdfile = self.po2dtd(simplestring) 151 dtdsource = str(dtdfile) 152 assert dtdsource.startswith("<!-- Comment1 -->")
153
154 - def test_retains_hashprefix(self):
155 """tests that hash prefixes in the dtd are retained""" 156 hashpo = '''#: lang.version\nmsgid "__MOZILLA_LOCALE_VERSION__"\nmsgstr "__MOZILLA_LOCALE_VERSION__"\n''' 157 hashdtd = '#expand <!ENTITY lang.version "__MOZILLA_LOCALE_VERSION__">\n' 158 dtdfile = self.merge2dtd(hashdtd, hashpo) 159 regendtd = str(dtdfile) 160 assert regendtd == hashdtd
161
162 - def test_convertdtd(self):
163 """checks that the convertdtd function is working""" 164 posource = '''#: simple.label\n#: simple.accesskey\nmsgid "Simple &String"\nmsgstr "Dimpled &Ring"\n''' 165 dtdtemplate = '''<!ENTITY simple.label "Simple String">\n<!ENTITY simple.accesskey "S">\n''' 166 dtdexpected = '''<!ENTITY simple.label "Dimpled Ring">\n<!ENTITY simple.accesskey "R">\n''' 167 newdtd = self.convertdtd(posource, dtdtemplate) 168 print newdtd 169 assert newdtd == dtdexpected
170
171 - def test_newlines_escapes(self):
172 """check that we can handle a \n in the PO file""" 173 posource = '''#: simple.label\n#: simple.accesskey\nmsgid "A hard coded newline.\\n"\nmsgstr "Hart gekoeerde nuwe lyne\\n"\n''' 174 dtdtemplate = '<!ENTITY simple.label "A hard coded newline.\n">\n' 175 dtdexpected = '''<!ENTITY simple.label "Hart gekoeerde nuwe lyne\n">\n''' 176 dtdfile = self.merge2dtd(dtdtemplate, posource) 177 print dtdfile 178 assert str(dtdfile) == dtdexpected
179
180 - def test_roundtrip_simple(self):
181 """checks that simple strings make it through a dtd->po->dtd roundtrip""" 182 self.check_roundtrip('"Hello"') 183 self.check_roundtrip('"Hello Everybody"')
184
185 - def test_roundtrip_escape(self):
186 """checks that escapes in strings make it through a dtd->po->dtd roundtrip""" 187 self.check_roundtrip(r'"Simple Escape \ \n \\ \: \t \r "') 188 self.check_roundtrip(r'"End Line Escape \"')
189
190 - def test_roundtrip_quotes(self):
191 """checks that (escaped) quotes in strings make it through a dtd->po->dtd roundtrip""" 192 self.check_roundtrip(r"""'Quote Escape "" '""") 193 self.check_roundtrip(r'''"Single-Quote ' "''') 194 self.check_roundtrip(r'''"Single-Quote Escape \' "''') 195 # NOTE: if both quote marks are present, than ' is converted to &apos; 196 self.check_roundtrip(r"""'Both Quotes "" &apos;&apos; '""")
197
199 """dtd2po removes pretty printed spaces, this tests that we can merge this back into the pretty printed dtd""" 200 posource = '''#: simple.label\nmsgid "First line then "\n"next lines."\nmsgstr "Eerste lyne en dan volgende lyne."\n''' 201 dtdtemplate = '<!ENTITY simple.label "First line then\n' + \ 202 ' next lines.">\n' 203 dtdexpected = '<!ENTITY simple.label "Eerste lyne en dan volgende lyne.">\n' 204 dtdfile = self.merge2dtd(dtdtemplate, posource) 205 print dtdfile 206 assert str(dtdfile) == dtdexpected
207
208 - def test_comments(self):
209 """test that we preserve comments, bug 351""" 210 posource = '''#: name\nmsgid "Text"\nmsgstr "Teks"''' 211 dtdtemplate = '''<!ENTITY name "%s">\n<!-- \n\nexample -->\n''' 212 dtdfile = self.merge2dtd(dtdtemplate % "Text", posource) 213 print dtdfile 214 assert str(dtdfile) == dtdtemplate % "Teks"
215
216 -class TestPO2DTDCommand(test_convert.TestConvertCommand, TestPO2DTD):
217 """Tests running actual po2dtd commands on files""" 218 convertmodule = po2dtd 219 defaultoptions = {"progress": "none"} 220 # TODO: because of having 2 base classes, we need to call all their setup and teardown methods 221 # (otherwise we won't reset the warnings etc)
222 - def setup_method(self, method):
223 """call both base classes setup_methods""" 224 test_convert.TestConvertCommand.setup_method(self, method) 225 TestPO2DTD.setup_method(self, method)
226 - def teardown_method(self, method):
227 """call both base classes teardown_methods""" 228 test_convert.TestConvertCommand.teardown_method(self, method) 229 TestPO2DTD.teardown_method(self, method)
230
231 - def test_help(self):
232 """tests getting help""" 233 options = test_convert.TestConvertCommand.test_help(self) 234 options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE") 235 options = self.help_check(options, "--fuzzy") 236 options = self.help_check(options, "--nofuzzy", last=True)
237