Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: third_party/closure_linter/closure_linter/scopeutil_test.py

Issue 2592193002: Remove closure_linter from Chrome (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright 2012 The Closure Linter Authors. All Rights Reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS-IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """Unit tests for the scopeutil module."""
17
18 # Allow non-Google copyright
19 # pylint: disable=g-bad-file-header
20
21 __author__ = ('nnaze@google.com (Nathan Naze)')
22
23
24 import unittest as googletest
25
26 from closure_linter import ecmametadatapass
27 from closure_linter import scopeutil
28 from closure_linter import testutil
29
30
31 def _FindContexts(start_token):
32 """Depth first search of all contexts referenced by a token stream.
33
34 Includes contexts' parents, which might not be directly referenced
35 by any token in the stream.
36
37 Args:
38 start_token: First token in the token stream.
39
40 Yields:
41 All contexts referenced by this token stream.
42 """
43
44 seen_contexts = set()
45
46 # For each token, yield the context if we haven't seen it before.
47 for token in start_token:
48
49 token_context = token.metadata.context
50 contexts = [token_context]
51
52 # Also grab all the context's ancestors.
53 parent = token_context.parent
54 while parent:
55 contexts.append(parent)
56 parent = parent.parent
57
58 # Yield each of these contexts if we've not seen them.
59 for context in contexts:
60 if context not in seen_contexts:
61 yield context
62
63 seen_contexts.add(context)
64
65
66 def _FindFirstContextOfType(token, context_type):
67 """Returns the first statement context."""
68 for context in _FindContexts(token):
69 if context.type == context_type:
70 return context
71
72
73 def _ParseAssignment(script):
74 start_token = testutil.TokenizeSourceAndRunEcmaPass(script)
75 statement = _FindFirstContextOfType(
76 start_token, ecmametadatapass.EcmaContext.VAR)
77 return statement
78
79
80 class StatementTest(googletest.TestCase):
81
82 def assertAlias(self, expected_match, script):
83 statement = _ParseAssignment(script)
84 match = scopeutil.MatchAlias(statement)
85 self.assertEquals(expected_match, match)
86
87 def assertModuleAlias(self, expected_match, script):
88 statement = _ParseAssignment(script)
89 match = scopeutil.MatchModuleAlias(statement)
90 self.assertEquals(expected_match, match)
91
92 def testSimpleAliases(self):
93 self.assertAlias(
94 ('foo', 'goog.foo'),
95 'var foo = goog.foo;')
96
97 self.assertAlias(
98 ('foo', 'goog.foo'),
99 'var foo = goog.foo') # No semicolon
100
101 def testAliasWithComment(self):
102 self.assertAlias(
103 ('Component', 'goog.ui.Component'),
104 'var Component = /* comment */ goog.ui.Component;')
105
106 def testMultilineAlias(self):
107 self.assertAlias(
108 ('Component', 'goog.ui.Component'),
109 'var Component = \n goog.ui.\n Component;')
110
111 def testNonSymbolAliasVarStatements(self):
112 self.assertAlias(None, 'var foo = 3;')
113 self.assertAlias(None, 'var foo = function() {};')
114 self.assertAlias(None, 'var foo = bar ? baz : qux;')
115
116 def testModuleAlias(self):
117 self.assertModuleAlias(
118 ('foo', 'goog.foo'),
119 'var foo = goog.require("goog.foo");')
120 self.assertModuleAlias(
121 None,
122 'var foo = goog.require(notastring);')
123
124
125 class ScopeBlockTest(googletest.TestCase):
126
127 @staticmethod
128 def _GetBlocks(source):
129 start_token = testutil.TokenizeSourceAndRunEcmaPass(source)
130 for context in _FindContexts(start_token):
131 if context.type is ecmametadatapass.EcmaContext.BLOCK:
132 yield context
133
134 def assertNoBlocks(self, script):
135 blocks = list(self._GetBlocks(script))
136 self.assertEquals([], blocks)
137
138 def testNotBlocks(self):
139 # Ensure these are not considered blocks.
140 self.assertNoBlocks('goog.scope(if{});')
141 self.assertNoBlocks('goog.scope(for{});')
142 self.assertNoBlocks('goog.scope(switch{});')
143 self.assertNoBlocks('goog.scope(function foo{});')
144
145 def testNonScopeBlocks(self):
146
147 blocks = list(self._GetBlocks('goog.scope(try{});'))
148 self.assertEquals(1, len(blocks))
149 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
150
151 blocks = list(self._GetBlocks('goog.scope(function(a,b){});'))
152 self.assertEquals(1, len(blocks))
153 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
154
155 blocks = list(self._GetBlocks('goog.scope(try{} catch(){});'))
156 # Two blocks: try and catch.
157 self.assertEquals(2, len(blocks))
158 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
159 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
160
161 blocks = list(self._GetBlocks('goog.scope(try{} catch(){} finally {});'))
162 self.assertEquals(3, len(blocks))
163 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
164 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
165 self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop()))
166
167
168 class AliasTest(googletest.TestCase):
169
170 def setUp(self):
171 self.start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_SCRIPT)
172
173 def testMatchAliasStatement(self):
174 matches = set()
175 for context in _FindContexts(self.start_token):
176 match = scopeutil.MatchAlias(context)
177 if match:
178 matches.add(match)
179
180 self.assertEquals(
181 set([('bar', 'baz'),
182 ('foo', 'this.foo_'),
183 ('Component', 'goog.ui.Component'),
184 ('MyClass', 'myproject.foo.MyClass'),
185 ('NonClosurizedClass', 'aaa.bbb.NonClosurizedClass')]),
186 matches)
187
188 def testMatchAliasStatement_withClosurizedNamespaces(self):
189
190 closurized_namepaces = frozenset(['goog', 'myproject'])
191
192 matches = set()
193 for context in _FindContexts(self.start_token):
194 match = scopeutil.MatchAlias(context)
195 if match:
196 unused_alias, symbol = match
197 if scopeutil.IsInClosurizedNamespace(symbol, closurized_namepaces):
198 matches.add(match)
199
200 self.assertEquals(
201 set([('MyClass', 'myproject.foo.MyClass'),
202 ('Component', 'goog.ui.Component')]),
203 matches)
204
205 _TEST_SCRIPT = """
206 goog.scope(function() {
207 var Component = goog.ui.Component; // scope alias
208 var MyClass = myproject.foo.MyClass; // scope alias
209
210 // Scope alias of non-Closurized namespace.
211 var NonClosurizedClass = aaa.bbb.NonClosurizedClass;
212
213 var foo = this.foo_; // non-scope object property alias
214 var bar = baz; // variable alias
215
216 var component = new Component();
217 });
218
219 """
220
221 if __name__ == '__main__':
222 googletest.main()
OLDNEW
« no previous file with comments | « third_party/closure_linter/closure_linter/scopeutil.py ('k') | third_party/closure_linter/closure_linter/statetracker.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698