Don't use `flake8: noqa`.
[mailman.git] / src / mailman / testing / nose.py
blobf88ac409aa817096b94834ad202c4f68888124cc
1 # Copyright (C) 2013-2016 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """nose2 test infrastructure."""
20 import os
21 import re
22 import doctest
23 import importlib
25 from mailman import public
26 from mailman.testing.documentation import setup, teardown
27 from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer, SMTPLayer
28 from nose2.events import Plugin
29 from pkg_resources import resource_filename
32 DOT = '.'
33 FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF
34 TOPDIR = os.path.dirname(resource_filename('mailman', '__init__.py'))
37 @public
38 class NosePlugin(Plugin):
39 configSection = 'mailman'
41 def __init__(self):
42 super().__init__()
43 self.patterns = []
44 self.stderr = False
45 def set_stderr(ignore): # noqa
46 self.stderr = True
47 self.addArgument(self.patterns, 'P', 'pattern',
48 'Add a test matching pattern')
49 self.addFlag(set_stderr, 'E', 'stderr',
50 'Enable stderr logging to sub-runners')
52 def startTestRun(self, event):
53 MockAndMonkeyLayer.testing_mode = True
54 if (self.stderr or
55 len(os.environ.get('MM_VERBOSE_TESTLOG', '').strip()) > 0):
56 ConfigLayer.stderr = True
58 def getTestCaseNames(self, event):
59 if len(self.patterns) == 0:
60 # No filter patterns, so everything should be tested.
61 return
62 # Does the pattern match the fully qualified class name?
63 for pattern in self.patterns:
64 full_class_name = '{}.{}'.format(
65 event.testCase.__module__, event.testCase.__name__)
66 if re.search(pattern, full_class_name):
67 # Don't suppress this test class.
68 return
69 names = filter(event.isTestMethod, dir(event.testCase))
70 for name in names:
71 full_test_name = '{}.{}.{}'.format(
72 event.testCase.__module__,
73 event.testCase.__name__,
74 name)
75 for pattern in self.patterns:
76 if re.search(pattern, full_test_name):
77 break
78 else:
79 event.excludedNames.append(name)
81 def handleFile(self, event):
82 path = event.path[len(TOPDIR)+1:]
83 if len(self.patterns) > 0:
84 for pattern in self.patterns:
85 if re.search(pattern, path):
86 break
87 else:
88 # Skip this doctest.
89 return
90 base, ext = os.path.splitext(path)
91 if ext != '.rst':
92 return
93 # Look to see if the package defines a test layer, otherwise use the
94 # default layer. First turn the file system path into a dotted Python
95 # module path.
96 parent = os.path.dirname(path)
97 dotted = 'mailman.' + DOT.join(parent.split(os.path.sep))
98 try:
99 module = importlib.import_module(dotted)
100 except ImportError:
101 layer = SMTPLayer
102 else:
103 layer = getattr(module, 'layer', SMTPLayer)
104 test = doctest.DocFileTest(
105 path, package='mailman',
106 optionflags=FLAGS,
107 setUp=setup,
108 tearDown=teardown)
109 test.layer = layer
110 # Suppress the extra "Doctest: ..." line.
111 test.shortDescription = lambda: None
112 event.extraTests.append(test)
114 # def startTest(self, event):
115 # import sys; print('vvvvv', event.test, file=sys.stderr)
117 # def stopTest(self, event):
118 # import sys; print('^^^^^', event.test, file=sys.stderr)