Mercurial > bitten > bitten-test
changeset 182:cafe294fa835
* Make the chart generation `ExtensionPoint`-based.
* Minor improvements to the generated charts.
* Fix display of the charts in IE6/Win.
author | cmlenz |
---|---|
date | Wed, 31 Aug 2005 13:34:17 +0000 |
parents | 5ab5418d56cc |
children | fda952491beb |
files | bitten/trac_ext/api.py bitten/trac_ext/charts.py bitten/trac_ext/summarizers.py bitten/trac_ext/templates/bitten_chart_coverage.cs bitten/trac_ext/templates/bitten_chart_tests.cs bitten/trac_ext/templates/bitten_config.cs bitten/trac_ext/web_ui.py |
diffstat | 7 files changed, 134 insertions(+), 80 deletions(-) [+] |
line wrap: on
line diff
--- a/bitten/trac_ext/api.py +++ b/bitten/trac_ext/api.py @@ -33,3 +33,18 @@ def render_report_summary(req, build, step, report): """Render a summary for the given report and return the results HTML as a string.""" + + +class IReportChartGenerator(Interface): + """Extension point interface for components that generator a chart for a + set of reports.""" + + def get_supported_report_types(): + """Return a list of strings identifying the types of reports this + component supports.""" + + def generate_chart_data(req, config, type): + """Generate the data for the chart. + + This method should store the data in the HDF of the request and return + the name of the template that should process the data."""
--- a/bitten/trac_ext/charts.py +++ b/bitten/trac_ext/charts.py @@ -14,12 +14,15 @@ from trac.web import IRequestHandler from bitten.model import BuildConfig, Build from bitten.store import ReportStore +from bitten.trac_ext.api import IReportChartGenerator from bitten.util import xmlio class BittenChartRenderer(Component): implements(IRequestHandler) + generators = ExtensionPoint(IReportChartGenerator) + # IRequestHandler methods def match_request(self, req): @@ -30,26 +33,37 @@ return True def process_request(self, req): - type = req.args.get('type') + report_type = req.args.get('type') config = BuildConfig.fetch(self.env, name=req.args.get('config')) - if type == 'unittest': - return self._render_tests(req, config) - elif type == 'trace': - return self._render_coverage(req, config) + + for generator in self.generators: + if report_type in generator.get_supported_report_types(): + template = generator.generate_chart_data(req, config, + report_type) + break else: - raise TracError, 'Unknown report type' + raise TracError, 'Unknown report type "%s"' % report_type - # Internal methods + return template, 'text/xml' - def _render_tests(self, req, config): + +class TestResultsChartGenerator(Component): + implements(IReportChartGenerator) + + # IReportChartGenerator methods + + def get_supported_report_types(self): + return ['unittest'] + + def generate_chart_data(self, req, config, report_type): rev_time = {} rev = {} for build in Build.select(self.env, config=config.name): rev[str(build.id)] = build.rev - rev_time[str(build.id)] = build.rev_time + rev_time[str(build.id)] = datetime.fromtimestamp(build.rev_time) store = ReportStore(self.env) - query = """ + xquery = """ for $report in $reports return <tests build="{dbxml:metadata('build', $report)}" @@ -59,28 +73,42 @@ """ tests = [] - for test in store.query_reports(query, config=config, type='unittest'): - tests.append({ - 'time': datetime.fromtimestamp(rev_time[test.attr['build']]), - 'rev': rev[test.attr['build']], 'total': test.attr['total'], - 'failed': test.attr['failed'], - }) - tests.sort(lambda x, y: cmp(x['time'], y['time'])) + for test in store.query_reports(xquery, config=config, type='unittest'): + tests.append(( + rev_time[test.attr['build']], # Changeset date/time + rev[test.attr['build']], # Changeset/revision + test.attr['total'], # Total number of tests + test.attr['failed'] # Number of errors/failures + )) + tests.sort() req.hdf['chart.title'] = 'Unit Tests' - req.hdf['chart.data'] = tests + req.hdf['chart.data'] = [ + [''] + [item[1] for item in tests], + ['Total'] + [item[2] for item in tests], + ['Failures'] + [int(item[3]) for item in tests] + ] - return 'bitten_chart_tests.cs', 'text/xml' + return 'bitten_chart_tests.cs' - def _render_coverage(self, req, config): + +class TestResultsChartGenerator(Component): + implements(IReportChartGenerator) + + # IReportChartGenerator methods + + def get_supported_report_types(self): + return ['trace'] + + def generate_chart_data(self, req, config, report_type): rev_time = {} rev = {} for build in Build.select(self.env, config=config.name): rev[str(build.id)] = build.rev - rev_time[str(build.id)] = build.rev_time + rev_time[str(build.id)] = datetime.fromtimestamp(build.rev_time) store = ReportStore(self.env) - query = """ + xquery = """ for $report in $reports return <coverage build="{dbxml:metadata('build', $report)}" @@ -94,17 +122,20 @@ """ coverage = [] - for test in store.query_reports(query, config=config, type='trace'): - values = [float(val) for val in test.gettext().split()] - coverage.append({ - 'time': datetime.fromtimestamp(rev_time[test.attr['build']]), - 'rev': rev[test.attr['build']], 'loc': test.attr['loc'], - 'cov': int(sum(values)) - }) - coverage.sort(lambda x, y: cmp(x['time'], y['time'])) - + for test in store.query_reports(xquery, config=config, type='trace'): + coverage.append(( + rev_time[test.attr['build']], # Changeset date/time + rev[test.attr['build']], # Changeset/revision + test.attr['loc'], # Lines of code + sum([float(val) for val in test.gettext().split()]) + )) + coverage.sort() req.hdf['chart.title'] = 'Code Coverage' - req.hdf['chart.data'] = coverage + req.hdf['chart.data'] = [ + [''] + [item[1] for item in coverage], + ['Lines of code'] + [item[2] for item in coverage], + ['Coverage'] + [int(item[3]) for item in coverage] + ] - return 'bitten_chart_coverage.cs', 'text/xml' + return 'bitten_chart_coverage.cs'
--- a/bitten/trac_ext/summarizers.py +++ b/bitten/trac_ext/summarizers.py @@ -31,7 +31,7 @@ hdf = HDFWrapper(loadpaths=Chrome(self.env).get_all_templates_dirs()) config = BuildConfig.fetch(self.env, name=build.config) store = ReportStore(self.env) - results = store.query_reports(self.query, config=config,build=build, + results = store.query_reports(self.query, config=config, build=build, step=step, type=self.report_type) for idx, elem in enumerate(results): data = {}
--- a/bitten/trac_ext/templates/bitten_chart_coverage.cs +++ b/bitten/trac_ext/templates/bitten_chart_coverage.cs @@ -3,33 +3,37 @@ <value>area</value> <value>area</value> </chart_type> - <axis_category size='10' - skip='<?cs var:len(chart.data) / 6 ?>' orientation='vertical' /> - <axis_ticks value_ticks='false' category_ticks='true' major_thickness='1' - minor_thickness='0' major_color='000000' position='outside' /> - - <chart_data> - <row><string /><?cs - each:item = chart.data ?><string><?cs var:item.rev ?></string><?cs - /each ?></row><row><string>Lines of Code</string><?cs - each:item = chart.data ?><string><?cs var:item.loc ?></string><?cs - /each ?></row><row><string>Coverage</string><?cs - each:item = chart.data ?><string><?cs var:item.cov ?></string><?cs - /each ?></row> - </chart_data> - - <chart_grid_h alpha='5' color='333333' thickness='2'/> - <chart_pref line_thickness='2' point_shape='none'/> - <legend_rect x='-100' y='-100' width='10' height='10'/> + + <axis_category size="10" + skip="<?cs var:len(chart.data.0) / 6 ?>" orientation="vertical" /> + <axis_ticks value_ticks="false" category_ticks="true" major_thickness="1" + minor_thickness="0" major_color="000000" position="outside" /> + + <chart_data><?cs + each:row = chart.data ?><row><?cs + each:value = row ?><?cs + if:name(value) == 0 ?><string><?cs + var:value ?></string><?cs + else ?><number><?cs + var:value ?></number><?cs + /if ?><?cs + /each ?></row><?cs + /each ?></chart_data> + + <chart_border color="999999" left_thickness="1" bottom_thickness="1"/> + <chart_grid_h alpha="5" color="666666" thickness="3"/> + <chart_pref line_thickness="2" point_shape="none"/> + <series_color> + <color>bbbbbb</color> + <color>9999ff</color> + </series_color> + + <legend_label layout="vertical" alpha="60"/> + <legend_rect x="60" y="50" width="10"/> <draw> <text width="320" height="40" h_align="center" v_align="bottom" size="12" ><?cs var:chart.title ?></text> </draw> - - <series_color> - <color>bbbbbb</color> - <color>99ff99</color> - </series_color> </chart>
--- a/bitten/trac_ext/templates/bitten_chart_tests.cs +++ b/bitten/trac_ext/templates/bitten_chart_tests.cs @@ -3,32 +3,36 @@ <value>area</value> <value>column</value> </chart_type> - <axis_category size='10' - skip='<?cs var:len(chart.data) / 6 ?>' orientation='vertical' /> - <axis_ticks value_ticks='false' category_ticks='true' major_thickness='2' - minor_thickness='0' major_color='000000' position='outside' /> + <axis_category size="10" + skip="<?cs var:len(chart.data.0) / 6 ?>" orientation="vertical" /> + <axis_ticks value_ticks="false" category_ticks="true" major_thickness="2" + minor_thickness="0" major_color="000000" position="outside" /> - <chart_data> - <row><string /><?cs - each:item = chart.data ?><string><?cs var:item.rev ?></string><?cs - /each ?></row><row><string>Total</string><?cs - each:item = chart.data ?><string><?cs var:item.total ?></string><?cs - /each ?></row><row><string>Failures</string><?cs - each:item = chart.data ?><string><?cs var:item.failed ?></string><?cs - /each ?></row> - </chart_data> - - <chart_grid_h alpha='5' color='333333' thickness='2'/> - <legend_rect x='-100' y='-100' width='10' height='10'/> + <chart_data><?cs + each:row = chart.data ?><row><?cs + each:value = row ?><?cs + if:name(value) == 0 ?><string><?cs + var:value ?></string><?cs + else ?><number><?cs + var:value ?></number><?cs + /if ?><?cs + /each ?></row><?cs + /each ?></chart_data> + + <chart_border color="999999" left_thickness="1" bottom_thickness="1"/> + <chart_grid_h alpha="5" color="666666" thickness="3"/> + <chart_pref line_thickness="2" point_shape="none"/> + <series_color> + <color>99dd99</color> + <color>ff0000</color> + </series_color> + + <legend_label layout="vertical" alpha="60"/> + <legend_rect x="60" y="50" width="10"/> <draw> <text width="320" height="40" h_align="center" v_align="bottom" size="12" ><?cs var:chart.title ?></text> </draw> - - <series_color> - <color>99dd99</color> - <color>ff0000</color> - </series_color> </chart>
--- a/bitten/trac_ext/templates/bitten_config.cs +++ b/bitten/trac_ext/templates/bitten_config.cs @@ -103,7 +103,8 @@ <div id="charts"><?cs each:chart = config.charts ?> <object type="application/x-shockwave-flash" width="320" height="240" data="<?cs - var:chrome.href ?>/bitten/charts.swf"> + var:chrome.href ?>/bitten/charts.swf"> + <param name="movie" value="<?cs var:chrome.href ?>/bitten/charts.swf" /> <param name="FlashVars" value="library_path=<?cs var:chrome.href ?>/bitten&xml_source=<?cs var:chart.href ?><?cs if:config.charts_license ?>&license=<?cs
--- a/bitten/trac_ext/web_ui.py +++ b/bitten/trac_ext/web_ui.py @@ -495,7 +495,6 @@ for summarizer in self.report_summarizers: types = summarizer.get_supported_report_types() summarizers.update(dict([(type, summarizer) for type in types])) - self.log.debug("Report summarizers: %s", summarizers) store = ReportStore(self.env) reports = []