From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 9DFC21381F3 for ; Fri, 9 Aug 2013 23:01:18 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 4B0CAE0E9E; Fri, 9 Aug 2013 23:01:16 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id C4991E0E9E for ; Fri, 9 Aug 2013 23:01:15 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 5B08C33EBA3 for ; Fri, 9 Aug 2013 23:01:14 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 0B9D6E468F for ; Fri, 9 Aug 2013 23:01:13 +0000 (UTC) From: "Michał Górny" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Michał Górny" Message-ID: <1376089268.937c6ffa48527d5898fa9fab3ca97010aca0d1a1.mgorny@gentoo> Subject: [gentoo-commits] proj/pms-test-suite:master commit in: pmstestsuite/output/ X-VCS-Repository: proj/pms-test-suite X-VCS-Files: pmstestsuite/output/__init__.py pmstestsuite/output/wiki.py X-VCS-Directories: pmstestsuite/output/ X-VCS-Committer: mgorny X-VCS-Committer-Name: Michał Górny X-VCS-Revision: 937c6ffa48527d5898fa9fab3ca97010aca0d1a1 X-VCS-Branch: master Date: Fri, 9 Aug 2013 23:01:13 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 4e1c06d9-8867-474b-ba6d-10e1c682b8b4 X-Archives-Hash: dffcb706cfa8e6a46cba83df200569fd commit: 937c6ffa48527d5898fa9fab3ca97010aca0d1a1 Author: Michał Górny gentoo org> AuthorDate: Fri Aug 9 23:00:48 2013 +0000 Commit: Michał Górny gentoo org> CommitDate: Fri Aug 9 23:01:08 2013 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/pms-test-suite.git;a=commit;h=937c6ffa Add a wiki output backend. --- pmstestsuite/output/__init__.py | 3 +- pmstestsuite/output/wiki.py | 187 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 1 deletion(-) diff --git a/pmstestsuite/output/__init__.py b/pmstestsuite/output/__init__.py index fcfd27e..7736b45 100644 --- a/pmstestsuite/output/__init__.py +++ b/pmstestsuite/output/__init__.py @@ -90,5 +90,6 @@ def get_output_modules(): from pmstestsuite.output.cli import CLIOutput from pmstestsuite.output.html import HTMLOutput + from pmstestsuite.output.wiki import WikiOutput - return (CLIOutput, HTMLOutput) + return (CLIOutput, HTMLOutput, WikiOutput) diff --git a/pmstestsuite/output/wiki.py b/pmstestsuite/output/wiki.py new file mode 100644 index 0000000..23b7178 --- /dev/null +++ b/pmstestsuite/output/wiki.py @@ -0,0 +1,187 @@ +# vim:fileencoding=utf-8 +# (c) 2011 Michał Górny +# Released under the terms of the 2-clause BSD license. + +from collections import defaultdict +from gentoopm.util import ABCObject +from abc import abstractmethod + +from . import OutputModule + +class WikiOutput(OutputModule): + """ Gentoo Wiki markup output module. """ + + name = 'wiki' + + def __init__(self, path = None): + if path is None: + path = 'pms-test-suite-output.txt' + self._path = path + + def __call__(self, allresults, verbose = False): + mypms = [] + + def _results_by_test(allresults): + ret = defaultdict(lambda: defaultdict(lambda: None)) + for pm, results in allresults.items(): + mypms.append(pm) + for t, r in results.items(): + ret[t][pm] = r + return ret + + def _results_by_class(reorderedresults): + ret = defaultdict(dict) + for t, r in reorderedresults.items(): + ret[t.short_name][t] = r + for cl in sorted(ret): + yield cl, ret[cl] + + def _sorted_pms(pms): + for pm in sorted(pms, key = lambda pm: mypms.index(pm)): + yield (pm, pms[pm]) + + class HTMLElem(ABCObject): + @abstractmethod + def set_rowspan(self, rowspan): + pass + + @abstractmethod + def __str__(self): + pass + + class TD(HTMLElem): + _elem = '|' + + def __init__(self, text, colspan = 1): + self._attrs = [] + self._text = text + self._colspan = colspan + if colspan != 1: + self._attrs.append('colspan="%d"' % colspan) + + def set_rowspan(self, rowspan): + if rowspan != 1: + self._attrs.append('rowspan="%d"' % rowspan) + + def __str__(self): + out = self._text + if self._attrs: + out = '%s | %s' % (' '.join(self._attrs), out) + return '| %s\n' % out + + class TH(TD): + _elem = '!' + + class ValCell(TD): + _color_class = '' + + def __init__(self, text): + text = '%s' % text + TD.__init__(self, text) + if self._color_class: + self._attrs.append('style="%s"' % self._color_class) + + style_good = 'background: #88e888;' + style_bad = 'background: #e88888;' + style_unk_good = 'color: #008800;' + style_unk_bad = 'color: #880000;' + + class ColorValCell(ValCell): + def __init__(self, text, a): + if a.undefined: + self._color_class = style_unk_good if a else style_unk_bad + else: + self._color_class = style_good if a else style_bad + ValCell.__init__(self, text) + + class BoolCell(ValCell): + def __init__(self, r): + if not r.undefined: + self._color_class = style_good if r else style_bad + ValCell.__init__(self, 'OK' if r else 'FAIL') + else: # undefined result + self._color_class = style_unk_good if r else style_unk_bad + ValCell.__init__(self, 'n/a (but OK)' if r \ + else 'n/a (but FAIL)') + + class UnknownValCell(ValCell): + def __init__(self): + ValCell.__init__(self, '?') + + class NoCell(HTMLElem): + def __init__(self): + pass + + def set_rowspan(self, rowspan): + pass + + def __str__(self): + return '' + + ret = True + results = _results_by_test(allresults) + table = defaultdict(lambda: defaultdict(lambda: None)) + + table[0][0] = TH('Test name') + table[0][1] = TH('EAPI') + table[0][2] = TH('Assertion', colspan = 2) + table[0][4] = TH('Expected') + for i, pm in enumerate(mypms): + table[0][5 + i*2] = TH('%s %s' % (pm.name, pm.version), colspan = 2) + table[0][6 + i*2] = NoCell() + table[1][5 + i*2] = TH('Actual') + table[1][6 + i*2] = TH('Result') + maxcol = 7 + i*2 + + row = 2 + for cl, tests in _results_by_class(results): + table[row][0] = cl + for t in sorted(tests, key = lambda t: t.eapi): + table[row][1] = t.eapi + test_asserts = [] + col = 5 + for pm, r in _sorted_pms(tests[t]): + table[row][col+1] = BoolCell(r) + for ai, a in enumerate(r.assertions): + if a.name not in test_asserts: + test_asserts.append(a.name) + crow = row + test_asserts.index(a.name) + if a.prefix is not None: + if ai == 0 or table[crow-1][2] != a.prefix: + table[crow][2] = a.prefix + table[crow][3] = a.unprefixed_name + else: + table[crow][2] = TD(a.name, colspan = 2) + table[crow][3] = NoCell() + table[crow][4] = ValCell(a.expected) + for c in range(5, maxcol, 2): + table[crow][c] = UnknownValCell() + else: + crow = row + test_asserts.index(a.name) + + table[crow][col] = ColorValCell(a.actual, a) + col += 2 + row += len(test_asserts) + + f = open(self._path, 'w') + f.write('{| class="wikitable"\n') + for y in range(0, row): + f.write('|-\n') + for x in range(0, maxcol): + cell = table[y][x] + if cell is not None: + rowspan = 1 + for y2 in range(y + 1, row): + if table[y2][x] is None: + rowspan += 1 + else: + break + + if not isinstance(cell, HTMLElem): + cell = TD(cell) + cell.set_rowspan(rowspan) + f.write(str(cell)) + f.write('|}\n') + f.close() + + return ret