| # Copyright (c) 2003-2007 LOGILAB S.A. (Paris, FRANCE). |
| # This program is free software; you can redistribute it and/or modify it under |
| # the terms of the GNU General Public License as published by the Free Software |
| # Foundation; either version 2 of the License, or (at your option) any later |
| # version. |
| # |
| # This program is distributed in the hope that it will be useful, but WITHOUT |
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License along with |
| # this program; if not, write to the Free Software Foundation, Inc., |
| # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| |
| import sys |
| import os |
| import tempfile |
| from shutil import rmtree |
| from os.path import join, basename, dirname, isdir, abspath |
| from cStringIO import StringIO |
| |
| from logilab.common.testlib import TestCase, unittest_main, create_files |
| from logilab.common.compat import reload |
| |
| from pylint import config |
| from pylint.lint import PyLinter, Run, UnknownMessage |
| from pylint.utils import sort_msgs, PyLintASTWalker |
| from pylint import checkers |
| |
| class SortMessagesTC(TestCase): |
| |
| def test(self): |
| l = ['E0501', 'E0503', 'F0002', 'I0201', 'W0540', |
| 'R0202', 'F0203', 'R0220', 'W0321', 'I0001'] |
| self.assertEqual(sort_msgs(l), ['E0501', 'E0503', |
| 'W0321', 'W0540', |
| 'R0202', 'R0220', |
| 'I0001', 'I0201', |
| 'F0002', 'F0203',]) |
| |
| try: |
| optimized = True |
| raise AssertionError |
| except AssertionError: |
| optimized = False |
| |
| class GetNoteMessageTC(TestCase): |
| def test(self): |
| msg = None |
| for note in range(-1, 11): |
| note_msg = config.get_note_message(note) |
| self.assertNotEqual(msg, note_msg) |
| msg = note_msg |
| if optimized: |
| self.assertRaises(AssertionError, config.get_note_message, 11) |
| |
| |
| HERE = abspath(dirname(__file__)) |
| INPUTDIR = join(HERE, 'input') |
| |
| class RunTC(TestCase): |
| |
| def _test_run(self, args, exit_code=1, no_exit_fail=True): |
| sys.stdout = sys.sterr = StringIO() |
| try: |
| try: |
| Run(args) |
| except SystemExit, ex: |
| print sys.stdout.getvalue() |
| self.assertEqual(ex.code, exit_code) |
| else: |
| if no_exit_fail: |
| self.fail() |
| finally: |
| sys.stdout = sys.__stdout__ |
| sys.stderr = sys.__stderr__ |
| |
| |
| class PyLinterTC(TestCase): |
| |
| def setUp(self): |
| self.linter = PyLinter() |
| self.linter.disable('I') |
| self.linter.config.persistent = 0 |
| # register checkers |
| checkers.initialize(self.linter) |
| |
| def test_message_help(self): |
| msg = self.linter.get_message_help('F0001', checkerref=True) |
| expected = ':F0001:\n Used when an error occurred preventing the analysis of a module (unable to\n find it for instance). This message belongs to the master checker.' |
| self.assertMultiLineEqual(msg, expected) |
| self.assertRaises(UnknownMessage, self.linter.get_message_help, 'YB12') |
| |
| def test_enable_message(self): |
| linter = self.linter |
| linter.open() |
| linter.set_current_module('toto') |
| self.assert_(linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('W0102')) |
| linter.disable('W0101', scope='package') |
| linter.disable('W0102', scope='module', line=1) |
| self.assert_(not linter.is_message_enabled('W0101')) |
| self.assert_(not linter.is_message_enabled('W0102', 1)) |
| linter.set_current_module('tutu') |
| self.assert_(not linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('W0102')) |
| linter.enable('W0101', scope='package') |
| linter.enable('W0102', scope='module', line=1) |
| self.assert_(linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('W0102', 1)) |
| |
| def test_enable_message_category(self): |
| linter = self.linter |
| linter.open() |
| linter.set_current_module('toto') |
| self.assert_(linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('C0121')) |
| linter.disable('W', scope='package') |
| linter.disable('C', scope='module', line=1) |
| self.assert_(not linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('C0121')) |
| self.assert_(not linter.is_message_enabled('C0121', line=1)) |
| linter.set_current_module('tutu') |
| self.assert_(not linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('C0121')) |
| linter.enable('W', scope='package') |
| linter.enable('C', scope='module', line=1) |
| self.assert_(linter.is_message_enabled('W0101')) |
| self.assert_(linter.is_message_enabled('C0121')) |
| self.assert_(linter.is_message_enabled('C0121', line=1)) |
| |
| def test_enable_message_block(self): |
| linter = self.linter |
| linter.open() |
| filepath = join(INPUTDIR, 'func_block_disable_msg.py') |
| linter.set_current_module('func_block_disable_msg') |
| astng = linter.get_astng(filepath, 'func_block_disable_msg') |
| linter.process_module(astng) |
| orig_state = linter._module_msgs_state.copy() |
| linter._module_msgs_state = {} |
| linter.collect_block_lines(astng, orig_state) |
| # global (module level) |
| self.assert_(linter.is_message_enabled('W0613')) |
| self.assert_(linter.is_message_enabled('E1101')) |
| # meth1 |
| self.assert_(linter.is_message_enabled('W0613', 13)) |
| # meth2 |
| self.assert_(not linter.is_message_enabled('W0613', 18)) |
| # meth3 |
| self.assert_(not linter.is_message_enabled('E1101', 24)) |
| self.assert_(linter.is_message_enabled('E1101', 26)) |
| # meth4 |
| self.assert_(not linter.is_message_enabled('E1101', 32)) |
| self.assert_(linter.is_message_enabled('E1101', 36)) |
| # meth5 |
| self.assert_(not linter.is_message_enabled('E1101', 42)) |
| self.assert_(not linter.is_message_enabled('E1101', 43)) |
| self.assert_(linter.is_message_enabled('E1101', 46)) |
| self.assert_(not linter.is_message_enabled('E1101', 49)) |
| self.assert_(not linter.is_message_enabled('E1101', 51)) |
| # meth6 |
| self.assert_(not linter.is_message_enabled('E1101', 57)) |
| self.assert_(linter.is_message_enabled('E1101', 61)) |
| self.assert_(not linter.is_message_enabled('E1101', 64)) |
| self.assert_(not linter.is_message_enabled('E1101', 66)) |
| |
| self.assert_(linter.is_message_enabled('E0602', 57)) |
| self.assert_(linter.is_message_enabled('E0602', 61)) |
| self.assert_(not linter.is_message_enabled('E0602', 62)) |
| self.assert_(linter.is_message_enabled('E0602', 64)) |
| self.assert_(linter.is_message_enabled('E0602', 66)) |
| # meth7 |
| self.assert_(not linter.is_message_enabled('E1101', 70)) |
| self.assert_(linter.is_message_enabled('E1101', 72)) |
| self.assert_(linter.is_message_enabled('E1101', 75)) |
| self.assert_(linter.is_message_enabled('E1101', 77)) |
| |
| def test_list_messages(self): |
| sys.stdout = StringIO() |
| try: |
| # just invoke it, don't check the output |
| self.linter.list_messages() |
| finally: |
| sys.stdout = sys.__stdout__ |
| |
| def test_lint_ext_module_with_file_output(self): |
| if sys.version_info < (3, 0): |
| strio = 'StringIO' |
| else: |
| strio = 'io' |
| self.linter.config.files_output = True |
| pylint_strio = 'pylint_%s.txt' % strio |
| try: |
| self.linter.check(strio) |
| self.assert_(os.path.exists(pylint_strio)) |
| self.assert_(os.path.exists('pylint_global.txt')) |
| finally: |
| try: |
| os.remove(pylint_strio) |
| os.remove('pylint_global.txt') |
| except: |
| pass |
| |
| def test_enable_report(self): |
| self.assertEqual(self.linter.report_is_enabled('RP0001'), True) |
| self.linter.disable('RP0001') |
| self.assertEqual(self.linter.report_is_enabled('RP0001'), False) |
| self.linter.enable('RP0001') |
| self.assertEqual(self.linter.report_is_enabled('RP0001'), True) |
| |
| def test_set_option_1(self): |
| linter = self.linter |
| linter.set_option('disable', 'C0111,W0142') |
| self.assert_(not linter.is_message_enabled('C0111')) |
| self.assert_(not linter.is_message_enabled('W0142')) |
| self.assert_(linter.is_message_enabled('W0113')) |
| |
| def test_set_option_2(self): |
| linter = self.linter |
| linter.set_option('disable', ('C0111', 'W0142') ) |
| self.assert_(not linter.is_message_enabled('C0111')) |
| self.assert_(not linter.is_message_enabled('W0142')) |
| self.assert_(linter.is_message_enabled('W0113')) |
| |
| def test_enable_checkers(self): |
| self.linter.disable('design') |
| self.failIf('design' in [c.name for c in self.linter.prepare_checkers()]) |
| self.linter.enable('design') |
| self.failUnless('design' in [c.name for c in self.linter.prepare_checkers()]) |
| |
| def test_errors_only(self): |
| linter = self.linter |
| self.linter.error_mode() |
| checkers = self.linter.prepare_checkers() |
| checker_names = tuple(c.name for c in checkers) |
| should_not = ('design', 'format', 'imports', 'logging', 'metrics', |
| 'miscellaneous', 'similarities') |
| self.failIf(any(name in checker_names for name in should_not)) |
| |
| def test_disable_similar(self): |
| # XXX we have to disable them both, that's no good |
| self.linter.set_option('reports', False) |
| self.linter.set_option('disable', 'R0801') |
| self.failIf('similarities' in [c.name for c in self.linter.prepare_checkers()]) |
| |
| def test_disable_alot(self): |
| """check that we disabled a lot of checkers""" |
| self.linter.set_option('reports', False) |
| # FIXME should it be necessary to explicitly desactivate failures ? |
| self.linter.set_option('disable', 'R,C,W') |
| checker_names = [c.name for c in self.linter.prepare_checkers()] |
| should_not = ('design', 'logging', 'metrics', 'similarities') |
| rest = [name for name in checker_names if name in should_not] |
| self.assertListEqual(rest, []) |
| self.linter.set_option('disable', 'R,C,W,F') |
| checker_names = [c.name for c in self.linter.prepare_checkers()] |
| should_not += ('format', 'imports') |
| rest = [name for name in checker_names if name in should_not] |
| self.assertListEqual(rest, []) |
| |
| |
| class ConfigTC(TestCase): |
| |
| def setUp(self): |
| os.environ.pop('PYLINTRC', None) |
| |
| def test_pylint_home(self): |
| uhome = os.path.expanduser('~') |
| if uhome == '~': |
| expected = '.pylint.d' |
| else: |
| expected = os.path.join(uhome, '.pylint.d') |
| self.assertEqual(config.PYLINT_HOME, expected) |
| |
| try: |
| pylintd = join(tempfile.gettempdir(), '.pylint.d') |
| os.environ['PYLINTHOME'] = pylintd |
| try: |
| reload(config) |
| self.assertEqual(config.PYLINT_HOME, pylintd) |
| finally: |
| try: |
| os.remove(pylintd) |
| except: |
| pass |
| finally: |
| del os.environ['PYLINTHOME'] |
| |
| def test_pylintrc(self): |
| fake_home = tempfile.mkdtemp('fake-home') |
| home = os.environ['HOME'] |
| try: |
| os.environ['HOME'] = fake_home |
| self.assertEqual(config.find_pylintrc(), None) |
| os.environ['PYLINTRC'] = join(tempfile.gettempdir(), '.pylintrc') |
| self.assertEqual(config.find_pylintrc(), None) |
| os.environ['PYLINTRC'] = '.' |
| self.assertEqual(config.find_pylintrc(), None) |
| finally: |
| os.environ.pop('PYLINTRC', '') |
| os.environ['HOME'] = home |
| rmtree(fake_home, ignore_errors=True) |
| reload(config) |
| |
| def test_pylintrc_parentdir(self): |
| chroot = tempfile.mkdtemp() |
| try: |
| create_files(['a/pylintrc', 'a/b/__init__.py', 'a/b/pylintrc', |
| 'a/b/c/__init__.py', 'a/b/c/d/__init__.py'], chroot) |
| os.chdir(chroot) |
| fake_home = tempfile.mkdtemp('fake-home') |
| home = os.environ['HOME'] |
| try: |
| os.environ['HOME'] = fake_home |
| self.assertEqual(config.find_pylintrc(), None) |
| finally: |
| os.environ['HOME'] = home |
| os.rmdir(fake_home) |
| results = {'a' : join(chroot, 'a', 'pylintrc'), |
| 'a/b' : join(chroot, 'a', 'b', 'pylintrc'), |
| 'a/b/c' : join(chroot, 'a', 'b', 'pylintrc'), |
| 'a/b/c/d' : join(chroot, 'a', 'b', 'pylintrc'), |
| } |
| for basedir, expected in results.items(): |
| os.chdir(join(chroot, basedir)) |
| self.assertEqual(config.find_pylintrc(), expected) |
| finally: |
| os.chdir(HERE) |
| rmtree(chroot) |
| |
| |
| def test_pylintrc_parentdir_no_package(self): |
| chroot = tempfile.mkdtemp() |
| fake_home = tempfile.mkdtemp('fake-home') |
| home = os.environ['HOME'] |
| os.environ['HOME'] = fake_home |
| try: |
| create_files(['a/pylintrc', 'a/b/pylintrc', 'a/b/c/d/__init__.py'], chroot) |
| os.chdir(chroot) |
| self.assertEqual(config.find_pylintrc(), None) |
| results = {'a' : join(chroot, 'a', 'pylintrc'), |
| 'a/b' : join(chroot, 'a', 'b', 'pylintrc'), |
| 'a/b/c' : None, |
| 'a/b/c/d' : None, |
| } |
| for basedir, expected in results.items(): |
| os.chdir(join(chroot, basedir)) |
| self.assertEqual(config.find_pylintrc(), expected) |
| finally: |
| os.environ['HOME'] = home |
| rmtree(fake_home, ignore_errors=True) |
| os.chdir(HERE) |
| rmtree(chroot) |
| |
| if __name__ == '__main__': |
| unittest_main() |