Ned Batchelder avatar Ned Batchelder committed 033dfc7

Clean up the plugins more. Add the rcfile and include options. Omit can no longer be a file of omissions, use the rcfile for that.

Comments (0)

Files changed (6)

 Coverage TODO
 
 * plugin work
-    - add --cover-include.
-    - add --cover-rcfile, and maybe remove a bunch of options.
+    + add --cover-include.
+    + add --cover-rcfile.
+    - maybe remove a bunch of options.
 
 * 3.3
 

coverage/cmdline.py

         # Listify the list options.
         omit = None
         if options.omit:
-            omit = self.pattern_list(options.omit)
+            omit = pattern_list(options.omit)
         include = None
         if options.include:
-            include = self.pattern_list(options.include)
+            include = pattern_list(options.include)
 
         # Do something.
         self.coverage = self.covpkg.coverage(
             self.coverage.save()
 
         # Remaining actions are reporting, with some common options.
-        report_args = {
-            'morfs': args,
-            'ignore_errors': options.ignore_errors,
-            }
-
-        report_args['omit'] = omit
-        report_args['include'] = include
+        report_args = dict(
+            morfs = args,
+            ignore_errors = options.ignore_errors,
+            omit = omit,
+            include = include,
+            )
 
         if 'report' in options.actions:
             self.coverage.report(
 
         return OK
 
-    def pattern_list(self, s):
-        """Turn an argument into a list of patterns."""
-        if sys.platform == 'win32':
-            # When running coverage as coverage.exe, some of the behavior
-            # of the shell is emulated: wildcards are expanded into a list of
-            # filenames.  So you have to single-quote patterns on the command
-            # line, but (not) helpfully, the single quotes are included in the
-            # argument, so we have to strip them off here.
-            s = s.strip("'")
-        return s.split(',')
+
+def pattern_list(s):
+    """Turn an argument into a list of patterns."""
+    if sys.platform == 'win32':
+        # When running coverage as coverage.exe, some of the behavior
+        # of the shell is emulated: wildcards are expanded into a list of
+        # filenames.  So you have to single-quote patterns on the command
+        # line, but (not) helpfully, the single quotes are included in the
+        # argument, so we have to strip them off here.
+        s = s.strip("'")
+    return s.split(',')
 
 
 HELP_TOPICS = r"""

coverage/runners/noseplugin.py

 import logging
 from nose.plugins import Plugin
 
-from coverage.runners.plugin import CoverageTestWrapper, options as coverage_opts
+from coverage.runners.plugin import CoverageTestWrapper
+from coverage.runners.plugin import options as coverage_opts
 
 
-log = logging.getLogger(__name__)
+log = logging.getLogger("nose.plugins.coverage")
 
 
 class Coverage(Plugin):
-    """Nose plugin for coverage reporting."""
+    """The nose plugin to measure test coverage."""
 
-    score = 1
+    score = 200
     status = {}
 
+    def help(self):
+        """The help for the --with-coverage option."""
+        return "Measure test coverage using coverage.py."
+
     def options(self, parser, env):
         """Add command-line options."""
 
 
         self.config = config
         self.status['active'] = True
-        self.options = options
+        self.opts = options
 
     def begin(self):
         """Begin recording coverage information."""
 
         log.debug("Coverage begin")
-        self.coverage = CoverageTestWrapper(self.options)
+        self.coverage = CoverageTestWrapper(self.opts)
         self.coverage.start()
 
     def report(self, stream):

coverage/runners/plugin.py

 
 import optparse, sys
 import coverage
+from coverage.cmdline import pattern_list
+
 
 class CoverageTestWrapper(object):
     """A coverage test wrapper.
         self.coverPackages = options.cover_package
 
     def start(self):
+        # cover_omit is a ',' separated list if provided
+        self.omit = pattern_list(self.options.cover_omit)
+        self.include = pattern_list(self.options.cover_omit)
+
         self.coverage = self.covpkg.coverage(
+            config_file = self.options.cover_rcfile,
             data_suffix = bool(self.options.cover_parallel_mode),
             cover_pylib = self.options.cover_pylib,
             timid = self.options.cover_timid,
             branch = self.options.cover_branch,
+            include = self.include,
+            omit = self.omit,
         )
 
-        self.skipModules = sys.modules.keys()[:] #TODO: is this necessary??
-
         self.coverage.start()
 
     def finish(self, stream=None):
         modules = [module for name, module in sys.modules.items()
                    if self._want_module(name, module)]
 
-        # Remaining actions are reporting, with some common self.options.
-        report_args = {
-            'morfs': modules,
-            'ignore_errors': self.options.cover_ignore_errors,
-            }
+        # Remaining actions are reporting, with some common options.
+        report_args = dict(
+            morfs = modules,
+            ignore_errors = True,
+            omit = self.omit,
+            include = self.include,
+            )
 
-        try: # try looking for an omit file
-            omit_file = open(self.options.cover_omit)
-            omit = [line.strip() for line in omit_file.readlines()]
-            report_args['omit'] = omit
-        except: # assume cover_omit is a ',' separated list if provided
-            omit = self.options.cover_omit.split(',')
-            report_args['omit'] = omit
-
-        if 'report' in self.options.cover_actions:
+        if 'report' in self.options.cover_reports:
             self.coverage.report(
                     show_missing=self.options.cover_show_missing,
                     file=stream, **report_args)
-        if 'annotate' in self.options.cover_actions:
+        if 'annotate' in self.options.cover_reports:
             self.coverage.annotate(
                     directory=self.options.cover_directory, **report_args)
-        if 'html' in self.options.cover_actions:
+        if 'html' in self.options.cover_reports:
             self.coverage.html_report(
                     directory=self.options.cover_directory, **report_args)
-        if 'xml' in self.options.cover_actions:
+        if 'xml' in self.options.cover_reports:
             outfile = self.options.cover_outfile
             if outfile == '-':
                 outfile = None
 
 
 options = [
-    optparse.Option('--cover-action', action='append', default=['report'],
-                    dest='cover_actions', type="choice",
+    optparse.Option('--cover-rcfile', action='store', metavar="RC",
+                    help="Specify configuration file.  ['.coveragerc']",
+                    default=True),
+
+    optparse.Option('--cover-report', action='append', default=['report'],
+                    dest='cover_reports', type="choice",
                     choices=['annotate', 'html', 'report', 'xml'],
-                    help="""\
-annotate    Annotate source files with execution information.
-html        Create an HTML report.
-report      Report coverage stats on modules.
-xml         Create an XML report of coverage results.
-                    """.strip()),
+                    help=("Choose what coverage report(s) to create: "
+                        "annotate: Annotated source files; "
+                        "html: Browsable HTML report; "
+                        "report: Simple text report; "
+                        "xml: Cobertura-compatible XML report.")
+                    ),
 
     optparse.Option('--cover-package', action='append', default=[],
                     dest="cover_package", metavar="COVER_PACKAGE",
     optparse.Option('--cover-directory', action='store', metavar="DIR",
                     help="Write the output files to DIR."),
 
-    optparse.Option('--cover-ignore-errors', action='store_true',
-                    help="Ignore errors while reading source files."),
-
     optparse.Option('--cover-pylib', action='store_true',
                     help=("Measure coverage even inside the Python installed "
                          "library, which isn't done by default.")),
                     help=("Show line numbers of statements in each module "
                          "that weren't executed.")),
 
+    optparse.Option('--cover-include', action='store',
+                    metavar="PAT1,PAT2,...", default='',
+                    help=("Include files when their filename path matches one "
+                         "of these file patterns.")),
+
     optparse.Option('--cover-omit', action='store',
-                    metavar="PRE1,PRE2,...", default='',
+                    metavar="PAT1,PAT2,...", default='',
                     help=("Omit files when their filename path matches one "
-                         "of these patterns.")),
+                         "of these file patterns.")),
 
     optparse.Option('--cover-outfile', action='store', metavar="OUTFILE",
                     help=("Write the XML report to this file. Defaults to "
         'pytest11': [
             'coverage = coverage.runners.pytestplugin',
             ],
-        'nose.plugins.0.10': [
+        'nose.plugins': [
             'coverage = coverage.runners.noseplugin:Coverage',
             ],
         },

test/test_testplugin.py

 class TestCoverage(PluginTester, unittest.TestCase):
     activate = '--with-coverage' # enables the plugin
     plugins = [Coverage()]
-    args = ['--cover-action=report']
+    args = ['--cover-report=report']
 
     @py.test.mark.skipif(True) # "requires nose test runner"
     def test_output(self):
         def test_whatever():
             pass
         """)
-    result = testdir.runpytest("--cover-action=annotate")
+    result = testdir.runpytest("--cover-report=annotate")
     assert result.ret == 0
     assert result.stdout.fnmatch_lines([
         '*Processing Coverage*'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.