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 |