| 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 |