def get_stats_xml(db=None, whitelist=None, blacklist=None): '''return a header-only cobertura xml''' stats = get_stats(db=db, whitelist=whitelist, blacklist=blacklist) # calculate overall rates good_stats = [result for result in stats if type(result) is FileStatus] branch_rates = [result.branch_rate for result in good_stats if type(result.branch_rate) is Rate] line_rates = [result.line_rate for result in good_stats if type(result.line_rate) is Rate] line_rate = None if line_rates: line_rate = reduce(lambda result, rate: result | rate, line_rates[1:], line_rates[0]) branch_rate = None if branch_rates: branch_rate = reduce(lambda result, rate: result | rate, branch_rates[1:], branch_rates[0]) # create module xml nodes import time import lxml.etree as ET from lxml.builder import E packages = [] for result in good_stats: line_elements = [] for line in result.lines: line_element = E.line(number=str(line), hits=line in result.hit_count and \ str(result.hit_count[line]) or "0") if line in result.branches: line_element.set('branch', 'true') line_element.set('condition-coverage', "{0:}% ({1:})".format( int(result.conditions[line]*100), result.conditions[line])) line_elements.append(line_element) class_element = E("class", E.methods(), E.lines(*line_elements), name=os.path.basename(result.filename), complexity='0.00', filename=result.filename) class_element.set('branch-rate', "%1.4f" % (result.branch_rate or 0.0)) class_element.set('line-rate', "%1.4f" % (result.line_rate or 0.0)) package = E.package(E.classes(class_element), name="", complexity='0.00') package.set('branch-rate', "%1.4f" % (result.branch_rate or 0.0)) package.set('line-rate', "%1.4f" % (result.line_rate or 0.0)) packages.append(package) tree = E.coverage( E.packages(*packages), timestamp=str(int(time.time()*1000)), version='3.7', complexity='0.00' ) tree.set('branch-rate', '%1.4f' % (branch_rate or 0.0)) tree.set('line-rate', '%1.4f' % (line_rate or 0.0)) tree.set('lines-covered', line_rate and str(line_rate.numerator) or "0") tree.set('lines-valid', line_rate and str(line_rate.denominator) or "0") tree.set('branches-covered', branch_rate and str(branch_rate.numerator) or "0") tree.set('branches-valid', branch_rate and str(branch_rate.denominator) or "0") return ET.tostring(tree, pretty_print=True, xml_declaration=True, doctype="<!DOCTYPE coverage SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>")
(WHT, IFO): PUSH([IFO, WHT]), # entering nested while statement from within if.orelse (WHB, FOT): PUSH([FOB]), # entering while.body (WHB, WHT): PUSH([WHB]), # entering while.body from within while.test (WHX, FOB): NOOP(), # leaving while statement from within for.body (WHX, IFB): NOOP(), # leaving while statement from within if.body (WHX, IFO): NOOP(), # leaving while statement from within if.orelse (WHX, WHB): NOOP(), # leaving while statement from within while.body (WHX, WHT): NOOP(), # leaving while statement from within while.body } # get data from redis # create xml skeleton E = ElementMaker() xml = E.coverage(E.sources(E.source(), E.source), E.packages()) xml_tree = etree.ElementTree(xml) xml.insert(0, etree.Comment("Generated by pushdown_moncov.py: http://github.com/python-moncov/bla-bla")) class PushDownAutomaton(object): # by default, use `lambda event, stack_event: None' callbacks for any event def __init__(self, stack=None, callbacks=collections.defaultdict(lambda: lambda event, stack_event: None)): if stack is None: stack = [BTT] self.reset(stack) self.callbacks = callbacks def reset(self, stack=None): if stack is None: