Commit 57ab47f0 authored by Barry Warsaw's avatar Barry Warsaw

* The bin directory is no longer needed.

* setup.py:
  - get version from __init__.py file.
  - add nose2 as requirement
* Clean up _client.py a little bit.
* Transpose the doctest infrastructure from mailman to mailmanclient.
* Add a nose2 plugin.
* Remove test_docs.py
* tox.ini now runs nose2
parent 6e2f52a4
#!/usr/bin/env python
# Copyright (C) 2010-2015 by the Free Software Foundation, Inc.
#
# This file is part of mailman.client.
#
# mailman.client is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, version 3 of the License.
#
# mailman.client is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with mailman.client. If not, see <http://www.gnu.org/licenses/>.
"""Test runner."""
from __future__ import absolute_import, unicode_literals
__metaclass__ = type
import os
import sys
import unittest
from mailmanclient.tests.test_docs import additional_tests
if __name__ == '__main__':
suite = additional_tests()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
......@@ -16,16 +16,17 @@
# along with mailman.client. If not, see <http://www.gnu.org/licenses/>.
from setup_helpers import (
description, find_doctests, long_description, require_python)
description, find_doctests, get_version, long_description, require_python)
from setuptools import setup, find_packages
require_python(0x20600f0)
__version__ = get_version('src/mailmanclient/__init__.py')
setup(
name='mailmanclient',
version='1.0.0b1',
version=__version__,
packages=find_packages('src'),
package_dir = {'': 'src'},
include_package_data=True,
......@@ -41,5 +42,10 @@ setup(
# Auto-conversion to Python 3.
use_2to3=True,
convert_2to3_doctests=find_doctests(),
install_requires=['httplib2', 'mock', 'WebTest', ],
)
install_requires=[
'httplib2',
'mock',
'WebTest',
'nose2',
],
)
......@@ -16,7 +16,7 @@
"""Package contents."""
from __future__ import absolute_import, unicode_literals
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
......
......@@ -25,20 +25,17 @@ __all__ = [
]
import re
import json
from base64 import b64encode
from httplib2 import Http
from mailmanclient import __version__
from operator import itemgetter
from urllib import urlencode
from urllib2 import HTTPError
from urlparse import urljoin
from mailmanclient import __version__
DEFAULT_PAGE_ITEM_COUNT = 50
......
# Copyright (C) 2007-2015 by the Free Software Foundation, Inc.
#
# This file is part of GNU Mailman.
#
# GNU Mailman is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
"""Harness for testing Mailman's documentation.
Note that doctest extraction does not currently work for zip file
distributions. doctest discovery currently requires file system traversal.
"""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'setup',
'teardown'
]
from inspect import isfunction, ismethod
def stop():
"""Call into pdb.set_trace()"""
# Do the import here so that you get the wacky special hacked pdb instead
# of Python's normal pdb.
import pdb
pdb.set_trace()
def dump(results):
if results is None:
print(None)
return
for key in sorted(results):
if key == 'entries':
for i, entry in enumerate(results[key]):
# entry is a dictionary.
print('entry %d:' % i)
for entry_key in sorted(entry):
print(' {0}: {1}'.format(entry_key, entry[entry_key]))
else:
print('{0}: {1}'.format(key, results[key]))
def setup(testobj):
"""Test setup."""
# Make sure future statements in our doctests are the same as everywhere
# else.
testobj.globs['absolute_import'] = absolute_import
testobj.globs['print_function'] = print_function
testobj.globs['unicode_literals'] = unicode_literals
# In general, I don't like adding convenience functions, since I think
# doctests should do the imports themselves. It makes for better
# documentation that way. However, a few are really useful, or help to
# hide some icky test implementation details.
testobj.globs['stop'] = stop
testobj.globs['dump'] = dump
# Add this so that cleanups can be automatically added by the doctest.
testobj.globs['cleanups'] = []
def teardown(testobj):
for cleanup in testobj.globs['cleanups']:
if isfunction(cleanup) or ismethod(cleanup):
cleanup()
else:
cleanup[0](*cleanup[1:])
# Copyright (C) 2013-2014 by the Free Software Foundation, Inc.
#
# This file is part of GNU Mailman.
#
# GNU Mailman is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
"""nose2 test infrastructure."""
__all__ = [
'NosePlugin',
]
import os
import re
import doctest
import mailmanclient
from mailmanclient.testing.documentation import setup, teardown
from nose2.events import Plugin
DOT = '.'
FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF
TOPDIR = os.path.dirname(mailmanclient.__file__)
class NosePlugin(Plugin):
configSection = 'mailman'
def __init__(self):
super(NosePlugin, self).__init__()
self.patterns = []
self.stderr = False
def set_stderr(ignore):
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')
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):
path = event.path[len(TOPDIR)+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
test = doctest.DocFileTest(
path, package=mailmanclient,
optionflags=FLAGS,
setUp=setup,
tearDown=teardown)
# Suppress the extra "Doctest: ..." line.
test.shortDescription = lambda: None
event.extraTests.append(test)
## def startTest(self, event):
## import sys; print('vvvvv', event.test, file=sys.stderr)
## def stopTest(self, event):
## import sys; print('^^^^^', event.test, file=sys.stderr)
# Copyright (C) 2010-2015 by the Free Software Foundation, Inc.
#
# This file is part of mailman.client.
#
# mailman.client is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# mailman.client is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with mailman.client. If not, see <http://www.gnu.org/licenses/>.
"""Test harness for doctests."""
from __future__ import absolute_import, unicode_literals, print_function
__metaclass__ = type
__all__ = [
'additional_tests',
]
import os
import time
import atexit
import shutil
import doctest
import tempfile
import unittest
import subprocess
from textwrap import dedent
from mock import patch
# pylint: disable-msg=F0401
from pkg_resources import (
resource_filename, resource_exists, resource_listdir, cleanup_resources)
from mailman.config import config
from mailmanclient.tests.utils import FakeMailmanClient, inject_message
COMMASPACE = ', '
DOT = '.'
DOCTEST_FLAGS = (
doctest.ELLIPSIS |
doctest.NORMALIZE_WHITESPACE |
doctest.REPORT_NDIFF)
def dump(results):
if results is None:
print(None)
return
for key in sorted(results):
if key == 'entries':
for i, entry in enumerate(results[key]):
# entry is a dictionary.
print('entry %d:' % i)
for entry_key in sorted(entry):
print(' {0}: {1}'.format(entry_key, entry[entry_key]))
else:
print('{0}: {1}'.format(key, results[key]))
def stop():
"""Call into pdb.set_trace()"""
# Do the import here so that you get the wacky special hacked pdb instead
# of Python's normal pdb.
import pdb
pdb.set_trace()
def setup(testobj):
testobj.globs['stop'] = stop
testobj.globs['dump'] = dump
testobj.globs['inject_message'] = inject_message
FakeMailmanClient.setUp()
# In unit tests, passwords aren't encrypted. Don't show this in the doctests
passlib_cfg = os.path.join(config.VAR_DIR, 'passlib.cfg')
with open(passlib_cfg, 'w') as fp:
print(dedent("""
[passlib]
schemes = sha512_crypt
"""), file=fp)
conf_hash_pw = dedent("""
[passwords]
configuration: {}
""".format(passlib_cfg))
config.push('conf_hash_pw', conf_hash_pw)
# Use the FakeMailmanClient
testobj.patcher = patch("mailmanclient.Client", FakeMailmanClient)
fmc = testobj.patcher.start()
def teardown(testobj):
"""Test teardown."""
testobj.patcher.stop()
config.pop('conf_hash_pw')
FakeMailmanClient.tearDown()
def additional_tests():
"Run the doc tests (README.txt and docs/*, if any exist)"
doctest_files = []
if resource_exists('mailmanclient', 'docs'):
for name in resource_listdir('mailmanclient', 'docs'):
if name.endswith('.txt'):
doctest_files.append(
os.path.abspath(
resource_filename('mailmanclient', 'docs/%s' % name)))
kwargs = dict(module_relative=False,
optionflags=DOCTEST_FLAGS,
setUp=setup, tearDown=teardown,
)
atexit.register(cleanup_resources)
return unittest.TestSuite((
doctest.DocFileSuite(*doctest_files, **kwargs)))
......@@ -2,4 +2,4 @@
envlist = py26,py27,py32,py33,py34
[testenv]
commands = python setup.py test
commands = python -m nose2 -v
[unittest]
verbose = 2
plugins = mailmanclient.testing.nose
nose2.plugins.layers
[mailman]
always-on = True
[log-capture]
always-on = False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment