diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..f205e92 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,7 @@ +[run] +source = src + +[report] +exclude_lines = + pragma: no cover + if __name__ == '__main__': diff --git a/.gitignore b/.gitignore index 5149542..7d30d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ build/ dist/ *.egg-info/ .tox/ +htmlcov/ +.coverage diff --git a/.travis.yml b/.travis.yml index 02dca11..986be75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,25 @@ language: python +sudo: false python: - - 2.7 -install: - - pip install . + - 2.7 + - 3.5 + - 3.6 + - pypy-5.4.1 script: - - python setup.py test -q + - coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress + +after_success: + - coveralls notifications: - email: false + email: false + +install: + - pip install -U pip setuptools + - pip install -U coveralls coverage + - pip install -U -e ".[test]" + + +cache: pip + +before_cache: + - rm -f $HOME/.cache/pip/log/debug.log diff --git a/CHANGES.txt b/CHANGES.rst similarity index 87% rename from CHANGES.txt rename to CHANGES.rst index e9d4657..ba5c9ba 100644 --- a/CHANGES.txt +++ b/CHANGES.rst @@ -2,10 +2,10 @@ CHANGES ======= -3.5.4 (unreleased) +4.0.0 (unreleased) ------------------ -- Nothing changed yet. +- Add support for Python 3.4, 3.5, 3.6 and PyPy. 3.5.3 (2010-09-01) @@ -28,7 +28,7 @@ CHANGES - Use zope.ManageServices permission instead of zope.ManageContent for errorRedirect view and menu item, because all IErrorReportingUtility - views are registered for zope.ManageServices as well. + views are registered for zope.ManageServices as well. - Fix package's README.txt diff --git a/MANIFEST.in b/MANIFEST.in index 97a3f58..33e5aeb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,12 @@ include *.py include *.txt +include *.rst include buildout.cfg +include .travis.yml +include .coveragerc +include tox.ini + recursive-include src *.gif recursive-include src *.pt -recursive-include src *.txt +recursive-include src *.rst recursive-include src *.zcml diff --git a/README.txt b/README.rst similarity index 100% rename from README.txt rename to README.rst diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2a9acf1 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 diff --git a/setup.py b/setup.py index a525f7e..33ce0d6 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,6 @@ ############################################################################## """Setup for zope.app.error package -$Id$ """ import os @@ -26,43 +25,70 @@ from setuptools import setup, find_packages def read(*rnames): - return open(os.path.join(os.path.dirname(__file__), *rnames)).read() + with open(os.path.join(os.path.dirname(__file__), *rnames)) as f: + return f.read() setup(name='zope.app.error', - version='3.5.4dev', + version='4.0.0.dev0', author='Zope Corporation and Contributors', author_email='zope-dev@zope.org', - description = "Error reporting utility management UI for Zope3", + description="Error reporting utility management UI for Zope3", long_description=( - read('README.txt') + read('README.rst') + '\n\n' + - read('CHANGES.txt') + read('src','zope', 'app', 'error', 'README.rst') + + '\n\n' + + read('CHANGES.rst') ), license='ZPL 2.1', - keywords = "zope3 error reporting utility views UI", - classifiers = [ + keywords="zope3 error reporting utility views UI", + classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: Zope Public License', 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy', 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', - 'Framework :: Zope3'], - url='http://pypi.python.org/pypi/zope.app.error', + 'Framework :: Zope3', + ], + url='http://github.com/zopefoundation/zope.app.error', packages=find_packages('src'), - package_dir = {'': 'src'}, - extras_require=dict( - test=['zope.app.testing']), + package_dir={'': 'src'}, + extras_require={ + 'test': [ + 'zope.testing', + 'zope.testrunner', + 'zope.browserpage', + 'zope.browsermenu', + 'zope.browserresource', + ], + 'browser': [ + 'zope.browsermenu', + 'zope.browserpage', + 'zope.browserresource', + ], + }, namespace_packages=['zope', 'zope.app'], - install_requires=['setuptools', - 'zope.component', - 'zope.error', - 'zope.publisher', - 'zope.traversing', - ], - include_package_data = True, - - zip_safe = False, - ) + install_requires=[ + 'setuptools', + # zope.error has an undeclared dependency on zope.annotation + 'zope.annotation', + 'zope.component', + 'zope.error', + 'zope.publisher', + 'zope.security', + 'zope.traversing', + ], + include_package_data=True, + zip_safe=False, +) diff --git a/src/zope/__init__.py b/src/zope/__init__.py index bf99a9d..2cdb0e4 100644 --- a/src/zope/__init__.py +++ b/src/zope/__init__.py @@ -1,8 +1 @@ -# this is a namespace package -try: - import pkg_resources - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) - +__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover diff --git a/src/zope/app/__init__.py b/src/zope/app/__init__.py index bf99a9d..2cdb0e4 100644 --- a/src/zope/app/__init__.py +++ b/src/zope/app/__init__.py @@ -1,8 +1 @@ -# this is a namespace package -try: - import pkg_resources - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) - +__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover diff --git a/src/zope/app/error/README.rst b/src/zope/app/error/README.rst new file mode 100644 index 0000000..e4615fa --- /dev/null +++ b/src/zope/app/error/README.rst @@ -0,0 +1,57 @@ +====== +README +====== + +This package provides an error reporting utility which is able to +store errors. (Notice that the implementation classes have been moved +to the ``zope.error`` package.) + +Let's create one: + + >>> from zope.app.error.error import ErrorReportingUtility + >>> util = ErrorReportingUtility() + >>> util + + + >>> from zope.app.error.interfaces import IErrorReportingUtility + >>> IErrorReportingUtility.providedBy(util) + True + >>> IErrorReportingUtility + + +This package contains ZMI views in the ``browser`` sub-package: + + >>> from zope.app.error.browser import EditErrorLog, ErrorRedirect + >>> EditErrorLog + + >>> ErrorRedirect + + +These are configured when the configuration for this package is +executed (as long as the right dependencies are available). + +Certain ZMI menus must first be available: + + >>> from zope.configuration import xmlconfig + >>> _ = xmlconfig.string(r""" + ... + ... + ... + ... + ... + ... + ... """) + +Now we can configure the package: + + >>> _ = xmlconfig.string(r""" + ... + ... + ... + ... """) diff --git a/src/zope/app/error/README.txt b/src/zope/app/error/README.txt deleted file mode 100644 index 4f29338..0000000 --- a/src/zope/app/error/README.txt +++ /dev/null @@ -1,15 +0,0 @@ -====== -README -====== - -This package provides an error reporting utility which is able to store errors. -Let's create one: - - >>> from zope.error.error import ErrorReportingUtility - >>> util = ErrorReportingUtility() - >>> util - - - >>> from zope.error.interfaces import IErrorReportingUtility - >>> IErrorReportingUtility.providedBy(util) - True diff --git a/src/zope/app/error/browser/__init__.py b/src/zope/app/error/browser/__init__.py index 78419ca..468f5f8 100644 --- a/src/zope/app/error/browser/__init__.py +++ b/src/zope/app/error/browser/__init__.py @@ -12,8 +12,6 @@ # ############################################################################## """Define view component for event utility control. - -$Id$ """ from zope.component import getUtility from zope.publisher.browser import BrowserView diff --git a/src/zope/app/error/browser/configure.zcml b/src/zope/app/error/browser/configure.zcml index 9dccedc..23a4d7b 100644 --- a/src/zope/app/error/browser/configure.zcml +++ b/src/zope/app/error/browser/configure.zcml @@ -1,6 +1,15 @@ + xmlns:zcml="http://namespaces.zope.org/zcml" + xmlns="http://namespaces.zope.org/browser" + i18n_domain="zope"> + + + + + + + - diff --git a/src/zope/app/error/browser/ftesting.zcml b/src/zope/app/error/browser/ftesting.zcml new file mode 100644 index 0000000..e6f1728 --- /dev/null +++ b/src/zope/app/error/browser/ftesting.zcml @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/src/zope/app/error/browser/tests.py b/src/zope/app/error/browser/tests.py new file mode 100644 index 0000000..b164015 --- /dev/null +++ b/src/zope/app/error/browser/tests.py @@ -0,0 +1,115 @@ +############################################################################## +# +# Copyright (c) 2017 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## + +import unittest + + +from zope.component.testlayer import ZCMLFileLayer +from zope.publisher.interfaces.http import IHTTPRequest +from zope.interface import implementer + +import zope.app.error.browser +from zope.app.error.browser import EditErrorLog +from zope.app.error.browser import ErrorRedirect + +class TestEditErrorLog(unittest.TestCase): + + def test_updateProperties(self): + class Context(object): + props = None + def setProperties(self, keep_entries, copy_to_zlog, ignored_exceptions): + self.props = dict(locals()) + del self.props['self'] + + class Request(object): + url = None + @property + def response(self): + return self + def redirect(self, url): + self.url = url + + edit = EditErrorLog() + edit.context = Context() + edit.request = Request() + edit.updateProperties('keep') + + self.assertEqual(edit.context.props, + {'copy_to_zlog': 0, + 'ignored_exceptions': None, + 'keep_entries': 'keep'}) + self.assertEqual(edit.request.url, '@@configure.html') + +class TestErrorRedirect(unittest.TestCase): + + layer = ZCMLFileLayer(zope.app.error.browser, + name='AppErrorLayer') + + def test_action_type_error(self): + + @implementer(IHTTPRequest) + class Request(object): + url = None + + @property + def response(self): + return self + + def getVirtualHostRoot(self): + return None + + def getApplicationURL(self): + return 'http://localhost' + + def redirect(self, url): + self.url = url + + redirect = ErrorRedirect(None, Request()) + redirect.action() + + self.assertEqual(redirect.request.url, + 'http://localhost/@@errorRedirect.html') + + def test_action_no_type_error(self): + from zope.component import getUtility + from zope.error.interfaces import IErrorReportingUtility + + @implementer(IHTTPRequest) + class Request(object): + url = None + + @property + def response(self): + return self + + root = None + def getVirtualHostRoot(self): + return self.root + + def getApplicationURL(self): + return 'http://localhost' + + def redirect(self, url): + self.url = url + + redirect = ErrorRedirect(None, Request()) + redirect.request.root = getUtility(IErrorReportingUtility) + redirect.action() + + self.assertEqual(redirect.request.url, + 'http://localhost/@@SelectedManagementView.html') + + +def test_suite(): + return unittest.defaultTestLoader.loadTestsFromName(__name__) diff --git a/src/zope/app/error/configure.zcml b/src/zope/app/error/configure.zcml index 1e06f25..c0f34a9 100644 --- a/src/zope/app/error/configure.zcml +++ b/src/zope/app/error/configure.zcml @@ -1,7 +1,14 @@ - + + + + + + - + diff --git a/src/zope/app/error/tests.py b/src/zope/app/error/tests.py index 7f1904f..3bd82ba 100644 --- a/src/zope/app/error/tests.py +++ b/src/zope/app/error/tests.py @@ -19,7 +19,7 @@ def test_suite(): return unittest.TestSuite(( - doctest.DocFileSuite('README.txt', + doctest.DocFileSuite('README.rst', optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS, ), )) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2cbdb94 --- /dev/null +++ b/tox.ini @@ -0,0 +1,8 @@ +[tox] +envlist = py27,py35,py36,pypy + +[testenv] +commands = + zope-testrunner --test-path=src [] +deps = + .[test]