summaryrefslogtreecommitdiff
path: root/tests/plugins.py
blob: bbeed6031fb7f118267c8e193e4435038d8f399b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import traceback
from .util import MarkdownSyntaxError
from nose.plugins import Plugin
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin

class Markdown(ErrorClassPlugin):
    """ Add MarkdownSyntaxError and ensure proper formatting. """
    mdsyntax = ErrorClass(MarkdownSyntaxError, 
                          label='MarkdownSyntaxError', 
                          isfailure=True)
    enabled = True

    def configure(self, options, conf):
        self.conf = conf

    def addError(self, test, err):
        """ Ensure other plugins see the error by returning nothing here. """
        pass

    def formatError(self, test, err):
        """ Remove unnessecary and unhelpful traceback from error report. """
        et, ev, tb = err
        if et.__name__ == 'MarkdownSyntaxError':
            return et, ev, ''
        return err


def escape(html):
    """ Escape HTML for display as source within HTML. """
    html = html.replace('&', '&')
    html = html.replace('<', '&lt;')
    html = html.replace('>', '&gt;')
    return html


class HtmlOutput(Plugin):
    """Output test results as ugly, unstyled html. """
    
    name = 'html-output'
    score = 2 # run late
    enabled = True
    
    def __init__(self):
        super(HtmlOutput, self).__init__()
        self.html = [ '<html><head>',
                      '<title>Test output</title>',
                      '</head><body>' ]
   
    def configure(self, options, conf):
        self.conf = conf

    def addSuccess(self, test):
        self.html.append('<span>ok</span>')
    
    def addError(self, test, err):
        err = self.formatErr(err)
        self.html.append('<span>ERROR</span>')
        self.html.append('<pre>%s</pre>' % escape(err))
            
    def addFailure(self, test, err):
        err = self.formatErr(err)
        self.html.append('<span>FAIL</span>')
        self.html.append('<pre>%s</pre>' % escape(err))

    def finalize(self, result):
        self.html.append('<div>')
        self.html.append("Ran %d test%s" %
                         (result.testsRun, result.testsRun != 1 and "s" 
or ""))
        self.html.append('</div>')
        self.html.append('<div>')
        if not result.wasSuccessful():
            self.html.extend(['<span>FAILED (',
                              'failures=%d ' % len(result.failures),
                              'errors=%d' % len(result.errors)])
            for cls in list(result.errorClasses.keys()):
                storage, label, isfail = result.errorClasses[cls]
                if len(storage):
                    self.html.append(' %ss=%d' % (label, len(storage)))
            self.html.append(')</span>')
        else:
            self.html.append('OK')
        self.html.append('</div></body></html>')
        f = open('test-output.html', 'w')
        for l in self.html:
            f.write(l)
        f.close()

    def formatErr(self, err):
        exctype, value, tb = err
        return ''.join(traceback.format_exception(exctype, value, tb))
    
    def startContext(self, ctx):
        try:
            n = ctx.__name__
        except AttributeError:
            n = str(ctx).replace('<', '').replace('>', '')
        self.html.extend(['<fieldset>', '<legend>', n, '</legend>'])
        try:
            path = ctx.__file__.replace('.pyc', '.py')
            self.html.extend(['<div>', path, '</div>'])
        except AttributeError:
            pass

    def stopContext(self, ctx):
        self.html.append('</fieldset>')
    
    def startTest(self, test):
        self.html.extend([ '<div><span>',
                           test.shortDescription() or str(test),
                           '</span>' ])
        
    def stopTest(self, test):
        self.html.append('</div>')