Home | History | Annotate | Download | only in closure_linter
      1 #!/usr/bin/env python
      2 #
      3 # Copyright 2010 The Closure Linter Authors. All Rights Reserved.
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS-IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 """Unit tests for ClosurizedNamespacesInfo."""
     18 
     19 
     20 
     21 import unittest as googletest
     22 from closure_linter import aliaspass
     23 from closure_linter import closurizednamespacesinfo
     24 from closure_linter import ecmametadatapass
     25 from closure_linter import javascriptstatetracker
     26 from closure_linter import javascripttokens
     27 from closure_linter import testutil
     28 from closure_linter import tokenutil
     29 
     30 # pylint: disable=g-bad-name
     31 TokenType = javascripttokens.JavaScriptTokenType
     32 
     33 
     34 class ClosurizedNamespacesInfoTest(googletest.TestCase):
     35   """Tests for ClosurizedNamespacesInfo."""
     36 
     37   _test_cases = {
     38       'goog.global.anything': None,
     39       'package.CONSTANT': 'package',
     40       'package.methodName': 'package',
     41       'package.subpackage.methodName': 'package.subpackage',
     42       'package.subpackage.methodName.apply': 'package.subpackage',
     43       'package.ClassName.something': 'package.ClassName',
     44       'package.ClassName.Enum.VALUE.methodName': 'package.ClassName',
     45       'package.ClassName.CONSTANT': 'package.ClassName',
     46       'package.namespace.CONSTANT.methodName': 'package.namespace',
     47       'package.ClassName.inherits': 'package.ClassName',
     48       'package.ClassName.apply': 'package.ClassName',
     49       'package.ClassName.methodName.apply': 'package.ClassName',
     50       'package.ClassName.methodName.call': 'package.ClassName',
     51       'package.ClassName.prototype.methodName': 'package.ClassName',
     52       'package.ClassName.privateMethod_': 'package.ClassName',
     53       'package.className.privateProperty_': 'package.className',
     54       'package.className.privateProperty_.methodName': 'package.className',
     55       'package.ClassName.PrivateEnum_': 'package.ClassName',
     56       'package.ClassName.prototype.methodName.apply': 'package.ClassName',
     57       'package.ClassName.property.subProperty': 'package.ClassName',
     58       'package.className.prototype.something.somethingElse': 'package.className'
     59   }
     60 
     61   def testGetClosurizedNamespace(self):
     62     """Tests that the correct namespace is returned for various identifiers."""
     63     namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
     64         closurized_namespaces=['package'], ignored_extra_namespaces=[])
     65     for identifier, expected_namespace in self._test_cases.items():
     66       actual_namespace = namespaces_info.GetClosurizedNamespace(identifier)
     67       self.assertEqual(
     68           expected_namespace,
     69           actual_namespace,
     70           'expected namespace "' + str(expected_namespace) +
     71           '" for identifier "' + str(identifier) + '" but was "' +
     72           str(actual_namespace) + '"')
     73 
     74   def testIgnoredExtraNamespaces(self):
     75     """Tests that ignored_extra_namespaces are ignored."""
     76     token = self._GetRequireTokens('package.Something')
     77     namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
     78         closurized_namespaces=['package'],
     79         ignored_extra_namespaces=['package.Something'])
     80 
     81     self.assertFalse(namespaces_info.IsExtraRequire(token),
     82                      'Should be valid since it is in ignored namespaces.')
     83 
     84     namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
     85         ['package'], [])
     86 
     87     self.assertTrue(namespaces_info.IsExtraRequire(token),
     88                     'Should be invalid since it is not in ignored namespaces.')
     89 
     90   def testIsExtraProvide_created(self):
     91     """Tests that provides for created namespaces are not extra."""
     92     input_lines = [
     93         'goog.provide(\'package.Foo\');',
     94         'package.Foo = function() {};'
     95     ]
     96 
     97     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
     98         input_lines, ['package'])
     99 
    100     self.assertFalse(namespaces_info.IsExtraProvide(token),
    101                      'Should not be extra since it is created.')
    102 
    103   def testIsExtraProvide_createdIdentifier(self):
    104     """Tests that provides for created identifiers are not extra."""
    105     input_lines = [
    106         'goog.provide(\'package.Foo.methodName\');',
    107         'package.Foo.methodName = function() {};'
    108     ]
    109 
    110     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    111         input_lines, ['package'])
    112 
    113     self.assertFalse(namespaces_info.IsExtraProvide(token),
    114                      'Should not be extra since it is created.')
    115 
    116   def testIsExtraProvide_notCreated(self):
    117     """Tests that provides for non-created namespaces are extra."""
    118     input_lines = ['goog.provide(\'package.Foo\');']
    119 
    120     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    121         input_lines, ['package'])
    122 
    123     self.assertTrue(namespaces_info.IsExtraProvide(token),
    124                     'Should be extra since it is not created.')
    125 
    126   def testIsExtraProvide_duplicate(self):
    127     """Tests that providing a namespace twice makes the second one extra."""
    128     input_lines = [
    129         'goog.provide(\'package.Foo\');',
    130         'goog.provide(\'package.Foo\');',
    131         'package.Foo = function() {};'
    132     ]
    133 
    134     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    135         input_lines, ['package'])
    136 
    137     # Advance to the second goog.provide token.
    138     token = tokenutil.Search(token.next, TokenType.IDENTIFIER)
    139 
    140     self.assertTrue(namespaces_info.IsExtraProvide(token),
    141                     'Should be extra since it is already provided.')
    142 
    143   def testIsExtraProvide_notClosurized(self):
    144     """Tests that provides of non-closurized namespaces are not extra."""
    145     input_lines = ['goog.provide(\'notclosurized.Foo\');']
    146 
    147     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    148         input_lines, ['package'])
    149 
    150     self.assertFalse(namespaces_info.IsExtraProvide(token),
    151                      'Should not be extra since it is not closurized.')
    152 
    153   def testIsExtraRequire_used(self):
    154     """Tests that requires for used namespaces are not extra."""
    155     input_lines = [
    156         'goog.require(\'package.Foo\');',
    157         'var x = package.Foo.methodName();'
    158     ]
    159 
    160     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    161         input_lines, ['package'])
    162 
    163     self.assertFalse(namespaces_info.IsExtraRequire(token),
    164                      'Should not be extra since it is used.')
    165 
    166   def testIsExtraRequire_usedIdentifier(self):
    167     """Tests that requires for used methods on classes are extra."""
    168     input_lines = [
    169         'goog.require(\'package.Foo.methodName\');',
    170         'var x = package.Foo.methodName();'
    171     ]
    172 
    173     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    174         input_lines, ['package'])
    175 
    176     self.assertTrue(namespaces_info.IsExtraRequire(token),
    177                     'Should require the package, not the method specifically.')
    178 
    179   def testIsExtraRequire_notUsed(self):
    180     """Tests that requires for unused namespaces are extra."""
    181     input_lines = ['goog.require(\'package.Foo\');']
    182 
    183     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    184         input_lines, ['package'])
    185 
    186     self.assertTrue(namespaces_info.IsExtraRequire(token),
    187                     'Should be extra since it is not used.')
    188 
    189   def testIsExtraRequire_notClosurized(self):
    190     """Tests that requires of non-closurized namespaces are not extra."""
    191     input_lines = ['goog.require(\'notclosurized.Foo\');']
    192 
    193     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    194         input_lines, ['package'])
    195 
    196     self.assertFalse(namespaces_info.IsExtraRequire(token),
    197                      'Should not be extra since it is not closurized.')
    198 
    199   def testIsExtraRequire_objectOnClass(self):
    200     """Tests that requiring an object on a class is extra."""
    201     input_lines = [
    202         'goog.require(\'package.Foo.Enum\');',
    203         'var x = package.Foo.Enum.VALUE1;',
    204     ]
    205 
    206     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    207         input_lines, ['package'])
    208 
    209     self.assertTrue(namespaces_info.IsExtraRequire(token),
    210                     'The whole class, not the object, should be required.');
    211 
    212   def testIsExtraRequire_constantOnClass(self):
    213     """Tests that requiring a constant on a class is extra."""
    214     input_lines = [
    215         'goog.require(\'package.Foo.CONSTANT\');',
    216         'var x = package.Foo.CONSTANT',
    217     ]
    218 
    219     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    220         input_lines, ['package'])
    221 
    222     self.assertTrue(namespaces_info.IsExtraRequire(token),
    223                     'The class, not the constant, should be required.');
    224 
    225   def testIsExtraRequire_constantNotOnClass(self):
    226     """Tests that requiring a constant not on a class is OK."""
    227     input_lines = [
    228         'goog.require(\'package.subpackage.CONSTANT\');',
    229         'var x = package.subpackage.CONSTANT',
    230     ]
    231 
    232     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    233         input_lines, ['package'])
    234 
    235     self.assertFalse(namespaces_info.IsExtraRequire(token),
    236                     'Constants can be required except on classes.');
    237 
    238   def testIsExtraRequire_methodNotOnClass(self):
    239     """Tests that requiring a method not on a class is OK."""
    240     input_lines = [
    241         'goog.require(\'package.subpackage.method\');',
    242         'var x = package.subpackage.method()',
    243     ]
    244 
    245     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    246         input_lines, ['package'])
    247 
    248     self.assertFalse(namespaces_info.IsExtraRequire(token),
    249                     'Methods can be required except on classes.');
    250 
    251   def testIsExtraRequire_defaults(self):
    252     """Tests that there are no warnings about extra requires for test utils"""
    253     input_lines = ['goog.require(\'goog.testing.jsunit\');']
    254 
    255     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    256         input_lines, ['goog'])
    257 
    258     self.assertFalse(namespaces_info.IsExtraRequire(token),
    259                      'Should not be extra since it is for testing.')
    260 
    261   def testGetMissingProvides_provided(self):
    262     """Tests that provided functions don't cause a missing provide."""
    263     input_lines = [
    264         'goog.provide(\'package.Foo\');',
    265         'package.Foo = function() {};'
    266     ]
    267 
    268     namespaces_info = self._GetNamespacesInfoForScript(
    269         input_lines, ['package'])
    270 
    271     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    272 
    273   def testGetMissingProvides_providedIdentifier(self):
    274     """Tests that provided identifiers don't cause a missing provide."""
    275     input_lines = [
    276         'goog.provide(\'package.Foo.methodName\');',
    277         'package.Foo.methodName = function() {};'
    278     ]
    279 
    280     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    281     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    282 
    283   def testGetMissingProvides_providedParentIdentifier(self):
    284     """Tests that provided identifiers on a class don't cause a missing provide
    285     on objects attached to that class."""
    286     input_lines = [
    287         'goog.provide(\'package.foo.ClassName\');',
    288         'package.foo.ClassName.methodName = function() {};',
    289         'package.foo.ClassName.ObjectName = 1;',
    290     ]
    291 
    292     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    293     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    294 
    295   def testGetMissingProvides_unprovided(self):
    296     """Tests that unprovided functions cause a missing provide."""
    297     input_lines = ['package.Foo = function() {};']
    298 
    299     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    300 
    301     missing_provides = namespaces_info.GetMissingProvides()
    302     self.assertEquals(1, len(missing_provides))
    303     missing_provide = missing_provides.popitem()
    304     self.assertEquals('package.Foo', missing_provide[0])
    305     self.assertEquals(1, missing_provide[1])
    306 
    307   def testGetMissingProvides_privatefunction(self):
    308     """Tests that unprovided private functions don't cause a missing provide."""
    309     input_lines = ['package.Foo_ = function() {};']
    310 
    311     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    312     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    313 
    314   def testGetMissingProvides_required(self):
    315     """Tests that required namespaces don't cause a missing provide."""
    316     input_lines = [
    317         'goog.require(\'package.Foo\');',
    318         'package.Foo.methodName = function() {};'
    319     ]
    320 
    321     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    322     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    323 
    324   def testGetMissingRequires_required(self):
    325     """Tests that required namespaces don't cause a missing require."""
    326     input_lines = [
    327         'goog.require(\'package.Foo\');',
    328         'package.Foo();'
    329     ]
    330 
    331     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    332     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    333 
    334   def testGetMissingRequires_requiredIdentifier(self):
    335     """Tests that required namespaces satisfy identifiers on that namespace."""
    336     input_lines = [
    337         'goog.require(\'package.Foo\');',
    338         'package.Foo.methodName();'
    339     ]
    340 
    341     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    342     self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
    343 
    344   def testGetMissingRequires_requiredParentClass(self):
    345     """Tests that requiring a parent class of an object is sufficient to prevent
    346     a missing require on that object."""
    347     input_lines = [
    348         'goog.require(\'package.Foo\');',
    349         'package.Foo.methodName();',
    350         'package.Foo.methodName(package.Foo.ObjectName);'
    351     ]
    352 
    353     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    354     self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
    355 
    356   def testGetMissingRequires_unrequired(self):
    357     """Tests that unrequired namespaces cause a missing require."""
    358     input_lines = ['package.Foo();']
    359 
    360     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    361 
    362     missing_requires = namespaces_info.GetMissingRequires()
    363     self.assertEquals(1, len(missing_requires))
    364     missing_req = missing_requires.popitem()
    365     self.assertEquals('package.Foo', missing_req[0])
    366     self.assertEquals(1, missing_req[1])
    367 
    368   def testGetMissingRequires_provided(self):
    369     """Tests that provided namespaces satisfy identifiers on that namespace."""
    370     input_lines = [
    371         'goog.provide(\'package.Foo\');',
    372         'package.Foo.methodName();'
    373     ]
    374 
    375     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    376     self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
    377 
    378   def testGetMissingRequires_created(self):
    379     """Tests that created namespaces do not satisfy usage of an identifier."""
    380     input_lines = [
    381         'package.Foo = function();',
    382         'package.Foo.methodName();',
    383         'package.Foo.anotherMethodName1();',
    384         'package.Foo.anotherMethodName2();'
    385     ]
    386 
    387     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    388 
    389     missing_requires = namespaces_info.GetMissingRequires()
    390     self.assertEquals(1, len(missing_requires))
    391     missing_require = missing_requires.popitem()
    392     self.assertEquals('package.Foo', missing_require[0])
    393     # Make sure line number of first occurrence is reported
    394     self.assertEquals(2, missing_require[1])
    395 
    396   def testGetMissingRequires_createdIdentifier(self):
    397     """Tests that created identifiers satisfy usage of the identifier."""
    398     input_lines = [
    399         'package.Foo.methodName = function();',
    400         'package.Foo.methodName();'
    401     ]
    402 
    403     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    404     self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
    405 
    406   def testGetMissingRequires_objectOnClass(self):
    407     """Tests that we should require a class, not the object on the class."""
    408     input_lines = [
    409         'goog.require(\'package.Foo.Enum\');',
    410         'var x = package.Foo.Enum.VALUE1;',
    411     ]
    412 
    413     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package'])
    414     self.assertEquals(1, len(namespaces_info.GetMissingRequires()),
    415                       'The whole class, not the object, should be required.')
    416 
    417   def testGetMissingRequires_variableWithSameName(self):
    418     """Tests that we should not goog.require variables and parameters.
    419 
    420     b/5362203 Variables in scope are not missing namespaces.
    421     """
    422     input_lines = [
    423         'goog.provide(\'Foo\');',
    424         'Foo.A = function();',
    425         'Foo.A.prototype.method = function(ab) {',
    426         '  if (ab) {',
    427         '    var docs;',
    428         '    var lvalue = new Obj();',
    429         '    // Variable in scope hence not goog.require here.',
    430         '    docs.foo.abc = 1;',
    431         '    lvalue.next();',
    432         '  }',
    433         '  // Since js is function scope this should also not goog.require.',
    434         '  docs.foo.func();',
    435         '  // Its not a variable in scope hence goog.require.',
    436         '  dummy.xyz.reset();',
    437         ' return this.method2();',
    438         '};',
    439         'Foo.A.prototype.method1 = function(docs, abcd, xyz) {',
    440         '  // Parameter hence not goog.require.',
    441         '  docs.nodes.length = 2;',
    442         '  lvalue.abc.reset();',
    443         '};'
    444     ]
    445 
    446     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['Foo',
    447                                                                      'docs',
    448                                                                      'lvalue',
    449                                                                      'dummy'])
    450     missing_requires = namespaces_info.GetMissingRequires()
    451     self.assertEquals(2, len(missing_requires))
    452     self.assertItemsEqual(
    453         {'dummy.xyz': 14,
    454          'lvalue.abc': 20}, missing_requires)
    455 
    456   def testIsFirstProvide(self):
    457     """Tests operation of the isFirstProvide method."""
    458     input_lines = [
    459         'goog.provide(\'package.Foo\');',
    460         'package.Foo.methodName();'
    461     ]
    462 
    463     token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    464         input_lines, ['package'])
    465     self.assertTrue(namespaces_info.IsFirstProvide(token))
    466 
    467   def testGetWholeIdentifierString(self):
    468     """Tests that created identifiers satisfy usage of the identifier."""
    469     input_lines = [
    470         'package.Foo.',
    471         '    veryLong.',
    472         '    identifier;'
    473     ]
    474 
    475     token = testutil.TokenizeSource(input_lines)
    476 
    477     self.assertEquals('package.Foo.veryLong.identifier',
    478                       tokenutil.GetIdentifierForToken(token))
    479 
    480     self.assertEquals(None,
    481                       tokenutil.GetIdentifierForToken(token.next))
    482 
    483   def testScopified(self):
    484     """Tests that a goog.scope call is noticed."""
    485     input_lines = [
    486         'goog.scope(function() {',
    487         '});'
    488         ]
    489 
    490     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog'])
    491     self.assertTrue(namespaces_info._scopified_file)
    492 
    493   def testScope_unusedAlias(self):
    494     """Tests that an used alias symbol doesn't result in a require."""
    495     input_lines = [
    496         'goog.scope(function() {',
    497         'var Event = goog.events.Event;',
    498         '});'
    499         ]
    500 
    501     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog'])
    502     missing_requires = namespaces_info.GetMissingRequires()
    503     self.assertEquals({}, missing_requires)
    504 
    505   def testScope_usedAlias(self):
    506     """Tests that aliased symbols result in correct requires."""
    507     input_lines = [
    508         'goog.scope(function() {',
    509         'var Event = goog.events.Event;',
    510         'var dom = goog.dom;',
    511         'Event(dom.classes.get);',
    512         '});'
    513         ]
    514 
    515     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog'])
    516     missing_requires = namespaces_info.GetMissingRequires()
    517     self.assertEquals({'goog.dom.classes': 4, 'goog.events.Event': 4},
    518                       missing_requires)
    519 
    520   def testScope_provides(self):
    521     """Tests that aliased symbols result in correct provides."""
    522     input_lines = [
    523         'goog.scope(function() {',
    524         'goog.bar = {};',
    525         'var bar = goog.bar;',
    526         'bar.Foo = {};',
    527         '});'
    528         ]
    529 
    530     namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog'])
    531     missing_provides = namespaces_info.GetMissingProvides()
    532     self.assertEquals({'goog.bar.Foo': 4}, missing_provides)
    533 
    534   def testSetTestOnlyNamespaces(self):
    535     """Tests that a namespace in setTestOnly makes it a valid provide."""
    536     namespaces_info = self._GetNamespacesInfoForScript([
    537         'goog.setTestOnly(\'goog.foo.barTest\');'
    538         ], ['goog'])
    539 
    540     token = self._GetProvideTokens('goog.foo.barTest')
    541     self.assertFalse(namespaces_info.IsExtraProvide(token))
    542 
    543     token = self._GetProvideTokens('goog.foo.bazTest')
    544     self.assertTrue(namespaces_info.IsExtraProvide(token))
    545 
    546   def testSetTestOnlyComment(self):
    547     """Ensure a comment in setTestOnly does not cause a created namespace."""
    548     namespaces_info = self._GetNamespacesInfoForScript([
    549         'goog.setTestOnly(\'this is a comment\');'
    550         ], ['goog'])
    551 
    552     self.assertEquals(
    553         [], namespaces_info._created_namespaces,
    554         'A comment in setTestOnly should not modify created namespaces.')
    555 
    556   def _GetNamespacesInfoForScript(self, script, closurized_namespaces=None):
    557     _, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript(
    558         script, closurized_namespaces)
    559 
    560     return namespaces_info
    561 
    562   def _GetStartTokenAndNamespacesInfoForScript(
    563       self, script, closurized_namespaces):
    564 
    565     token = testutil.TokenizeSource(script)
    566     return token, self._GetInitializedNamespacesInfo(
    567         token, closurized_namespaces, [])
    568 
    569   def _GetInitializedNamespacesInfo(self, token, closurized_namespaces,
    570                                     ignored_extra_namespaces):
    571     """Returns a namespaces info initialized with the given token stream."""
    572     namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
    573         closurized_namespaces=closurized_namespaces,
    574         ignored_extra_namespaces=ignored_extra_namespaces)
    575     state_tracker = javascriptstatetracker.JavaScriptStateTracker()
    576 
    577     ecma_pass = ecmametadatapass.EcmaMetaDataPass()
    578     ecma_pass.Process(token)
    579 
    580     alias_pass = aliaspass.AliasPass(closurized_namespaces)
    581     alias_pass.Process(token)
    582 
    583     while token:
    584       state_tracker.HandleToken(token, state_tracker.GetLastNonSpaceToken())
    585       namespaces_info.ProcessToken(token, state_tracker)
    586       state_tracker.HandleAfterToken(token)
    587       token = token.next
    588 
    589     return namespaces_info
    590 
    591   def _GetProvideTokens(self, namespace):
    592     """Returns a list of tokens for a goog.require of the given namespace."""
    593     line_text = 'goog.require(\'' + namespace + '\');\n'
    594     return testutil.TokenizeSource([line_text])
    595 
    596   def _GetRequireTokens(self, namespace):
    597     """Returns a list of tokens for a goog.require of the given namespace."""
    598     line_text = 'goog.require(\'' + namespace + '\');\n'
    599     return testutil.TokenizeSource([line_text])
    600 
    601 if __name__ == '__main__':
    602   googletest.main()
    603