1 """Reporter foundation for Coverage.""" |
1 """Reporter foundation for Coverage.""" |
2 |
2 |
3 import os |
3 import fnmatch, os |
4 from .codeunit import code_unit_factory |
4 from .codeunit import code_unit_factory |
5 from .misc import CoverageException, NoSource |
5 from .files import prep_patterns |
|
6 from .misc import CoverageException, NoSource, NotPython |
6 |
7 |
7 class Reporter(object): |
8 class Reporter(object): |
8 """A base class for all reporters.""" |
9 """A base class for all reporters.""" |
9 |
10 |
10 def __init__(self, coverage, ignore_errors=False): |
11 def __init__(self, coverage, config): |
11 """Create a reporter. |
12 """Create a reporter. |
12 |
13 |
13 `coverage` is the coverage instance. `ignore_errors` controls how |
14 `coverage` is the coverage instance. `config` is an instance of |
14 skittish the reporter will be during file processing. |
15 CoverageConfig, for controlling all sorts of behavior. |
15 |
16 |
16 """ |
17 """ |
17 self.coverage = coverage |
18 self.coverage = coverage |
18 self.ignore_errors = ignore_errors |
19 self.config = config |
19 |
20 |
20 # The code units to report on. Set by find_code_units. |
21 # The code units to report on. Set by find_code_units. |
21 self.code_units = [] |
22 self.code_units = [] |
22 |
23 |
23 # The directory into which to place the report, used by some derived |
24 # The directory into which to place the report, used by some derived |
24 # classes. |
25 # classes. |
25 self.directory = None |
26 self.directory = None |
26 |
27 |
27 def find_code_units(self, morfs, omit_prefixes): |
28 def find_code_units(self, morfs): |
28 """Find the code units we'll report on. |
29 """Find the code units we'll report on. |
29 |
30 |
30 `morfs` is a list of modules or filenames. `omit_prefixes` is a list |
31 `morfs` is a list of modules or filenames. |
31 of prefixes to leave out of the list. |
|
32 |
32 |
33 """ |
33 """ |
34 morfs = morfs or self.coverage.data.executed_files() |
34 morfs = morfs or self.coverage.data.measured_files() |
35 self.code_units = code_unit_factory( |
35 file_locator = self.coverage.file_locator |
36 morfs, self.coverage.file_locator, omit_prefixes) |
36 self.code_units = code_unit_factory(morfs, file_locator) |
|
37 |
|
38 if self.config.include: |
|
39 patterns = prep_patterns(self.config.include) |
|
40 filtered = [] |
|
41 for cu in self.code_units: |
|
42 for pattern in patterns: |
|
43 if fnmatch.fnmatch(cu.filename, pattern): |
|
44 filtered.append(cu) |
|
45 break |
|
46 self.code_units = filtered |
|
47 |
|
48 if self.config.omit: |
|
49 patterns = prep_patterns(self.config.omit) |
|
50 filtered = [] |
|
51 for cu in self.code_units: |
|
52 for pattern in patterns: |
|
53 if fnmatch.fnmatch(cu.filename, pattern): |
|
54 break |
|
55 else: |
|
56 filtered.append(cu) |
|
57 self.code_units = filtered |
|
58 |
37 self.code_units.sort() |
59 self.code_units.sort() |
38 |
60 |
39 def report_files(self, report_fn, morfs, directory=None, |
61 def report_files(self, report_fn, morfs, directory=None): |
40 omit_prefixes=None): |
|
41 """Run a reporting function on a number of morfs. |
62 """Run a reporting function on a number of morfs. |
42 |
63 |
43 `report_fn` is called for each relative morf in `morfs`. |
64 `report_fn` is called for each relative morf in `morfs`. It is called |
|
65 as:: |
|
66 |
|
67 report_fn(code_unit, analysis) |
|
68 |
|
69 where `code_unit` is the `CodeUnit` for the morf, and `analysis` is |
|
70 the `Analysis` for the morf. |
44 |
71 |
45 """ |
72 """ |
46 self.find_code_units(morfs, omit_prefixes) |
73 self.find_code_units(morfs) |
47 |
74 |
48 if not self.code_units: |
75 if not self.code_units: |
49 raise CoverageException("No data to report.") |
76 raise CoverageException("No data to report.") |
50 |
77 |
51 self.directory = directory |
78 self.directory = directory |