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."""
8 from __future__ import print_function
14 sys.path.insert(0, os.path.abspath('%s/../../..' % os.path.dirname(__file__)))
16 from chromite.lib import cros_test_lib
20 class TestNode(object):
21 """Object good enough to stand in for lint funcs"""
23 Args = collections.namedtuple('Args', ('args', 'vararg', 'kwarg'))
24 Arg = collections.namedtuple('Arg', ('name',))
26 def __init__(self, doc='', fromlineno=0, path='foo.py', args=(), vararg='',
29 self.lines = doc.split('\n')
30 self.fromlineno = fromlineno
32 self.args = self.Args(args=[self.Arg(name=x) for x in args],
33 vararg=vararg, kwarg=kwarg)
39 class DocStringCheckerTest(cros_test_lib.TestCase):
40 """Tests for DocStringChecker module"""
42 GOOD_FUNC_DOCSTRINGS = (
72 BAD_FUNC_DOCSTRINGS = (
76 """ whitespace is wrong""",
77 """whitespace is wrong """,
78 """ whitespace is wrong
80 Multiline tickles differently.
82 """Should be no trailing blank lines
91 """we want Args/Returns not Arguments/Return
96 """section order is wrong here
101 """sections lack whitespace between them
108 """yields is misspelled
113 """Section name has bad spacing
118 """too many blank lines
124 """wrongly uses javadoc
130 # The current linter isn't good enough yet to detect these.
131 TODO_BAD_FUNC_DOCSTRINGS = (
132 """The returns section isn't a proper section
139 """the indentation is incorrect
146 def add_message(self, msg_id, node=None, line=None, args=None):
147 """Capture lint checks"""
148 # We include node.doc here explicitly so the pretty assert message
149 # inclues it in the output automatically.
150 self.results.append((msg_id, node.doc, line, args))
154 self.checker = lint.DocStringChecker()
155 self.checker.add_message = self.add_message
157 def testGood_visit_function(self):
158 """Allow known good docstrings"""
159 for dc in self.GOOD_FUNC_DOCSTRINGS:
161 node = TestNode(doc=dc)
162 self.checker.visit_function(node)
163 self.assertEqual(self.results, [],
164 msg='docstring was not accepted:\n"""%s"""' % dc)
166 def testBad_visit_function(self):
167 """Reject known bad docstrings"""
168 for dc in self.BAD_FUNC_DOCSTRINGS:
170 node = TestNode(doc=dc)
171 self.checker.visit_function(node)
172 self.assertNotEqual(self.results, [],
173 msg='docstring was not rejected:\n"""%s"""' % dc)
175 def testSmoke_visit_module(self):
176 """Smoke test for modules"""
177 self.checker.visit_module(TestNode(doc='foo'))
178 self.assertEqual(self.results, [])
179 self.checker.visit_module(TestNode(doc='', path='/foo/__init__.py'))
180 self.assertEqual(self.results, [])
182 def testSmoke_visit_class(self):
183 """Smoke test for classes"""
184 self.checker.visit_class(TestNode(doc='bar'))
186 def testGood_check_first_line(self):
187 """Verify _check_first_line accepts good inputs"""
188 # pylint: disable=W0212
192 for dc in docstrings:
194 node = TestNode(doc=dc)
195 self.checker._check_first_line(node, node.lines)
196 self.assertEqual(self.results, [],
197 msg='docstring was not accepted:\n"""%s"""' % dc)
199 def testBad_check_first_line(self):
200 """Verify _check_first_line rejects bad inputs"""
201 # pylint: disable=W0212
205 for dc in docstrings:
207 node = TestNode(doc=dc)
208 self.checker._check_first_line(node, node.lines)
209 self.assertEqual(len(self.results), 1)
211 def testGoodFuncVarKwArg(self):
212 """Check valid inputs for *args and **kwargs"""
213 # pylint: disable=W0212
214 for vararg in (None, 'args', '_args'):
215 for kwarg in (None, 'kwargs', '_kwargs'):
217 node = TestNode(vararg=vararg, kwarg=kwarg)
218 self.checker._check_func_signature(node)
219 self.assertEqual(len(self.results), 0)
221 def testMisnamedFuncVarKwArg(self):
222 """Reject anything but *args and **kwargs"""
223 # pylint: disable=W0212
224 for vararg in ('arg', 'params', 'kwargs', '_moo'):
226 node = TestNode(vararg=vararg)
227 self.checker._check_func_signature(node)
228 self.assertEqual(len(self.results), 1)
230 for kwarg in ('kwds', '_kwds', 'args', '_moo'):
232 node = TestNode(kwarg=kwarg)
233 self.checker._check_func_signature(node)
234 self.assertEqual(len(self.results), 1)
236 def testGoodFuncArgs(self):
237 """Verify normal args in Args are allowed"""
238 # pylint: disable=W0212
240 ("""args are correct, and cls is ignored
245 ('cls', 'moo',), None, None,
247 ("""args are correct, and self is ignored
253 ('self', 'moo',), 'args', 'kwargs',
255 ("""args are allowed to wrap
260 that takes many lines
261 to describe its fatness
263 ('moo',), None, 'kwargs',
266 for dc, args, vararg, kwarg in datasets:
268 node = TestNode(doc=dc, args=args, vararg=vararg, kwarg=kwarg)
269 self.checker._check_all_args_in_doc(node, node.lines)
270 self.assertEqual(len(self.results), 0)
272 def testBadFuncArgs(self):
273 """Verify bad/missing args in Args are caught"""
274 # pylint: disable=W0212
283 ("""missing 'cow' but has 'bloop'
290 ("""too much space after colon
297 ("""not enough space after colon
305 for dc, args in datasets:
307 node = TestNode(doc=dc, args=args)
308 self.checker._check_all_args_in_doc(node, node.lines)
309 self.assertEqual(len(self.results), 1)
312 if __name__ == '__main__':