* refactor plugin support to work directly with

modules, no classes required anymore.
* call funcarg hook if defined on class

--HG--
branch : trunk
This commit is contained in:
holger krekel
2009-05-18 23:26:16 +02:00
parent 4035fa6326
commit 191d02aef2
33 changed files with 606 additions and 628 deletions

View File

@@ -5,9 +5,8 @@ EXPECTTIMEOUT=10.0
class TestGeneralUsage:
def test_config_error(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_configure(self, config):
raise config.Error("hello")
def pytest_configure(config):
raise config.Error("hello")
""")
result = testdir.runpytest(testdir.tmpdir)
assert result.ret != 0
@@ -17,9 +16,8 @@ class TestGeneralUsage:
def test_config_preparse_plugin_option(self, testdir):
testdir.makepyfile(pytest_xyz="""
class XyzPlugin:
def pytest_addoption(self, parser):
parser.addoption("--xyz", dest="xyz", action="store")
def pytest_addoption(parser):
parser.addoption("--xyz", dest="xyz", action="store")
""")
testdir.makepyfile(test_one="""
import py

View File

@@ -193,11 +193,10 @@ class TestCustomConftests:
def test_avoid_directory_on_option(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_addoption(self, parser):
parser.addoption("--XX", action="store_true", default=False)
def pytest_collect_recurse(self, path, parent):
return parent.config.getvalue("XX")
def pytest_addoption(parser):
parser.addoption("--XX", action="store_true", default=False)
def pytest_collect_recurse(path, parent):
return parent.config.getvalue("XX")
""")
testdir.mkdir("hello")
sorter = testdir.inline_run(testdir.tmpdir)

View File

@@ -19,9 +19,8 @@ def test_getfuncargnames():
class TestFillFuncArgs:
def test_funcarg_lookupfails(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_funcarg__xyzsomething(self, request):
return 42
def pytest_funcarg__xyzsomething(request):
return 42
""")
item = testdir.getitem("def test_func(some): pass")
exc = py.test.raises(LookupError, "funcargs.fillfuncargs(item)")
@@ -67,6 +66,19 @@ class TestFillFuncArgs:
funcargs.fillfuncargs(item2)
assert item2.funcargs['something'] == "test_func"
def test_funcarg_lookup_classlevel(self, testdir):
p = testdir.makepyfile("""
class TestClass:
def pytest_funcarg__something(self, request):
return request.instance
def test_method(self, something):
assert something is self
""")
result = testdir.runpytest(p)
assert result.stdout.fnmatch_lines([
"*1 passed*"
])
class TestRequest:
def test_request_attributes(self, testdir):
item = testdir.getitem("""
@@ -90,6 +102,7 @@ class TestRequest:
""")
req = funcargs.FuncargRequest(item, argname="something")
assert req.cls.__name__ == "TestB"
assert req.instance.__class__ == req.cls
def test_request_contains_funcargs_provider(self, testdir):
modcol = testdir.getmodulecol("""
@@ -284,10 +297,9 @@ class TestGenfuncFunctional:
def test_addcall_with_funcargs_two(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_generate_tests(self, metafunc):
assert "arg1" in metafunc.funcargnames
metafunc.addcall(funcargs=dict(arg1=1, arg2=2))
def pytest_generate_tests(metafunc):
assert "arg1" in metafunc.funcargnames
metafunc.addcall(funcargs=dict(arg1=1, arg2=2))
""")
p = testdir.makepyfile("""
def pytest_generate_tests(metafunc):
@@ -328,10 +340,9 @@ class TestGenfuncFunctional:
def test_generate_plugin_and_module(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_generate_tests(self, metafunc):
assert "arg1" in metafunc.funcargnames
metafunc.addcall(id="world", param=(2,100))
def pytest_generate_tests(metafunc):
assert "arg1" in metafunc.funcargnames
metafunc.addcall(id="world", param=(2,100))
""")
p = testdir.makepyfile("""
def pytest_generate_tests(metafunc):

View File

@@ -87,11 +87,10 @@ class TestConfigPickling:
def test_config_pickling_customoption(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_addoption(self, parser):
group = parser.addgroup("testing group")
group.addoption('-G', '--glong', action="store", default=42,
type="int", dest="gdest", help="g value.")
def pytest_addoption(parser):
group = parser.addgroup("testing group")
group.addoption('-G', '--glong', action="store", default=42,
type="int", dest="gdest", help="g value.")
""")
config = testdir.parseconfig("-G", "11")
assert config.option.gdest == 11
@@ -108,11 +107,10 @@ class TestConfigPickling:
tmp = testdir.tmpdir.ensure("w1", "w2", dir=1)
tmp.ensure("__init__.py")
tmp.join("conftest.py").write(py.code.Source("""
class ConftestPlugin:
def pytest_addoption(self, parser):
group = parser.addgroup("testing group")
group.addoption('-G', '--glong', action="store", default=42,
type="int", dest="gdest", help="g value.")
def pytest_addoption(parser):
group = parser.addgroup("testing group")
group.addoption('-G', '--glong', action="store", default=42,
type="int", dest="gdest", help="g value.")
"""))
config = testdir.parseconfig(tmp, "-G", "11")
assert config.option.gdest == 11

View File

@@ -1,6 +1,5 @@
import py, os
from py.__.test.pluginmanager import PluginManager, canonical_names
from py.__.test.pluginmanager import registerplugin, importplugin
from py.__.test.pluginmanager import PluginManager, canonical_importname
class TestBootstrapping:
def test_consider_env_fails_to_import(self, monkeypatch):
@@ -17,7 +16,7 @@ class TestBootstrapping:
def test_consider_env_plugin_instantiation(self, testdir, monkeypatch):
pluginmanager = PluginManager()
testdir.syspathinsert()
testdir.makepyfile(pytest_xy123="class Xy123Plugin: pass")
testdir.makepyfile(pytest_xy123="#")
monkeypatch.setitem(os.environ, 'PYTEST_PLUGINS', 'xy123')
l1 = len(pluginmanager.getplugins())
pluginmanager.consider_env()
@@ -29,7 +28,7 @@ class TestBootstrapping:
assert l2 == l3
def test_pluginmanager_ENV_startup(self, testdir, monkeypatch):
x500 = testdir.makepyfile(pytest_x500="class X500Plugin: pass")
x500 = testdir.makepyfile(pytest_x500="#")
p = testdir.makepyfile("""
import py
def test_hello():
@@ -48,59 +47,49 @@ class TestBootstrapping:
reset = testdir.syspathinsert()
pluginname = "pytest_hello"
testdir.makepyfile(**{pluginname: """
class HelloPlugin:
pass
"""})
testdir.makepyfile(**{pluginname: ""})
pluginmanager.import_plugin("hello")
len1 = len(pluginmanager.getplugins())
pluginmanager.import_plugin("pytest_hello")
len2 = len(pluginmanager.getplugins())
assert len1 == len2
plugin1 = pluginmanager.getplugin("pytest_hello")
assert plugin1.__class__.__name__ == 'HelloPlugin'
assert plugin1.__name__.endswith('pytest_hello')
plugin2 = pluginmanager.getplugin("hello")
assert plugin2 is plugin1
def test_consider_module(self, testdir):
pluginmanager = PluginManager()
testdir.syspathinsert()
testdir.makepyfile(pytest_plug1="class Plug1Plugin: pass")
testdir.makepyfile(pytest_plug2="class Plug2Plugin: pass")
testdir.makepyfile(pytest_plug1="#")
testdir.makepyfile(pytest_plug2="#")
mod = py.std.new.module("temp")
mod.pytest_plugins = ["pytest_plug1", "pytest_plug2"]
pluginmanager.consider_module(mod)
assert pluginmanager.getplugin("plug1").__class__.__name__ == "Plug1Plugin"
assert pluginmanager.getplugin("plug2").__class__.__name__ == "Plug2Plugin"
assert pluginmanager.getplugin("plug1").__name__ == "pytest_plug1"
assert pluginmanager.getplugin("plug2").__name__ == "pytest_plug2"
def test_consider_module_import_module(self, testdir):
mod = py.std.new.module("x")
mod.pytest_plugins = "pytest_a"
aplugin = testdir.makepyfile(pytest_a="""class APlugin: pass""")
aplugin = testdir.makepyfile(pytest_a="#")
pluginmanager = PluginManager()
sorter = testdir.geteventrecorder(pluginmanager)
#syspath.prepend(aplugin.dirpath())
py.std.sys.path.insert(0, str(aplugin.dirpath()))
pluginmanager.consider_module(mod)
call = sorter.getcall(pluginmanager.hook.pytest_plugin_registered.name)
assert call.plugin.__class__.__name__ == "APlugin"
assert call.plugin.__name__ == "pytest_a"
# check that it is not registered twice
pluginmanager.consider_module(mod)
l = sorter.getcalls("plugin_registered")
assert len(l) == 1
def test_consider_conftest(self, testdir):
def test_consider_conftest_deprecated(self, testdir):
pp = PluginManager()
mod = testdir.makepyfile("class ConftestPlugin: hello = 1").pyimport()
pp.consider_conftest(mod)
l = [x for x in pp.getplugins() if isinstance(x, mod.ConftestPlugin)]
assert len(l) == 1
assert l[0].hello == 1
pp.consider_conftest(mod)
l = [x for x in pp.getplugins() if isinstance(x, mod.ConftestPlugin)]
assert len(l) == 1
mod = testdir.makepyfile("class ConftestPlugin: pass").pyimport()
call = py.test.raises(ValueError, pp.consider_conftest, mod)
def test_config_sets_conftesthandle_onimport(self, testdir):
config = testdir.parseconfig([])
@@ -124,33 +113,16 @@ class TestBootstrapping:
pp.unregister(a2)
assert not pp.isregistered(a2)
def test_canonical_names(self):
def test_canonical_importname(self):
for name in 'xyz', 'pytest_xyz', 'pytest_Xyz', 'Xyz':
impname, clsname = canonical_names(name)
assert impname == "pytest_xyz"
assert clsname == "XyzPlugin"
def test_registerplugin(self):
l = []
registerfunc = l.append
registerplugin(registerfunc, py.io, "TerminalWriter")
assert len(l) == 1
assert isinstance(l[0], py.io.TerminalWriter)
def test_importplugin(self):
assert importplugin("py") == py
py.test.raises(ImportError, "importplugin('laksjd.qwe')")
mod = importplugin("pytest_terminal")
assert mod is py.__.test.plugin.pytest_terminal
impname = canonical_importname(name)
class TestPytestPluginInteractions:
def test_do_option_conftestplugin(self, testdir):
from py.__.test.config import Config
p = testdir.makepyfile("""
class ConftestPlugin:
def pytest_addoption(self, parser):
parser.addoption('--test123', action="store_true")
def pytest_addoption(parser):
parser.addoption('--test123', action="store_true")
""")
config = Config()
config._conftest.importconftest(p)
@@ -165,10 +137,9 @@ class TestPytestPluginInteractions:
config.pluginmanager.do_configure(config=config)
assert not hasattr(config.option, 'test123')
p = testdir.makepyfile("""
class ConftestPlugin:
def pytest_addoption(self, parser):
parser.addoption('--test123', action="store_true",
default=True)
def pytest_addoption(parser):
parser.addoption('--test123', action="store_true",
default=True)
""")
config._conftest.importconftest(p)
assert config.option.test123

View File

@@ -255,6 +255,19 @@ class TestFunction:
assert f5 != f5b
assert not (f5 == f5b)
class callspec1:
param = 1
funcargs = {}
class callspec2:
param = 2
funcargs = {}
f5 = py.test.collect.Function(name="name", config=config,
callspec=callspec1, callobj=isinstance)
f5b = py.test.collect.Function(name="name", config=config,
callspec=callspec2, callobj=isinstance)
assert f5 != f5b
assert not (f5 == f5b)
class TestSorting:
def test_check_equality_and_cmp_basic(self, testdir):
modcol = testdir.getmodulecol("""

View File

@@ -9,21 +9,20 @@ class TestTracebackCutting:
def test_traceback_argsetup(self, testdir):
testdir.makeconftest("""
class ConftestPlugin:
def pytest_funcarg__hello(self, request):
raise ValueError("xyz")
def pytest_funcarg__hello(request):
raise ValueError("xyz")
""")
p = testdir.makepyfile("def test(hello): pass")
result = testdir.runpytest(p)
assert result.ret != 0
out = result.stdout.str()
assert out.find("xyz") != -1
assert out.find("conftest.py:3: ValueError") != -1
assert out.find("conftest.py:2: ValueError") != -1
numentries = out.count("_ _ _") # separator for traceback entries
assert numentries == 0
result = testdir.runpytest("--fulltrace", p)
out = result.stdout.str()
assert out.find("conftest.py:3: ValueError") != -1
assert out.find("conftest.py:2: ValueError") != -1
numentries = out.count("_ _ _ _") # separator for traceback entries
assert numentries >3