| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 '''Unit tests for grit.clique''' | |
| 7 | |
| 8 import os | |
| 9 import sys | |
| 10 if __name__ == '__main__': | |
| 11 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | |
| 12 | |
| 13 import re | |
| 14 import StringIO | |
| 15 import unittest | |
| 16 | |
| 17 from grit import clique | |
| 18 from grit import exception | |
| 19 from grit import pseudo | |
| 20 from grit import tclib | |
| 21 from grit import grd_reader | |
| 22 from grit import util | |
| 23 | |
| 24 class MessageCliqueUnittest(unittest.TestCase): | |
| 25 def testClique(self): | |
| 26 factory = clique.UberClique() | |
| 27 msg = tclib.Message(text='Hello USERNAME, how are you?', | |
| 28 placeholders=[ | |
| 29 tclib.Placeholder('USERNAME', '%s', 'Joi')]) | |
| 30 c = factory.MakeClique(msg) | |
| 31 | |
| 32 self.failUnless(c.GetMessage() == msg) | |
| 33 self.failUnless(c.GetId() == msg.GetId()) | |
| 34 | |
| 35 msg_fr = tclib.Translation(text='Bonjour USERNAME, comment ca va?', | |
| 36 id=msg.GetId(), placeholders=[ | |
| 37 tclib.Placeholder('USERNAME', '%s', 'Joi')]) | |
| 38 msg_de = tclib.Translation(text='Guten tag USERNAME, wie geht es dir?', | |
| 39 id=msg.GetId(), placeholders=[ | |
| 40 tclib.Placeholder('USERNAME', '%s', 'Joi')]) | |
| 41 | |
| 42 c.AddTranslation(msg_fr, 'fr') | |
| 43 factory.FindCliqueAndAddTranslation(msg_de, 'de') | |
| 44 | |
| 45 # sort() sorts lists in-place and does not return them | |
| 46 for lang in ('en', 'fr', 'de'): | |
| 47 self.failUnless(lang in c.clique) | |
| 48 | |
| 49 self.failUnless(c.MessageForLanguage('fr').GetRealContent() == | |
| 50 msg_fr.GetRealContent()) | |
| 51 | |
| 52 try: | |
| 53 c.MessageForLanguage('zh-CN', False) | |
| 54 self.fail('Should have gotten exception') | |
| 55 except: | |
| 56 pass | |
| 57 | |
| 58 self.failUnless(c.MessageForLanguage('zh-CN', True) != None) | |
| 59 | |
| 60 rex = re.compile('fr|de|bingo') | |
| 61 self.failUnless(len(c.AllMessagesThatMatch(rex, False)) == 2) | |
| 62 self.failUnless(c.AllMessagesThatMatch(rex, True)[pseudo.PSEUDO_LANG] != Non
e) | |
| 63 | |
| 64 def testBestClique(self): | |
| 65 factory = clique.UberClique() | |
| 66 factory.MakeClique(tclib.Message(text='Alfur', description='alfaholl')) | |
| 67 factory.MakeClique(tclib.Message(text='Alfur', description='')) | |
| 68 factory.MakeClique(tclib.Message(text='Vaettur', description='')) | |
| 69 factory.MakeClique(tclib.Message(text='Vaettur', description='')) | |
| 70 factory.MakeClique(tclib.Message(text='Troll', description='')) | |
| 71 factory.MakeClique(tclib.Message(text='Gryla', description='ID: IDS_GRYLA')) | |
| 72 factory.MakeClique(tclib.Message(text='Gryla', description='vondakerling')) | |
| 73 factory.MakeClique(tclib.Message(text='Leppaludi', description='ID: IDS_LL')
) | |
| 74 factory.MakeClique(tclib.Message(text='Leppaludi', description='')) | |
| 75 | |
| 76 count_best_cliques = 0 | |
| 77 for c in factory.BestCliquePerId(): | |
| 78 count_best_cliques += 1 | |
| 79 msg = c.GetMessage() | |
| 80 text = msg.GetRealContent() | |
| 81 description = msg.GetDescription() | |
| 82 if text == 'Alfur': | |
| 83 self.failUnless(description == 'alfaholl') | |
| 84 elif text == 'Gryla': | |
| 85 self.failUnless(description == 'vondakerling') | |
| 86 elif text == 'Leppaludi': | |
| 87 self.failUnless(description == 'ID: IDS_LL') | |
| 88 self.failUnless(count_best_cliques == 5) | |
| 89 | |
| 90 def testAllInUberClique(self): | |
| 91 resources = grd_reader.Parse( | |
| 92 StringIO.StringIO(u'''<?xml version="1.0" encoding="UTF-8"?> | |
| 93 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_
dir="."> | |
| 94 <release seq="3"> | |
| 95 <messages> | |
| 96 <message name="IDS_GREETING" desc="Printed to greet the currently logged i
n user"> | |
| 97 Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? | |
| 98 </message> | |
| 99 </messages> | |
| 100 <structures> | |
| 101 <structure type="dialog" name="IDD_ABOUTBOX" encoding="utf-16" file="grit/
testdata/klonk.rc" /> | |
| 102 <structure type="tr_html" name="ID_HTML" file="grit/testdata/simple.html"
/> | |
| 103 </structures> | |
| 104 </release> | |
| 105 </grit>'''), util.PathFromRoot('.')) | |
| 106 resources.SetOutputLanguage('en') | |
| 107 resources.RunGatherers() | |
| 108 content_list = [] | |
| 109 for clique_list in resources.UberClique().cliques_.values(): | |
| 110 for clique in clique_list: | |
| 111 content_list.append(clique.GetMessage().GetRealContent()) | |
| 112 self.failUnless('Hello %s, how are you doing today?' in content_list) | |
| 113 self.failUnless('Jack "Black" Daniels' in content_list) | |
| 114 self.failUnless('Hello!' in content_list) | |
| 115 | |
| 116 def testCorrectExceptionIfWrongEncodingOnResourceFile(self): | |
| 117 '''This doesn't really belong in this unittest file, but what the heck.''' | |
| 118 resources = grd_reader.Parse( | |
| 119 StringIO.StringIO(u'''<?xml version="1.0" encoding="UTF-8"?> | |
| 120 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_
dir="."> | |
| 121 <release seq="3"> | |
| 122 <structures> | |
| 123 <structure type="dialog" name="IDD_ABOUTBOX" file="grit/testdata/klonk.rc"
/> | |
| 124 </structures> | |
| 125 </release> | |
| 126 </grit>'''), util.PathFromRoot('.')) | |
| 127 self.assertRaises(exception.SectionNotFound, resources.RunGatherers) | |
| 128 | |
| 129 def testSemiIdenticalCliques(self): | |
| 130 messages = [ | |
| 131 tclib.Message(text='Hello USERNAME', | |
| 132 placeholders=[tclib.Placeholder('USERNAME', '$1', 'Joi')]), | |
| 133 tclib.Message(text='Hello USERNAME', | |
| 134 placeholders=[tclib.Placeholder('USERNAME', '%s', 'Joi')]), | |
| 135 ] | |
| 136 self.failUnless(messages[0].GetId() == messages[1].GetId()) | |
| 137 | |
| 138 # Both of the above would share a translation. | |
| 139 translation = tclib.Translation(id=messages[0].GetId(), | |
| 140 text='Bonjour USERNAME', | |
| 141 placeholders=[tclib.Placeholder( | |
| 142 'USERNAME', '$1', 'Joi')]) | |
| 143 | |
| 144 factory = clique.UberClique() | |
| 145 cliques = [factory.MakeClique(msg) for msg in messages] | |
| 146 | |
| 147 for clq in cliques: | |
| 148 clq.AddTranslation(translation, 'fr') | |
| 149 | |
| 150 self.failUnless(cliques[0].MessageForLanguage('fr').GetRealContent() == | |
| 151 'Bonjour $1') | |
| 152 self.failUnless(cliques[1].MessageForLanguage('fr').GetRealContent() == | |
| 153 'Bonjour %s') | |
| 154 | |
| 155 def testMissingTranslations(self): | |
| 156 messages = [ tclib.Message(text='Hello'), tclib.Message(text='Goodbye') ] | |
| 157 factory = clique.UberClique() | |
| 158 cliques = [factory.MakeClique(msg) for msg in messages] | |
| 159 | |
| 160 cliques[1].MessageForLanguage('fr', False, True) | |
| 161 | |
| 162 self.failUnless(not factory.HasMissingTranslations()) | |
| 163 | |
| 164 cliques[0].MessageForLanguage('de', False, False) | |
| 165 | |
| 166 self.failUnless(factory.HasMissingTranslations()) | |
| 167 | |
| 168 report = factory.MissingTranslationsReport() | |
| 169 self.failUnless(report.count('WARNING') == 1) | |
| 170 self.failUnless(report.count('8053599568341804890 "Goodbye" fr') == 1) | |
| 171 self.failUnless(report.count('ERROR') == 1) | |
| 172 self.failUnless(report.count('800120468867715734 "Hello" de') == 1) | |
| 173 | |
| 174 def testCustomTypes(self): | |
| 175 factory = clique.UberClique() | |
| 176 message = tclib.Message(text='Bingo bongo') | |
| 177 c = factory.MakeClique(message) | |
| 178 try: | |
| 179 c.SetCustomType(DummyCustomType()) | |
| 180 self.fail() | |
| 181 except: | |
| 182 pass # expected case - 'Bingo bongo' does not start with 'jjj' | |
| 183 | |
| 184 message = tclib.Message(text='jjjBingo bongo') | |
| 185 c = factory.MakeClique(message) | |
| 186 c.SetCustomType(util.NewClassInstance( | |
| 187 'grit.clique_unittest.DummyCustomType', clique.CustomType)) | |
| 188 translation = tclib.Translation(id=message.GetId(), text='Bilingo bolongo') | |
| 189 c.AddTranslation(translation, 'fr') | |
| 190 self.failUnless(c.MessageForLanguage('fr').GetRealContent().startswith('jjj'
)) | |
| 191 | |
| 192 def testWhitespaceMessagesAreNontranslateable(self): | |
| 193 factory = clique.UberClique() | |
| 194 | |
| 195 message = tclib.Message(text=' \t') | |
| 196 c = factory.MakeClique(message, translateable=True) | |
| 197 self.failIf(c.IsTranslateable()) | |
| 198 | |
| 199 message = tclib.Message(text='\n \n ') | |
| 200 c = factory.MakeClique(message, translateable=True) | |
| 201 self.failIf(c.IsTranslateable()) | |
| 202 | |
| 203 message = tclib.Message(text='\n hello') | |
| 204 c = factory.MakeClique(message, translateable=True) | |
| 205 self.failUnless(c.IsTranslateable()) | |
| 206 | |
| 207 def testEachCliqueKeptSorted(self): | |
| 208 factory = clique.UberClique() | |
| 209 msg_a = tclib.Message(text='hello', description='a') | |
| 210 msg_b = tclib.Message(text='hello', description='b') | |
| 211 msg_c = tclib.Message(text='hello', description='c') | |
| 212 # Insert out of order | |
| 213 clique_b = factory.MakeClique(msg_b, translateable=True) | |
| 214 clique_a = factory.MakeClique(msg_a, translateable=True) | |
| 215 clique_c = factory.MakeClique(msg_c, translateable=True) | |
| 216 clique_list = factory.cliques_[clique_a.GetId()] | |
| 217 self.failUnless(len(clique_list) == 3) | |
| 218 self.failUnless(clique_list[0] == clique_a) | |
| 219 self.failUnless(clique_list[1] == clique_b) | |
| 220 self.failUnless(clique_list[2] == clique_c) | |
| 221 | |
| 222 def testBestCliqueSortIsStable(self): | |
| 223 factory = clique.UberClique() | |
| 224 text = 'hello' | |
| 225 msg_no_description = tclib.Message(text=text) | |
| 226 msg_id_description_a = tclib.Message(text=text, description='ID: a') | |
| 227 msg_id_description_b = tclib.Message(text=text, description='ID: b') | |
| 228 msg_description_x = tclib.Message(text=text, description='x') | |
| 229 msg_description_y = tclib.Message(text=text, description='y') | |
| 230 clique_id = msg_no_description.GetId() | |
| 231 | |
| 232 # Insert in an order that tests all outcomes. | |
| 233 clique_no_description = factory.MakeClique(msg_no_description, | |
| 234 translateable=True) | |
| 235 self.failUnless(factory.BestClique(clique_id) == clique_no_description) | |
| 236 clique_id_description_b = factory.MakeClique(msg_id_description_b, | |
| 237 translateable=True) | |
| 238 self.failUnless(factory.BestClique(clique_id) == clique_id_description_b) | |
| 239 clique_id_description_a = factory.MakeClique(msg_id_description_a, | |
| 240 translateable=True) | |
| 241 self.failUnless(factory.BestClique(clique_id) == clique_id_description_a) | |
| 242 clique_description_y = factory.MakeClique(msg_description_y, | |
| 243 translateable=True) | |
| 244 self.failUnless(factory.BestClique(clique_id) == clique_description_y) | |
| 245 clique_description_x = factory.MakeClique(msg_description_x, | |
| 246 translateable=True) | |
| 247 self.failUnless(factory.BestClique(clique_id) == clique_description_x) | |
| 248 | |
| 249 | |
| 250 class DummyCustomType(clique.CustomType): | |
| 251 def Validate(self, message): | |
| 252 return message.GetRealContent().startswith('jjj') | |
| 253 def ValidateAndModify(self, lang, translation): | |
| 254 is_ok = self.Validate(translation) | |
| 255 self.ModifyEachTextPart(lang, translation) | |
| 256 def ModifyTextPart(self, lang, text): | |
| 257 return 'jjj%s' % text | |
| 258 | |
| 259 | |
| 260 if __name__ == '__main__': | |
| 261 unittest.main() | |
| OLD | NEW |