File: nose.py

package info (click to toggle)
flufl.testing 0.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 144 kB
  • sloc: python: 277; makefile: 5
file content (118 lines) | stat: -rw-r--r-- 4,164 bytes parent folder | download
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
116
117
118
"""nose2 test infrastructure."""

import os
import re
import sys
import doctest
import importlib

from nose2.events import Plugin


DOT = '.'
FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF


def as_object(path):
    if path is None:
        return None
    # mod.ule.object -> import(mod.ule); mod.ule.object
    module_name, dot, object_name = path.rpartition('.')
    if dot != '.' or len(object_name) == 0:
        return None
    module = importlib.import_module(module_name)
    return getattr(module, object_name, None)


class NosePlugin(Plugin):
    configSection = 'flufl.testing'

    def __init__(self):
        super().__init__()
        self.patterns = []
        self.stderr = False
        def set_stderr(ignore):                                  # noqa: E306
            self.stderr = True
        self.addArgument(self.patterns, 'P', 'pattern',
                         'Add a test matching pattern')
        self.addFlag(set_stderr, 'E', 'stderr',
                     'Enable stderr logging to sub-runners')
        # Get the topdir out of the plugin configuration file.
        self.package = self.config.as_str('package')
        if self.package is None:
            raise RuntimeError('flufl.nose2 plugin missing "package" setting')

    def startTestRun(self, event):
        callback = as_object(self.config.get('start_run'))
        if callback is not None:
            callback(self)

    def getTestCaseNames(self, event):
        if len(self.patterns) == 0:
            # No filter patterns, so everything should be tested.
            return
        # Does the pattern match the fully qualified class name?
        for pattern in self.patterns:
            full_class_name = '{}.{}'.format(
                event.testCase.__module__, event.testCase.__name__)
            if re.search(pattern, full_class_name):
                # Don't suppress this test class.
                return
        names = filter(event.isTestMethod, dir(event.testCase))
        for name in names:
            full_test_name = '{}.{}.{}'.format(
                event.testCase.__module__,
                event.testCase.__name__,
                name)
            for pattern in self.patterns:
                if re.search(pattern, full_test_name):
                    break
            else:
                event.excludedNames.append(name)

    def handleFile(self, event):
        package = importlib.import_module(self.package)
        path = event.path[len(os.path.dirname(package.__file__))+1:]
        if len(self.patterns) > 0:
            for pattern in self.patterns:
                if re.search(pattern, path):
                    break
            else:
                # Skip this doctest.
                return
        base, ext = os.path.splitext(path)
        if ext != '.rst':
            return
        # Look to see if the package defines a test layer, otherwise use the
        # default layer.  First turn the file system path into a dotted Python
        # module path.
        parent = os.path.dirname(path)
        dotted = '{}.{}'.format(
            self.package, DOT.join(parent.split(os.path.sep)))
        layer = None
        default_layer = as_object(self.config.get('default_layer'))
        try:
            module = importlib.import_module(dotted)
        except ImportError:
            layer = default_layer
        else:
            layer = getattr(module, 'layer', default_layer)
        setup = as_object(self.config.get('setup'))
        teardown = as_object(self.config.get('teardown'))
        test = doctest.DocFileTest(
            path, package=self.package,
            optionflags=FLAGS,
            setUp=setup,
            tearDown=teardown)
        test.layer = layer
        # Suppress the extra "Doctest: ..." line.
        test.shortDescription = lambda: None
        event.extraTests.append(test)

    def startTest(self, event):
        if self.config.as_bool('trace', False):
            print('vvvvv', event.test, file=sys.stderr)

    def stopTest(self, event):
        if self.config.as_bool('trace', False):
            print('^^^^^', event.test, file=sys.stderr)