diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2009-10-15 06:38:10 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2009-10-15 06:38:10 -0400 |
commit | 19e52a9bdcfc3318efb2cdcbf1e9cf3343b3dbf8 (patch) | |
tree | 972db1acbbc684ed65af93e96f971e535e7d28c3 | |
parent | 3722bcb056f0d1bf5562d8c31341eaf0a7ae5977 (diff) | |
download | python-coveragepy-git-19e52a9bdcfc3318efb2cdcbf1e9cf3343b3dbf8.tar.gz |
Refactor the analysis results so we aren't passing so many tuples around.
-rw-r--r-- | coverage/annotate.py | 6 | ||||
-rw-r--r-- | coverage/control.py | 90 | ||||
-rw-r--r-- | coverage/html.py | 16 | ||||
-rw-r--r-- | coverage/report.py | 3 | ||||
-rw-r--r-- | coverage/summary.py | 8 | ||||
-rw-r--r-- | coverage/xmlreport.py | 10 |
6 files changed, 74 insertions, 59 deletions
diff --git a/coverage/annotate.py b/coverage/annotate.py index 3130c001..2fa9d5cf 100644 --- a/coverage/annotate.py +++ b/coverage/annotate.py @@ -37,7 +37,7 @@ class AnnotateReporter(Reporter): """Run the report.""" self.report_files(self.annotate_file, morfs, directory, omit_prefixes) - def annotate_file(self, cu, statements, excluded, missing): + def annotate_file(self, cu, analysis): """Annotate a single file. `cu` is the CodeUnit for the file to annotate. @@ -55,6 +55,10 @@ class AnnotateReporter(Reporter): dest_file = filename + ",cover" dest = open(dest_file, 'w') + statements = analysis.statements + missing = analysis.missing + excluded = analysis.excluded + lineno = 0 i = 0 j = 0 diff --git a/coverage/control.py b/coverage/control.py index 275e21ed..0db77ec1 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -242,51 +242,16 @@ class coverage: """ code_unit = code_unit_factory(morf, self.file_locator)[0] - st, ex, m, mf = self._analyze(code_unit) - return code_unit.filename, st, ex, m, mf + analysis = self._analyze(code_unit) + return code_unit.filename, analysis.statements, analysis.excluded, analysis.missing, analysis.missing_formatted() def _analyze(self, code_unit): """Analyze a single code unit. - Returns a 4-tuple: (statements, excluded, missing, missing formatted). + Returns an `Analysis` object. """ - from coverage.parser import CodeParser - - filename = code_unit.filename - ext = os.path.splitext(filename)[1] - source = None - if ext == '.py': - if not os.path.exists(filename): - source = self.file_locator.get_zip_data(filename) - if not source: - raise CoverageException( - "No source for code '%s'." % code_unit.filename - ) - - parser = CodeParser( - text=source, filename=filename, exclude=self.exclude_re - ) - statements, excluded, line_map = parser.parse_source() - - # Identify missing statements. - missing = [] - execed = self.data.executed_lines(filename) - for line in statements: - lines = line_map.get(line) - if lines: - for l in range(lines[0], lines[1]+1): - if l in execed: - break - else: - missing.append(line) - else: - if line not in execed: - missing.append(line) - - return ( - statements, excluded, missing, format_lines(statements, missing) - ) + return Analysis(self, code_unit) def report(self, morfs=None, show_missing=True, ignore_errors=False, file=None, omit_prefixes=None): # pylint: disable-msg=W0622 @@ -357,3 +322,50 @@ class coverage: ]), ] return info + + +class Analysis: + """The results of analyzing a code unit.""" + + def __init__(self, cov, code_unit): + self.code_unit = code_unit + + from coverage.parser import CodeParser + + filename = code_unit.filename + ext = os.path.splitext(filename)[1] + source = None + if ext == '.py': + if not os.path.exists(filename): + source = cov.file_locator.get_zip_data(filename) + if not source: + raise CoverageException( + "No source for code '%s'." % code_unit.filename + ) + + parser = CodeParser( + text=source, filename=filename, exclude=cov.exclude_re + ) + self.statements, self.excluded, line_map = parser.parse_source() + + # Identify missing statements. + self.missing = [] + execed = cov.data.executed_lines(filename) + for line in self.statements: + lines = line_map.get(line) + if lines: + for l in range(lines[0], lines[1]+1): + if l in execed: + break + else: + self.missing.append(line) + else: + if line not in execed: + self.missing.append(line) + + def missing_formatted(self): + return format_lines(self.statements, self.missing) + + #return ( + # statements, excluded, missing, format_lines(statements, missing) + # ) diff --git a/coverage/html.py b/coverage/html.py index f096c728..d5811317 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -82,15 +82,15 @@ class HtmlReporter(Reporter): os.path.join(directory, "jquery-1.3.2.min.js") ) - def html_file(self, cu, statements, excluded, missing): + def html_file(self, cu, analysis): """Generate an HTML file for one source file.""" source = cu.source_file().read().expandtabs(4) source_lines = source.split("\n") - n_stm = len(statements) - n_exc = len(excluded) - n_mis = len(missing) + n_stm = len(analysis.statements) + n_exc = len(analysis.excluded) + n_mis = len(analysis.missing) n_run = n_stm - n_mis if n_stm > 0: pc_cov = 100.0 * n_run / n_stm @@ -114,13 +114,13 @@ class HtmlReporter(Reporter): if part == '\n': line_class = "" - if lineno in statements: + if lineno in analysis.statements: line_class += " stm" - if lineno not in missing and lineno not in excluded: + if lineno not in analysis.missing and lineno not in analysis.excluded: line_class += c_run - if lineno in excluded: + if lineno in analysis.excluded: line_class += c_exc - if lineno in missing: + if lineno in analysis.missing: line_class += c_mis lineinfo = { diff --git a/coverage/report.py b/coverage/report.py index 0ae4ce64..8b069d7a 100644 --- a/coverage/report.py +++ b/coverage/report.py @@ -50,8 +50,7 @@ class Reporter(object): for cu in self.code_units: try: - statements, excluded, missing, _ = self.coverage._analyze(cu) - report_fn(cu, statements, excluded, missing) + report_fn(cu, self.coverage._analyze(cu)) except KeyboardInterrupt: raise except: diff --git a/coverage/summary.py b/coverage/summary.py index 916b41e7..989256fc 100644 --- a/coverage/summary.py +++ b/coverage/summary.py @@ -41,16 +41,16 @@ class SummaryReporter(Reporter): for cu in self.code_units: try: - statements, _, missing, readable = self.coverage._analyze(cu) - n = len(statements) - m = n - len(missing) + analysis = self.coverage._analyze(cu) + n = len(analysis.statements) + m = n - len(analysis.missing) if n > 0: pc = 100.0 * m / n else: pc = 100.0 args = (cu.name, n, m, pc) if self.show_missing: - args = args + (readable,) + args = args + (analysis.missing_formatted(),) outfile.write(fmt_coverage % args) total_units += 1 total_statements = total_statements + n diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py index 9898e7e1..155f7bf5 100644 --- a/coverage/xmlreport.py +++ b/coverage/xmlreport.py @@ -80,7 +80,7 @@ class XmlReporter(Reporter): # Use the DOM to write the output file. outfile.write(self.xml_out.toprettyxml()) - def xml_file(self, cu, statements, excluded_unused, missing): + def xml_file(self, cu, analysis): """Add to the XML report for a single file.""" # Create the 'lines' and 'package' XML elements, which @@ -101,14 +101,14 @@ class XmlReporter(Reporter): xclass.setAttribute("complexity", "0.0") # For each statement, create an XML 'line' element. - for line in statements: + for line in analysis.statements: l = self.xml_out.createElement("line") l.setAttribute("number", str(line)) # Q: can we get info about the number of times # a statement is executed? If so, that should be # recorded here. - l.setAttribute("hits", str(int(not line in missing))) + l.setAttribute("hits", str(int(not line in analysis.missing))) # Q: can we get info about whether this statement # is a branch? If so, that data should be @@ -116,8 +116,8 @@ class XmlReporter(Reporter): #l.setAttribute("branch", "false") xlines.appendChild(l) - class_lines = 1.0 * len(statements) - class_hits = class_lines - len(missing) + class_lines = 1.0 * len(analysis.statements) + class_hits = class_lines - len(analysis.missing) class_branches = 0.0 class_branch_hits = 0.0 |