Merge lp:~barry/mailman/nose2 into lp:mailman

Proposed by Barry Warsaw
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
Reviewer Review Type Date Requested Status
Mailman Coders Pending
Review via email: mp+182144@code.launchpad.net

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