Files
deb-python-hacking/hacking/tests/test_doctest.py
James Carey b65962ab62 Add support for flake8 off_by_default for optional checks
This allows hacking checks to be added as optional which means
that they are assumed to be excluded and have to be explicitly
added as part of a 'select' entry in the [flake8]
stanza of tox.ini.

The goal is to allow checks to be staged into the projects instead
of requiring all of the projects to change to adhere to the
check prior to the check being added (which creates a window where
failing code could be added).  Instead checks can be staged in with
enforcement and once all (or the majority) of projects have enabled
it, the check can be changed to a required check.

One optional check is added as an example:
  H106: Don't put vim configuration in source files

Depends-On: I7f8ef22254703a53b73ccd048322191cfc677958
Change-Id: If188f85e8093974802bd2bacc2a72b2ae35ee5a1
2015-05-18 00:46:18 +00:00

98 lines
3.4 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
from flake8 import engine
import pep8
import pkg_resources
import six
import testscenarios
from testtools import content
from testtools import matchers
import hacking
import hacking.tests
SELFTEST_REGEX = re.compile(r'\b(Okay|[HEW]\d{3}):\s(.*)')
# Each scenario is (name, dict(lines=.., options=..., code=...))
file_cases = []
class HackingTestCase(hacking.tests.TestCase):
scenarios = file_cases
def test_pep8(self):
# NOTE(jecarey): Add tests marked as off_by_default to enable testing
turn_on = set(['H106'])
if self.options.select:
turn_on.update(self.options.select)
self.options.select = tuple(turn_on)
report = pep8.BaseReport(self.options)
checker = pep8.Checker(lines=self.lines, options=self.options,
report=report)
checker.check_all()
self.addDetail('doctest', content.text_content(self.raw))
if self.code == 'Okay':
self.assertThat(
len(report.counters),
matchers.Not(matchers.GreaterThan(
len(self.options.benchmark_keys))),
"incorrectly found %s" % ', '.join(
[key for key in report.counters
if key not in self.options.benchmark_keys]))
else:
self.addDetail('reason',
content.text_content("Failed to trigger rule %s" %
self.code))
self.assertIn(self.code, report.counters)
def _get_lines(check):
for line in check.__doc__.splitlines():
line = line.lstrip()
match = SELFTEST_REGEX.match(line)
if match is None:
continue
yield (line, match.groups())
def load_tests(loader, tests, pattern):
flake8_style = engine.get_style_guide(parse_argv=False,
# Ignore H104 otherwise it's
# raised on doctests.
ignore=('F', 'H104'))
options = flake8_style.options
for entry in pkg_resources.iter_entry_points('flake8.extension'):
if not entry.module_name.startswith('hacking.'):
continue
check = entry.load()
name = entry.attrs[0]
if check.skip_on_py3 and six.PY3:
continue
for (lineno, (raw, (code, source))) in enumerate(_get_lines(check)):
lines = [part.replace(r'\t', '\t') + '\n'
for part in source.split(r'\n')]
file_cases.append(("%s-%s-line-%s" % (entry.name, name, lineno),
dict(lines=lines, raw=raw, options=options,
code=code)))
return testscenarios.load_tests_apply_scenarios(loader, tests, pattern)