diff options
author | Andoni Morales Alastruey <ylatuya@gmail.com> | 2012-05-09 23:14:29 +0200 |
---|---|---|
committer | Andoni Morales Alastruey <ylatuya@gmail.com> | 2012-05-10 10:45:49 +0200 |
commit | 76849d97274b9c9efa76a85491c5c8d8bdcc1b15 (patch) | |
tree | bf3fea85ef69270c677999d344b40a8c048e9991 | |
parent | f91c72117cad845835d1002688192d7aece786f6 (diff) |
Makefile: add coverage rules
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | tools/show-coverage.py | 104 |
2 files changed, 112 insertions, 0 deletions
@@ -16,3 +16,11 @@ dist-tarball: check: PYTHONPATH=$(PYTHONPATH):./test:./cerbero; trial test find cerbero ! -regex cerbero/packages/debian.py -name \*.py | sort -u | xargs pep8 --repeat + +coverage: + rm -rf _trial_temp + PYTHONPATH=$(PYTHONPATH):./test:./cerbero; trial --coverage test cerbero + make show-coverage + +show-coverage: + python tools/show-coverage.py _trial_temp/coverage/cerbero.* diff --git a/tools/show-coverage.py b/tools/show-coverage.py new file mode 100644 index 00000000..2e89ff42 --- /dev/null +++ b/tools/show-coverage.py @@ -0,0 +1,104 @@ +import os +import re +import sys + + +class Presentation: + + def __init__(self, name, lines, covered): + self.name = name + self.lines = lines + self.covered = covered + + if self.covered == 0: + self.percent = 0 + else: + self.percent = 100 * self.covered / float(self.lines) + + def show(self, maxlen=20): + format = '%%-%ds %%3d %%%% (%%4d / %%4d)' % maxlen + print format % (self.name, self.percent, self.covered, self.lines) + + +class Coverage: + + def __init__(self): + self.files = [] + self.total_lines = 0 + self.total_covered = 0 + + # The python Trace class prints coverage results by prefixing + # lines that got executed with a couple of spaces, the number + # of times it has been executed and a colon. Uncovered lines + # get prefixed with six angle brackets. Lines like comments + # and blank lines just get indented. + # This regexp will match executed and executable-but-not-covered lines. + self.codeline_matcher = re.compile(r'^(>>>>>>)|(\s*\d+:)') + + def _strip_filename(self, filename): + filename = os.path.basename(filename) + if filename.endswith('.cover'): + filename = filename[:-6] + return filename + + def add_file(self, file): + self.files.append(file) + + def show_results(self): + if not hasattr(self, 'files'): + print 'No coverage data' + return + + if self.files: + self.maxlen = max(map(lambda f: len(self._strip_filename(f)), + self.files)) + else: + self.maxlen = 0 + + print 'Coverage report:' + print '-' * (self.maxlen + 23) + for file in self.files: + self.show_one(file) + print '-' * (self.maxlen + 23) + + p = Presentation('Total', self.total_lines, self.total_covered) + p.show(self.maxlen) + + def show_one(self, filename): + f = open(filename) + # Grab all executables lines + lines = [line for line in f.readlines() + if self.codeline_matcher.match(line)] + + # Find out which of them were not executed + uncovered_lines = [line for line in lines + if line.startswith('>>>>>>')] + if not lines: + return + + filename = self._strip_filename(filename) + + p = Presentation(filename, + len(lines), + len(lines) - len(uncovered_lines)) + p.show(self.maxlen) + + self.total_lines += p.lines + self.total_covered += p.covered + + +def main(args): + c = Coverage() + files = args[1:] + files.sort() + for file in files: + if 'flumotion.test' in file: + continue + if '__init__' in file: + continue + c.add_file(file) + + c.show_results() + +if __name__ == '__main__': + sys.exit(main(sys.argv)) |