1from io import BytesIO 2 3from translate.convert import csv2po, po2csv, test_convert 4from translate.storage import csvl10n, po 5from translate.storage.test_base import first_translatable, headerless_len 6 7 8class TestPO2CSV: 9 def po2csv(self, posource): 10 """helper that converts po source to csv source without requiring files""" 11 inputfile = BytesIO(posource.encode()) 12 inputpo = po.pofile(inputfile) 13 convertor = po2csv.po2csv() 14 return convertor.convertstore(inputpo) 15 16 def csv2po(self, csvsource, template=None): 17 """helper that converts csv source to po source without requiring files""" 18 inputfile = BytesIO(csvsource) 19 inputcsv = csvl10n.csvfile(inputfile) 20 if template: 21 templatefile = BytesIO(template.encode()) 22 inputpot = po.pofile(templatefile) 23 else: 24 inputpot = None 25 convertor = csv2po.csv2po(templatepo=inputpot) 26 return convertor.convertstore(inputcsv) 27 28 def singleelement(self, storage): 29 """checks that the pofile contains a single non-header element, and returns it""" 30 assert headerless_len(storage.units) == 1 31 return first_translatable(storage) 32 33 def test_simpleentity(self): 34 """checks that a simple csv entry definition converts properly to a po entry""" 35 minipo = r'''#: term.cpp 36msgid "Term" 37msgstr "asdf"''' 38 csvfile = self.po2csv(minipo) 39 unit = self.singleelement(csvfile) 40 assert unit.location == "term.cpp" 41 assert unit.source == "Term" 42 assert unit.target == "asdf" 43 44 def test_multiline(self): 45 """tests multiline po entries""" 46 minipo = r'''msgid "First part " 47"and extra" 48msgstr "Eerste deel " 49"en ekstra"''' 50 csvfile = self.po2csv(minipo) 51 unit = self.singleelement(csvfile) 52 assert unit.source == "First part and extra" 53 assert unit.target == "Eerste deel en ekstra" 54 55 def test_escapednewlines(self): 56 """Test the escaping of newlines""" 57 minipo = r"""msgid "First line\nSecond line" 58msgstr "Eerste lyn\nTweede lyn" 59""" 60 csvfile = self.po2csv(minipo) 61 unit = self.singleelement(csvfile) 62 assert unit.source == "First line\nSecond line" 63 assert unit.target == "Eerste lyn\nTweede lyn" 64 pofile = self.csv2po(bytes(csvfile)) 65 unit = self.singleelement(pofile) 66 assert unit.source == "First line\nSecond line" 67 assert unit.target == "Eerste lyn\nTweede lyn" 68 69 def test_escapedtabs(self): 70 """Test the escaping of tabs""" 71 minipo = r"""msgid "First column\tSecond column" 72msgstr "Eerste kolom\tTweede kolom" 73""" 74 csvfile = self.po2csv(minipo) 75 unit = self.singleelement(csvfile) 76 assert unit.source == "First column\tSecond column" 77 assert unit.target == "Eerste kolom\tTweede kolom" 78 assert ( 79 csvfile.findunit("First column\tSecond column").target 80 == "Eerste kolom\tTweede kolom" 81 ) 82 83 def test_escapedquotes(self): 84 """Test the escaping of quotes (and slash)""" 85 minipo = r"""msgid "Hello \"Everyone\"" 86msgstr "Good day \"All\"" 87 88msgid "Use \\\"." 89msgstr "Gebruik \\\"." 90""" 91 csvfile = self.po2csv(minipo) 92 assert csvfile.findunit('Hello "Everyone"').target == 'Good day "All"' 93 assert csvfile.findunit('Use \\".').target == 'Gebruik \\".' 94 95 def test_escapedescape(self): 96 """Test the escaping of pure escapes is unaffected""" 97 minipo = r"""msgid "Find\\Options" 98msgstr "Vind\\Opsies" 99""" 100 csvfile = self.po2csv(minipo) 101 print(minipo) 102 print(csvfile) 103 assert csvfile.findunit(r"Find\Options").target == r"Vind\Opsies" 104 105 def test_singlequotes(self): 106 """Tests that single quotes are preserved correctly""" 107 minipo = """msgid "source 'source'"\nmsgstr "target 'target'"\n""" 108 csvfile = self.po2csv(minipo) 109 print(bytes(csvfile)) 110 assert csvfile.findunit("source 'source'").target == "target 'target'" 111 # Make sure we don't mess with start quotes until writing 112 minipo = """msgid "'source'"\nmsgstr "'target'"\n""" 113 csvfile = self.po2csv(minipo) 114 print(bytes(csvfile)) 115 assert csvfile.findunit(r"'source'").target == r"'target'" 116 # TODO check that we escape on writing not in the internal representation 117 118 def test_empties(self): 119 """Tests that things keep working with empty entries""" 120 minipo = 'msgid "Source"\nmsgstr ""\n\nmsgid ""\nmsgstr ""' 121 csvfile = self.po2csv(minipo) 122 assert csvfile.findunit("Source") is not None 123 assert csvfile.findunit("Source").target == "" 124 assert headerless_len(csvfile.units) == 1 125 126 def test_kdecomments(self): 127 """test that we don't carry KDE comments to CSV""" 128 minipo = '#: simple.c\nmsgid "_: KDE comment\\n"\n"Same"\nmsgstr "Same"\n' 129 csvfile = self.po2csv(minipo) 130 unit = self.singleelement(csvfile) 131 assert unit.source == "Same" 132 assert unit.target == "Same" 133 134 135class TestPO2CSVCommand(test_convert.TestConvertCommand, TestPO2CSV): 136 """Tests running actual po2csv commands on files""" 137 138 convertmodule = po2csv 139 140 def test_help(self, capsys): 141 """tests getting help""" 142 options = super().test_help(capsys) 143 options = self.help_check(options, "--columnorder=COLUMNORDER", last=True) 144 145 def test_columnorder(self): 146 pocontent = '#: simple.c\nmsgid "Same"\nmsgstr "Target"\n' 147 self.create_testfile("test.po", pocontent) 148 149 self.run_command("test.po", "test.csv") 150 content = self.open_testfile("test.csv", "r").read() 151 assert ( 152 content 153 == """"location","source","target" 154"simple.c","Same","Target" 155""" 156 ) 157 158 self.run_command("test.po", "test.csv", columnorder="target,source") 159 content = self.open_testfile("test.csv", "r").read() 160 assert ( 161 content 162 == """"target","source" 163"Target","Same" 164""" 165 ) 166