1
# Copyright 2014 Red Hat, Inc.
3
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4
# not use this file except in compliance with the License. You may obtain
5
# a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
# License for the specific language governing permissions and limitations
20
from manila.hacking import checks
21
from manila import test
24
class HackingTestCase(test.TestCase):
27
This class tests the hacking checks in manila.hacking.checks by passing
28
strings to the check methods like the pep8/flake8 parser would. The parser
29
loops over each line in the file and then passes the parameters to the
30
check method. The parameter names in the check method dictate what type of
31
object is passed to the check method. The parameter types are::
33
logical_line: A processed line with the following modifications:
34
- Multi-line statements converted to a single line.
35
- Stripped left and right.
36
- Contents of strings replaced with "xxx" of same length.
38
physical_line: Raw line of text from the input file.
39
lines: a list of the raw lines from the input file
40
tokens: the tokens that contribute to this logical line
41
line_number: line number in the input file
42
total_lines: number of lines in the input file
43
blank_lines: blank lines before this one
44
indent_char: indentation character in this file (" " or "\t")
45
indent_level: indentation (with tabs expanded to multiples of 8)
46
previous_indent_level: indentation on previous line
47
previous_logical: previous logical line
48
filename: Path of the file being run through pep8
50
When running a test on a check method the return will be False/None if
51
there is no violation in the sample input. If there is an error a tuple is
52
returned with a position in the line, and a message. So to check the result
53
just assertTrue if the check is expected to fail and assertFalse if it
57
def test_no_translate_debug_logs(self):
58
self.assertEqual(len(list(checks.no_translate_debug_logs(
59
"LOG.debug(_('foo'))", "manila/scheduler/foo.py"))), 1)
61
self.assertEqual(len(list(checks.no_translate_debug_logs(
62
"LOG.debug('foo')", "manila/scheduler/foo.py"))), 0)
64
self.assertEqual(len(list(checks.no_translate_debug_logs(
65
"LOG.info(_('foo'))", "manila/scheduler/foo.py"))), 0)
67
def test_check_explicit_underscore_import(self):
68
self.assertEqual(len(list(checks.check_explicit_underscore_import(
69
"LOG.info(_('My info message'))",
70
"cinder/tests/other_files.py"))), 1)
71
self.assertEqual(len(list(checks.check_explicit_underscore_import(
72
"msg = _('My message')",
73
"cinder/tests/other_files.py"))), 1)
74
self.assertEqual(len(list(checks.check_explicit_underscore_import(
75
"from cinder.i18n import _",
76
"cinder/tests/other_files.py"))), 0)
77
self.assertEqual(len(list(checks.check_explicit_underscore_import(
78
"LOG.info(_('My info message'))",
79
"cinder/tests/other_files.py"))), 0)
80
self.assertEqual(len(list(checks.check_explicit_underscore_import(
81
"msg = _('My message')",
82
"cinder/tests/other_files.py"))), 0)
83
self.assertEqual(len(list(checks.check_explicit_underscore_import(
84
"from cinder.i18n import _, _LW",
85
"cinder/tests/other_files2.py"))), 0)
86
self.assertEqual(len(list(checks.check_explicit_underscore_import(
87
"msg = _('My message')",
88
"cinder/tests/other_files2.py"))), 0)
89
self.assertEqual(len(list(checks.check_explicit_underscore_import(
90
"_ = translations.ugettext",
91
"cinder/tests/other_files3.py"))), 0)
92
self.assertEqual(len(list(checks.check_explicit_underscore_import(
93
"msg = _('My message')",
94
"cinder/tests/other_files3.py"))), 0)
96
# We are patching pep8 so that only the check under test is actually
98
@mock.patch('pep8._checks',
99
{'physical_line': {}, 'logical_line': {}, 'tree': {}})
100
def _run_check(self, code, checker, filename=None):
101
pep8.register_check(checker)
103
lines = textwrap.dedent(code).strip().splitlines(True)
105
checker = pep8.Checker(filename=filename, lines=lines)
107
checker.report._deferred_print.sort()
108
return checker.report._deferred_print
110
def _assert_has_errors(self, code, checker, expected_errors=None,
112
actual_errors = [e[:3] for e in
113
self._run_check(code, checker, filename)]
114
self.assertEqual(expected_errors or [], actual_errors)
116
def test_str_exception(self):
118
checker = checks.CheckForStrExc
123
except ValueError as e:
127
errors = [(5, 16, 'M325')]
128
self._assert_has_errors(code, checker, expected_errors=errors)
134
except ValueError as e:
139
self._assert_has_errors(code, checker, expected_errors=errors)
145
except ValueError as e:
147
p = unicode(a) + unicode(b)
148
except ValueError as ve:
153
errors = [(8, 20, 'M325'), (8, 29, 'M325')]
154
self._assert_has_errors(code, checker, expected_errors=errors)
156
def test_trans_add(self):
158
checker = checks.CheckForTransAdd
172
msg = _('test') + 'add me'
173
msg = _LI('test') + 'add me'
174
msg = _LW('test') + 'add me'
175
msg = _LE('test') + 'add me'
176
msg = _LC('test') + 'add me'
177
msg = 'add to me' + _('test')
180
errors = [(13, 10, 'M326'), (14, 10, 'M326'), (15, 10, 'M326'),
181
(16, 10, 'M326'), (17, 10, 'M326'), (18, 24, 'M326')]
182
self._assert_has_errors(code, checker, expected_errors=errors)
186
msg = 'test' + 'add me'
190
self._assert_has_errors(code, checker, expected_errors=errors)