summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndoni Morales Alastruey <ylatuya@gmail.com>2012-05-09 23:14:29 +0200
committerAndoni Morales Alastruey <ylatuya@gmail.com>2012-05-10 10:45:49 +0200
commit76849d97274b9c9efa76a85491c5c8d8bdcc1b15 (patch)
treebf3fea85ef69270c677999d344b40a8c048e9991
parentf91c72117cad845835d1002688192d7aece786f6 (diff)
Makefile: add coverage rules
-rw-r--r--Makefile8
-rw-r--r--tools/show-coverage.py104
2 files changed, 112 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index c73031c2..92da11b7 100644
--- a/Makefile
+++ b/Makefile
@@ -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))