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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 """Unit tests for the javascriptstatetracker module."""
18 # Allow non-Google copyright
19 # pylint: disable=g-bad-file-header
21 __author__ = ('nnaze@google.com (Nathan Naze)')
24 import unittest as googletest
26 from closure_linter import javascripttokens
27 from closure_linter import testutil
28 from closure_linter import tokenutil
31 _FUNCTION_SCRIPT = """\
34 function foo(aaa, bbb, ccc) {
42 var bar = function(ddd, eee, fff) {
48 * Verify that nested functions get their proper parameters recorded.
50 var baz = function(ggg, hhh, iii) {
51 var qux = function(jjj, kkk, lll) {
53 // make sure that entering a new block does not change baz' parameters.
60 class FunctionTest(googletest.TestCase):
62 def testFunctionParse(self):
63 functions, _ = testutil.ParseFunctionsAndComments(_FUNCTION_SCRIPT)
64 self.assertEquals(4, len(functions))
67 function = functions[0]
68 self.assertEquals(['aaa', 'bbb', 'ccc'], function.parameters)
70 start_token = function.start_token
71 end_token = function.end_token
74 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION,
75 function.start_token.type)
77 self.assertEquals('function', start_token.string)
78 self.assertEquals(3, start_token.line_number)
79 self.assertEquals(0, start_token.start_index)
81 self.assertEquals('}', end_token.string)
82 self.assertEquals(5, end_token.line_number)
83 self.assertEquals(0, end_token.start_index)
85 self.assertEquals('foo', function.name)
87 self.assertIsNone(function.doc)
90 function = functions[1]
91 self.assertEquals(['ddd', 'eee', 'fff'], function.parameters)
93 start_token = function.start_token
94 end_token = function.end_token
97 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION,
98 function.start_token.type)
100 self.assertEquals('function', start_token.string)
101 self.assertEquals(11, start_token.line_number)
102 self.assertEquals(10, start_token.start_index)
104 self.assertEquals('}', end_token.string)
105 self.assertEquals(13, end_token.line_number)
106 self.assertEquals(0, end_token.start_index)
108 self.assertEquals('bar', function.name)
110 self.assertIsNotNone(function.doc)
112 # Check function JSDoc
114 doc_tokens = tokenutil.GetTokenRange(doc.start_token, doc.end_token)
116 comment_type = javascripttokens.JavaScriptTokenType.COMMENT
117 comment_tokens = filter(lambda t: t.type is comment_type, doc_tokens)
119 self.assertEquals('JSDoc comment.',
120 tokenutil.TokensToString(comment_tokens).strip())
123 function = functions[2]
124 self.assertEquals(['ggg', 'hhh', 'iii'], function.parameters)
126 start_token = function.start_token
127 end_token = function.end_token
130 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION,
131 function.start_token.type)
133 self.assertEquals('function', start_token.string)
134 self.assertEquals(19, start_token.line_number)
135 self.assertEquals(10, start_token.start_index)
137 self.assertEquals('}', end_token.string)
138 self.assertEquals(24, end_token.line_number)
139 self.assertEquals(0, end_token.start_index)
141 self.assertEquals('baz', function.name)
142 self.assertIsNotNone(function.doc)
144 # Fourth function (inside third function)
145 function = functions[3]
146 self.assertEquals(['jjj', 'kkk', 'lll'], function.parameters)
148 start_token = function.start_token
149 end_token = function.end_token
152 javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION,
153 function.start_token.type)
155 self.assertEquals('function', start_token.string)
156 self.assertEquals(20, start_token.line_number)
157 self.assertEquals(12, start_token.start_index)
159 self.assertEquals('}', end_token.string)
160 self.assertEquals(21, end_token.line_number)
161 self.assertEquals(2, end_token.start_index)
163 self.assertEquals('qux', function.name)
164 self.assertIsNone(function.doc)
168 class CommentTest(googletest.TestCase):
170 def testGetDescription(self):
171 comment = self._ParseComment("""
173 * Comment targeting goog.foo.
175 * This is the second line.
176 * @param {number} foo The count of foo.
181 'Comment targeting goog.foo.\n\nThis is the second line.',
184 def testCommentGetTarget(self):
185 self.assertCommentTarget('goog.foo', """
187 * Comment targeting goog.foo.
192 self.assertCommentTarget('bar', """
194 * Comment targeting bar.
199 self.assertCommentTarget('doThing', """
201 * Comment targeting doThing.
203 function doThing() {};
206 self.assertCommentTarget('this.targetProperty', """
207 goog.bar.Baz = function() {
209 * Comment targeting targetProperty.
211 this.targetProperty = 3;
215 self.assertCommentTarget('goog.bar.prop', """
217 * Comment targeting goog.bar.prop.
222 self.assertCommentTarget('goog.aaa.bbb', """
224 * Comment targeting goog.aaa.bbb.
229 self.assertCommentTarget('theTarget', """
231 * Comment targeting symbol preceded by newlines, whitespace,
232 * and parens -- things we ignore.
237 self.assertCommentTarget(None, """
239 * @fileoverview File overview.
244 self.assertCommentTarget(None, """
246 * Comment that doesn't find a target.
250 self.assertCommentTarget('theTarget.is.split.across.lines', """
252 * Comment that addresses a symbol split across lines.
258 self.assertCommentTarget('theTarget.is.split.across.lines', """
260 * Comment that addresses a symbol split across lines.
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))
272 def assertCommentTarget(self, target, script):
273 comment = self._ParseComment(script)
274 self.assertEquals(target, comment.GetTargetIdentifier())
277 if __name__ == '__main__':