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
    198 -    def test_merging_entries_with_spaces_removed(self):
    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