Home | History | Annotate | Download | only in node
      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 base.Node functionality (as used in various subclasses)'''
      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 StringIO
     15 import unittest
     16 
     17 from grit import grd_reader
     18 from grit import util
     19 from grit.node import base
     20 from grit.node import message
     21 
     22 
     23 def MakePlaceholder(phname='BINGO'):
     24   ph = message.PhNode()
     25   ph.StartParsing(u'ph', None)
     26   ph.HandleAttribute(u'name', phname)
     27   ph.AppendContent(u'bongo')
     28   ph.EndParsing()
     29   return ph
     30 
     31 
     32 class NodeUnittest(unittest.TestCase):
     33   def testWhitespaceHandling(self):
     34     # We test using the Message node type.
     35     node = message.MessageNode()
     36     node.StartParsing(u'hello', None)
     37     node.HandleAttribute(u'name', u'bla')
     38     node.AppendContent(u" '''  two spaces  ")
     39     node.EndParsing()
     40     self.failUnless(node.GetCdata() == u'  two spaces')
     41 
     42     node = message.MessageNode()
     43     node.StartParsing(u'message', None)
     44     node.HandleAttribute(u'name', u'bla')
     45     node.AppendContent(u"  two spaces  '''  ")
     46     node.EndParsing()
     47     self.failUnless(node.GetCdata() == u'two spaces  ')
     48 
     49   def testWhitespaceHandlingWithChildren(self):
     50     # We test using the Message node type.
     51     node = message.MessageNode()
     52     node.StartParsing(u'message', None)
     53     node.HandleAttribute(u'name', u'bla')
     54     node.AppendContent(u" '''  two spaces  ")
     55     node.AddChild(MakePlaceholder())
     56     node.AppendContent(u' space before and after ')
     57     node.AddChild(MakePlaceholder('BONGO'))
     58     node.AppendContent(u" space before two after  '''")
     59     node.EndParsing()
     60     self.failUnless(node.mixed_content[0] == u'  two spaces  ')
     61     self.failUnless(node.mixed_content[2] == u' space before and after ')
     62     self.failUnless(node.mixed_content[-1] == u' space before two after  ')
     63 
     64   def testXmlFormatMixedContent(self):
     65     # Again test using the Message node type, because it is the only mixed
     66     # content node.
     67     node = message.MessageNode()
     68     node.StartParsing(u'message', None)
     69     node.HandleAttribute(u'name', u'name')
     70     node.AppendContent(u'Hello <young> ')
     71 
     72     ph = message.PhNode()
     73     ph.StartParsing(u'ph', None)
     74     ph.HandleAttribute(u'name', u'USERNAME')
     75     ph.AppendContent(u'$1')
     76     ex = message.ExNode()
     77     ex.StartParsing(u'ex', None)
     78     ex.AppendContent(u'Joi')
     79     ex.EndParsing()
     80     ph.AddChild(ex)
     81     ph.EndParsing()
     82 
     83     node.AddChild(ph)
     84     node.EndParsing()
     85 
     86     non_indented_xml = node.FormatXml()
     87     self.failUnless(non_indented_xml == u'<message name="name">\n  Hello '
     88                     u'&lt;young&gt; <ph name="USERNAME">$1<ex>Joi</ex></ph>'
     89                     u'\n</message>')
     90 
     91     indented_xml = node.FormatXml(u'  ')
     92     self.failUnless(indented_xml == u'  <message name="name">\n    Hello '
     93                     u'&lt;young&gt; <ph name="USERNAME">$1<ex>Joi</ex></ph>'
     94                     u'\n  </message>')
     95 
     96   def testXmlFormatMixedContentWithLeadingWhitespace(self):
     97     # Again test using the Message node type, because it is the only mixed
     98     # content node.
     99     node = message.MessageNode()
    100     node.StartParsing(u'message', None)
    101     node.HandleAttribute(u'name', u'name')
    102     node.AppendContent(u"'''   Hello <young> ")
    103 
    104     ph = message.PhNode()
    105     ph.StartParsing(u'ph', None)
    106     ph.HandleAttribute(u'name', u'USERNAME')
    107     ph.AppendContent(u'$1')
    108     ex = message.ExNode()
    109     ex.StartParsing(u'ex', None)
    110     ex.AppendContent(u'Joi')
    111     ex.EndParsing()
    112     ph.AddChild(ex)
    113     ph.EndParsing()
    114 
    115     node.AddChild(ph)
    116     node.AppendContent(u" yessiree '''")
    117     node.EndParsing()
    118 
    119     non_indented_xml = node.FormatXml()
    120     self.failUnless(non_indented_xml ==
    121                     u"<message name=\"name\">\n  '''   Hello"
    122                     u' &lt;young&gt; <ph name="USERNAME">$1<ex>Joi</ex></ph>'
    123                     u" yessiree '''\n</message>")
    124 
    125     indented_xml = node.FormatXml(u'  ')
    126     self.failUnless(indented_xml ==
    127                     u"  <message name=\"name\">\n    '''   Hello"
    128                     u' &lt;young&gt; <ph name="USERNAME">$1<ex>Joi</ex></ph>'
    129                     u" yessiree '''\n  </message>")
    130 
    131     self.failUnless(node.GetNodeById('name'))
    132 
    133   def testXmlFormatContentWithEntities(self):
    134     '''Tests a bug where &nbsp; would not be escaped correctly.'''
    135     from grit import tclib
    136     msg_node = message.MessageNode.Construct(None, tclib.Message(
    137       text = 'BEGIN_BOLDHelloWHITESPACEthere!END_BOLD Bingo!',
    138       placeholders = [
    139         tclib.Placeholder('BEGIN_BOLD', '<b>', 'bla'),
    140         tclib.Placeholder('WHITESPACE', '&nbsp;', 'bla'),
    141         tclib.Placeholder('END_BOLD', '</b>', 'bla')]),
    142                                              'BINGOBONGO')
    143     xml = msg_node.FormatXml()
    144     self.failUnless(xml.find('&nbsp;') == -1, 'should have no entities')
    145 
    146   def testIter(self):
    147     # First build a little tree of message and ph nodes.
    148     node = message.MessageNode()
    149     node.StartParsing(u'message', None)
    150     node.HandleAttribute(u'name', u'bla')
    151     node.AppendContent(u" '''  two spaces  ")
    152     node.AppendContent(u' space before and after ')
    153     ph = message.PhNode()
    154     ph.StartParsing(u'ph', None)
    155     ph.AddChild(message.ExNode())
    156     ph.HandleAttribute(u'name', u'BINGO')
    157     ph.AppendContent(u'bongo')
    158     node.AddChild(ph)
    159     node.AddChild(message.PhNode())
    160     node.AppendContent(u" space before two after  '''")
    161 
    162     order = [message.MessageNode, message.PhNode, message.ExNode, message.PhNode]
    163     for n in node:
    164       self.failUnless(type(n) == order[0])
    165       order = order[1:]
    166     self.failUnless(len(order) == 0)
    167 
    168   def testGetChildrenOfType(self):
    169     xml = '''<?xml version="1.0" encoding="UTF-8"?>
    170       <grit latest_public_release="2" source_lang_id="en-US"
    171             current_release="3" base_dir=".">
    172         <outputs>
    173           <output filename="resource.h" type="rc_header" />
    174           <output filename="en/generated_resources.rc" type="rc_all"
    175                   lang="en" />
    176           <if expr="pp_if('NOT_TRUE')">
    177             <output filename="de/generated_resources.rc" type="rc_all"
    178                     lang="de" />
    179           </if>
    180         </outputs>
    181         <release seq="3">
    182           <messages>
    183             <message name="ID_HELLO">Hello!</message>
    184           </messages>
    185         </release>
    186       </grit>'''
    187     grd = grd_reader.Parse(StringIO.StringIO(xml),
    188                            util.PathFromRoot('grit/test/data'))
    189     from grit.node import io
    190     output_nodes = grd.GetChildrenOfType(io.OutputNode)
    191     self.failUnlessEqual(len(output_nodes), 3)
    192     self.failUnlessEqual(output_nodes[2].attrs['filename'],
    193                          'de/generated_resources.rc')
    194 
    195   def testEvaluateExpression(self):
    196     def AssertExpr(expected_value, expr, defs, target_platform,
    197                    extra_variables):
    198       self.failUnlessEqual(expected_value, base.Node.EvaluateExpression(
    199           expr, defs, target_platform, extra_variables))
    200 
    201     AssertExpr(True, "True", {}, 'linux', {})
    202     AssertExpr(False, "False", {}, 'linux', {})
    203     AssertExpr(True, "True or False", {}, 'linux', {})
    204     AssertExpr(False, "True and False", {}, 'linux', {})
    205     AssertExpr(True, "os == 'linux'", {}, 'linux', {})
    206     AssertExpr(False, "os == 'linux'", {}, 'ios', {})
    207     AssertExpr(True, "'foo' in defs", {'foo': 'bar'}, 'ios', {})
    208     AssertExpr(False, "'foo' in defs", {'baz': 'bar'}, 'ios', {})
    209     AssertExpr(False, "'foo' in defs", {}, 'ios', {})
    210     AssertExpr(True, "is_linux", {}, 'linux2', {})
    211     AssertExpr(False, "is_linux", {}, 'win32', {})
    212     AssertExpr(True, "is_macosx", {}, 'darwin', {})
    213     AssertExpr(False, "is_macosx", {}, 'ios', {})
    214     AssertExpr(True, "is_win", {}, 'win32', {})
    215     AssertExpr(False, "is_win", {}, 'darwin', {})
    216     AssertExpr(True, "is_android", {}, 'android', {})
    217     AssertExpr(False, "is_android", {}, 'linux3', {})
    218     AssertExpr(True, "is_ios", {}, 'ios', {})
    219     AssertExpr(False, "is_ios", {}, 'darwin', {})
    220     AssertExpr(True, "is_posix", {}, 'linux2', {})
    221     AssertExpr(True, "is_posix", {}, 'darwin', {})
    222     AssertExpr(True, "is_posix", {}, 'android', {})
    223     AssertExpr(True, "is_posix", {}, 'ios', {})
    224     AssertExpr(True, "is_posix", {}, 'freebsd7', {})
    225     AssertExpr(False, "is_posix", {}, 'win32', {})
    226     AssertExpr(True, "pp_ifdef('foo')", {'foo': True}, 'win32', {})
    227     AssertExpr(True, "pp_ifdef('foo')", {'foo': False}, 'win32', {})
    228     AssertExpr(False, "pp_ifdef('foo')", {'bar': True}, 'win32', {})
    229     AssertExpr(True, "pp_if('foo')", {'foo': True}, 'win32', {})
    230     AssertExpr(False, "pp_if('foo')", {'foo': False}, 'win32', {})
    231     AssertExpr(False, "pp_if('foo')", {'bar': True}, 'win32', {})
    232     AssertExpr(True, "foo", {'foo': True}, 'win32', {})
    233     AssertExpr(False, "foo", {'foo': False}, 'win32', {})
    234     AssertExpr(False, "foo", {'bar': True}, 'win32', {})
    235     AssertExpr(True, "foo == 'baz'", {'foo': 'baz'}, 'win32', {})
    236     AssertExpr(False, "foo == 'baz'", {'foo': True}, 'win32', {})
    237     AssertExpr(False, "foo == 'baz'", {}, 'win32', {})
    238     AssertExpr(True, "lang == 'de'", {}, 'win32', {'lang': 'de'})
    239     AssertExpr(False, "lang == 'de'", {}, 'win32', {'lang': 'fr'})
    240     AssertExpr(False, "lang == 'de'", {}, 'win32', {})
    241 
    242     # Test a couple more complex expressions for good measure.
    243     AssertExpr(True, "is_ios and (lang in ['de', 'fr'] or foo)",
    244                {'foo': 'bar'}, 'ios', {'lang': 'fr', 'context': 'today'})
    245     AssertExpr(False, "is_ios and (lang in ['de', 'fr'] or foo)",
    246                {'foo': False}, 'linux2', {'lang': 'fr', 'context': 'today'})
    247     AssertExpr(False, "is_ios and (lang in ['de', 'fr'] or foo)",
    248                {'baz': 'bar'}, 'ios', {'lang': 'he', 'context': 'today'})
    249     AssertExpr(True, "foo == 'bar' or not baz",
    250                {'foo': 'bar', 'fun': True}, 'ios', {'lang': 'en'})
    251     AssertExpr(True, "foo == 'bar' or not baz",
    252                {}, 'ios', {'lang': 'en', 'context': 'java'})
    253     AssertExpr(False, "foo == 'bar' or not baz",
    254                {'foo': 'ruz', 'baz': True}, 'ios', {'lang': 'en'})
    255 
    256 if __name__ == '__main__':
    257   unittest.main()
    258 
    259