1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

[soc2009/testing] Removing old reporting library. Port has been tested using coverage.py 3.0b3

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/test-improvements@10891 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Kevin Kubasik 2009-06-02 14:57:53 +00:00
parent f0489dffb9
commit f092095612
14 changed files with 0 additions and 990 deletions

View File

@ -1,18 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from html_report import *

View File

@ -1,57 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import coverage, time
try:
set
except:
from sets import Set as set
class ModuleVars(object):
modules = dict()
def __new__(cls, module_name, module=None):
if cls.modules.get(module_name, None):
return cls.modules.get(module_name)
else:
obj=super(ModuleVars, cls).__new__(cls)
obj._init(module_name, module)
cls.modules[module_name] = obj
return obj
def _init(self, module_name, module):
source_file, stmts, excluded, missed, missed_display = coverage.analysis2(module)
executed = list(set(stmts).difference(missed))
total = list(set(stmts).union(excluded))
total.sort()
title = module.__name__
total_count = len(total)
executed_count = len(executed)
excluded_count = len(excluded)
missed_count = len(missed)
try:
percent_covered = float(len(executed))/len(stmts)*100
except ZeroDivisionError:
percent_covered = 100
test_timestamp = time.strftime('%a %Y-%m-%d %H:%M %Z')
severity = 'normal'
if percent_covered < 75: severity = 'warning'
if percent_covered < 50: severity = 'critical'
for k, v in locals().iteritems():
setattr(self, k, v)

View File

@ -1,91 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import cgi, os
from data_storage import ModuleVars
from templates import default_module_detail as module_detail
def html_module_detail(filename, module_name, nav=None):
"""
Creates a module detail report based on coverage testing at the specified
filename. If ``nav`` is specified, the nav template will be used as well.
It uses `templates.default_module_detail` to create the page. The template
contains the following sections which need to be rendered and assembled into
the final HTML.
TOP: Contains the HTML declaration and head information, as well as the
inline stylesheet. It requires the following variable:
* %(title)s The module name is probably fitting for this.
CONTENT_HEADER: The header portion of the body. Requires the following variable:
* %(title)s
* %(source_file)s File path to the module
* %(total_count)d
* %(executed_count)d
* %(excluded_count)d
* %(ignored_count)d
* %(percent_covered)0.1f
* %(test_timestamp)s
CONTENT_BODY: Annotated module source code listing. Requires the following variable:
* ``%(source_lines)s`` The actual source listing which is generated by
looping through each line and concatenanting together rendered
``SOURCE_LINE`` template (see below).
BOTTOM: Just a closing ``</body></html>``
SOURCE_LINE: Used to assemble the content of ``%(source_lines)s`` for ``CONTENT_BODY``.
Requires the following variables:
* ``%(line_status)s`` (ignored, executed, missed, excluded) used as CSS class
identifier to style the each source line.
* ``%(source_line)s``
"""
if not nav:
nav = {}
m_vars = ModuleVars(module_name)
m_vars.source_lines = source_lines = list()
i = 0
for i, source_line in enumerate(
[cgi.escape(l.rstrip()) for l in file(m_vars.source_file, 'rb').readlines()]):
line_status = 'ignored'
if i+1 in m_vars.executed: line_status = 'executed'
if i+1 in m_vars.excluded: line_status = 'excluded'
if i+1 in m_vars.missed: line_status = 'missed'
source_lines.append(module_detail.SOURCE_LINE %vars())
m_vars.ignored_count = i+1 - m_vars.total_count
m_vars.source_lines = os.linesep.join(source_lines)
if 'prev_link' in nav and 'next_link' in nav:
nav_html = module_detail.NAV %nav
elif 'prev_link' in nav:
nav_html = module_detail.NAV_NO_NEXT %nav
elif 'next_link' in nav:
nav_html = module_detail.NAV_NO_PREV %nav
fo = file(filename, 'wb+')
print >>fo, module_detail.TOP %m_vars.__dict__
if nav:
print >>fo, nav_html
print >>fo, module_detail.CONTENT_HEADER %m_vars.__dict__
print >>fo, module_detail.CONTENT_BODY %m_vars.__dict__
if nav:
print >>fo, nav_html
print >>fo, module_detail.BOTTOM
fo.close()

View File

@ -1,53 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from html_module_exceptions import html_module_exceptions
from templates import default_module_errors as module_errors
def html_module_errors(filename, errors):
"""
Creates an index page of packages and modules which had problems being imported
for coverage analysis at the specified filename.
It uses `templates.default_module_errors` to create the page. The template
contains the following sections which need to be rendered and assembled into
the final HTML.
TOP: Contains the HTML declaration and head information, as well as the
inline stylesheet.
CONTENT_HEADER: The header portion of the body.
CONTENT_BODY: A list of excluded packages and modules. Requires the following
variable:
* ``%(long_desc)s`` A long description of what this page
is about.
* ``%(exception_list)s`` List of package and module names
which is generated by looping through each line and
concatenanting together rendered ``EXCEPTION_LINE``
template (see below).
BOTTOM: Just a closing ``</body></html>``
EXCEPTION_LINE: Used to assemble the content of ``%(exception_list)s`` for ``CONTENT_BODY``.
Requires the following variable:
* ``%(module_name)s``
"""
long_desc = """\
<code>test_coverage.utils.module_tools.find_or_load_module</code> had
problems importing these packages and modules:
"""
html_module_exceptions(filename, errors, module_errors, long_desc)

View File

@ -1,32 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import os
def html_module_exceptions(filename, exceptions, template, long_desc):
exception_list = []
exceptions.sort()
for module_name in exceptions:
exception_list.append(template.EXCEPTION_LINE %vars())
exception_list = os.linesep.join(exception_list)
fo = file(filename, 'wb+')
print >>fo, template.TOP
print >>fo, template.CONTENT_HEADER
print >>fo, template.CONTENT_BODY %vars()
print >>fo, template.BOTTOM
fo.close()

View File

@ -1,55 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from html_module_exceptions import html_module_exceptions
from templates import default_module_excludes as module_excludes
def html_module_excludes(filename, excludes):
"""
Creates an index page of packages and modules which were excluded from the
coverage analysis at the specified filename.
It uses `templates.default_module_excludes` to create the page. The template
contains the following sections which need to be rendered and assembled into
the final HTML.
TOP: Contains the HTML declaration and head information, as well as the
inline stylesheet.
CONTENT_HEADER: The header portion of the body.
CONTENT_BODY: A list of excluded packages and modules. Requires the following
variable:
* ``%(long_desc)s`` A long description of what this page
is about.
* ``%(exception_list)s`` List of package and module names
which is generated by looping through each line and
concatenanting together rendered ``EXCEPTION_LINE``
template (see below).
BOTTOM: Just a closing ``</body></html>``
EXCEPTION_LINE: Used to assemble the content of ``%(exclude_list)s`` for ``CONTENT_BODY``.
Requires the following variable:
* ``%(module_name)s``
"""
long_desc = """\
These packages and modules were excluded from the coverage analysis in
<code>django.conf.settings.COVERAGE_MODULE_EXCLUDES</code> or they do
not contain any executable statements:
"""
html_module_exceptions(filename, excludes, module_excludes, long_desc)

View File

@ -1,143 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import os, time
from urllib import pathname2url as p2url
from data_storage import ModuleVars
from html_module_detail import html_module_detail
from html_module_errors import html_module_errors
from html_module_excludes import html_module_excludes
from templates import default_module_index as module_index
def html_report(outdir, modules, excludes=None, errors=None):
"""
Creates an ``index.html`` in the specified ``outdir``. Also attempts to create
a ``modules`` subdirectory to create module detail html pages, which are named
`module.__name__` + '.html'.
It uses `templates.default_module_index` to create the index page. The template
contains the following sections which need to be rendered and assembled into
`index.html`.
TOP: Contains the HTML declaration and head information, as well as the
inline stylesheet. It doesn't require any variables.
CONTENT_HEADER: The header portion of the body. Requires the following variable:
* ``%(test_timestamp)s``
CONTENT_BODY: A table of contents to the different module detail pages, with some
basic stats. Requires the following variables:
* ``%(module_stats)s`` This is the actual content of the table and is
generated by looping through the modules we want to report on and
concatenanting together rendered ``MODULE_STAT`` template (see below).
* ``%(total_lines)d``
* ``%(total_executed)d``
* ``%(total_excluded)d``
* ``%(overall_covered)0.1f``
EXCEPTIONS_LINK: Link to the excludes and errors index page which shows
packages and modules which were not part of the coverage
analysis. Requires the following variable:
* ``%(exceptions_link)s`` Link to the index page.
* ``%(exceptions_desc)s`` Describe the exception.
ERRORS_LINK: Link to the errors index page which shows packages and modules which
had problems being imported. Requires the following variable:
* ``%(errors_link)s`` Link to the index page.
BOTTOM: Just a closing ``</body></html>``
MODULE_STAT: Used to assemble the content of ``%(module_stats)s`` for ``CONTENT_BODY``.
Requires the following variables:
* ``%(severity)s`` (normal, warning, critical) used as CSS class identifier
to style the coverage percentage.
* ``%(module_link)s``
* ``%(module_name)s``
* ``%(total_count)d``
* ``%(executed_count)d``
* ``%(excluded_count)d``
* ``%(percent_covered)0.1f``
"""
# TODO: More robust directory checking and creation
outdir = os.path.abspath(outdir)
test_timestamp = time.strftime('%a %Y-%m-%d %H:%M %Z')
m_subdirname = 'modules'
m_dir = os.path.join(outdir, m_subdirname)
try:
os.mkdir(m_dir)
except OSError:
pass
total_lines = 0
total_executed = 0
total_excluded = 0
total_stmts = 0
module_stats = list()
m_names = modules.keys()
m_names.sort()
for n in m_names:
m_vars = ModuleVars(n, modules[n])
if not m_vars.total_count:
excludes.append(m_vars.module_name)
del modules[n]
continue
m_vars.module_link = p2url(os.path.join(m_subdirname, m_vars.module_name + '.html'))
module_stats.append(module_index.MODULE_STAT %m_vars.__dict__)
total_lines += m_vars.total_count
total_executed += m_vars.executed_count
total_excluded += m_vars.excluded_count
total_stmts += len(m_vars.stmts)
module_stats = os.linesep.join(module_stats)
overall_covered = float(total_executed)/total_stmts*100
m_names = modules.keys()
m_names.sort()
i = 0
for i, n in enumerate(m_names):
m_vars = ModuleVars(n)
nav = dict(up_link=p2url(os.path.join('..', 'index.html')),
up_label='index')
if i > 0:
m = ModuleVars(m_names[i-1])
nav['prev_link'] = os.path.basename(m.module_link)
nav['prev_label'] = m.module_name
if i+1 < len(modules):
m = ModuleVars(m_names[i+1])
nav['next_link'] = os.path.basename(m.module_link)
nav['next_label'] = m.module_name
html_module_detail(
os.path.join(m_dir, m_vars.module_name + '.html'), n, nav)
fo = file(os.path.join(outdir, 'index.html'), 'wb+')
print >>fo, module_index.TOP
print >>fo, module_index.CONTENT_HEADER %vars()
print >>fo, module_index.CONTENT_BODY %vars()
if excludes:
_file = 'excludes.html'
exceptions_link = _file
exception_desc = "Excluded packages and modules"
print >>fo, module_index.EXCEPTIONS_LINK %vars()
html_module_excludes(os.path.join(outdir, _file), excludes)
if errors:
_file = 'errors.html'
exceptions_link = _file
exception_desc = "Error packages and modules"
print >>fo, module_index.EXCEPTIONS_LINK %vars()
html_module_errors(os.path.join(outdir, _file), errors)
print >>fo, module_index.BOTTOM
fo.close()

View File

@ -1,17 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

View File

@ -1,193 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
TOP = """\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Test coverage report: %(title)s</title>
<style type="text/css" media="screen">
a
{
color: #3d707a;
}
a:hover, a:active
{
color: #bf7d18;
}
body
{
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 13px;
}
.nav
{
font-size: 12px;
margin-left: 50px;
}
.ignored
{
color: #707070;
}
.executed
{
color: #3d9900;
}
.missed
{
color: red;
font-weight: bold;
}
.excluded
{
color: #6090f0;
font-weight: lighter;
}
#content-header
{
font-size: 12px;
padding: 18px 0 18px 50px;
}
#content-header h1
{
font-size: 16px;
margin: 10px 0 0 0;
color: #909090;
}
#module-name
{
color: #583707;
}
#content-header p
{
font-size: 13px;
margin: 0;
color: #909090;
}
#content-header .normal
{
color: #609030;
}
#content-header .warning
{
color: #d0a000;
}
#content-header .critical
{
color: red;
}
#source-listing
{
margin-bottom: 24px;
}
#source-listing ol
{
padding: 0 0 0 50px;
width: 90%%;
font-family: monospace;
list-style-position: outside;
}
#source-listing ol li
{
line-height: 18px;
font-size: small;
}
#source-listing ol code
{
padding: 0 .001em 0 0; /* Firefox doesn't render empty li's properly */
font-size: medium;
white-space: pre;
}
</style>
</head>
<body>
"""
NAV = """\
<div class="nav">
<a href="%(prev_link)s">%(prev_label)s</a> &lt;&lt;
<a href="%(up_link)s">%(up_label)s</a>
&gt;&gt; <a href="%(next_link)s">%(next_label)s</a>
</div>
"""
NAV_NO_PREV = """\
<div class="nav">
<a href="%(up_link)s">%(up_label)s</a>
&gt;&gt; <a href="%(next_link)s">%(next_label)s</a>
</div>
"""
NAV_NO_NEXT = """\
<div class="nav">
<a href="%(prev_link)s">%(prev_label)s</a> &lt;&lt;
<a href="%(up_link)s">%(up_label)s</a>
</div>
"""
CONTENT_HEADER = """\
<div id="content-header">
<h1>
<span id="module-name">%(title)s</span>:
%(total_count)d total statements,
<span class="%(severity)s">%(percent_covered)0.1f%% covered</span>
</h1>
<p>Generated: %(test_timestamp)s</p>
<p>Source file: %(source_file)s</p>
<p>
Stats:
<span class="executed">%(executed_count)d executed</span>,
<span class="missed">%(missed_count)d missed</span>,
<span class="excluded">%(excluded_count)d excluded</span>,
<span class="ignored">%(ignored_count)d ignored</span>
</p>
</div>
"""
CONTENT_BODY = """\
<div id="source-listing">
<ol>
%(source_lines)s
</ol>
</div>
"""
SOURCE_LINE = '<li class="%(line_status)s"><code>%(source_line)s</code></li>'
BOTTOM = """\
</body>
</html>
"""

View File

@ -1,23 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from default_module_exceptions import *
title = "error packages and modules"
TOP = TOP %vars()
CONTENT_HEADER = CONTENT_HEADER %vars()

View File

@ -1,89 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import time
test_timestamp = time.strftime('%a %Y-%m-%d %H:%M %Z')
TOP = """\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Test coverage report: %(title)s</title>
<style type="text/css" media="screen">
body
{
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 13px;
}
#content-header
{
margin-left: 50px;
}
#content-header h1
{
font-size: 18px;
margin-bottom: 0;
}
#content-header p
{
font-size: 13px;
margin: 0;
color: #909090;
}
#result-list
{
margin: 0 50px;
}
#result-list ul
{
padding-left: 13px;
list-style-position: inside;
}
</style>
</head>
<body>
"""
CONTENT_HEADER = """\
<div id="content-header">
<h1>Test Coverage Report: %(title)s</h1>"""
CONTENT_HEADER += "<p>Generated: %(test_timestamp)s</p>" %vars()
CONTENT_HEADER += "</div>"
CONTENT_BODY = """\
<div id="result-list">
<p>%(long_desc)s</p>
<ul>
%(exception_list)s
</ul>
Back to <a href="index.html">index</a>.
</div>
"""
EXCEPTION_LINE = "<li>%(module_name)s</li>"
BOTTOM = """\
</body>
</html>
"""

View File

@ -1,23 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from default_module_exceptions import *
title = "excluded packages and modules"
TOP = TOP %vars()
CONTENT_HEADER = CONTENT_HEADER %vars()

View File

@ -1,195 +0,0 @@
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
TOP = """\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Test coverage report</title>
<style type="text/css" media="screen">
a
{
color: #3d707a;
}
a:hover, a:active
{
color: #bf7d18;
}
body
{
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 13px;
}
tr:hover
{
background: #f5f5f5;
}
#content-header
{
margin-left: 50px;
}
#content-header h1
{
font-size: 18px;
margin-bottom: 0;
}
#content-header p
{
font-size: 13px;
margin: 0;
color: #909090;
}
#result-list table
{
font-size: 13px;
background: white;
margin: 15px 50px;
width: 600px;
border-collapse: collapse;
text-align: right;
}
#result-list thead tr.last th,
th.statements
{
border-bottom: 1px solid #6d5e48;
}
th.statements
{
text-align: center;
}
#result-list th
{
padding: 3px 12px;
font-size: 14px;
font-weight: normal;
color: #937F61;
}
#result-list td
{
border-bottom: 1px solid #e0e0e0;
color: #606060;
padding: 6px 12px;
}
#result-list tfoot td
{
color: #937F61;
font-weight: bold;
}
#result-list .normal
{
color: #609030;
}
#result-list .warning
{
color: #d0a000;
}
#result-list .critical
{
color: red;
}
#result-list .module-name
{
text-align: left;
}
.footer-link
{
margin-left: 62px;
}
</style>
</head>
<body>
"""
CONTENT_HEADER = """\
<div id="content-header">
<h1>Test Coverage Report</h1>
<p>Generated: %(test_timestamp)s</p>
</div>
"""
CONTENT_BODY = """\
<div id="result-list">
<table>
<thead>
<tr>
<th>&nbsp;</th>
<th colspan="3" class="statements">Statements</th>
</tr>
<tr class="last">
<th class="module-name">Module</th>
<th>total</th>
<th>executed</th>
<th>excluded</th>
<th>%% covered</th>
</tr>
</thead>
<tfoot>
<tr>
<td class="module-name">Total</td>
<td>%(total_lines)d</td>
<td>%(total_executed)d</td>
<td>%(total_excluded)d</td>
<td>%(overall_covered)0.1f%%</td>
</tr>
</tfoot>
<tbody>
%(module_stats)s
</tbody>
</table>
</div>
"""
MODULE_STAT = """\
<tr>
<td class="module-name"><a href="%(module_link)s">%(module_name)s</a></td>
<td>%(total_count)d</td>
<td>%(executed_count)d</td>
<td>%(excluded_count)d</td>
<td class="%(severity)s">%(percent_covered)0.1f%%</td>
</tr>
"""
EXCEPTIONS_LINK = """\
<div>
<a class="footer-link" href="%(exceptions_link)s">
%(exception_desc)s
</a>
</div>
"""
BOTTOM = """\
</body>
</html>
"""

View File

@ -6,7 +6,6 @@ from django.db.models import get_app, get_apps
from django.test.simple import DefaultTestRunner as base_run_tests from django.test.simple import DefaultTestRunner as base_run_tests
from django.utils.module_tools import get_all_modules from django.utils.module_tools import get_all_modules
#from django.test.coverage_report import html_report
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
def _get_app_package(app_model_module): def _get_app_package(app_model_module):