2 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Test the lint module."""
12 sys.path.insert(0, os.path.abspath('%s/../../..' % os.path.dirname(__file__)))
14 from chromite.lib import cros_test_lib
18 class TestNode(object):
19 """Object good enough to stand in for lint funcs"""
21 Args = collections.namedtuple('Args', ('args', 'vararg', 'kwarg'))
22 Arg = collections.namedtuple('Arg', ('name',))
24 def __init__(self, doc='', fromlineno=0, path='foo.py', args=(), vararg='',
27 self.lines = doc.split('\n')
28 self.fromlineno = fromlineno
30 self.args = self.Args(args=[self.Arg(name=x) for x in args],
31 vararg=vararg, kwarg=kwarg)
37 class DocStringCheckerTest(cros_test_lib.TestCase):
38 """Tests for DocStringChecker module"""
40 GOOD_FUNC_DOCSTRINGS = (
70 BAD_FUNC_DOCSTRINGS = (
74 """ whitespace is wrong""",
75 """whitespace is wrong """,
76 """Should be no trailing blank lines
85 """we want Args/Returns not Arguments/Return
90 """section order is wrong here
95 """sections lack whitespace between them
102 """yields is misspelled
107 """Section name has bad spacing
112 """too many blank lines
118 """wrongly uses javadoc
124 # The current linter isn't good enough yet to detect these.
125 TODO_BAD_FUNC_DOCSTRINGS = (
126 """The returns section isn't a proper section
133 """the indentation is incorrect
140 def add_message(self, msg_id, node=None, line=None, args=None):
141 """Capture lint checks"""
142 # We include node.doc here explicitly so the pretty assert message
143 # inclues it in the output automatically.
144 self.results.append((msg_id, node.doc, line, args))
148 self.checker = lint.DocStringChecker()
149 self.checker.add_message = self.add_message
151 def testGood_visit_function(self):
152 """Allow known good docstrings"""
153 for dc in self.GOOD_FUNC_DOCSTRINGS:
155 node = TestNode(doc=dc)
156 self.checker.visit_function(node)
157 self.assertEqual(self.results, [],
158 msg='docstring was not accepted:\n"""%s"""' % dc)
160 def testBad_visit_function(self):
161 """Reject known bad docstrings"""
162 for dc in self.BAD_FUNC_DOCSTRINGS:
164 node = TestNode(doc=dc)
165 self.checker.visit_function(node)
166 self.assertNotEqual(self.results, [],
167 msg='docstring was not rejected:\n"""%s"""' % dc)
169 def testSmoke_visit_module(self):
170 """Smoke test for modules"""
171 self.checker.visit_module(TestNode(doc='foo'))
172 self.assertEqual(self.results, [])
173 self.checker.visit_module(TestNode(doc='', path='/foo/__init__.py'))
174 self.assertEqual(self.results, [])
176 def testSmoke_visit_class(self):
177 """Smoke test for classes"""
178 self.checker.visit_class(TestNode(doc='bar'))
180 def testGood_check_first_line(self):
181 """Verify _check_first_line accepts good inputs"""
182 # pylint: disable=W0212
186 for dc in docstrings:
188 node = TestNode(doc=dc)
189 self.checker._check_first_line(node, node.lines)
190 self.assertEqual(self.results, [],
191 msg='docstring was not accepted:\n"""%s"""' % dc)
193 def testBad_check_first_line(self):
194 """Verify _check_first_line rejects bad inputs"""
195 # pylint: disable=W0212
199 for dc in docstrings:
201 node = TestNode(doc=dc)
202 self.checker._check_first_line(node, node.lines)
203 self.assertEqual(len(self.results), 1)
205 def testGoodFuncVarKwArg(self):
206 """Check valid inputs for *args and **kwargs"""
207 # pylint: disable=W0212
208 for vararg in (None, 'args', '_args'):
209 for kwarg in (None, 'kwargs', '_kwargs'):
211 node = TestNode(vararg=vararg, kwarg=kwarg)
212 self.checker._check_func_signature(node)
213 self.assertEqual(len(self.results), 0)
215 def testMisnamedFuncVarKwArg(self):
216 """Reject anything but *args and **kwargs"""
217 # pylint: disable=W0212
218 for vararg in ('arg', 'params', 'kwargs', '_moo'):
220 node = TestNode(vararg=vararg)
221 self.checker._check_func_signature(node)
222 self.assertEqual(len(self.results), 1)
224 for kwarg in ('kwds', '_kwds', 'args', '_moo'):
226 node = TestNode(kwarg=kwarg)
227 self.checker._check_func_signature(node)
228 self.assertEqual(len(self.results), 1)
230 def testGoodFuncArgs(self):
231 """Verify normal args in Args are allowed"""
232 # pylint: disable=W0212
234 ("""args are correct, and cls is ignored
239 ('cls', 'moo',), None, None,
241 ("""args are correct, and self is ignored
247 ('self', 'moo',), 'args', 'kwargs',
249 ("""args are allowed to wrap
254 that takes many lines
255 to describe its fatness
257 ('moo',), None, 'kwargs',
260 for dc, args, vararg, kwarg in datasets:
262 node = TestNode(doc=dc, args=args, vararg=vararg, kwarg=kwarg)
263 self.checker._check_all_args_in_doc(node, node.lines)
264 self.assertEqual(len(self.results), 0)
266 def testBadFuncArgs(self):
267 """Verify bad/missing args in Args are caught"""
268 # pylint: disable=W0212
277 ("""missing 'cow' but has 'bloop'
284 ("""too much space after colon
291 ("""not enough space after colon
299 for dc, args in datasets:
301 node = TestNode(doc=dc, args=args)
302 self.checker._check_all_args_in_doc(node, node.lines)
303 self.assertEqual(len(self.results), 1)
306 if __name__ == '__main__':