aboutsummaryrefslogtreecommitdiff
path: root/tools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py')
-rwxr-xr-xtools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py451
1 files changed, 451 insertions, 0 deletions
diff --git a/tools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py b/tools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py
new file mode 100755
index 0000000..9a4c578
--- /dev/null
+++ b/tools/closure_linter-2.3.4/closure_linter/closurizednamespacesinfo_test.py
@@ -0,0 +1,451 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 The Closure Linter Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for ClosurizedNamespacesInfo."""
+
+
+
+import unittest as googletest
+from closure_linter import closurizednamespacesinfo
+from closure_linter import javascriptstatetracker
+from closure_linter import javascripttokenizer
+from closure_linter import javascripttokens
+from closure_linter import tokenutil
+
+# pylint: disable-msg=C6409
+TokenType = javascripttokens.JavaScriptTokenType
+
+
+class ClosurizedNamespacesInfoTest(googletest.TestCase):
+ """Tests for ClosurizedNamespacesInfo."""
+
+ _test_cases = {
+ 'goog.global.anything': None,
+ 'package.CONSTANT': 'package',
+ 'package.methodName': 'package',
+ 'package.subpackage.methodName': 'package.subpackage',
+ 'package.subpackage.methodName.apply': 'package.subpackage',
+ 'package.ClassName.something': 'package.ClassName',
+ 'package.ClassName.Enum.VALUE.methodName': 'package.ClassName',
+ 'package.ClassName.CONSTANT': 'package.ClassName',
+ 'package.namespace.CONSTANT.methodName': 'package.namespace',
+ 'package.ClassName.inherits': 'package.ClassName',
+ 'package.ClassName.apply': 'package.ClassName',
+ 'package.ClassName.methodName.apply': 'package.ClassName',
+ 'package.ClassName.methodName.call': 'package.ClassName',
+ 'package.ClassName.prototype.methodName': 'package.ClassName',
+ 'package.ClassName.privateMethod_': 'package.ClassName',
+ 'package.className.privateProperty_': 'package.className',
+ 'package.className.privateProperty_.methodName': 'package.className',
+ 'package.ClassName.PrivateEnum_': 'package.ClassName',
+ 'package.ClassName.prototype.methodName.apply': 'package.ClassName',
+ 'package.ClassName.property.subProperty': 'package.ClassName',
+ 'package.className.prototype.something.somethingElse': 'package.className'
+ }
+
+ _tokenizer = javascripttokenizer.JavaScriptTokenizer()
+
+ def testGetClosurizedNamespace(self):
+ """Tests that the correct namespace is returned for various identifiers."""
+ namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
+ closurized_namespaces=['package'], ignored_extra_namespaces=[])
+ for identifier, expected_namespace in self._test_cases.items():
+ actual_namespace = namespaces_info._GetClosurizedNamespace(identifier)
+ self.assertEqual(
+ expected_namespace,
+ actual_namespace,
+ 'expected namespace "' + str(expected_namespace) +
+ '" for identifier "' + str(identifier) + '" but was "' +
+ str(actual_namespace) + '"')
+
+ def testIgnoredExtraNamespaces(self):
+ """Tests that ignored_extra_namespaces are ignored."""
+ token = self._GetRequireTokens('package.Something')
+ namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
+ closurized_namespaces=['package'],
+ ignored_extra_namespaces=['package.Something'])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Should be valid since it is in ignored namespaces.')
+
+ namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
+ ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraRequire(token),
+ 'Should be invalid since it is not in ignored namespaces.')
+
+ def testIsExtraProvide_created(self):
+ """Tests that provides for created namespaces are not extra."""
+ input_lines = [
+ 'goog.provide(\'package.Foo\');',
+ 'package.Foo = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraProvide(token),
+ 'Should not be extra since it is created.')
+
+ def testIsExtraProvide_createdIdentifier(self):
+ """Tests that provides for created identifiers are not extra."""
+ input_lines = [
+ 'goog.provide(\'package.Foo.methodName\');',
+ 'package.Foo.methodName = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraProvide(token),
+ 'Should not be extra since it is created.')
+
+ def testIsExtraProvide_notCreated(self):
+ """Tests that provides for non-created namespaces are extra."""
+ input_lines = ['goog.provide(\'package.Foo\');']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraProvide(token),
+ 'Should be extra since it is not created.')
+
+ def testIsExtraProvide_duplicate(self):
+ """Tests that providing a namespace twice makes the second one extra."""
+ input_lines = [
+ 'goog.provide(\'package.Foo\');',
+ 'goog.provide(\'package.Foo\');',
+ 'package.Foo = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ # Advance to the second goog.provide token.
+ token = tokenutil.Search(token.next, TokenType.IDENTIFIER)
+
+ self.assertTrue(namespaces_info.IsExtraProvide(token),
+ 'Should be extra since it is already provided.')
+
+ def testIsExtraProvide_notClosurized(self):
+ """Tests that provides of non-closurized namespaces are not extra."""
+ input_lines = ['goog.provide(\'notclosurized.Foo\');']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraProvide(token),
+ 'Should not be extra since it is not closurized.')
+
+ def testIsExtraRequire_used(self):
+ """Tests that requires for used namespaces are not extra."""
+ input_lines = [
+ 'goog.require(\'package.Foo\');',
+ 'var x = package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Should not be extra since it is used.')
+
+ def testIsExtraRequire_usedIdentifier(self):
+ """Tests that requires for used methods on classes are extra."""
+ input_lines = [
+ 'goog.require(\'package.Foo.methodName\');',
+ 'var x = package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraRequire(token),
+ 'Should require the package, not the method specifically.')
+
+ def testIsExtraRequire_notUsed(self):
+ """Tests that requires for unused namespaces are extra."""
+ input_lines = ['goog.require(\'package.Foo\');']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraRequire(token),
+ 'Should be extra since it is not used.')
+
+ def testIsExtraRequire_notClosurized(self):
+ """Tests that requires of non-closurized namespaces are not extra."""
+ input_lines = ['goog.require(\'notclosurized.Foo\');']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Should not be extra since it is not closurized.')
+
+ def testIsExtraRequire_objectOnClass(self):
+ """Tests that requiring an object on a class is extra."""
+ input_lines = [
+ 'goog.require(\'package.Foo.Enum\');',
+ 'var x = package.Foo.Enum.VALUE1;',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraRequire(token),
+ 'The whole class, not the object, should be required.');
+
+ def testIsExtraRequire_constantOnClass(self):
+ """Tests that requiring a constant on a class is extra."""
+ input_lines = [
+ 'goog.require(\'package.Foo.CONSTANT\');',
+ 'var x = package.Foo.CONSTANT',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsExtraRequire(token),
+ 'The class, not the constant, should be required.');
+
+ def testIsExtraRequire_constantNotOnClass(self):
+ """Tests that requiring a constant not on a class is OK."""
+ input_lines = [
+ 'goog.require(\'package.subpackage.CONSTANT\');',
+ 'var x = package.subpackage.CONSTANT',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Constants can be required except on classes.');
+
+ def testIsExtraRequire_methodNotOnClass(self):
+ """Tests that requiring a method not on a class is OK."""
+ input_lines = [
+ 'goog.require(\'package.subpackage.method\');',
+ 'var x = package.subpackage.method()',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Methods can be required except on classes.');
+
+ def testIsExtraRequire_defaults(self):
+ """Tests that there are no warnings about extra requires for test utils"""
+ input_lines = ['goog.require(\'goog.testing.jsunit\');']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['goog'], [])
+
+ self.assertFalse(namespaces_info.IsExtraRequire(token),
+ 'Should not be extra since it is for testing.')
+
+ def testGetMissingProvides_provided(self):
+ """Tests that provided functions don't cause a missing provide."""
+ input_lines = [
+ 'goog.provide(\'package.Foo\');',
+ 'package.Foo = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingProvides_providedIdentifier(self):
+ """Tests that provided identifiers don't cause a missing provide."""
+ input_lines = [
+ 'goog.provide(\'package.Foo.methodName\');',
+ 'package.Foo.methodName = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingProvides_providedParentIdentifier(self):
+ """Tests that provided identifiers on a class don't cause a missing provide
+ on objects attached to that class."""
+ input_lines = [
+ 'goog.provide(\'package.foo.ClassName\');',
+ 'package.foo.ClassName.methodName = function() {};',
+ 'package.foo.ClassName.ObjectName = 1;',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingProvides_unprovided(self):
+ """Tests that unprovided functions cause a missing provide."""
+ input_lines = ['package.Foo = function() {};']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(1, len(namespaces_info.GetMissingProvides()))
+ self.assertTrue('package.Foo' in namespaces_info.GetMissingProvides())
+
+ def testGetMissingProvides_privatefunction(self):
+ """Tests that unprovided private functions don't cause a missing provide."""
+ input_lines = ['package.Foo_ = function() {};']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingProvides_required(self):
+ """Tests that required namespaces don't cause a missing provide."""
+ input_lines = [
+ 'goog.require(\'package.Foo\');',
+ 'package.Foo.methodName = function() {};'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingRequires_required(self):
+ """Tests that required namespaces don't cause a missing require."""
+ input_lines = [
+ 'goog.require(\'package.Foo\');',
+ 'package.Foo();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingRequires_requiredIdentifier(self):
+ """Tests that required namespaces satisfy identifiers on that namespace."""
+ input_lines = [
+ 'goog.require(\'package.Foo\');',
+ 'package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingProvides()))
+
+ def testGetMissingRequires_requiredParentClass(self):
+ """Tests that requiring a parent class of an object is sufficient to prevent
+ a missing require on that object."""
+ input_lines = [
+ 'goog.require(\'package.Foo\');',
+ 'package.Foo.methodName();',
+ 'package.Foo.methodName(package.Foo.ObjectName);'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
+
+ def testGetMissingRequires_unrequired(self):
+ """Tests that unrequired namespaces cause a missing require."""
+ input_lines = ['package.Foo();']
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(1, len(namespaces_info.GetMissingRequires()))
+ self.assertTrue('package.Foo' in namespaces_info.GetMissingRequires())
+
+ def testGetMissingRequires_provided(self):
+ """Tests that provided namespaces satisfy identifiers on that namespace."""
+ input_lines = [
+ 'goog.provide(\'package.Foo\');',
+ 'package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
+
+ def testGetMissingRequires_created(self):
+ """Tests that created namespaces do not satisfy usage of an identifier."""
+ input_lines = [
+ 'package.Foo = function();',
+ 'package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(1, len(namespaces_info.GetMissingRequires()))
+ self.assertTrue('package.Foo' in namespaces_info.GetMissingRequires())
+
+ def testGetMissingRequires_createdIdentifier(self):
+ """Tests that created identifiers satisfy usage of the identifier."""
+ input_lines = [
+ 'package.Foo.methodName = function();',
+ 'package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(0, len(namespaces_info.GetMissingRequires()))
+
+ def testGetMissingRequires_objectOnClass(self):
+ """Tests that we should require a class, not the object on the class."""
+ input_lines = [
+ 'goog.require(\'package.Foo.Enum\');',
+ 'var x = package.Foo.Enum.VALUE1;',
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertEquals(1, len(namespaces_info.GetMissingRequires()),
+ 'The whole class, not the object, should be required.');
+
+ def testIsFirstProvide(self):
+ """Tests operation of the isFirstProvide method."""
+ input_lines = [
+ 'goog.provide(\'package.Foo\');',
+ 'package.Foo.methodName();'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = self._GetInitializedNamespacesInfo(token, ['package'], [])
+
+ self.assertTrue(namespaces_info.IsFirstProvide(token))
+
+ def testGetWholeIdentifierString(self):
+ """Tests that created identifiers satisfy usage of the identifier."""
+ input_lines = [
+ 'package.Foo.',
+ ' veryLong.',
+ ' identifier;'
+ ]
+ token = self._tokenizer.TokenizeFile(input_lines)
+ namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo([], [])
+
+ self.assertEquals('package.Foo.veryLong.identifier',
+ namespaces_info._GetWholeIdentifierString(token))
+ self.assertEquals(None,
+ namespaces_info._GetWholeIdentifierString(token.next))
+
+ def _GetInitializedNamespacesInfo(self, token, closurized_namespaces,
+ ignored_extra_namespaces):
+ """Returns a namespaces info initialized with the given token stream."""
+ namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo(
+ closurized_namespaces=closurized_namespaces,
+ ignored_extra_namespaces=ignored_extra_namespaces)
+ state_tracker = javascriptstatetracker.JavaScriptStateTracker()
+
+ while token:
+ namespaces_info.ProcessToken(token, state_tracker)
+ token = token.next
+
+ return namespaces_info
+
+ def _GetProvideTokens(self, namespace):
+ """Returns a list of tokens for a goog.require of the given namespace."""
+ line_text = 'goog.require(\'' + namespace + '\');\n'
+ return javascripttokenizer.JavaScriptTokenizer().TokenizeFile([line_text])
+
+ def _GetRequireTokens(self, namespace):
+ """Returns a list of tokens for a goog.require of the given namespace."""
+ line_text = 'goog.require(\'' + namespace + '\');\n'
+ return javascripttokenizer.JavaScriptTokenizer().TokenizeFile([line_text])
+
+if __name__ == '__main__':
+ googletest.main()