diff --git a/.gitignore b/.gitignore
index 89ba6f5..a28036f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ build
develop-eggs
dist
lib
+local
include
man
parts
diff --git a/.travis.yml b/.travis.yml
index 55bc622..7c18b48 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,9 @@ language: python
sudo: false
python:
- 2.7
- - 3.3
- 3.4
- 3.5
+ - 3.6
install:
- pip install tox-travis
script:
diff --git a/CHANGES.rst b/CHANGES.rst
index 109b071..b54f2a2 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,7 +4,8 @@ Changelog
1.3.1 (unreleased)
------------------
-- Nothing changed yet.
+- Turn fucntional tests into better covering unit tests and also add more tests.
+ This removes test dependencies on unrelated packages.
1.3 (2016-10-22)
diff --git a/README.rst b/README.rst
index 9762a0f..af6d89f 100644
--- a/README.rst
+++ b/README.rst
@@ -1 +1,15 @@
-Please refer to src/zope/globalrequest/README.rst.
+zope.globalrequest
+==================
+
+Introduction
+------------
+
+This package provides a global way to retrieve the currently active request object in a zope-based web framework.
+To do so you simply need to do the following::
+
+ from zope.globalrequest import getRequest
+ request = getRequest()
+
+This package is mainly intended to be used with the Zope2/Plone stack.
+While it also works with the Zope3 framework,
+the latter promotes a clean separation of concerns and the pattern of having a globally available request object is discouraged.
diff --git a/buildout.cfg b/buildout.cfg
index 4c1cc23..2cfebf7 100644
--- a/buildout.cfg
+++ b/buildout.cfg
@@ -1,13 +1,14 @@
[buildout]
develop = .
-parts = interpreter test
+parts = interpreter test
[interpreter]
recipe = zc.recipe.egg
eggs = zope.globalrequest
-interpreter = python
+interpreter = zopepy
[test]
recipe = zc.recipe.testrunner
eggs = zope.globalrequest [test]
defaults = ['-v']
+
diff --git a/setup.py b/setup.py
index cb42e4f..02c8b06 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,9 @@
+# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
-from os.path import join
version = '1.3.1.dev0'
-readme = open(join('src', 'zope', 'globalrequest', 'README.rst')).read()
+readme = open('README.rst').read()
changes = open('CHANGES.rst').read()
setup(
@@ -25,9 +25,9 @@
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
],
keywords='zope request global',
author='Zope Foundation and Contributors',
@@ -47,13 +47,7 @@
'zope.traversing',
],
extras_require=dict(
- test=[
- 'zope.browserpage',
- 'zope.app.wsgi',
- 'zope.configuration',
- 'zope.principalregistry',
- 'zope.testbrowser>=5.0',
- 'zope.testing',
+ test=[ # keep empty in case someone uses it
],
),
)
diff --git a/src/zope/globalrequest/README.rst b/src/zope/globalrequest/README.rst
deleted file mode 100644
index ab1b99a..0000000
--- a/src/zope/globalrequest/README.rst
+++ /dev/null
@@ -1,133 +0,0 @@
-zope.globalrequest
-==================
-
-Introduction
-------------
-
-This package provides a global way to retrieve the currently active request
-object in a zope-based web framework. To do so you simply need to do the
-following::
-
- from zope.globalrequest import getRequest
- request = getRequest()
-
-This package is mainly intended to be used with the Zope2/Plone stack. While
-it also works with the Zope3 framework, the latter promotes a clean separation
-of concerns and the pattern of having a globally available request object is
-discouraged.
-
-
-Functional Tests
-----------------
-
-The remainder of this file contains functional tests to demonstrate that the
-package works as intended.
-
-First we need to define a browser view along with an interface for a utility
-that will be used by that view:
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface):
- ... """ interface for a foo-ish utility """
- ... def foo():
- ... """ return some foo """
-
- >>> from zope.publisher.browser import BrowserPage
- >>> from zope.component import queryUtility
- >>> class FooView(BrowserPage):
- ... """ a browser view """
- ... def __call__(self, *args, **kw):
- ... foo = queryUtility(IFoo, default=None)
- ... if foo is not None:
- ... return foo.foo()
- ... else:
- ... return 'sif!'
-
-Unfortunately the view class cannot be directly imported from here, i.e.
-relatively, so we have to make it available from somewhere else in order to register it:
-
- >>> from zope.globalrequest import tests
- >>> tests.FooView = FooView
- >>> zcml("""
- ...
- ...
- ...
- ...
- ... """)
-
-Next let's make sure our test view actually works:
-
- >>> from zope.testbrowser.wsgi import Browser
- >>> browser = Browser()
- >>> browser.open('http://localhost/@@foo')
- >>> browser.contents
- 'sif!'
-
-The view tries to query for a utility and use it to "calculate" it's response,
-so let's define one:
-
- >>> from zope.globalrequest import getRequest
- >>> class Foo(object):
- ... def foo(self):
- ... request = getRequest()
- ... if request:
- ... name = request.get('name', 'n00b')
- ... else:
- ... name = 'foo'
- ... return 'y0 %s!' % name
-
-Again, the utility class and interface cannot be directly imported from here,
-so let's also make them available from somewhere else in order to register
-utility:
-
- >>> tests.Foo = Foo
- >>> tests.IFoo = IFoo
- >>> zcml("""
- ...
- ...
- ...
- ...
- ... """)
-
-Rendering the view again should now give us the default value provided by the
-utility:
-
- >>> browser.reload()
- >>> browser.contents
- 'y0 foo!'
-
-Up to now the request hasn't been stored for us yet, so let's hook up the
-necessary event subscribers and try that again:
-
- >>> zcml("""
- ...
- ...
- ...
- ...
- ... """)
-
-Now we should get the request and therefore the fallback value from the form
-lookup:
-
- >>> browser.reload()
- >>> browser.contents
- 'y0 n00b!'
-
-If we now provide a request value we should be greeted properly:
-
- >>> browser.open('?name=d4wg!')
- >>> browser.contents
- 'y0 d4wg!!'
-
-Once the request has been processed, it should not be available anymore:
-
- >>> print(getRequest())
- None
diff --git a/src/zope/globalrequest/__init__.py b/src/zope/globalrequest/__init__.py
index 3d72a2c..11b03d8 100644
--- a/src/zope/globalrequest/__init__.py
+++ b/src/zope/globalrequest/__init__.py
@@ -1,11 +1,11 @@
-from zope.interface.declarations import moduleProvides
+# -*- coding: utf-8 -*-
from zope.globalrequest.interfaces import IGlobalRequest
-
-moduleProvides(IGlobalRequest)
-
-
from zope.globalrequest.local import getLocal
from zope.globalrequest.local import setLocal
+from zope.globalrequest.local import marker
+from zope.interface.declarations import moduleProvides
+
+moduleProvides(IGlobalRequest)
def getRequest():
@@ -20,4 +20,4 @@ def setRequest(request):
def clearRequest():
""" clear the stored request object """
- setRequest(None)
+ setRequest(marker)
diff --git a/src/zope/globalrequest/ftesting.zcml b/src/zope/globalrequest/ftesting.zcml
deleted file mode 100644
index 6166a06..0000000
--- a/src/zope/globalrequest/ftesting.zcml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/zope/globalrequest/tests.py b/src/zope/globalrequest/tests.py
index a6465c2..1f42d1e 100644
--- a/src/zope/globalrequest/tests.py
+++ b/src/zope/globalrequest/tests.py
@@ -1,37 +1,93 @@
-from unittest import TestSuite
-from zope.configuration import config
-from zope.configuration import xmlconfig
-from zope.testing.cleanup import cleanUp
-import doctest
-import zope.app.wsgi.testlayer
-import zope.globalrequest
-import zope.testbrowser.wsgi
+# -*- coding: utf-8 -*-
+import unittest
-def zcml(source):
- context = config.ConfigurationMachine()
- xmlconfig.registerCommonDirectives(context)
- xmlconfig.string(source, context)
+class TestGlobalrequest(unittest.TestCase):
+ def tearDown(self):
+ # reset the threading local context
+ from threading import local
+ import zope.globalrequest.local
+ zope.globalrequest.local.localData = local()
-def tearDown(test):
- cleanUp()
+ def test_unset_local(self):
+ # test with unset values
+ import zope.globalrequest.local
+ self.assertIs(zope.globalrequest.local.getLocal('unsetkey'), None)
+ def test_set_get_local(self):
+ # test with simple values
+ import zope.globalrequest.local
+ zope.globalrequest.local.setLocal('testkey', 'testvalue')
+ self.assertIs(
+ zope.globalrequest.local.getLocal('testkey'),
+ 'testvalue'
+ )
-class Layer(zope.testbrowser.wsgi.TestBrowserLayer,
- zope.app.wsgi.testlayer.BrowserLayer):
- """Layer to prepare zope.testbrowser using the WSGI app."""
+ def test_unset_local_with_factory(self):
+ # test with a factory given and marker set/not set
+ dummy_default = 'dummy_test_default_value'
-testLayer = Layer(zope.globalrequest)
+ def dummy_default_factory():
+ return dummy_default
+
+ import zope.globalrequest.local
+
+ self.assertEqual(
+ zope.globalrequest.local.getLocal(
+ 'testdefaultkey',
+ factory=dummy_default_factory
+ ),
+ dummy_default
+ )
+
+ def test_unset_global_request(self):
+ # get w/o any value set returns None
+ import zope.globalrequest
+ self.assertIs(zope.globalrequest.getRequest(), None)
+
+ def test_set_get_globalrequest(self):
+ # set a value and get it back
+ import zope.globalrequest
+ test_request = dict(value='I am a dummy request')
+ zope.globalrequest.setRequest(test_request)
+ self.assertIs(zope.globalrequest.getRequest(), test_request)
+
+ def test_clear_global_request(self):
+ # set a value and get it back
+ import zope.globalrequest
+ test_request = dict(value='I am a dummy request')
+ zope.globalrequest.setRequest(test_request)
+ zope.globalrequest.clearRequest()
+ self.assertIs(zope.globalrequest.getRequest(), None)
+
+ def test_set_subscriber(self):
+ import zope.globalrequest.subscribers
+ test_request = dict(value='I am a dummy request')
+
+ class DummyEvent(object):
+ request = test_request
+
+ dummy_event = DummyEvent()
+
+ # test set
+ zope.globalrequest.subscribers.set(None, dummy_event)
+ self.assertIs(zope.globalrequest.getRequest(), test_request)
+
+ def test_clear_subscriber(self):
+ import zope.globalrequest.subscribers
+ test_request = dict(value='I am a dummy request')
+
+ class DummyEvent(object):
+ request = test_request
+
+ dummy_event = DummyEvent()
+
+ # test clear
+ zope.globalrequest.subscribers.set(None, dummy_event)
+ zope.globalrequest.subscribers.clearRequest()
+ self.assertIs(zope.globalrequest.getRequest(), None)
def test_suite():
- flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
- readme = doctest.DocFileSuite(
- 'README.rst',
- package='zope.globalrequest',
- globs={'zcml': zcml},
- optionflags=flags,
- tearDown=tearDown)
- readme.layer = testLayer
- return TestSuite((readme,))
+ return unittest.defaultTestLoader.loadTestsFromName(__name__)
diff --git a/tox.ini b/tox.ini
index 05d8d19..26a12aa 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
envlist =
- py27,py33,py34,py35
+ py27,py34,py35,py36
[testenv]
deps =