iannucci@chromium.org | 3665cd2 | 2013-11-07 09:37:03 +0000 | [diff] [blame] | 1 | """Summary reporting""" |
| 2 | |
| 3 | import sys |
| 4 | |
| 5 | from coverage.report import Reporter |
| 6 | from coverage.results import Numbers |
| 7 | from coverage.misc import NotPython |
| 8 | |
| 9 | |
| 10 | class SummaryReporter(Reporter): |
| 11 | """A reporter for writing the summary report.""" |
| 12 | |
| 13 | def __init__(self, coverage, config): |
| 14 | super(SummaryReporter, self).__init__(coverage, config) |
| 15 | self.branches = coverage.data.has_arcs() |
| 16 | |
| 17 | def report(self, morfs, outfile=None): |
| 18 | """Writes a report summarizing coverage statistics per module. |
| 19 | |
| 20 | `outfile` is a file object to write the summary to. |
| 21 | |
| 22 | """ |
| 23 | self.find_code_units(morfs) |
| 24 | |
| 25 | # Prepare the formatting strings |
| 26 | max_name = max([len(cu.name) for cu in self.code_units] + [5]) |
| 27 | fmt_name = "%%- %ds " % max_name |
| 28 | fmt_err = "%s %s: %s\n" |
| 29 | header = (fmt_name % "Name") + " Stmts Miss" |
| 30 | fmt_coverage = fmt_name + "%6d %6d" |
| 31 | if self.branches: |
| 32 | header += " Branch BrMiss" |
| 33 | fmt_coverage += " %6d %6d" |
| 34 | width100 = Numbers.pc_str_width() |
| 35 | header += "%*s" % (width100+4, "Cover") |
| 36 | fmt_coverage += "%%%ds%%%%" % (width100+3,) |
| 37 | if self.config.show_missing: |
| 38 | header += " Missing" |
| 39 | fmt_coverage += " %s" |
| 40 | rule = "-" * len(header) + "\n" |
| 41 | header += "\n" |
| 42 | fmt_coverage += "\n" |
| 43 | |
| 44 | if not outfile: |
| 45 | outfile = sys.stdout |
| 46 | |
| 47 | # Write the header |
| 48 | outfile.write(header) |
| 49 | outfile.write(rule) |
| 50 | |
| 51 | total = Numbers() |
| 52 | |
| 53 | for cu in self.code_units: |
| 54 | try: |
| 55 | analysis = self.coverage._analyze(cu) |
| 56 | nums = analysis.numbers |
| 57 | args = (cu.name, nums.n_statements, nums.n_missing) |
| 58 | if self.branches: |
| 59 | args += (nums.n_branches, nums.n_missing_branches) |
| 60 | args += (nums.pc_covered_str,) |
| 61 | if self.config.show_missing: |
| 62 | args += (analysis.missing_formatted(),) |
| 63 | outfile.write(fmt_coverage % args) |
| 64 | total += nums |
| 65 | except KeyboardInterrupt: # pragma: not covered |
| 66 | raise |
| 67 | except: |
| 68 | report_it = not self.config.ignore_errors |
| 69 | if report_it: |
| 70 | typ, msg = sys.exc_info()[:2] |
| 71 | if typ is NotPython and not cu.should_be_python(): |
| 72 | report_it = False |
| 73 | if report_it: |
| 74 | outfile.write(fmt_err % (cu.name, typ.__name__, msg)) |
| 75 | |
| 76 | if total.n_files > 1: |
| 77 | outfile.write(rule) |
| 78 | args = ("TOTAL", total.n_statements, total.n_missing) |
| 79 | if self.branches: |
| 80 | args += (total.n_branches, total.n_missing_branches) |
| 81 | args += (total.pc_covered_str,) |
| 82 | if self.config.show_missing: |
| 83 | args += ("",) |
| 84 | outfile.write(fmt_coverage % args) |
| 85 | |
| 86 | return total.pc_covered |