74
75
def find_occurences(self, rule, filename):
75
76
"""Find the number of occurences of rule in a file."""
77
source = file(filename, 'r')
78
source = open(filename, 'r')
78
79
for line in source:
79
80
if line.find(rule) > -1:
88
89
# increase it, then you almost certainly are doing something wrong as
89
90
# the relationship from working_tree to branch is one way.
90
91
# Note that this is an exact equality so that when the number drops,
91
#it is not given a buffer but rather has this test updated immediately.
92
# it is not given a buffer but rather has this test updated immediately.
92
93
self.assertEqual(0, occurences)
94
95
def test_branch_WorkingTree(self):
146
147
def get_source_file_contents(self, extensions=None):
147
148
for fname in self.get_source_files(extensions=extensions):
148
f = open(fname, 'rb')
149
with open(fname, 'r') as f:
150
yield fname, f.read()
155
152
def is_our_code(self, fname):
156
153
"""True if it's a "real" part of breezy rather than external code"""
223
220
"or add '# Copyright (C)"
224
221
" 2007 Bazaar hackers' to these files:",
227
224
for fname, comment in incorrect:
228
225
help_text.append(fname)
229
226
help_text.append((' ' * 4) + comment)
280
277
def _format_message(self, dict_, message):
281
278
files = sorted(["%s: %s" % (f, ', '.join([str(i + 1) for i in lines]))
282
for f, lines in dict_.items()])
279
for f, lines in dict_.items()])
283
280
return message + '\n\n %s' % ('\n '.join(files))
285
282
def test_coding_style(self):
315
312
problems.append(self._format_message(tabs,
316
'Tab characters were found in the following source files.'
317
'\nThey should either be replaced by "\\t" or by spaces:'))
313
'Tab characters were found in the following source files.'
314
'\nThey should either be replaced by "\\t" or by spaces:'))
318
315
if illegal_newlines:
319
316
problems.append(self._format_message(illegal_newlines,
320
'Non-unix newlines were found in the following source files:'))
317
'Non-unix newlines were found in the following source files:'))
321
318
if no_newline_at_eof:
322
319
no_newline_at_eof.sort()
323
320
problems.append("The following source files doesn't have a "
324
"newline at the end:"
326
% ('\n '.join(no_newline_at_eof)))
321
"newline at the end:"
323
% ('\n '.join(no_newline_at_eof)))
328
325
self.fail('\n\n'.join(problems))
327
def test_flake8(self):
328
self.requireFeature(features.flake8)
329
# Older versions of flake8 don't support the 'paths'
331
new_path = list(sys.path)
333
0, os.path.join(os.path.dirname(__file__), '..', '..', 'tools'))
334
self.overrideAttr(sys, 'path', new_path)
335
from flake8.main.application import Application
336
from flake8.formatting.base import BaseFormatter
338
app.config = u'setup.cfg'
341
class Formatter(BaseFormatter):
350
app.file_checker_manager.report()
352
def handle(self, error):
353
self.errors.append(error)
355
app.formatter = Formatter()
359
self.assertEqual(app.formatter.errors, [])
330
361
def test_no_asserts(self):
331
362
"""bzr shouldn't use the 'assert' statement."""
332
363
# assert causes too much variation between -O and not, and tends to
368
400
both_exc_and_no_exc = []
369
401
missing_except = []
402
common_classes = ('StaticTuple',)
370
403
class_re = re.compile(r'^(cdef\s+)?(public\s+)?'
371
404
r'(api\s+)?class (\w+).*:', re.MULTILINE)
372
extern_class_re = re.compile(r'## extern cdef class (\w+)',
374
405
except_re = re.compile(
375
406
r'cdef\s+' # start with cdef
376
407
r'([\w *]*?)\s*' # this is the return signature
381
412
for fname, text in self.get_source_file_contents(
382
413
extensions=('.pyx',)):
383
414
known_classes = {m[-1] for m in class_re.findall(text)}
384
known_classes.update(extern_class_re.findall(text))
415
known_classes.update(common_classes)
385
416
cdefs = except_re.findall(text)
386
417
for sig, func, exc_clause, no_exc_comment in cdefs:
387
418
if sig.startswith('api '):
413
444
error_msg.extend(('', ''))
415
446
self.fail('\n'.join(error_msg))
417
def test_feature_absolute_import(self):
418
"""Using absolute imports means avoiding unnecesary stat and
421
Make sure that all non-test files have absolute imports enabled.
423
missing_absolute_import = []
424
for fname, text in self.get_source_file_contents(
425
extensions=('.py', '.pyx')):
426
if "/tests/" in fname or "test_" in fname:
427
# We don't really care about tests
429
if not "from __future__ import absolute_import" in text:
430
missing_absolute_import.append(fname)
432
if missing_absolute_import:
434
'The following files do not have absolute_import enabled:\n'
435
'\n' + '\n'.join(missing_absolute_import))