[Checkins] SVN: z3c.coverage/trunk/ - Feature: The ``main()``
coverage report function now accepts the arguments
Stephan Richter
srichter at cosmos.phy.tufts.edu
Tue Jan 29 13:22:32 EST 2008
Log message for revision 83302:
- Feature: The ``main()`` coverage report function now accepts the arguments
of the script as a function argument, making it easier to configure the
script from buildout.
- Feature: When the report directory does not exist, the report generator
creates it for you.
- Feature: Eat your own dog food by creating a buildout that can create
coverage reports.
- Bug: Improved the test coverage to 100%.
Get ready for release.
Changed:
_U z3c.coverage/trunk/
U z3c.coverage/trunk/CHANGES.txt
U z3c.coverage/trunk/README.txt
U z3c.coverage/trunk/buildout.cfg
U z3c.coverage/trunk/setup.py
A z3c.coverage/trunk/src/z3c/coverage/README.txt
U z3c.coverage/trunk/src/z3c/coverage/coveragediff.txt
U z3c.coverage/trunk/src/z3c/coverage/coveragereport.py
U z3c.coverage/trunk/src/z3c/coverage/tests.py
-=-
Property changes on: z3c.coverage/trunk
___________________________________________________________________
Name: svn:ignore
- develop-eggs
eggs
parts
.installed.cfg
build
dist
bin
+ .installed.cfg
bin
build
coverage
develop-eggs
dist
eggs
parts
Modified: z3c.coverage/trunk/CHANGES.txt
===================================================================
--- z3c.coverage/trunk/CHANGES.txt 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/CHANGES.txt 2008-01-29 18:22:32 UTC (rev 83302)
@@ -1,27 +1,47 @@
CHANGES
-------
+1.1.0 (2008-01-29)
+~~~~~~~~~~~~~~~~~~
+
+- Feature: The ``main()`` coverage report function now accepts the arguments
+ of the script as a function argument, making it easier to configure the
+ script from buildout.
+
+- Feature: When the report directory does not exist, the report generator
+ creates it for you.
+
+- Feature: Eat your own dog food by creating a buildout that can create
+ coverage reports.
+
+- Bug: Improved the test coverage to 100%.
+
+
1.0.1 (2007-09-26)
~~~~~~~~~~~~~~~~~~
-- Fixed meta-data.
+- Bug: Fixed meta-data.
+
1.0.0 (2007-09-26)
~~~~~~~~~~~~~~~~~~
- First public release.
+
0.2.1
~~~~~
-- Added the ``--web`` option to ``coveragediff``.
-- Added a test suite.
+- Feature: Added the ``--web`` option to ``coveragediff``.
+- Feature: Added a test suite.
+
0.2.0
~~~~~
-- Added ``coveragediff.py``.
+- Feature: Added ``coveragediff.py``.
+
0.1.0
~~~~~
Modified: z3c.coverage/trunk/README.txt
===================================================================
--- z3c.coverage/trunk/README.txt 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/README.txt 2008-01-29 18:22:32 UTC (rev 83302)
@@ -1,7 +1,3 @@
-============
-z3c.coverage
-============
-
This package produces a nice HTML representation of the coverage data
generated by the Zope test runner.
Modified: z3c.coverage/trunk/buildout.cfg
===================================================================
--- z3c.coverage/trunk/buildout.cfg 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/buildout.cfg 2008-01-29 18:22:32 UTC (rev 83302)
@@ -1,8 +1,19 @@
[buildout]
develop = .
-parts = test
+parts = test coverage-test coverage-report
[test]
recipe = zc.recipe.testrunner
eggs = z3c.coverage [test]
defaults = ['--ndiff']
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = z3c.coverage [test]
+defaults = ['--ndiff', '--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage
+arguments = ('coverage', 'coverage/report')
Modified: z3c.coverage/trunk/setup.py
===================================================================
--- z3c.coverage/trunk/setup.py 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/setup.py 2008-01-29 18:22:32 UTC (rev 83302)
@@ -23,13 +23,18 @@
setup (
name='z3c.coverage',
- version='1.0.1',
+ version='1.1.0',
author = "Zope Community",
author_email = "zope3-dev at zope.org",
description = "A script to visualize coverage reports via HTML",
long_description=(
read('README.txt')
+ '\n\n' +
+ 'Detailed Documentation\n'
+ '**********************'
+ + '\n\n' +
+ read('src', 'z3c', 'formui', 'README.txt')
+ + '\n\n' +
read('CHANGES.txt')
),
license = "ZPL 2.1",
Added: z3c.coverage/trunk/src/z3c/coverage/README.txt
===================================================================
--- z3c.coverage/trunk/src/z3c/coverage/README.txt (rev 0)
+++ z3c.coverage/trunk/src/z3c/coverage/README.txt 2008-01-29 18:22:32 UTC (rev 83302)
@@ -0,0 +1,208 @@
+=====================
+Test Coverage Reports
+=====================
+
+The main objective of this package is to convert the text-based coverage
+output into an HTML coverage report. This is simply done by specifying the
+directory of the test reports and the desired output directory.
+
+Luckily we already have the text input ready:
+
+ >>> import os
+ >>> import z3c.coverage
+ >>> inputDir = os.path.join(
+ ... os.path.split(z3c.coverage.__file__)[0], 'sampleinput')
+
+The output directory has to be created first:
+
+ >>> import tempfile
+ >>> outputDir = os.path.join(tempfile.mkdtemp(), 'report')
+
+We can now simply create the coverage report as follows:
+
+ >>> from z3c.coverage import coveragereport
+ >>> coveragereport.main((inputDir, outputDir))
+
+Looking at the output directory, we now see several files:
+
+ >>> print '\n'.join(os.listdir(outputDir))
+ all.html
+ z3c.coverage.coveragereport.html
+ z3c.coverage.coveragediff.html
+ z3c.coverage.html
+ z3c.coverage.__init__.html
+ z3c.html
+
+
+API Tests
+=========
+
+``CoverageNode`` Class
+----------------------
+
+This class represents a node in the source tree. Simple modules are considered
+leaves and do not have children. Let's create a node for the `z3c` namespace
+first:
+
+ >>> z3cNode = coveragereport.CoverageNode()
+
+Before using the API, let's create a few more nodes and a tree from it:
+
+ >>> coverageNode = coveragereport.CoverageNode()
+ >>> z3cNode['coverage'] = coverageNode
+
+ >>> reportNode = coveragereport.CoverageNode()
+ >>> reportNode._covered, reportNode._total = 40, 134
+ >>> coverageNode['coveragereport'] = reportNode
+
+ >>> diffNode = coveragereport.CoverageNode()
+ >>> diffNode._covered, diffNode._total = 128, 128
+ >>> coverageNode['coveragediff'] = diffNode
+
+ >>> initNode = coveragereport.CoverageNode()
+ >>> initNode._covered, initNode._total = 0, 0
+ >>> coverageNode['__init__'] = initNode
+
+Let's now have a look at the coverage of the `z3c` namespace:
+
+ >>> z3cNode.coverage
+ (168, 262)
+
+We can also ask for the percentile:
+
+ >>> z3cNode.percent
+ 64
+ >>> initNode.percent
+ 100
+
+We can ask for the amoutn of uncovered lines:
+
+ >>> z3cNode.uncovered
+ 94
+
+Finally, we also can get a nice output:
+
+ >>> print z3cNode
+ 64% covered (94 of 262 lines uncovered)
+
+
+`index_to_filename()` function
+------------------------------
+
+Takes an indexed Python path and produces the cover filename for it:
+
+ >>> coveragereport.index_to_filename(('z3c', 'coverage', 'coveragereport'))
+ 'z3c.coverage.coveragereport.cover'
+
+ >>> coveragereport.index_to_filename(())
+ ''
+
+`index_to_nice_name()` function
+-------------------------------
+
+Takes an indexed Python path and produces a nice "human-readable" string:
+
+ >>> coveragereport.index_to_nice_name(('z3c', 'coverage', 'coveragereport'))
+ ' coveragereport'
+
+ >>> coveragereport.index_to_nice_name(())
+ 'Everything'
+
+
+`index_to_name()` function
+--------------------------
+
+Takes an indexed Python path and produces a "human-readable" string:
+
+ >>> coveragereport.index_to_name(('z3c', 'coverage', 'coveragereport'))
+ 'z3c.coverage.coveragereport'
+
+ >>> coveragereport.index_to_name(())
+ 'everything'
+
+
+`percent_to_colour()` function
+------------------------------
+
+Given a coverage percentage, this function returns a color to represent the
+coverage:
+
+ >>> coveragereport.percent_to_colour(100)
+ 'green'
+ >>> coveragereport.percent_to_colour(92)
+ 'yellow'
+ >>> coveragereport.percent_to_colour(85)
+ 'orange'
+ >>> coveragereport.percent_to_colour(50)
+ 'red'
+
+
+`get_svn_revision()` function
+-----------------------------
+
+Given a path, the function tries to determine the revision number of the
+file. If it fails, "UNKNOWN" is returned:
+
+ >>> path = os.path.split(z3c.coverage.__file__)[0]
+ >>> coveragereport.get_svn_revision(path)
+ '8...M'
+
+ >>> coveragereport.get_svn_revision(path + '/__init__.py')
+ 'UNKNOWN'
+
+
+`syntax_highlight()` function
+-----------------------------
+
+This function takes a cover file, converts it to a nicely colored HTML output:
+
+ >>> filename = os.path.join(
+ ... os.path.split(z3c.coverage.__file__)[0], '__init__.py')
+
+ >>> print coveragereport.syntax_highlight(filename)
+ <BLANKLINE>
+ <I><FONT COLOR="#B22222"># Make a package.
+ </FONT></I>
+
+If the highlighing command is not available, no coloration is done:
+
+ >>> command_orig = coveragereport.HIGHLIGHT_COMMAND
+ >>> coveragereport.HIGHLIGHT_COMMAND = 'foobar %s'
+
+ >>> print coveragereport.syntax_highlight(filename)
+ # Make a package.
+ <BLANKLINE>
+
+ >>> coveragereport.HIGHLIGHT_COMMAND = command_orig
+
+
+`coveragereport.py` is a script
+-------------------------------
+
+For convenience you can download the ``coveragereport.py`` module and run it
+as a script:
+
+ >>> import sys
+ >>> sys.argv = ['coveragereport', inputDir, outputDir]
+
+ >>> script_file = os.path.join(
+ ... z3c.coverage.__path__[0], 'coveragereport.py')
+
+ >>> execfile(script_file, dict(__name__='__main__'))
+
+Defaults are chosen, when no input and output dir is specified:
+
+ >>> def make_coverage_reports_stub(path, report_path):
+ ... print path
+ ... print report_path
+
+ >>> make_coverage_reports_orig = coveragereport.make_coverage_reports
+ >>> coveragereport.make_coverage_reports = make_coverage_reports_stub
+
+ >>> sys.argv = ['coveragereport']
+ >>> coveragereport.main()
+ coverage
+ coverage/reports
+
+ >>> coveragereport.make_coverage_reports = make_coverage_reports_orig
+
Property changes on: z3c.coverage/trunk/src/z3c/coverage/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.coverage/trunk/src/z3c/coverage/coveragediff.txt
===================================================================
--- z3c.coverage/trunk/src/z3c/coverage/coveragediff.txt 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/src/z3c/coverage/coveragediff.txt 2008-01-29 18:22:32 UTC (rev 83302)
@@ -1,3 +1,4 @@
+======================
coveragediff internals
======================
Modified: z3c.coverage/trunk/src/z3c/coverage/coveragereport.py
===================================================================
--- z3c.coverage/trunk/src/z3c/coverage/coveragereport.py 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/src/z3c/coverage/coveragereport.py 2008-01-29 18:22:32 UTC (rev 83302)
@@ -42,6 +42,9 @@
import cgi
+HIGHLIGHT_COMMAND = ('enscript -q --footer --header -h --language=html'
+ ' --highlight=python --color -o - "%s"')
+
class CoverageNode(dict):
"""Tree node.
@@ -115,8 +118,8 @@
One example is worth a thousand descriptions:
- >>> filename_to_list('schooltool.app.__init__.cover')
- ['schooltool', 'app', '__init__']
+ >>> filename_to_list('z3c.coverage.__init__.cover')
+ ['z3c', 'coverage', '__init__']
"""
return filename.split('.')[:-1]
@@ -290,7 +293,9 @@
file_path = os.path.join(path, index_to_filename(my_index))
text = syntax_highlight(file_path)
def color_uncov(line):
- if '>>>>>>' in line:
+ # The line must start with the missing line indicator or some HTML
+ # was put in front of it.
+ if line.startswith('>'*6) or '>'+'>'*6 in line:
return ('<div class="notcovered">%s</div>'
% line.rstrip('\n'))
return line
@@ -303,8 +308,7 @@
def syntax_highlight(filename):
"""Return HTML with syntax-highlighted Python code from a file."""
# XXX can get painful if filenames contain unsafe characters
- pipe = os.popen('enscript -q --footer --header -h --language=html'
- ' --highlight=python --color -o - "%s"' % filename,
+ pipe = os.popen(HIGHLIGHT_COMMAND % filename,
'r')
text = pipe.read()
if pipe.close():
@@ -360,8 +364,20 @@
html.close()
+def create_report_path(report_path):
+ report_path = os.path.abspath(report_path)
+ missing_dirs = []
+ while not os.path.exists(report_path):
+ report_path, missing_dir = os.path.split(report_path)
+ missing_dirs.append(missing_dir)
+ while missing_dirs:
+ report_path = os.path.join(report_path, missing_dirs.pop())
+ os.mkdir(report_path)
+
+
def make_coverage_reports(path, report_path):
"""Convert reports from ``path`` into HTML files in ``report_path``."""
+ create_report_path(report_path)
def filter_fn(filename):
return (filename.endswith('.cover') and
'test' not in filename and
@@ -372,8 +388,8 @@
timestamp = str(datetime.datetime.utcnow())+"Z"
footer = "Generated for revision %s on %s" % (rev, timestamp)
generate_htmls_from_tree(tree, path, report_path, footer)
- generate_overall_html_from_tree(tree, os.path.join(report_path,
- 'all.html'), footer)
+ generate_overall_html_from_tree(
+ tree, os.path.join(report_path, 'all.html'), footer)
def get_svn_revision(path):
@@ -384,16 +400,21 @@
return rev
-def main():
+def main(args=None):
"""Process command line arguments and produce HTML coverage reports."""
- if len(sys.argv) > 1:
- path = sys.argv[1]
+ if args is None:
+ args = sys.argv[1:]
+
+ if len(args) > 0:
+ path = args[0]
else:
path = 'coverage'
- if len(sys.argv) > 2:
- report_path = sys.argv[2]
+
+ if len(args) > 1:
+ report_path = args[1]
else:
report_path = 'coverage/reports'
+
make_coverage_reports(path, report_path)
Modified: z3c.coverage/trunk/src/z3c/coverage/tests.py
===================================================================
--- z3c.coverage/trunk/src/z3c/coverage/tests.py 2008-01-29 17:15:16 UTC (rev 83301)
+++ z3c.coverage/trunk/src/z3c/coverage/tests.py 2008-01-29 18:22:32 UTC (rev 83302)
@@ -15,10 +15,14 @@
(re.compile('^options:', re.MULTILINE), 'Options:'),
])
return unittest.TestSuite([
- doctest.DocFileSuite('coveragediff.txt', checker=checker),
- doctest.DocTestSuite('z3c.coverage.coveragediff'),
- doctest.DocTestSuite('z3c.coverage.coveragereport'),
- ])
+ doctest.DocFileSuite(
+ 'README.txt', checker=checker,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ doctest.DocFileSuite('coveragediff.txt', checker=checker),
+ doctest.DocTestSuite('z3c.coverage.coveragediff'),
+ doctest.DocTestSuite('z3c.coverage.coveragereport'),
+ ])
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
More information about the Checkins
mailing list