diff options
Diffstat (limited to 'chromium/tools/code_coverage/croc_html.py')
-rw-r--r-- | chromium/tools/code_coverage/croc_html.py | 451 |
1 files changed, 0 insertions, 451 deletions
diff --git a/chromium/tools/code_coverage/croc_html.py b/chromium/tools/code_coverage/croc_html.py deleted file mode 100644 index 7866f472f7b..00000000000 --- a/chromium/tools/code_coverage/croc_html.py +++ /dev/null @@ -1,451 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Crocodile HTML output.""" - -import os -import shutil -import time -import xml.dom - - -class CrocHtmlError(Exception): - """Coverage HTML error.""" - - -class HtmlElement(object): - """Node in a HTML file.""" - - def __init__(self, doc, element): - """Constructor. - - Args: - doc: XML document object. - element: XML element. - """ - self.doc = doc - self.element = element - - def E(self, name, **kwargs): - """Adds a child element. - - Args: - name: Name of element. - kwargs: Attributes for element. To use an attribute which is a python - reserved word (i.e. 'class'), prefix the attribute name with 'e_'. - - Returns: - The child element. - """ - he = HtmlElement(self.doc, self.doc.createElement(name)) - element = he.element - self.element.appendChild(element) - - for k, v in kwargs.iteritems(): - if k.startswith('e_'): - # Remove prefix - element.setAttribute(k[2:], str(v)) - else: - element.setAttribute(k, str(v)) - - return he - - def Text(self, text): - """Adds a text node. - - Args: - text: Text to add. - - Returns: - self. - """ - t = self.doc.createTextNode(str(text)) - self.element.appendChild(t) - return self - - -class HtmlFile(object): - """HTML file.""" - - def __init__(self, xml_impl, filename): - """Constructor. - - Args: - xml_impl: DOMImplementation to use to create document. - filename: Path to file. - """ - self.xml_impl = xml_impl - doctype = xml_impl.createDocumentType( - 'HTML', '-//W3C//DTD HTML 4.01//EN', - 'http://www.w3.org/TR/html4/strict.dtd') - self.doc = xml_impl.createDocument(None, 'html', doctype) - self.filename = filename - - # Create head and body elements - root = HtmlElement(self.doc, self.doc.documentElement) - self.head = root.E('head') - self.body = root.E('body') - - def Write(self, cleanup=True): - """Writes the file. - - Args: - cleanup: If True, calls unlink() on the internal xml document. This - frees up memory, but means that you can't use this file for anything - else. - """ - f = open(self.filename, 'wt') - self.doc.writexml(f, encoding='UTF-8') - f.close() - - if cleanup: - self.doc.unlink() - # Prevent future uses of the doc now that we've unlinked it - self.doc = None - -#------------------------------------------------------------------------------ - -COV_TYPE_STRING = {None: 'm', 0: 'i', 1: 'E', 2: ' '} -COV_TYPE_CLASS = {None: 'missing', 0: 'instr', 1: 'covered', 2: ''} - - -class CrocHtml(object): - """Crocodile HTML output class.""" - - def __init__(self, cov, output_root, base_url=None): - """Constructor.""" - self.cov = cov - self.output_root = output_root - self.base_url = base_url - self.xml_impl = xml.dom.getDOMImplementation() - self.time_string = 'Coverage information generated %s.' % time.asctime() - - def CreateHtmlDoc(self, filename, title): - """Creates a new HTML document. - - Args: - filename: Filename to write to, relative to self.output_root. - title: Title of page - - Returns: - The document. - """ - f = HtmlFile(self.xml_impl, self.output_root + '/' + filename) - - f.head.E('title').Text(title) - - if self.base_url: - css_href = self.base_url + 'croc.css' - base_href = self.base_url + os.path.dirname(filename) - if not base_href.endswith('/'): - base_href += '/' - f.head.E('base', href=base_href) - else: - css_href = '../' * (len(filename.split('/')) - 1) + 'croc.css' - - f.head.E('link', rel='stylesheet', type='text/css', href=css_href) - - return f - - def AddCaptionForFile(self, body, path): - """Adds a caption for the file, with links to each parent dir. - - Args: - body: Body elemement. - path: Path to file. - """ - # This is slightly different that for subdir, because it needs to have a - # link to the current directory's index.html. - hdr = body.E('h2') - hdr.Text('Coverage for ') - dirs = [''] + path.split('/') - num_dirs = len(dirs) - for i in range(num_dirs - 1): - hdr.E('a', href=( - '../' * (num_dirs - i - 2) + 'index.html')).Text(dirs[i] + '/') - hdr.Text(dirs[-1]) - - def AddCaptionForSubdir(self, body, path): - """Adds a caption for the subdir, with links to each parent dir. - - Args: - body: Body elemement. - path: Path to subdir. - """ - # Link to parent dirs - hdr = body.E('h2') - hdr.Text('Coverage for ') - dirs = [''] + path.split('/') - num_dirs = len(dirs) - for i in range(num_dirs - 1): - hdr.E('a', href=( - '../' * (num_dirs - i - 1) + 'index.html')).Text(dirs[i] + '/') - hdr.Text(dirs[-1] + '/') - - def AddSectionHeader(self, table, caption, itemtype, is_file=False): - """Adds a section header to the coverage table. - - Args: - table: Table to add rows to. - caption: Caption for section, if not None. - itemtype: Type of items in this section, if not None. - is_file: Are items in this section files? - """ - - if caption is not None: - table.E('tr').E('th', e_class='secdesc', colspan=8).Text(caption) - - sec_hdr = table.E('tr') - - if itemtype is not None: - sec_hdr.E('th', e_class='section').Text(itemtype) - - sec_hdr.E('th', e_class='section').Text('Coverage') - sec_hdr.E('th', e_class='section', colspan=3).Text( - 'Lines executed / instrumented / missing') - - graph = sec_hdr.E('th', e_class='section') - graph.E('span', style='color:#00FF00').Text('exe') - graph.Text(' / ') - graph.E('span', style='color:#FFFF00').Text('inst') - graph.Text(' / ') - graph.E('span', style='color:#FF0000').Text('miss') - - if is_file: - sec_hdr.E('th', e_class='section').Text('Language') - sec_hdr.E('th', e_class='section').Text('Group') - else: - sec_hdr.E('th', e_class='section', colspan=2) - - def AddItem(self, table, itemname, stats, attrs, link=None): - """Adds a bar graph to the element. This is a series of <td> elements. - - Args: - table: Table to add item to. - itemname: Name of item. - stats: Stats object. - attrs: Attributes dictionary; if None, no attributes will be printed. - link: Destination for itemname hyperlink, if not None. - """ - row = table.E('tr') - - # Add item name - if itemname is not None: - item_elem = row.E('td') - if link is not None: - item_elem = item_elem.E('a', href=link) - item_elem.Text(itemname) - - # Get stats - stat_exe = stats.get('lines_executable', 0) - stat_ins = stats.get('lines_instrumented', 0) - stat_cov = stats.get('lines_covered', 0) - - percent = row.E('td') - - # Add text - row.E('td', e_class='number').Text(stat_cov) - row.E('td', e_class='number').Text(stat_ins) - row.E('td', e_class='number').Text(stat_exe - stat_ins) - - # Add percent and graph; only fill in if there's something in there - graph = row.E('td', e_class='graph', width=100) - if stat_exe: - percent_cov = 100.0 * stat_cov / stat_exe - percent_ins = 100.0 * stat_ins / stat_exe - - # Color percent based on thresholds - percent.Text('%.1f%%' % percent_cov) - if percent_cov >= 80: - percent.element.setAttribute('class', 'high_pct') - elif percent_cov >= 60: - percent.element.setAttribute('class', 'mid_pct') - else: - percent.element.setAttribute('class', 'low_pct') - - # Graphs use integer values - percent_cov = int(percent_cov) - percent_ins = int(percent_ins) - - graph.Text('.') - graph.E('span', style='padding-left:%dpx' % percent_cov, - e_class='g_covered') - graph.E('span', style='padding-left:%dpx' % (percent_ins - percent_cov), - e_class='g_instr') - graph.E('span', style='padding-left:%dpx' % (100 - percent_ins), - e_class='g_missing') - - if attrs: - row.E('td', e_class='stat').Text(attrs.get('language')) - row.E('td', e_class='stat').Text(attrs.get('group')) - else: - row.E('td', colspan=2) - - def WriteFile(self, cov_file): - """Writes the HTML for a file. - - Args: - cov_file: croc.CoveredFile to write. - """ - print ' ' + cov_file.filename - title = 'Coverage for ' + cov_file.filename - - f = self.CreateHtmlDoc(cov_file.filename + '.html', title) - body = f.body - - # Write header section - self.AddCaptionForFile(body, cov_file.filename) - - # Summary for this file - table = body.E('table') - self.AddSectionHeader(table, None, None, is_file=True) - self.AddItem(table, None, cov_file.stats, cov_file.attrs) - - body.E('h2').Text('Line-by-line coverage:') - - # Print line-by-line coverage - if cov_file.local_path: - code_table = body.E('table').E('tr').E('td').E('pre') - - flines = open(cov_file.local_path, 'rt') - lineno = 0 - - for line in flines: - lineno += 1 - line_cov = cov_file.lines.get(lineno, 2) - e_class = COV_TYPE_CLASS.get(line_cov) - - code_table.E('span', e_class=e_class).Text('%4d %s : %s\n' % ( - lineno, - COV_TYPE_STRING.get(line_cov), - line.rstrip() - )) - - else: - body.Text('Line-by-line coverage not available. Make sure the directory' - ' containing this file has been scanned via ') - body.E('B').Text('add_files') - body.Text(' in a configuration file, or the ') - body.E('B').Text('--addfiles') - body.Text(' command line option.') - - # TODO: if file doesn't have a local path, try to find it by - # reverse-mapping roots and searching for the file. - - body.E('p', e_class='time').Text(self.time_string) - f.Write() - - def WriteSubdir(self, cov_dir): - """Writes the index.html for a subdirectory. - - Args: - cov_dir: croc.CoveredDir to write. - """ - print ' ' + cov_dir.dirpath + '/' - - # Create the subdir if it doesn't already exist - subdir = self.output_root + '/' + cov_dir.dirpath - if not os.path.exists(subdir): - os.mkdir(subdir) - - if cov_dir.dirpath: - title = 'Coverage for ' + cov_dir.dirpath + '/' - f = self.CreateHtmlDoc(cov_dir.dirpath + '/index.html', title) - else: - title = 'Coverage summary' - f = self.CreateHtmlDoc('index.html', title) - - body = f.body - - dirs = [''] + cov_dir.dirpath.split('/') - num_dirs = len(dirs) - sort_jsfile = '../' * (num_dirs - 1) + 'sorttable.js' - script = body.E('script', src=sort_jsfile) - body.E('/script') - - # Write header section - if cov_dir.dirpath: - self.AddCaptionForSubdir(body, cov_dir.dirpath) - else: - body.E('h2').Text(title) - - table = body.E('table', e_class='sortable') - table.E('h3').Text('Coverage by Group') - # Coverage by group - self.AddSectionHeader(table, None, 'Group') - - for group in sorted(cov_dir.stats_by_group): - self.AddItem(table, group, cov_dir.stats_by_group[group], None) - - # List subdirs - if cov_dir.subdirs: - table = body.E('table', e_class='sortable') - table.E('h3').Text('Subdirectories') - self.AddSectionHeader(table, None, 'Subdirectory') - - for d in sorted(cov_dir.subdirs): - self.AddItem(table, d + '/', cov_dir.subdirs[d].stats_by_group['all'], - None, link=d + '/index.html') - - # List files - if cov_dir.files: - table = body.E('table', e_class='sortable') - table.E('h3').Text('Files in This Directory') - self.AddSectionHeader(table, None, 'Filename', - is_file=True) - - for filename in sorted(cov_dir.files): - cov_file = cov_dir.files[filename] - self.AddItem(table, filename, cov_file.stats, cov_file.attrs, - link=filename + '.html') - - body.E('p', e_class='time').Text(self.time_string) - f.Write() - - def WriteRoot(self): - """Writes the files in the output root.""" - # Find ourselves - src_dir = os.path.split(self.WriteRoot.func_code.co_filename)[0] - - # Files to copy into output root - copy_files = ['croc.css'] - # Third_party files to copy into output root - third_party_files = ['sorttable.js'] - - # Copy files from our directory into the output directory - for copy_file in copy_files: - print ' Copying %s' % copy_file - shutil.copyfile(os.path.join(src_dir, copy_file), - os.path.join(self.output_root, copy_file)) - # Copy third party files from third_party directory into - # the output directory - src_dir = os.path.join(src_dir, 'third_party') - for third_party_file in third_party_files: - print ' Copying %s' % third_party_file - shutil.copyfile(os.path.join(src_dir, third_party_file), - os.path.join(self.output_root, third_party_file)) - - def Write(self): - """Writes HTML output.""" - - print 'Writing HTML to %s...' % self.output_root - - # Loop through the tree and write subdirs, breadth-first - # TODO: switch to depth-first and sort values - makes nicer output? - todo = [self.cov.tree] - while todo: - cov_dir = todo.pop(0) - - # Append subdirs to todo list - todo += cov_dir.subdirs.values() - - # Write this subdir - self.WriteSubdir(cov_dir) - - # Write files in this subdir - for cov_file in cov_dir.files.itervalues(): - self.WriteFile(cov_file) - - # Write files in root directory - self.WriteRoot() |