OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2011 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.format.rc''' | |
7 | |
8 import os | |
9 import re | |
10 import sys | |
11 if __name__ == '__main__': | |
12 sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) | |
13 | |
14 import tempfile | |
15 import unittest | |
16 import StringIO | |
17 | |
18 from grit import grd_reader | |
19 from grit import util | |
20 from grit.node import structure | |
21 from grit.tool import build | |
22 | |
23 | |
24 _PREAMBLE = '''\ | |
25 #include "resource.h" | |
26 #include <winresrc.h> | |
27 #ifdef IDC_STATIC | |
28 #undef IDC_STATIC | |
29 #endif | |
30 #define IDC_STATIC (-1) | |
31 ''' | |
32 | |
33 | |
34 class DummyOutput(object): | |
35 def __init__(self, type, language, file = 'hello.gif'): | |
36 self.type = type | |
37 self.language = language | |
38 self.file = file | |
39 def GetType(self): | |
40 return self.type | |
41 def GetLanguage(self): | |
42 return self.language | |
43 def GetOutputFilename(self): | |
44 return self.file | |
45 | |
46 class FormatRcUnittest(unittest.TestCase): | |
47 def testMessages(self): | |
48 root = util.ParseGrdForUnittest(''' | |
49 <messages> | |
50 <message name="IDS_BTN_GO" desc="Button text" meaning="verb">Go!</mess
age> | |
51 <message name="IDS_GREETING" desc="Printed to greet the currently logg
ed in user"> | |
52 Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing tod
ay? | |
53 </message> | |
54 <message name="BONGO" desc="Flippo nippo"> | |
55 Howdie "Mr. Elephant", how are you doing? \'\'\' | |
56 </message> | |
57 <message name="IDS_WITH_LINEBREAKS"> | |
58 Good day sir, | |
59 I am a bee | |
60 Sting sting | |
61 </message> | |
62 </messages> | |
63 ''') | |
64 | |
65 buf = StringIO.StringIO() | |
66 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) | |
67 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
68 self.assertEqual(_PREAMBLE + u'''\ | |
69 STRINGTABLE | |
70 BEGIN | |
71 IDS_BTN_GO "Go!" | |
72 IDS_GREETING "Hello %s, how are you doing today?" | |
73 BONGO "Howdie ""Mr. Elephant"", how are you doing? " | |
74 IDS_WITH_LINEBREAKS "Good day sir,\\nI am a bee\\nSting sting" | |
75 END''', output) | |
76 | |
77 | |
78 def testRcSection(self): | |
79 root = util.ParseGrdForUnittest(''' | |
80 <structures> | |
81 <structure type="menu" name="IDC_KLONKMENU" file="grit\\testdata\klonk
.rc" encoding="utf-16" /> | |
82 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\testdata\klon
k.rc" encoding="utf-16" /> | |
83 <structure type="version" name="VS_VERSION_INFO" file="grit\\testdata\
klonk.rc" encoding="utf-16" /> | |
84 </structures>''') | |
85 root.SetOutputLanguage('en') | |
86 root.RunGatherers() | |
87 | |
88 buf = StringIO.StringIO() | |
89 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) | |
90 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
91 expected = _PREAMBLE + u'''\ | |
92 IDC_KLONKMENU MENU | |
93 BEGIN | |
94 POPUP "&File" | |
95 BEGIN | |
96 MENUITEM "E&xit", IDM_EXIT | |
97 MENUITEM "This be ""Klonk"" me like", ID_FILE_THISBE | |
98 POPUP "gonk" | |
99 BEGIN | |
100 MENUITEM "Klonk && is [good]", ID_GONK_KLONKIS | |
101 END | |
102 END | |
103 POPUP "&Help" | |
104 BEGIN | |
105 MENUITEM "&About ...", IDM_ABOUT | |
106 END | |
107 END | |
108 | |
109 IDD_ABOUTBOX DIALOGEX 22, 17, 230, 75 | |
110 STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | |
111 CAPTION "About" | |
112 FONT 8, "System", 0, 0, 0x0 | |
113 BEGIN | |
114 ICON IDI_KLONK,IDC_MYICON,14,9,20,20 | |
115 LTEXT "klonk Version ""yibbee"" 1.0",IDC_STATIC,49,10,119,8, | |
116 SS_NOPREFIX | |
117 LTEXT "Copyright (C) 2005",IDC_STATIC,49,20,119,8 | |
118 DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP | |
119 CONTROL "Jack ""Black"" Daniels",IDC_RADIO1,"Button", | |
120 BS_AUTORADIOBUTTON,46,51,84,10 | |
121 END | |
122 | |
123 VS_VERSION_INFO VERSIONINFO | |
124 FILEVERSION 1,0,0,1 | |
125 PRODUCTVERSION 1,0,0,1 | |
126 FILEFLAGSMASK 0x17L | |
127 #ifdef _DEBUG | |
128 FILEFLAGS 0x1L | |
129 #else | |
130 FILEFLAGS 0x0L | |
131 #endif | |
132 FILEOS 0x4L | |
133 FILETYPE 0x1L | |
134 FILESUBTYPE 0x0L | |
135 BEGIN | |
136 BLOCK "StringFileInfo" | |
137 BEGIN | |
138 BLOCK "040904b0" | |
139 BEGIN | |
140 VALUE "FileDescription", "klonk Application" | |
141 VALUE "FileVersion", "1, 0, 0, 1" | |
142 VALUE "InternalName", "klonk" | |
143 VALUE "LegalCopyright", "Copyright (C) 2005" | |
144 VALUE "OriginalFilename", "klonk.exe" | |
145 VALUE "ProductName", " klonk Application" | |
146 VALUE "ProductVersion", "1, 0, 0, 1" | |
147 END | |
148 END | |
149 BLOCK "VarFileInfo" | |
150 BEGIN | |
151 VALUE "Translation", 0x409, 1200 | |
152 END | |
153 END'''.strip() | |
154 for expected_line, output_line in zip(expected.split(), output.split()): | |
155 self.assertEqual(expected_line, output_line) | |
156 | |
157 def testRcIncludeStructure(self): | |
158 root = util.ParseGrdForUnittest(''' | |
159 <structures> | |
160 <structure type="tr_html" name="IDR_HTML" file="bingo.html"/> | |
161 <structure type="tr_html" name="IDR_HTML2" file="bingo2.html"/> | |
162 </structures>''', base_dir = '/temp') | |
163 # We do not run gatherers as it is not needed and wouldn't find the file | |
164 | |
165 buf = StringIO.StringIO() | |
166 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) | |
167 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
168 expected = (_PREAMBLE + | |
169 u'IDR_HTML HTML "%s"\n' | |
170 u'IDR_HTML2 HTML "%s"' | |
171 % (util.normpath('/temp/bingo.html').replace('\\', '\\\\'), | |
172 util.normpath('/temp/bingo2.html').replace('\\', '\\\\'))) | |
173 # hackety hack to work on win32&lin | |
174 output = re.sub('"[c-zC-Z]:', '"', output) | |
175 self.assertEqual(expected, output) | |
176 | |
177 def testRcIncludeFile(self): | |
178 root = util.ParseGrdForUnittest(''' | |
179 <includes> | |
180 <include type="TXT" name="TEXT_ONE" file="bingo.txt"/> | |
181 <include type="TXT" name="TEXT_TWO" file="bingo2.txt" filenameonly="tru
e" /> | |
182 </includes>''', base_dir = '/temp') | |
183 | |
184 buf = StringIO.StringIO() | |
185 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) | |
186 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
187 expected = (_PREAMBLE + | |
188 u'TEXT_ONE TXT "%s"\n' | |
189 u'TEXT_TWO TXT "%s"' | |
190 % (util.normpath('/temp/bingo.txt').replace('\\', '\\\\'), | |
191 'bingo2.txt')) | |
192 # hackety hack to work on win32&lin | |
193 output = re.sub('"[c-zC-Z]:', '"', output) | |
194 self.assertEqual(expected, output) | |
195 | |
196 def testRcIncludeFlattenedHtmlFile(self): | |
197 input_file = util.PathFromRoot('grit/testdata/include_test.html') | |
198 output_file = '%s/HTML_FILE1_include_test.html' % tempfile.gettempdir() | |
199 root = util.ParseGrdForUnittest(''' | |
200 <includes> | |
201 <include name="HTML_FILE1" flattenhtml="true" file="%s" type="BINDATA" /
> | |
202 </includes>''' % input_file) | |
203 | |
204 buf = StringIO.StringIO() | |
205 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en', output_file), | |
206 buf) | |
207 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
208 | |
209 expected = (_PREAMBLE + | |
210 u'HTML_FILE1 BINDATA "HTML_FILE1_include_test.html"') | |
211 # hackety hack to work on win32&lin | |
212 output = re.sub('"[c-zC-Z]:', '"', output) | |
213 self.assertEqual(expected, output) | |
214 | |
215 file_contents = util.ReadFile(output_file, util.RAW_TEXT) | |
216 | |
217 # Check for the content added by the <include> tag. | |
218 self.failUnless(file_contents.find('Hello Include!') != -1) | |
219 # Check for the content that was removed by if tag. | |
220 self.failUnless(file_contents.find('should be removed') == -1) | |
221 # Check for the content that was kept in place by if. | |
222 self.failUnless(file_contents.find('should be kept') != -1) | |
223 self.failUnless(file_contents.find('in the middle...') != -1) | |
224 self.failUnless(file_contents.find('at the end...') != -1) | |
225 # Check for nested content that was kept | |
226 self.failUnless(file_contents.find('nested true should be kept') != -1) | |
227 self.failUnless(file_contents.find('silbing true should be kept') != -1) | |
228 # Check for removed "<if>" and "</if>" tags. | |
229 self.failUnless(file_contents.find('<if expr=') == -1) | |
230 self.failUnless(file_contents.find('</if>') == -1) | |
231 | |
232 | |
233 def testStructureNodeOutputfile(self): | |
234 input_file = util.PathFromRoot('grit/testdata/simple.html') | |
235 root = util.ParseGrdForUnittest('''\ | |
236 <structures> | |
237 <structure type="tr_html" name="IDR_HTML" file="%s" /> | |
238 </structures>''' % input_file) | |
239 struct, = root.GetChildrenOfType(structure.StructureNode) | |
240 # We must run the gatherer since we'll be wanting the translation of the | |
241 # file. The file exists in the location pointed to. | |
242 root.SetOutputLanguage('en') | |
243 root.RunGatherers() | |
244 | |
245 output_dir = tempfile.gettempdir() | |
246 en_file = struct.FileForLanguage('en', output_dir) | |
247 self.failUnless(en_file == input_file) | |
248 fr_file = struct.FileForLanguage('fr', output_dir) | |
249 self.failUnless(fr_file == os.path.join(output_dir, 'fr_simple.html')) | |
250 | |
251 contents = util.ReadFile(fr_file, util.RAW_TEXT) | |
252 | |
253 self.failUnless(contents.find('<p>') != -1) # should contain the markup | |
254 self.failUnless(contents.find('Hello!') == -1) # should be translated | |
255 | |
256 | |
257 def testChromeHtmlNodeOutputfile(self): | |
258 input_file = util.PathFromRoot('grit/testdata/chrome_html.html') | |
259 output_file = '%s/HTML_FILE1_chrome_html.html' % tempfile.gettempdir() | |
260 root = util.ParseGrdForUnittest('''\ | |
261 <structures> | |
262 <structure type="chrome_html" name="HTML_FILE1" file="%s" flattenhtml=
"true" /> | |
263 </structures>''' % input_file) | |
264 struct, = root.GetChildrenOfType(structure.StructureNode) | |
265 struct.gatherer.SetDefines({'scale_factors': '2x'}) | |
266 # We must run the gatherers since we'll be wanting the chrome_html output. | |
267 # The file exists in the location pointed to. | |
268 root.SetOutputLanguage('en') | |
269 root.RunGatherers() | |
270 | |
271 buf = StringIO.StringIO() | |
272 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en', output_file), | |
273 buf) | |
274 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
275 expected = (_PREAMBLE + | |
276 u'HTML_FILE1 BINDATA "HTML_FILE1_chrome_html.html"') | |
277 # hackety hack to work on win32&lin | |
278 output = re.sub('"[c-zC-Z]:', '"', output) | |
279 self.assertEqual(expected, output) | |
280 | |
281 file_contents = util.ReadFile(output_file, util.RAW_TEXT) | |
282 | |
283 # Check for the content added by the <include> tag. | |
284 self.failUnless(file_contents.find('Hello Include!') != -1) | |
285 # Check for inserted -webkit-image-set. | |
286 self.failUnless(file_contents.find('content: -webkit-image-set') != -1) | |
287 | |
288 | |
289 def testSubstitutionHtml(self): | |
290 input_file = util.PathFromRoot('grit/testdata/toolbar_about.html') | |
291 root = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="U
TF-8"?> | |
292 <grit latest_public_release="2" source_lang_id="en-US" current_release="3"
base_dir="."> | |
293 <release seq="1" allow_pseudo="False"> | |
294 <structures fallback_to_english="True"> | |
295 <structure type="tr_html" name="IDR_HTML" file="%s" expand_variables
="true"/> | |
296 </structures> | |
297 </release> | |
298 </grit> | |
299 ''' % input_file), util.PathFromRoot('.')) | |
300 root.SetOutputLanguage('ar') | |
301 # We must run the gatherers since we'll be wanting the translation of the | |
302 # file. The file exists in the location pointed to. | |
303 root.RunGatherers() | |
304 | |
305 output_dir = tempfile.gettempdir() | |
306 struct, = root.GetChildrenOfType(structure.StructureNode) | |
307 ar_file = struct.FileForLanguage('ar', output_dir) | |
308 self.failUnless(ar_file == os.path.join(output_dir, | |
309 'ar_toolbar_about.html')) | |
310 | |
311 contents = util.ReadFile(ar_file, util.RAW_TEXT) | |
312 | |
313 self.failUnless(contents.find('dir="RTL"') != -1) | |
314 | |
315 | |
316 def testFallbackToEnglish(self): | |
317 root = util.ParseGrdForUnittest('''\ | |
318 <structures fallback_to_english="True"> | |
319 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\testdata\klon
k.rc" encoding="utf-16" /> | |
320 </structures>''', base_dir=util.PathFromRoot('.')) | |
321 root.SetOutputLanguage('en') | |
322 root.RunGatherers() | |
323 | |
324 buf = StringIO.StringIO() | |
325 formatter = build.RcBuilder.ProcessNode( | |
326 root, DummyOutput('rc_all', 'bingobongo'), buf) | |
327 output = util.StripBlankLinesAndComments(buf.getvalue()) | |
328 self.assertEqual(_PREAMBLE + '''\ | |
329 IDD_ABOUTBOX DIALOGEX 22, 17, 230, 75 | |
330 STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | |
331 CAPTION "About" | |
332 FONT 8, "System", 0, 0, 0x0 | |
333 BEGIN | |
334 ICON IDI_KLONK,IDC_MYICON,14,9,20,20 | |
335 LTEXT "klonk Version ""yibbee"" 1.0",IDC_STATIC,49,10,119,8, | |
336 SS_NOPREFIX | |
337 LTEXT "Copyright (C) 2005",IDC_STATIC,49,20,119,8 | |
338 DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP | |
339 CONTROL "Jack ""Black"" Daniels",IDC_RADIO1,"Button", | |
340 BS_AUTORADIOBUTTON,46,51,84,10 | |
341 END''', output) | |
342 | |
343 | |
344 def testSubstitutionRc(self): | |
345 root = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="U
TF-8"?> | |
346 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" | |
347 base_dir="."> | |
348 <outputs> | |
349 <output lang="en" type="rc_all" filename="grit\\testdata\klonk_resources
.rc"/> | |
350 </outputs> | |
351 <release seq="1" allow_pseudo="False"> | |
352 <structures> | |
353 <structure type="menu" name="IDC_KLONKMENU" | |
354 file="grit\\testdata\klonk.rc" encoding="utf-16" | |
355 expand_variables="true" /> | |
356 </structures> | |
357 <messages> | |
358 <message name="good" sub_variable="true"> | |
359 excellent | |
360 </message> | |
361 </messages> | |
362 </release> | |
363 </grit> | |
364 '''), util.PathFromRoot('.')) | |
365 root.SetOutputLanguage('en') | |
366 root.RunGatherers() | |
367 | |
368 buf = StringIO.StringIO() | |
369 build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) | |
370 output = buf.getvalue() | |
371 self.assertEqual(''' | |
372 // This file is automatically generated by GRIT. Do not edit. | |
373 | |
374 #include "resource.h" | |
375 #include <winresrc.h> | |
376 #ifdef IDC_STATIC | |
377 #undef IDC_STATIC | |
378 #endif | |
379 #define IDC_STATIC (-1) | |
380 | |
381 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |
382 | |
383 | |
384 IDC_KLONKMENU MENU | |
385 BEGIN | |
386 POPUP "&File" | |
387 BEGIN | |
388 MENUITEM "E&xit", IDM_EXIT | |
389 MENUITEM "This be ""Klonk"" me like", ID_FILE_THISBE | |
390 POPUP "gonk" | |
391 BEGIN | |
392 MENUITEM "Klonk && is excellent", ID_GONK_KLONKIS | |
393 END | |
394 END | |
395 POPUP "&Help" | |
396 BEGIN | |
397 MENUITEM "&About ...", IDM_ABOUT | |
398 END | |
399 END | |
400 | |
401 STRINGTABLE | |
402 BEGIN | |
403 good "excellent" | |
404 END | |
405 '''.strip(), output.strip()) | |
406 | |
407 | |
408 if __name__ == '__main__': | |
409 unittest.main() | |
OLD | NEW |