1 """Reporter foundation for Coverage.""" |
1 """Reporter foundation for Coverage.""" |
2 |
2 |
3 import os |
3 import os |
4 from .codeunit import code_unit_factory |
4 from .codeunit import code_unit_factory |
|
5 from .misc import CoverageException, NoSource |
5 |
6 |
6 class Reporter(object): |
7 class Reporter(object): |
7 """A base class for all reporters.""" |
8 """A base class for all reporters.""" |
8 |
9 |
9 def __init__(self, coverage, ignore_errors=False): |
10 def __init__(self, coverage, ignore_errors=False): |
10 """Create a reporter. |
11 """Create a reporter. |
11 |
12 |
12 `coverage` is the coverage instance. `ignore_errors` controls how |
13 `coverage` is the coverage instance. `ignore_errors` controls how |
13 skittish the reporter will be during file processing. |
14 skittish the reporter will be during file processing. |
14 |
15 |
15 """ |
16 """ |
16 self.coverage = coverage |
17 self.coverage = coverage |
17 self.ignore_errors = ignore_errors |
18 self.ignore_errors = ignore_errors |
18 |
19 |
19 # The code units to report on. Set by find_code_units. |
20 # The code units to report on. Set by find_code_units. |
20 self.code_units = [] |
21 self.code_units = [] |
21 |
22 |
22 # The directory into which to place the report, used by some derived |
23 # The directory into which to place the report, used by some derived |
23 # classes. |
24 # classes. |
24 self.directory = None |
25 self.directory = None |
25 |
26 |
26 def find_code_units(self, morfs, omit_prefixes): |
27 def find_code_units(self, morfs, omit_prefixes): |
27 """Find the code units we'll report on. |
28 """Find the code units we'll report on. |
28 |
29 |
29 `morfs` is a list of modules or filenames. `omit_prefixes` is a list |
30 `morfs` is a list of modules or filenames. `omit_prefixes` is a list |
30 of prefixes to leave out of the list. |
31 of prefixes to leave out of the list. |
31 |
32 |
32 """ |
33 """ |
33 morfs = morfs or self.coverage.data.executed_files() |
34 morfs = morfs or self.coverage.data.executed_files() |
34 self.code_units = code_unit_factory( |
35 self.code_units = code_unit_factory( |
35 morfs, self.coverage.file_locator, omit_prefixes) |
36 morfs, self.coverage.file_locator, omit_prefixes) |
36 self.code_units.sort() |
37 self.code_units.sort() |
37 |
38 |
38 def report_files(self, report_fn, morfs, directory=None, |
39 def report_files(self, report_fn, morfs, directory=None, |
39 omit_prefixes=None): |
40 omit_prefixes=None): |
40 """Run a reporting function on a number of morfs. |
41 """Run a reporting function on a number of morfs. |
41 |
42 |
42 `report_fn` is called for each relative morf in `morfs`. |
43 `report_fn` is called for each relative morf in `morfs`. |
43 |
44 |
44 """ |
45 """ |
45 self.find_code_units(morfs, omit_prefixes) |
46 self.find_code_units(morfs, omit_prefixes) |
|
47 |
|
48 if not self.code_units: |
|
49 raise CoverageException("No data to report.") |
46 |
50 |
47 self.directory = directory |
51 self.directory = directory |
48 if self.directory and not os.path.exists(self.directory): |
52 if self.directory and not os.path.exists(self.directory): |
49 os.makedirs(self.directory) |
53 os.makedirs(self.directory) |
50 |
54 |
51 for cu in self.code_units: |
55 for cu in self.code_units: |
52 try: |
56 try: |
53 if not cu.relative: |
57 report_fn(cu, self.coverage._analyze(cu)) |
54 continue |
58 except NoSource: |
55 statements, excluded, missing, _ = self.coverage._analyze(cu) |
|
56 report_fn(cu, statements, excluded, missing) |
|
57 except KeyboardInterrupt: |
|
58 raise |
|
59 except: |
|
60 if not self.ignore_errors: |
59 if not self.ignore_errors: |
61 raise |
60 raise |