diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-06-11 15:20:13 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-06-11 15:20:13 +0200 |
| commit | 8853e6b594eb0387939741ec2a8b208593c29646 (patch) | |
| tree | 2239af0a8a4b4df62b68bf05f8795e35de4f543f /odoo/addons/test_lint | |
| parent | bf139f06623916da846ed4776c105cadaee362bf (diff) | |
| parent | 7ef4ba03c4f8dce42f5a56b64d2374373d13aa8d (diff) | |
[MERGE] forward port branch 12.0 up to 7ef4ba03c4f
Diffstat (limited to 'odoo/addons/test_lint')
| -rw-r--r-- | odoo/addons/test_lint/__init__.py | 13 | ||||
| -rw-r--r-- | odoo/addons/test_lint/__manifest__.py | 12 | ||||
| -rw-r--r-- | odoo/addons/test_lint/tests/__init__.py | 2 | ||||
| -rw-r--r-- | odoo/addons/test_lint/tests/_odoo_checkers.py | 44 | ||||
| -rw-r--r-- | odoo/addons/test_lint/tests/test_ecmascript.py | 48 | ||||
| -rw-r--r-- | odoo/addons/test_lint/tests/test_pylint.py | 90 |
6 files changed, 209 insertions, 0 deletions
diff --git a/odoo/addons/test_lint/__init__.py b/odoo/addons/test_lint/__init__.py new file mode 100644 index 00000000000..0e68430dabe --- /dev/null +++ b/odoo/addons/test_lint/__init__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, SUPERUSER_ID + + +# TO REMOVE in master +def uninstall_test_pylint(cr): + env = api.Environment(cr, SUPERUSER_ID, {}) + env['ir.module.module'].search([ + ('name', '=', 'test_pylint'), + ('state', '=', 'installed') + ]).write({'state': 'uninstalled'}) diff --git a/odoo/addons/test_lint/__manifest__.py b/odoo/addons/test_lint/__manifest__.py new file mode 100644 index 00000000000..554e20ba3b2 --- /dev/null +++ b/odoo/addons/test_lint/__manifest__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'test-lint', + 'version': '0.1', + 'category': 'Tests', + 'description': """A module to test Odoo code with various linters.""", + 'maintainer': 'Odoo SA', + 'depends': ['base'], + 'installable': True, + 'auto_install': False, + 'pre_init_hook': 'uninstall_test_pylint' +} diff --git a/odoo/addons/test_lint/tests/__init__.py b/odoo/addons/test_lint/tests/__init__.py new file mode 100644 index 00000000000..d085060f6bf --- /dev/null +++ b/odoo/addons/test_lint/tests/__init__.py @@ -0,0 +1,2 @@ +from . import test_pylint +from . import test_ecmascript diff --git a/odoo/addons/test_lint/tests/_odoo_checkers.py b/odoo/addons/test_lint/tests/_odoo_checkers.py new file mode 100644 index 00000000000..5648ac52219 --- /dev/null +++ b/odoo/addons/test_lint/tests/_odoo_checkers.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import tokenize + +from pylint import checkers, interfaces + +class PEP3110TokenChecker(checkers.BaseTokenChecker): + __implements__ = interfaces.ITokenChecker + name = 'python3' + enabled = False + + msgs = { + 'E3110': ('Python 3 uses `as` instead of comma token to catch exceptions', + 'no-comma-exception', + 'See http://www.python.org/dev/peps/pep-3110/', + {'maxversion': (3, 0)}), + } + + def process_tokens(self, tokens): + comma_found = in_except = False + pcount = 0 + for tok_type, token, start, _, _ in tokens: + if tok_type == tokenize.NAME and token == 'except': + in_except = True + comma_found = False + pcount = 0 + + elif tok_type == tokenize.OP and in_except: + if token == '(': + pcount += 1 + elif token == ')': + pcount -= 1 + elif token == ',' and pcount == 0: + comma_found = True + if token == ':': + if in_except and comma_found: + self.add_message('no-comma-exception', line=start[0]) + comma_found = in_except = False + pcount = 0 + + +def register(linter): + linter.register_checker(PEP3110TokenChecker(linter)) diff --git a/odoo/addons/test_lint/tests/test_ecmascript.py b/odoo/addons/test_lint/tests/test_ecmascript.py new file mode 100644 index 00000000000..46008b0587d --- /dev/null +++ b/odoo/addons/test_lint/tests/test_ecmascript.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import os +import re +import subprocess +from unittest import skipIf +from odoo.tests.common import TransactionCase +from odoo import tools +from odoo.modules import get_modules, get_module_path + +MAX_ES_VERSION = 'es5' + +_logger = logging.getLogger(__name__) + +try: + es_check = tools.misc.find_in_path('es-check') +except IOError: + es_check = None + + +@skipIf(es_check is None, "es-check tool not found on this system") +class TestECMAScriptVersion(TransactionCase): + + longMessage = True + + def test_ecmascript_version(self): + """ Test that there is no unsupported ecmascript in javascript files """ + + black_re = re.compile(r'summernote.+(intro\.js|outro.js)$') + + mod_paths = [get_module_path(m) for m in get_modules()] + files_to_check = [] + for p in mod_paths: + for dp, _, file_names in os.walk(p): + if 'static/test' in dp: + continue + for fn in file_names: + fullpath_name = os.path.join(dp, fn) + if fullpath_name.endswith('.js') and not black_re.search(fullpath_name): + files_to_check.append(fullpath_name) + + _logger.info('Testing %s js files', len(files_to_check)) + cmd = [es_check, MAX_ES_VERSION] + files_to_check + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + self.assertEqual(process.returncode, 0, msg=out) diff --git a/odoo/addons/test_lint/tests/test_pylint.py b/odoo/addons/test_lint/tests/test_pylint.py new file mode 100644 index 00000000000..8e5e69fa351 --- /dev/null +++ b/odoo/addons/test_lint/tests/test_pylint.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +try: + import pylint +except ImportError: + pylint = None +import subprocess +from distutils.version import LooseVersion +import os +from os.path import join +import sys + +from odoo.tests.common import TransactionCase +from odoo import tools +from odoo.modules import get_modules, get_module_path + +HERE = os.path.dirname(os.path.realpath(__file__)) + +_logger = logging.getLogger(__name__) + + +class TestPyLint(TransactionCase): + + ENABLED_CODES = [ + 'used-before-assignment', + 'undefined-variable', + 'eval-used', + 'unreachable', + + 'mixed-indentation', + ] + + BAD_FUNCTIONS = [ + 'input', + ] + + BAD_MODULES = [ + 'csv', + 'urllib', + 'cgi', + ] + list(tools.SUPPORTED_DEBUGGER) + + def _skip_test(self, reason): + _logger.warn(reason) + self.skipTest(reason) + + def test_pylint(self): + if pylint is None: + self._skip_test('please install pylint') + required_pylint_version = LooseVersion('1.6.4') + if sys.version_info >= (3, 6): + required_pylint_version = LooseVersion('1.7.0') + if LooseVersion(getattr(pylint, '__version__', '0.0.1')) < required_pylint_version: + self._skip_test('please upgrade pylint to >= %s' % required_pylint_version) + + paths = [tools.config['root_path']] + for module in get_modules(): + module_path = get_module_path(module) + if not module_path.startswith(join(tools.config['root_path'], 'addons')): + paths.append(module_path) + + options = [ + '--rcfile=%s' % os.devnull, + '--disable=all', + '--enable=%s' % ','.join(self.ENABLED_CODES), + '--reports=n', + "--msg-template='{msg} ({msg_id}) at {path}:{line}'", + '--load-plugins=pylint.extensions.bad_builtin,_odoo_checkers', + '--bad-functions=%s' % ','.join(self.BAD_FUNCTIONS), + '--deprecated-modules=%s' % ','.join(self.BAD_MODULES) + ] + + pypath = HERE + os.pathsep + os.environ.get('PYTHONPATH', '') + env = dict(os.environ, PYTHONPATH=pypath) + try: + pylint_bin = tools.which('pylint') + process = subprocess.Popen( + [pylint_bin] + options + paths, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + ) + except (OSError, IOError): + self._skip_test('pylint executable not found in the path') + else: + out, err = process.communicate() + if process.returncode: + self.fail("pylint test failed:\n" + (b"\n" + out + b"\n" + err).decode('utf-8').strip()) |
