Status: | Merged |
---|---|
Merge reported by: | Barry Warsaw |
Merged at revision: | not available |
Proposed branch: | lp:~barry/mailman/nose2 |
Merge into: | lp:mailman |
Diff against target: |
329 lines (+120/-105) 9 files modified
setup.py (+2/-2) src/mailman/__init__.py (+1/-1) src/mailman/app/docs/hooks.rst (+2/-1) src/mailman/model/docs/autorespond.rst (+1/-1) src/mailman/testing/__init__.py (+0/-39) src/mailman/testing/documentation.py (+3/-60) src/mailman/testing/layers.py (+1/-1) src/mailman/testing/nose.py (+100/-0) unittest.cfg (+10/-0) |
To merge this branch: | bzr merge lp:~barry/mailman/nose2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mailman Coders | Pending | ||
Review via email: mp+182144@code.launchpad.net |
Commit message
Description of the change
Get rid of zc.buildout and zope.testing. Instead, use virtualenv and nose2.
To post a comment you must log in.
lp:~barry/mailman/nose2
updated
- 7218. By Barry Warsaw
-
Add enough __init__.py files to make these docs directories discoverable.
- 7219. By Barry Warsaw
-
* Suppress the extra Doctest: lines.
* Use DocFileTest directly.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'setup.py' | |||
2 | --- setup.py 2013-01-05 23:10:43 +0000 | |||
3 | +++ setup.py 2013-08-28 00:48:00 +0000 | |||
4 | @@ -101,14 +101,14 @@ | |||
5 | 101 | 'lazr.config', | 101 | 'lazr.config', |
6 | 102 | 'lazr.smtptest', | 102 | 'lazr.smtptest', |
7 | 103 | 'mock', | 103 | 'mock', |
8 | 104 | 'nose2', | ||
9 | 104 | 'passlib', | 105 | 'passlib', |
10 | 105 | 'restish', | 106 | 'restish', |
11 | 106 | 'storm', | 107 | 'storm', |
12 | 107 | 'zc.buildout', | ||
13 | 108 | 'zope.component', | 108 | 'zope.component', |
14 | 109 | 'zope.configuration', | 109 | 'zope.configuration', |
15 | 110 | 'zope.event', | 110 | 'zope.event', |
16 | 111 | 'zope.interface', | 111 | 'zope.interface', |
17 | 112 | 'zope.testing<4', | ||
18 | 113 | ], | 112 | ], |
19 | 113 | test_suite = 'nose2.collector.collector', | ||
20 | 114 | ) | 114 | ) |
21 | 115 | 115 | ||
22 | === modified file 'src/mailman/__init__.py' | |||
23 | --- src/mailman/__init__.py 2013-01-01 14:05:42 +0000 | |||
24 | +++ src/mailman/__init__.py 2013-08-28 00:48:00 +0000 | |||
25 | @@ -44,7 +44,7 @@ | |||
26 | 44 | # | 44 | # |
27 | 45 | # Do *not* do this if we're building the documentation. | 45 | # Do *not* do this if we're building the documentation. |
28 | 46 | if 'build_sphinx' not in sys.argv: | 46 | if 'build_sphinx' not in sys.argv: |
30 | 47 | if sys.argv[0].split(os.sep)[-1] == 'test': | 47 | if any('nose2' in arg for arg in sys.argv): |
31 | 48 | from mailman.testing.i18n import initialize | 48 | from mailman.testing.i18n import initialize |
32 | 49 | else: | 49 | else: |
33 | 50 | from mailman.core.i18n import initialize | 50 | from mailman.core.i18n import initialize |
34 | 51 | 51 | ||
35 | === modified file 'src/mailman/app/docs/hooks.rst' | |||
36 | --- src/mailman/app/docs/hooks.rst 2011-09-24 01:42:39 +0000 | |||
37 | +++ src/mailman/app/docs/hooks.rst 2013-08-28 00:48:00 +0000 | |||
38 | @@ -52,8 +52,9 @@ | |||
39 | 52 | >>> import subprocess | 52 | >>> import subprocess |
40 | 53 | >>> from mailman.testing.layers import ConfigLayer | 53 | >>> from mailman.testing.layers import ConfigLayer |
41 | 54 | >>> def call(): | 54 | >>> def call(): |
42 | 55 | ... exe = os.path.join(os.path.dirname(sys.executable), 'mailman') | ||
43 | 55 | ... proc = subprocess.Popen( | 56 | ... proc = subprocess.Popen( |
45 | 56 | ... 'bin/mailman lists --domain ignore -q'.split(), | 57 | ... [exe, 'lists', '--domain', 'ignore', '-q'], |
46 | 57 | ... cwd=ConfigLayer.root_directory, | 58 | ... cwd=ConfigLayer.root_directory, |
47 | 58 | ... env=dict(MAILMAN_CONFIG_FILE=config_path, | 59 | ... env=dict(MAILMAN_CONFIG_FILE=config_path, |
48 | 59 | ... PYTHONPATH=config_directory), | 60 | ... PYTHONPATH=config_directory), |
49 | 60 | 61 | ||
50 | === added file 'src/mailman/archiving/docs/__init__.py' | |||
51 | === added file 'src/mailman/commands/docs/__init__.py' | |||
52 | === added file 'src/mailman/handlers/docs/__init__.py' | |||
53 | === modified file 'src/mailman/model/docs/autorespond.rst' | |||
54 | --- src/mailman/model/docs/autorespond.rst 2011-09-24 01:42:39 +0000 | |||
55 | +++ src/mailman/model/docs/autorespond.rst 2013-08-28 00:48:00 +0000 | |||
56 | @@ -90,7 +90,7 @@ | |||
57 | 90 | >>> response.address | 90 | >>> response.address |
58 | 91 | <Address: aperson@example.com [not verified] at ...> | 91 | <Address: aperson@example.com [not verified] at ...> |
59 | 92 | >>> response.response_type | 92 | >>> response.response_type |
61 | 93 | <EnumValue: Response.hold [int=1]> | 93 | <EnumValue: Response.hold [value=1]> |
62 | 94 | >>> response.date_sent | 94 | >>> response.date_sent |
63 | 95 | datetime.date(2005, 8, 1) | 95 | datetime.date(2005, 8, 1) |
64 | 96 | 96 | ||
65 | 97 | 97 | ||
66 | === added file 'src/mailman/mta/docs/__init__.py' | |||
67 | === added file 'src/mailman/rules/docs/__init__.py' | |||
68 | === added file 'src/mailman/runners/docs/__init__.py' | |||
69 | === modified file 'src/mailman/testing/__init__.py' | |||
70 | --- src/mailman/testing/__init__.py 2013-01-01 14:05:42 +0000 | |||
71 | +++ src/mailman/testing/__init__.py 2013-08-28 00:48:00 +0000 | |||
72 | @@ -1,39 +0,0 @@ | |||
73 | 1 | # Copyright (C) 2011-2013 by the Free Software Foundation, Inc. | ||
74 | 2 | # | ||
75 | 3 | # This file is part of GNU Mailman. | ||
76 | 4 | # | ||
77 | 5 | # GNU Mailman is free software: you can redistribute it and/or modify it under | ||
78 | 6 | # the terms of the GNU General Public License as published by the Free | ||
79 | 7 | # Software Foundation, either version 3 of the License, or (at your option) | ||
80 | 8 | # any later version. | ||
81 | 9 | # | ||
82 | 10 | # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT | ||
83 | 11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
84 | 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
85 | 13 | # more details. | ||
86 | 14 | # | ||
87 | 15 | # You should have received a copy of the GNU General Public License along with | ||
88 | 16 | # GNU Mailman. If not, see <http://www.gnu.org/licenses/>. | ||
89 | 17 | |||
90 | 18 | """Set up testing. | ||
91 | 19 | |||
92 | 20 | This is used as an interface to buildout.cfg's [test] section. | ||
93 | 21 | zope.testrunner supports an initialization variable. It is set to import and | ||
94 | 22 | run the following test initialization method. | ||
95 | 23 | """ | ||
96 | 24 | |||
97 | 25 | from __future__ import absolute_import, unicode_literals | ||
98 | 26 | |||
99 | 27 | __metaclass__ = type | ||
100 | 28 | __all__ = [ | ||
101 | 29 | 'initialize', | ||
102 | 30 | ] | ||
103 | 31 | |||
104 | 32 | |||
105 | 33 | |||
106 | 34 | 0 | ||
107 | 35 | def initialize(root_directory): | ||
108 | 36 | """Initialize the test infrastructure.""" | ||
109 | 37 | from mailman.testing import layers | ||
110 | 38 | layers.MockAndMonkeyLayer.testing_mode = True | ||
111 | 39 | layers.ConfigLayer.enable_stderr(); | ||
112 | 40 | layers.ConfigLayer.set_root_directory(root_directory) | ||
113 | 41 | 1 | ||
114 | === renamed file 'src/mailman/tests/test_documentation.py' => 'src/mailman/testing/documentation.py' | |||
115 | --- src/mailman/tests/test_documentation.py 2013-01-01 14:05:42 +0000 | |||
116 | +++ src/mailman/testing/documentation.py 2013-08-28 00:48:00 +0000 | |||
117 | @@ -25,23 +25,16 @@ | |||
118 | 25 | 25 | ||
119 | 26 | __metaclass__ = type | 26 | __metaclass__ = type |
120 | 27 | __all__ = [ | 27 | __all__ = [ |
122 | 28 | 'test_suite', | 28 | 'setup', |
123 | 29 | 'teardown' | ||
124 | 29 | ] | 30 | ] |
125 | 30 | 31 | ||
126 | 31 | 32 | ||
127 | 32 | import os | ||
128 | 33 | import sys | ||
129 | 34 | import doctest | ||
130 | 35 | import unittest | ||
131 | 36 | |||
132 | 37 | from inspect import isfunction, ismethod | 33 | from inspect import isfunction, ismethod |
133 | 38 | 34 | ||
134 | 39 | import mailman | ||
135 | 40 | |||
136 | 41 | from mailman.app.lifecycle import create_list | 35 | from mailman.app.lifecycle import create_list |
137 | 42 | from mailman.config import config | 36 | from mailman.config import config |
140 | 43 | from mailman.testing.helpers import ( | 37 | from mailman.testing.helpers import call_api, specialized_message_from_string |
139 | 44 | call_api, chdir, specialized_message_from_string) | ||
141 | 45 | from mailman.testing.layers import SMTPLayer | 38 | from mailman.testing.layers import SMTPLayer |
142 | 46 | 39 | ||
143 | 47 | 40 | ||
144 | @@ -181,53 +174,3 @@ | |||
145 | 181 | cleanup() | 174 | cleanup() |
146 | 182 | else: | 175 | else: |
147 | 183 | cleanup[0](*cleanup[1:]) | 176 | cleanup[0](*cleanup[1:]) |
148 | 184 | |||
149 | 185 | |||
150 | 186 | |||
151 | 187 | 177 | ||
152 | 188 | def test_suite(): | ||
153 | 189 | """Create test suites for all .rst documentation tests. | ||
154 | 190 | |||
155 | 191 | .txt files are also tested, but .rst is highly preferred. | ||
156 | 192 | """ | ||
157 | 193 | suite = unittest.TestSuite() | ||
158 | 194 | topdir = os.path.dirname(mailman.__file__) | ||
159 | 195 | packages = [] | ||
160 | 196 | for dirpath, dirnames, filenames in os.walk(topdir): | ||
161 | 197 | if 'docs' in dirnames: | ||
162 | 198 | docsdir = os.path.join(dirpath, 'docs')[len(topdir)+1:] | ||
163 | 199 | packages.append(docsdir) | ||
164 | 200 | # Under higher verbosity settings, report all doctest errors, not just the | ||
165 | 201 | # first one. | ||
166 | 202 | flags = (doctest.ELLIPSIS | | ||
167 | 203 | doctest.NORMALIZE_WHITESPACE | | ||
168 | 204 | doctest.REPORT_NDIFF) | ||
169 | 205 | # Add all the doctests in all subpackages. | ||
170 | 206 | doctest_files = {} | ||
171 | 207 | with chdir(topdir): | ||
172 | 208 | for docsdir in packages: | ||
173 | 209 | # Look to see if the package defines a test layer, otherwise use | ||
174 | 210 | # SMTPLayer. | ||
175 | 211 | package_path = 'mailman.' + DOT.join(docsdir.split(os.sep)) | ||
176 | 212 | try: | ||
177 | 213 | __import__(package_path) | ||
178 | 214 | except ImportError: | ||
179 | 215 | layer = SMTPLayer | ||
180 | 216 | else: | ||
181 | 217 | layer = getattr(sys.modules[package_path], 'layer', SMTPLayer) | ||
182 | 218 | for filename in os.listdir(docsdir): | ||
183 | 219 | base, extension = os.path.splitext(filename) | ||
184 | 220 | if os.path.splitext(filename)[1] in ('.txt', '.rst'): | ||
185 | 221 | module_path = package_path + '.' + base | ||
186 | 222 | doctest_files[module_path] = ( | ||
187 | 223 | os.path.join(docsdir, filename), layer) | ||
188 | 224 | for module_path in sorted(doctest_files): | ||
189 | 225 | path, layer = doctest_files[module_path] | ||
190 | 226 | test = doctest.DocFileSuite( | ||
191 | 227 | path, | ||
192 | 228 | package='mailman', | ||
193 | 229 | optionflags=flags, | ||
194 | 230 | setUp=setup, | ||
195 | 231 | tearDown=teardown) | ||
196 | 232 | test.layer = layer | ||
197 | 233 | suite.addTest(test) | ||
198 | 234 | return suite | ||
199 | 235 | 178 | ||
200 | === modified file 'src/mailman/testing/layers.py' | |||
201 | --- src/mailman/testing/layers.py 2013-06-17 13:36:43 +0000 | |||
202 | +++ src/mailman/testing/layers.py 2013-08-28 00:48:00 +0000 | |||
203 | @@ -154,7 +154,7 @@ | |||
204 | 154 | continue | 154 | continue |
205 | 155 | logger_name = 'mailman.' + sub_name | 155 | logger_name = 'mailman.' + sub_name |
206 | 156 | log = logging.getLogger(logger_name) | 156 | log = logging.getLogger(logger_name) |
208 | 157 | log.propagate = True | 157 | #log.propagate = True |
209 | 158 | # Reopen the file to a new path that tests can get at. Instead of | 158 | # Reopen the file to a new path that tests can get at. Instead of |
210 | 159 | # using the configuration file path though, use a path that's | 159 | # using the configuration file path though, use a path that's |
211 | 160 | # specific to the logger so that tests can find expected output | 160 | # specific to the logger so that tests can find expected output |
212 | 161 | 161 | ||
213 | === added file 'src/mailman/testing/nose.py' | |||
214 | --- src/mailman/testing/nose.py 1970-01-01 00:00:00 +0000 | |||
215 | +++ src/mailman/testing/nose.py 2013-08-28 00:48:00 +0000 | |||
216 | @@ -0,0 +1,100 @@ | |||
217 | 1 | # Copyright (C) 2013 by the Free Software Foundation, Inc. | ||
218 | 2 | # | ||
219 | 3 | # This file is part of GNU Mailman. | ||
220 | 4 | # | ||
221 | 5 | # GNU Mailman is free software: you can redistribute it and/or modify it under | ||
222 | 6 | # the terms of the GNU General Public License as published by the Free | ||
223 | 7 | # Software Foundation, either version 3 of the License, or (at your option) | ||
224 | 8 | # any later version. | ||
225 | 9 | # | ||
226 | 10 | # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT | ||
227 | 11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
228 | 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
229 | 13 | # more details. | ||
230 | 14 | # | ||
231 | 15 | # You should have received a copy of the GNU General Public License along with | ||
232 | 16 | # GNU Mailman. If not, see <http://www.gnu.org/licenses/>. | ||
233 | 17 | |||
234 | 18 | """nose2 test infrastructure.""" | ||
235 | 19 | |||
236 | 20 | from __future__ import absolute_import, print_function, unicode_literals | ||
237 | 21 | |||
238 | 22 | __metaclass__ = type | ||
239 | 23 | __all__ = [ | ||
240 | 24 | 'NosePlugin', | ||
241 | 25 | ] | ||
242 | 26 | |||
243 | 27 | |||
244 | 28 | import os | ||
245 | 29 | import re | ||
246 | 30 | import doctest | ||
247 | 31 | import mailman | ||
248 | 32 | import importlib | ||
249 | 33 | |||
250 | 34 | from mailman.testing.documentation import setup, teardown | ||
251 | 35 | from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer, SMTPLayer | ||
252 | 36 | from nose2.events import Plugin | ||
253 | 37 | |||
254 | 38 | DOT = '.' | ||
255 | 39 | FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF | ||
256 | 40 | TOPDIR = os.path.dirname(mailman.__file__) | ||
257 | 41 | |||
258 | 42 | |||
259 | 43 | |||
260 | 0 | 44 | ||
261 | 45 | class NosePlugin(Plugin): | ||
262 | 46 | configSection = 'mailman' | ||
263 | 47 | |||
264 | 48 | def __init__(self): | ||
265 | 49 | super(NosePlugin, self).__init__() | ||
266 | 50 | self.patterns = [] | ||
267 | 51 | self.addArgument(self.patterns, 'P', 'pattern', | ||
268 | 52 | 'Add a test matching pattern') | ||
269 | 53 | |||
270 | 54 | def startTestRun(self, event): | ||
271 | 55 | MockAndMonkeyLayer.testing_mode = True | ||
272 | 56 | ConfigLayer.enable_stderr() | ||
273 | 57 | |||
274 | 58 | def getTestCaseNames(self, event): | ||
275 | 59 | if len(self.patterns) == 0: | ||
276 | 60 | # No filter patterns, so everything should be tested. | ||
277 | 61 | return | ||
278 | 62 | names = filter(event.isTestMethod, dir(event.testCase)) | ||
279 | 63 | for name in names: | ||
280 | 64 | for pattern in self.patterns: | ||
281 | 65 | if re.search(pattern, name): | ||
282 | 66 | break | ||
283 | 67 | else: | ||
284 | 68 | event.excludedNames.append(name) | ||
285 | 69 | |||
286 | 70 | def handleFile(self, event): | ||
287 | 71 | path = event.path[len(TOPDIR)+1:] | ||
288 | 72 | if len(self.patterns) > 0: | ||
289 | 73 | for pattern in self.patterns: | ||
290 | 74 | if re.search(pattern, path): | ||
291 | 75 | break | ||
292 | 76 | else: | ||
293 | 77 | # Skip this doctest. | ||
294 | 78 | return | ||
295 | 79 | base, ext = os.path.splitext(path) | ||
296 | 80 | if ext != '.rst': | ||
297 | 81 | return | ||
298 | 82 | # Look to see if the package defines a test layer, otherwise use the | ||
299 | 83 | # default layer. First turn the file system path into a dotted Python | ||
300 | 84 | # module path. | ||
301 | 85 | parent = os.path.dirname(path) | ||
302 | 86 | dotted = 'mailman.' + DOT.join(parent.split(os.path.sep)) | ||
303 | 87 | try: | ||
304 | 88 | module = importlib.import_module(dotted) | ||
305 | 89 | except ImportError: | ||
306 | 90 | layer = SMTPLayer | ||
307 | 91 | else: | ||
308 | 92 | layer = getattr(module, 'layer', SMTPLayer) | ||
309 | 93 | test = doctest.DocFileTest( | ||
310 | 94 | path, package='mailman', | ||
311 | 95 | optionflags=FLAGS, | ||
312 | 96 | setUp=setup, | ||
313 | 97 | tearDown=teardown) | ||
314 | 98 | test.layer = layer | ||
315 | 99 | # Suppress the extra "Doctest: ..." line. | ||
316 | 100 | test.shortDescription = lambda: None | ||
317 | 101 | event.extraTests.append(test) | ||
318 | 1 | 102 | ||
319 | === added file 'unittest.cfg' | |||
320 | --- unittest.cfg 1970-01-01 00:00:00 +0000 | |||
321 | +++ unittest.cfg 2013-08-28 00:48:00 +0000 | |||
322 | @@ -0,0 +1,10 @@ | |||
323 | 1 | [unittest] | ||
324 | 2 | verbose = 2 | ||
325 | 3 | plugins = mailman.testing.nose | ||
326 | 4 | nose2.plugins.layers | ||
327 | 5 | |||
328 | 6 | [mailman] | ||
329 | 7 | always-on = True | ||
330 | 8 | |||
331 | 9 | [log-capture] | ||
332 | 10 | always-on = False |