* remove redundant call_next_provider method, thus generalizing Request object
* refine according documentation --HG-- branch : trunk
This commit is contained in:
parent
3f50470c6a
commit
a59d602bce
|
@ -174,8 +174,10 @@ object that is to be closed when the test function finishes.
|
||||||
requesting values of other funcargs
|
requesting values of other funcargs
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
While setting up one function argument you may
|
Inside a funcarg provider, you sometimes may want to use a
|
||||||
want to retrieve another function argument.
|
different function argument which may be specified with
|
||||||
|
the test function or not. For such purposes you can
|
||||||
|
dynamically request a funcarg value:
|
||||||
|
|
||||||
.. sourcecode:: python
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
@ -184,26 +186,10 @@ want to retrieve another function argument.
|
||||||
Each function argument is only requested once per function setup.
|
Each function argument is only requested once per function setup.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Note that it does not matter if the test function
|
You can also use this function if you want to `decorate a funcarg`_
|
||||||
specifies the requested function argument.
|
locally, i.e. you want to provide the normal value but add/do something
|
||||||
|
extra. If a provider cannot be found a ``request.Error`` exception will be
|
||||||
decorating other funcarg providers
|
raised.
|
||||||
++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
If you want to **decorate a function argument** that is
|
|
||||||
provided elsewhere you can ask the request object
|
|
||||||
to provide the "next" value:
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
def pytest_funcarg__myfile(self, request):
|
|
||||||
myfile = request.call_next_provider()
|
|
||||||
# do something extra
|
|
||||||
return myfile
|
|
||||||
|
|
||||||
This will raise a ``request.Error`` exception if there
|
|
||||||
is no next provider left. See the `decorator example`_
|
|
||||||
for a use of this method.
|
|
||||||
|
|
||||||
|
|
||||||
.. _`test generators`:
|
.. _`test generators`:
|
||||||
|
@ -516,7 +502,7 @@ to your AcceptFuncarg and drive running of tools or
|
||||||
applications and provide ways to do assertions about
|
applications and provide ways to do assertions about
|
||||||
the output.
|
the output.
|
||||||
|
|
||||||
.. _`decorator example`:
|
.. _`decorate a funcarg`:
|
||||||
|
|
||||||
example: decorating a funcarg in a test module
|
example: decorating a funcarg in a test module
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
@ -528,7 +514,7 @@ extend the `accept example`_ by putting this in our test class:
|
||||||
.. sourcecode:: python
|
.. sourcecode:: python
|
||||||
|
|
||||||
def pytest_funcarg__accept(self, request):
|
def pytest_funcarg__accept(self, request):
|
||||||
arg = request.call_next_provider()
|
arg = request.getfuncargvalue("accept") # call the next provider
|
||||||
# create a special layout in our tempdir
|
# create a special layout in our tempdir
|
||||||
arg.tmpdir.mkdir("special")
|
arg.tmpdir.mkdir("special")
|
||||||
return arg
|
return arg
|
||||||
|
|
|
@ -116,33 +116,21 @@ class FuncargRequest:
|
||||||
self.addfinalizer(lambda: teardown(val), scope=scope)
|
self.addfinalizer(lambda: teardown(val), scope=scope)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def call_next_provider(self):
|
|
||||||
if not self._provider[self._argname]:
|
|
||||||
raise self.Error("no provider methods left for %r" % self._argname)
|
|
||||||
next_provider = self._provider[self._argname].pop()
|
|
||||||
return next_provider(request=self)
|
|
||||||
|
|
||||||
def getfuncargvalue(self, argname):
|
def getfuncargvalue(self, argname):
|
||||||
try:
|
try:
|
||||||
return self._funcargs[argname]
|
return self._funcargs[argname]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
assert argname not in self._provider
|
if argname not in self._provider:
|
||||||
self._provider[argname] = self.config.pluginmanager.listattr(
|
self._provider[argname] = self.config.pluginmanager.listattr(
|
||||||
plugins=self._plugins,
|
plugins=self._plugins,
|
||||||
attrname=self._argprefix + str(argname)
|
attrname=self._argprefix + str(argname)
|
||||||
)
|
)
|
||||||
# during call_next_provider() we keep state about the current
|
#else: we are called recursively
|
||||||
# argument on the request object - we may go for instantiating
|
if not self._provider[argname]:
|
||||||
# request objects per each funcargname if neccessary
|
|
||||||
oldname = self._argname
|
|
||||||
self._argname = argname
|
|
||||||
try:
|
|
||||||
self._funcargs[argname] = res = self.call_next_provider()
|
|
||||||
except self.Error:
|
|
||||||
self._raiselookupfailed(argname)
|
self._raiselookupfailed(argname)
|
||||||
if oldname:
|
funcargprovider = self._provider[argname].pop()
|
||||||
self._argname = oldname
|
self._funcargs[argname] = res = funcargprovider(request=self)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _getscopeitem(self, scope):
|
def _getscopeitem(self, scope):
|
||||||
|
|
|
@ -9,7 +9,7 @@ def pytest_collect_file(path, parent):
|
||||||
|
|
||||||
# decorate testdir to contain plugin under test
|
# decorate testdir to contain plugin under test
|
||||||
def pytest_funcarg__testdir(request):
|
def pytest_funcarg__testdir(request):
|
||||||
testdir = request.call_next_provider()
|
testdir = request.getfuncargvalue("testdir")
|
||||||
#for obj in (request.cls, request.module):
|
#for obj in (request.cls, request.module):
|
||||||
# if hasattr(obj, 'testplugin'):
|
# if hasattr(obj, 'testplugin'):
|
||||||
# testdir.plugins.append(obj.testplugin)
|
# testdir.plugins.append(obj.testplugin)
|
||||||
|
|
|
@ -391,7 +391,7 @@ class TestApigenLinkRole:
|
||||||
|
|
||||||
class TestDoctest:
|
class TestDoctest:
|
||||||
def pytest_funcarg__testdir(self, request):
|
def pytest_funcarg__testdir(self, request):
|
||||||
testdir = request.call_next_provider()
|
testdir = request.getfuncargvalue("testdir")
|
||||||
assert request.module.__name__ == __name__
|
assert request.module.__name__ == __name__
|
||||||
testdir.makepyfile(confrest="from py.__.misc.rest import Project")
|
testdir.makepyfile(confrest="from py.__.misc.rest import Project")
|
||||||
for p in testdir.plugins:
|
for p in testdir.plugins:
|
||||||
|
|
|
@ -128,15 +128,20 @@ class TestRequest:
|
||||||
assert len(provider) == 1
|
assert len(provider) == 1
|
||||||
assert provider[0].__name__ == "pytest_funcarg__something"
|
assert provider[0].__name__ == "pytest_funcarg__something"
|
||||||
|
|
||||||
def test_request_call_next_provider(self, testdir):
|
def test_getfuncargvalue_recursive(self, testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
def pytest_funcarg__something(request):
|
||||||
|
return 1
|
||||||
|
""")
|
||||||
item = testdir.getitem("""
|
item = testdir.getitem("""
|
||||||
def pytest_funcarg__something(request): return 1
|
def pytest_funcarg__something(request):
|
||||||
def test_func(something): pass
|
return request.getfuncargvalue("something") + 1
|
||||||
|
def test_func(something):
|
||||||
|
assert something == 2
|
||||||
""")
|
""")
|
||||||
req = funcargs.FuncargRequest(item)
|
req = funcargs.FuncargRequest(item)
|
||||||
val = req.getfuncargvalue("something")
|
val = req.getfuncargvalue("something")
|
||||||
assert val == 1
|
assert val == 2
|
||||||
py.test.raises(req.Error, "req.call_next_provider()")
|
|
||||||
|
|
||||||
def test_getfuncargvalue(self, testdir):
|
def test_getfuncargvalue(self, testdir):
|
||||||
item = testdir.getitem("""
|
item = testdir.getitem("""
|
||||||
|
|
|
@ -14,7 +14,7 @@ def setglobals(request):
|
||||||
|
|
||||||
def pytest_funcarg__testdir(request):
|
def pytest_funcarg__testdir(request):
|
||||||
setglobals(request)
|
setglobals(request)
|
||||||
return request.call_next_provider()
|
return request.getfuncargvalue("testdir")
|
||||||
|
|
||||||
class ImmutablePickleTransport:
|
class ImmutablePickleTransport:
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
|
|
Loading…
Reference in New Issue