aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pmstestsuite/output/__init__.py3
-rw-r--r--pmstestsuite/output/wiki.py187
2 files changed, 189 insertions, 1 deletions
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 <mgorny@gentoo.org>
+# 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 = '<tt><nowiki>%s</nowiki></tt>' % 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