OLD | NEW |
| (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 javascriptstatetracker 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 javascripttokens | |
27 from closure_linter import testutil | |
28 from closure_linter import tokenutil | |
29 | |
30 | |
31 _FUNCTION_SCRIPT = """\ | |
32 var a = 3; | |
33 | |
34 function foo(aaa, bbb, ccc) { | |
35 var b = 4; | |
36 } | |
37 | |
38 | |
39 /** | |
40 * JSDoc comment. | |
41 */ | |
42 var bar = function(ddd, eee, fff) { | |
43 | |
44 }; | |
45 | |
46 | |
47 /** | |
48 * Verify that nested functions get their proper parameters recorded. | |
49 */ | |
50 var baz = function(ggg, hhh, iii) { | |
51 var qux = function(jjj, kkk, lll) { | |
52 }; | |
53 // make sure that entering a new block does not change baz' parameters. | |
54 {}; | |
55 }; | |
56 | |
57 """ | |
58 | |
59 | |
60 class FunctionTest(googletest.TestCase): | |
61 | |
62 def testFunctionParse(self): | |
63 functions, _ = testutil.ParseFunctionsAndComments(_FUNCTION_SCRIPT) | |
64 self.assertEquals(4, len(functions)) | |
65 | |
66 # First function | |
67 function = functions[0] | |
68 self.assertEquals(['aaa', 'bbb', 'ccc'], function.parameters) | |
69 | |
70 start_token = function.start_token | |
71 end_token = function.end_token | |
72 | |
73 self.assertEquals( | |
74 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, | |
75 function.start_token.type) | |
76 | |
77 self.assertEquals('function', start_token.string) | |
78 self.assertEquals(3, start_token.line_number) | |
79 self.assertEquals(0, start_token.start_index) | |
80 | |
81 self.assertEquals('}', end_token.string) | |
82 self.assertEquals(5, end_token.line_number) | |
83 self.assertEquals(0, end_token.start_index) | |
84 | |
85 self.assertEquals('foo', function.name) | |
86 | |
87 self.assertIsNone(function.doc) | |
88 | |
89 # Second function | |
90 function = functions[1] | |
91 self.assertEquals(['ddd', 'eee', 'fff'], function.parameters) | |
92 | |
93 start_token = function.start_token | |
94 end_token = function.end_token | |
95 | |
96 self.assertEquals( | |
97 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, | |
98 function.start_token.type) | |
99 | |
100 self.assertEquals('function', start_token.string) | |
101 self.assertEquals(11, start_token.line_number) | |
102 self.assertEquals(10, start_token.start_index) | |
103 | |
104 self.assertEquals('}', end_token.string) | |
105 self.assertEquals(13, end_token.line_number) | |
106 self.assertEquals(0, end_token.start_index) | |
107 | |
108 self.assertEquals('bar', function.name) | |
109 | |
110 self.assertIsNotNone(function.doc) | |
111 | |
112 # Check function JSDoc | |
113 doc = function.doc | |
114 doc_tokens = tokenutil.GetTokenRange(doc.start_token, doc.end_token) | |
115 | |
116 comment_type = javascripttokens.JavaScriptTokenType.COMMENT | |
117 comment_tokens = filter(lambda t: t.type is comment_type, doc_tokens) | |
118 | |
119 self.assertEquals('JSDoc comment.', | |
120 tokenutil.TokensToString(comment_tokens).strip()) | |
121 | |
122 # Third function | |
123 function = functions[2] | |
124 self.assertEquals(['ggg', 'hhh', 'iii'], function.parameters) | |
125 | |
126 start_token = function.start_token | |
127 end_token = function.end_token | |
128 | |
129 self.assertEquals( | |
130 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, | |
131 function.start_token.type) | |
132 | |
133 self.assertEquals('function', start_token.string) | |
134 self.assertEquals(19, start_token.line_number) | |
135 self.assertEquals(10, start_token.start_index) | |
136 | |
137 self.assertEquals('}', end_token.string) | |
138 self.assertEquals(24, end_token.line_number) | |
139 self.assertEquals(0, end_token.start_index) | |
140 | |
141 self.assertEquals('baz', function.name) | |
142 self.assertIsNotNone(function.doc) | |
143 | |
144 # Fourth function (inside third function) | |
145 function = functions[3] | |
146 self.assertEquals(['jjj', 'kkk', 'lll'], function.parameters) | |
147 | |
148 start_token = function.start_token | |
149 end_token = function.end_token | |
150 | |
151 self.assertEquals( | |
152 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, | |
153 function.start_token.type) | |
154 | |
155 self.assertEquals('function', start_token.string) | |
156 self.assertEquals(20, start_token.line_number) | |
157 self.assertEquals(12, start_token.start_index) | |
158 | |
159 self.assertEquals('}', end_token.string) | |
160 self.assertEquals(21, end_token.line_number) | |
161 self.assertEquals(2, end_token.start_index) | |
162 | |
163 self.assertEquals('qux', function.name) | |
164 self.assertIsNone(function.doc) | |
165 | |
166 | |
167 | |
168 class CommentTest(googletest.TestCase): | |
169 | |
170 def testGetDescription(self): | |
171 comment = self._ParseComment(""" | |
172 /** | |
173 * Comment targeting goog.foo. | |
174 * | |
175 * This is the second line. | |
176 * @param {number} foo The count of foo. | |
177 */ | |
178 target;""") | |
179 | |
180 self.assertEqual( | |
181 'Comment targeting goog.foo.\n\nThis is the second line.', | |
182 comment.description) | |
183 | |
184 def testCommentGetTarget(self): | |
185 self.assertCommentTarget('goog.foo', """ | |
186 /** | |
187 * Comment targeting goog.foo. | |
188 */ | |
189 goog.foo = 6; | |
190 """) | |
191 | |
192 self.assertCommentTarget('bar', """ | |
193 /** | |
194 * Comment targeting bar. | |
195 */ | |
196 var bar = "Karate!"; | |
197 """) | |
198 | |
199 self.assertCommentTarget('doThing', """ | |
200 /** | |
201 * Comment targeting doThing. | |
202 */ | |
203 function doThing() {}; | |
204 """) | |
205 | |
206 self.assertCommentTarget('this.targetProperty', """ | |
207 goog.bar.Baz = function() { | |
208 /** | |
209 * Comment targeting targetProperty. | |
210 */ | |
211 this.targetProperty = 3; | |
212 }; | |
213 """) | |
214 | |
215 self.assertCommentTarget('goog.bar.prop', """ | |
216 /** | |
217 * Comment targeting goog.bar.prop. | |
218 */ | |
219 goog.bar.prop; | |
220 """) | |
221 | |
222 self.assertCommentTarget('goog.aaa.bbb', """ | |
223 /** | |
224 * Comment targeting goog.aaa.bbb. | |
225 */ | |
226 (goog.aaa.bbb) | |
227 """) | |
228 | |
229 self.assertCommentTarget('theTarget', """ | |
230 /** | |
231 * Comment targeting symbol preceded by newlines, whitespace, | |
232 * and parens -- things we ignore. | |
233 */ | |
234 (theTarget) | |
235 """) | |
236 | |
237 self.assertCommentTarget(None, """ | |
238 /** | |
239 * @fileoverview File overview. | |
240 */ | |
241 (notATarget) | |
242 """) | |
243 | |
244 self.assertCommentTarget(None, """ | |
245 /** | |
246 * Comment that doesn't find a target. | |
247 */ | |
248 """) | |
249 | |
250 self.assertCommentTarget('theTarget.is.split.across.lines', """ | |
251 /** | |
252 * Comment that addresses a symbol split across lines. | |
253 */ | |
254 (theTarget.is.split | |
255 .across.lines) | |
256 """) | |
257 | |
258 self.assertCommentTarget('theTarget.is.split.across.lines', """ | |
259 /** | |
260 * Comment that addresses a symbol split across lines. | |
261 */ | |
262 (theTarget.is.split. | |
263 across.lines) | |
264 """) | |
265 | |
266 def _ParseComment(self, script): | |
267 """Parse a script that contains one comment and return it.""" | |
268 _, comments = testutil.ParseFunctionsAndComments(script) | |
269 self.assertEquals(1, len(comments)) | |
270 return comments[0] | |
271 | |
272 def assertCommentTarget(self, target, script): | |
273 comment = self._ParseComment(script) | |
274 self.assertEquals(target, comment.GetTargetIdentifier()) | |
275 | |
276 | |
277 if __name__ == '__main__': | |
278 googletest.main() | |
OLD | NEW |