75
74
def find_occurences(self, rule, filename):
76
75
"""Find the number of occurences of rule in a file."""
78
source = open(filename, 'r')
77
source = file(filename, 'r')
79
78
for line in source:
80
79
if line.find(rule) > -1:
89
88
# increase it, then you almost certainly are doing something wrong as
90
89
# the relationship from working_tree to branch is one way.
91
90
# Note that this is an exact equality so that when the number drops,
92
# it is not given a buffer but rather has this test updated immediately.
91
#it is not given a buffer but rather has this test updated immediately.
93
92
self.assertEqual(0, occurences)
95
94
def test_branch_WorkingTree(self):
147
146
def get_source_file_contents(self, extensions=None):
148
147
for fname in self.get_source_files(extensions=extensions):
149
with open(fname, 'r') as f:
150
yield fname, f.read()
148
f = open(fname, 'rb')
152
155
def is_our_code(self, fname):
153
156
"""True if it's a "real" part of breezy rather than external code"""
220
223
"or add '# Copyright (C)"
221
224
" 2007 Bazaar hackers' to these files:",
224
227
for fname, comment in incorrect:
225
228
help_text.append(fname)
226
229
help_text.append((' ' * 4) + comment)
277
280
def _format_message(self, dict_, message):
278
281
files = sorted(["%s: %s" % (f, ', '.join([str(i + 1) for i in lines]))
279
for f, lines in dict_.items()])
282
for f, lines in dict_.items()])
280
283
return message + '\n\n %s' % ('\n '.join(files))
282
285
def test_coding_style(self):
312
315
problems.append(self._format_message(tabs,
313
'Tab characters were found in the following source files.'
314
'\nThey should either be replaced by "\\t" or by spaces:'))
316
'Tab characters were found in the following source files.'
317
'\nThey should either be replaced by "\\t" or by spaces:'))
315
318
if illegal_newlines:
316
319
problems.append(self._format_message(illegal_newlines,
317
'Non-unix newlines were found in the following source files:'))
320
'Non-unix newlines were found in the following source files:'))
318
321
if no_newline_at_eof:
319
322
no_newline_at_eof.sort()
320
323
problems.append("The following source files doesn't have a "
321
"newline at the end:"
323
% ('\n '.join(no_newline_at_eof)))
324
"newline at the end:"
326
% ('\n '.join(no_newline_at_eof)))
325
328
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)
336
from flake8.main.application import Application
337
from flake8.formatting.base import BaseFormatter
339
app.config = u'setup.cfg'
342
class Formatter(BaseFormatter):
351
app.file_checker_manager.report()
353
def handle(self, error):
354
self.errors.append(error)
358
except argparse.ArgumentError as e:
359
self.skipTest('broken flake8: %r' % e)
360
app.formatter = Formatter()
363
self.assertEqual(app.formatter.errors, [])
365
330
def test_no_asserts(self):
366
331
"""bzr shouldn't use the 'assert' statement."""
367
332
# assert causes too much variation between -O and not, and tends to
404
368
both_exc_and_no_exc = []
405
369
missing_except = []
406
common_classes = ('StaticTuple',)
407
370
class_re = re.compile(r'^(cdef\s+)?(public\s+)?'
408
371
r'(api\s+)?class (\w+).*:', re.MULTILINE)
372
extern_class_re = re.compile(r'## extern cdef class (\w+)',
409
374
except_re = re.compile(
410
375
r'cdef\s+' # start with cdef
411
376
r'([\w *]*?)\s*' # this is the return signature
416
381
for fname, text in self.get_source_file_contents(
417
382
extensions=('.pyx',)):
418
383
known_classes = {m[-1] for m in class_re.findall(text)}
419
known_classes.update(common_classes)
384
known_classes.update(extern_class_re.findall(text))
420
385
cdefs = except_re.findall(text)
421
386
for sig, func, exc_clause, no_exc_comment in cdefs:
422
387
if sig.startswith('api '):
448
413
error_msg.extend(('', ''))
450
415
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', )):
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))