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 misc.GritNode''' 7 8 9 import os 10 import sys 11 if __name__ == '__main__': 12 sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) 13 14 import unittest 15 import StringIO 16 17 from grit import grd_reader 18 import grit.exception 19 from grit import util 20 from grit.format import rc 21 from grit.node import misc 22 23 24 class GritNodeUnittest(unittest.TestCase): 25 def testUniqueNameAttribute(self): 26 try: 27 restree = grd_reader.Parse( 28 util.PathFromRoot('grit/testdata/duplicate-name-input.xml')) 29 self.fail('Expected parsing exception because of duplicate names.') 30 except grit.exception.Parsing: 31 pass # Expected case 32 33 def testReadFirstIdsFromFile(self): 34 test_resource_ids = os.path.join(os.path.dirname(__file__), '..', 35 'testdata', 'resource_ids') 36 base_dir = os.path.dirname(test_resource_ids) 37 38 src_dir, id_dict = misc._ReadFirstIdsFromFile( 39 test_resource_ids, 40 { 41 'FOO': os.path.join(base_dir, 'bar'), 42 'SHARED_INTERMEDIATE_DIR': os.path.join(base_dir, 43 'out/Release/obj/gen'), 44 }) 45 self.assertEqual({}, id_dict.get('bar/file.grd', None)) 46 self.assertEqual({}, 47 id_dict.get('out/Release/obj/gen/devtools/devtools.grd', None)) 48 49 src_dir, id_dict = misc._ReadFirstIdsFromFile( 50 test_resource_ids, 51 { 52 'SHARED_INTERMEDIATE_DIR': '/outside/src_dir', 53 }) 54 self.assertEqual({}, id_dict.get('devtools.grd', None)) 55 56 class IfNodeUnittest(unittest.TestCase): 57 def testIffyness(self): 58 grd = grd_reader.Parse(StringIO.StringIO(''' 59 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 60 <release seq="3"> 61 <messages> 62 <if expr="'bingo' in defs"> 63 <message name="IDS_BINGO"> 64 Bingo! 65 </message> 66 </if> 67 <if expr="'hello' in defs"> 68 <message name="IDS_HELLO"> 69 Hello! 70 </message> 71 </if> 72 <if expr="lang == 'fr' or 'FORCE_FRENCH' in defs"> 73 <message name="IDS_HELLO" internal_comment="French version"> 74 Good morning 75 </message> 76 </if> 77 <if expr="is_win"> 78 <message name="IDS_ISWIN">is_win</message> 79 </if> 80 </messages> 81 </release> 82 </grit>'''), dir='.') 83 84 messages_node = grd.children[0].children[0] 85 bingo_message = messages_node.children[0].children[0] 86 hello_message = messages_node.children[1].children[0] 87 french_message = messages_node.children[2].children[0] 88 is_win_message = messages_node.children[3].children[0] 89 90 self.assertTrue(bingo_message.name == 'message') 91 self.assertTrue(hello_message.name == 'message') 92 self.assertTrue(french_message.name == 'message') 93 94 grd.SetOutputLanguage('fr') 95 grd.SetDefines({'hello': '1'}) 96 active = set(grd.ActiveDescendants()) 97 self.failUnless(bingo_message not in active) 98 self.failUnless(hello_message in active) 99 self.failUnless(french_message in active) 100 101 grd.SetOutputLanguage('en') 102 grd.SetDefines({'bingo': 1}) 103 active = set(grd.ActiveDescendants()) 104 self.failUnless(bingo_message in active) 105 self.failUnless(hello_message not in active) 106 self.failUnless(french_message not in active) 107 108 grd.SetOutputLanguage('en') 109 grd.SetDefines({'FORCE_FRENCH': '1', 'bingo': '1'}) 110 active = set(grd.ActiveDescendants()) 111 self.failUnless(bingo_message in active) 112 self.failUnless(hello_message not in active) 113 self.failUnless(french_message in active) 114 115 grd.SetOutputLanguage('en') 116 grd.SetDefines({}) 117 self.failUnless(grd.target_platform == sys.platform) 118 grd.SetTargetPlatform('darwin') 119 active = set(grd.ActiveDescendants()) 120 self.failUnless(is_win_message not in active) 121 grd.SetTargetPlatform('win32') 122 active = set(grd.ActiveDescendants()) 123 self.failUnless(is_win_message in active) 124 125 def testElsiness(self): 126 grd = util.ParseGrdForUnittest(''' 127 <messages> 128 <if expr="True"> 129 <then> <message name="IDS_YES1"></message> </then> 130 <else> <message name="IDS_NO1"></message> </else> 131 </if> 132 <if expr="True"> 133 <then> <message name="IDS_YES2"></message> </then> 134 <else> </else> 135 </if> 136 <if expr="True"> 137 <then> </then> 138 <else> <message name="IDS_NO2"></message> </else> 139 </if> 140 <if expr="True"> 141 <then> </then> 142 <else> </else> 143 </if> 144 <if expr="False"> 145 <then> <message name="IDS_NO3"></message> </then> 146 <else> <message name="IDS_YES3"></message> </else> 147 </if> 148 <if expr="False"> 149 <then> <message name="IDS_NO4"></message> </then> 150 <else> </else> 151 </if> 152 <if expr="False"> 153 <then> </then> 154 <else> <message name="IDS_YES4"></message> </else> 155 </if> 156 <if expr="False"> 157 <then> </then> 158 <else> </else> 159 </if> 160 </messages>''') 161 included = [msg.attrs['name'] for msg in grd.ActiveDescendants() 162 if msg.name == 'message'] 163 self.assertEqual(['IDS_YES1', 'IDS_YES2', 'IDS_YES3', 'IDS_YES4'], included) 164 165 def testIffynessWithOutputNodes(self): 166 grd = grd_reader.Parse(StringIO.StringIO(''' 167 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 168 <outputs> 169 <output filename="uncond1.rc" type="rc_data" /> 170 <if expr="lang == 'fr' or 'hello' in defs"> 171 <output filename="only_fr.adm" type="adm" /> 172 <output filename="only_fr.plist" type="plist" /> 173 </if> 174 <if expr="lang == 'ru'"> 175 <output filename="doc.html" type="document" /> 176 </if> 177 <output filename="uncond2.adm" type="adm" /> 178 <output filename="iftest.h" type="rc_header"> 179 <emit emit_type='prepend'></emit> 180 </output> 181 </outputs> 182 </grit>'''), dir='.') 183 184 outputs_node = grd.children[0] 185 uncond1_output = outputs_node.children[0] 186 only_fr_adm_output = outputs_node.children[1].children[0] 187 only_fr_plist_output = outputs_node.children[1].children[1] 188 doc_output = outputs_node.children[2].children[0] 189 uncond2_output = outputs_node.children[0] 190 self.assertTrue(uncond1_output.name == 'output') 191 self.assertTrue(only_fr_adm_output.name == 'output') 192 self.assertTrue(only_fr_plist_output.name == 'output') 193 self.assertTrue(doc_output.name == 'output') 194 self.assertTrue(uncond2_output.name == 'output') 195 196 grd.SetOutputLanguage('ru') 197 grd.SetDefines({'hello': '1'}) 198 outputs = [output.GetFilename() for output in grd.GetOutputFiles()] 199 self.assertEquals( 200 outputs, 201 ['uncond1.rc', 'only_fr.adm', 'only_fr.plist', 'doc.html', 202 'uncond2.adm', 'iftest.h']) 203 204 grd.SetOutputLanguage('ru') 205 grd.SetDefines({'bingo': '2'}) 206 outputs = [output.GetFilename() for output in grd.GetOutputFiles()] 207 self.assertEquals( 208 outputs, 209 ['uncond1.rc', 'doc.html', 'uncond2.adm', 'iftest.h']) 210 211 grd.SetOutputLanguage('fr') 212 grd.SetDefines({'hello': '1'}) 213 outputs = [output.GetFilename() for output in grd.GetOutputFiles()] 214 self.assertEquals( 215 outputs, 216 ['uncond1.rc', 'only_fr.adm', 'only_fr.plist', 'uncond2.adm', 217 'iftest.h']) 218 219 grd.SetOutputLanguage('en') 220 grd.SetDefines({'bingo': '1'}) 221 outputs = [output.GetFilename() for output in grd.GetOutputFiles()] 222 self.assertEquals(outputs, ['uncond1.rc', 'uncond2.adm', 'iftest.h']) 223 224 grd.SetOutputLanguage('fr') 225 grd.SetDefines({'bingo': '1'}) 226 outputs = [output.GetFilename() for output in grd.GetOutputFiles()] 227 self.assertNotEquals(outputs, ['uncond1.rc', 'uncond2.adm', 'iftest.h']) 228 229 def testChildrenAccepted(self): 230 grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0"?> 231 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 232 <release seq="3"> 233 <includes> 234 <if expr="'bingo' in defs"> 235 <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> 236 </if> 237 <if expr="'bingo' in defs"> 238 <if expr="'hello' in defs"> 239 <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> 240 </if> 241 </if> 242 </includes> 243 <structures> 244 <if expr="'bingo' in defs"> 245 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 246 </if> 247 <if expr="'bingo' in defs"> 248 <if expr="'hello' in defs"> 249 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 250 </if> 251 </if> 252 </structures> 253 <messages> 254 <if expr="'bingo' in defs"> 255 <message name="IDS_BINGO">Bingo!</message> 256 </if> 257 <if expr="'bingo' in defs"> 258 <if expr="'hello' in defs"> 259 <message name="IDS_BINGO">Bingo!</message> 260 </if> 261 </if> 262 </messages> 263 </release> 264 <translations> 265 <if expr="'bingo' in defs"> 266 <file lang="nl" path="nl_translations.xtb" /> 267 </if> 268 <if expr="'bingo' in defs"> 269 <if expr="'hello' in defs"> 270 <file lang="nl" path="nl_translations.xtb" /> 271 </if> 272 </if> 273 </translations> 274 </grit>'''), dir='.') 275 276 def testIfBadChildrenNesting(self): 277 # includes 278 xml = StringIO.StringIO('''<?xml version="1.0"?> 279 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 280 <release seq="3"> 281 <includes> 282 <if expr="'bingo' in defs"> 283 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 284 </if> 285 </includes> 286 </release> 287 </grit>''') 288 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 289 # messages 290 xml = StringIO.StringIO('''<?xml version="1.0"?> 291 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 292 <release seq="3"> 293 <messages> 294 <if expr="'bingo' in defs"> 295 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 296 </if> 297 </messages> 298 </release> 299 </grit>''') 300 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 301 # structures 302 xml = StringIO.StringIO('''<?xml version="1.0"?> 303 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 304 <release seq="3"> 305 <structures> 306 <if expr="'bingo' in defs"> 307 <message name="IDS_BINGO">Bingo!</message> 308 </if> 309 </structures> 310 </release> 311 </grit>''') 312 # translations 313 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 314 xml = StringIO.StringIO('''<?xml version="1.0"?> 315 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 316 <translations> 317 <if expr="'bingo' in defs"> 318 <message name="IDS_BINGO">Bingo!</message> 319 </if> 320 </translations> 321 </grit>''') 322 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 323 # same with nesting 324 xml = StringIO.StringIO('''<?xml version="1.0"?> 325 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 326 <release seq="3"> 327 <includes> 328 <if expr="'bingo' in defs"> 329 <if expr="'hello' in defs"> 330 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 331 </if> 332 </if> 333 </includes> 334 </release> 335 </grit>''') 336 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 337 xml = StringIO.StringIO('''<?xml version="1.0"?> 338 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 339 <release seq="3"> 340 <messages> 341 <if expr="'bingo' in defs"> 342 <if expr="'hello' in defs"> 343 <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> 344 </if> 345 </if> 346 </messages> 347 </release> 348 </grit>''') 349 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 350 xml = StringIO.StringIO('''<?xml version="1.0"?> 351 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 352 <release seq="3"> 353 <structures> 354 <if expr="'bingo' in defs"> 355 <if expr="'hello' in defs"> 356 <message name="IDS_BINGO">Bingo!</message> 357 </if> 358 </if> 359 </structures> 360 </release> 361 </grit>''') 362 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 363 xml = StringIO.StringIO('''<?xml version="1.0"?> 364 <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> 365 <translations> 366 <if expr="'bingo' in defs"> 367 <if expr="'hello' in defs"> 368 <message name="IDS_BINGO">Bingo!</message> 369 </if> 370 </if> 371 </translations> 372 </grit>''') 373 self.assertRaises(grit.exception.UnexpectedChild, grd_reader.Parse, xml) 374 375 376 class ReleaseNodeUnittest(unittest.TestCase): 377 def testPseudoControl(self): 378 grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> 379 <grit latest_public_release="1" source_lang_id="en-US" current_release="2" base_dir="."> 380 <release seq="1" allow_pseudo="false"> 381 <messages> 382 <message name="IDS_HELLO"> 383 Hello 384 </message> 385 </messages> 386 <structures> 387 <structure type="dialog" name="IDD_ABOUTBOX" encoding="utf-16" file="klonk.rc" /> 388 </structures> 389 </release> 390 <release seq="2"> 391 <messages> 392 <message name="IDS_BINGO"> 393 Bingo 394 </message> 395 </messages> 396 <structures> 397 <structure type="menu" name="IDC_KLONKMENU" encoding="utf-16" file="klonk.rc" /> 398 </structures> 399 </release> 400 </grit>'''), util.PathFromRoot('grit/testdata')) 401 grd.SetOutputLanguage('en') 402 grd.RunGatherers() 403 404 hello = grd.GetNodeById('IDS_HELLO') 405 aboutbox = grd.GetNodeById('IDD_ABOUTBOX') 406 bingo = grd.GetNodeById('IDS_BINGO') 407 menu = grd.GetNodeById('IDC_KLONKMENU') 408 409 for node in [hello, aboutbox]: 410 self.failUnless(not node.PseudoIsAllowed()) 411 412 for node in [bingo, menu]: 413 self.failUnless(node.PseudoIsAllowed()) 414 415 # TODO(benrg): There was a test here that formatting hello and aboutbox with 416 # a pseudo language should fail, but they do not fail and the test was 417 # broken and failed to catch it. Fix this. 418 419 # Should not raise an exception since pseudo is allowed 420 rc.FormatMessage(bingo, 'xyz-pseudo') 421 rc.FormatStructure(menu, 'xyz-pseudo', '.') 422 423 424 if __name__ == '__main__': 425 unittest.main() 426