diff --git a/py/__init__.py b/py/__init__.py index e8e6771e6..6ea490bdb 100644 --- a/py/__init__.py +++ b/py/__init__.py @@ -27,8 +27,8 @@ version = "1.0.0a1" initpkg(__name__, description = "pylib and py.test: agile development and test support library", - revision = int('$LastChangedRevision: 62211 $'.split(':')[1][:-1]), - lastchangedate = '$LastChangedDate: 2009-02-27 11:18:27 +0100 (Fri, 27 Feb 2009) $', + revision = int('$LastChangedRevision: 62252 $'.split(':')[1][:-1]), + lastchangedate = '$LastChangedDate: 2009-02-27 20:56:51 +0100 (Fri, 27 Feb 2009) $', version = version, url = "http://pylib.org", download_url = "http://codespeak.net/py/0.9.2/download.html", @@ -73,7 +73,7 @@ initpkg(__name__, 'test.__doc__' : ('./test/__init__.py', '__doc__'), 'test._PytestPlugins' : ('./test/pytestplugin.py', 'PytestPlugins'), 'test.raises' : ('./test/outcome.py', 'raises'), - 'test.keywords' : ('./test/outcome.py', 'keywords',), + 'test.mark' : ('./test/outcome.py', 'mark',), 'test.deprecated_call' : ('./test/outcome.py', 'deprecated_call'), 'test.skip' : ('./test/outcome.py', 'skip'), 'test.importorskip' : ('./test/outcome.py', 'importorskip'), diff --git a/py/doc/test.txt b/py/doc/test.txt index 9fee5f9d7..53c790939 100644 --- a/py/doc/test.txt +++ b/py/doc/test.txt @@ -166,7 +166,7 @@ class/function names of a test function are put into the set of keywords for a given test. You may specify additional kewords like this:: - @py.test.keywords("webtest") + @py.test.mark(webtest=True) def test_send_http(): ... diff --git a/py/misc/testing/test_com.py b/py/misc/testing/test_com.py index 801389901..4a4c4a0bd 100644 --- a/py/misc/testing/test_com.py +++ b/py/misc/testing/test_com.py @@ -72,7 +72,7 @@ class TestPyPlugins: assert not plugins.isregistered(my) assert plugins.getplugins() == [my2] - #@py.test.keywords(xfail=True) + #@py.test.mark.xfail def test_onregister(self): py.test.skip("implement exitfirst plugin and " "modify xfail plugin to override exitfirst behaviour?") diff --git a/py/test/outcome.py b/py/test/outcome.py index 49e292d6d..6994c243e 100644 --- a/py/test/outcome.py +++ b/py/test/outcome.py @@ -139,14 +139,34 @@ def deprecated_call(func, *args, **kwargs): raise AssertionError("%r did not produce DeprecationWarning" %(func,)) return ret -class keywords: +class KeywordDecorator: """ decorator for setting function attributes. """ - def __init__(self, **kw): - self.kw = kw - def __call__(self, func): - func.func_dict.update(self.kw) + def __init__(self, keywords, lastname=None): + self._keywords = keywords + self._lastname = lastname + + def __call__(self, func=None, **kwargs): + if func is None: + kw = self._keywords.copy() + kw.update(kwargs) + return KeywordDecorator(kw) + elif not hasattr(func, 'func_dict'): + kw = self._keywords.copy() + name = self._lastname + if name is None: + name = "mark" + kw[name] = func + return KeywordDecorator(kw) + func.func_dict.update(self._keywords) return func + def __getattr__(self, name): + kw = self._keywords.copy() + kw[name] = True + return self.__class__(kw, lastname=name) + +mark = KeywordDecorator({}) + # exitcodes for the command line EXIT_OK = 0 EXIT_TESTSFAILED = 1 diff --git a/py/test/plugin/pytest_xfail.py b/py/test/plugin/pytest_xfail.py index 9926bdd3d..87fe0d716 100644 --- a/py/test/plugin/pytest_xfail.py +++ b/py/test/plugin/pytest_xfail.py @@ -1,6 +1,6 @@ """ for marking and reporting "expected to fail" tests. - @py.test.keywords(xfail="needs refactoring") + @py.test.mark(xfail="needs refactoring") def test_hello(): ... assert 0 @@ -51,7 +51,7 @@ def test_xfail(plugintester, linecomp): p = testdir.makepyfile(test_one=""" import py pytest_plugins="pytest_xfail", - @py.test.keywords(xfail=True) + @py.test.mark.xfail def test_this(): assert 0 """) diff --git a/py/test/testing/test_config.py b/py/test/testing/test_config.py index 2bcde4af7..d6088c465 100644 --- a/py/test/testing/test_config.py +++ b/py/test/testing/test_config.py @@ -3,7 +3,7 @@ import py pytest_plugins = 'pytest_iocapture' class TestConfigCmdlineParsing: - @py.test.keywords(xfail="commit parser") + @py.test.mark(xfail="commit parser") def test_config_addoption(self, stdcapture): from py.__.test.config import Config config = Config() @@ -73,7 +73,7 @@ class TestConfigCmdlineParsing: class TestConfigAPI: - @py.test.keywords(issue="ensuretemp should call config.maketemp(basename)") + @py.test.mark(issue="ensuretemp should call config.maketemp(basename)") def test_tmpdir(self): d1 = py.test.ensuretemp('hello') d2 = py.test.ensuretemp('hello') @@ -263,7 +263,7 @@ class TestConfig_gettopdir: assert gettopdir([c, Z]) == tmp class TestConfigPickling: - @py.test.keywords(xfail=True, issue="config's pytestplugins/bus initialization") + @py.test.mark(xfail=True, issue="config's pytestplugins/bus initialization") def test_config_initafterpickle_plugin(self, testdir): testdir.makepyfile(__init__="", conftest="x=1; y=2") hello = testdir.makepyfile(hello="") diff --git a/py/test/testing/test_outcome.py b/py/test/testing/test_outcome.py index ea6ad6854..71800d5c8 100644 --- a/py/test/testing/test_outcome.py +++ b/py/test/testing/test_outcome.py @@ -81,3 +81,22 @@ def test_importorskip(): print py.code.ExceptionInfo() py.test.fail("spurious skip") + +def test_pytest_mark(): + from py.__.test.outcome import mark + def f(): pass + mark(x=3)(f) + assert f.x == 3 + def g(): pass + mark(g) + assert not g.func_dict + + mark.hello(f) + assert f.hello == True + + mark.hello("test")(f) + assert f.hello == "test" + + mark("x1")(f) + assert f.mark == "x1" + diff --git a/py/test/testing/test_pytestplugin.py b/py/test/testing/test_pytestplugin.py index 2bd3ab7fe..c3f41c6ca 100644 --- a/py/test/testing/test_pytestplugin.py +++ b/py/test/testing/test_pytestplugin.py @@ -248,7 +248,7 @@ class TestPytestPluginInteractions: assert not plugins.listattr("hello") assert plugins.listattr("x") == [42] - @py.test.keywords(xfail="implement setupcall") + @py.test.mark(xfail="implement setupcall") def test_call_setup_participants(self, testdir): testdir.makepyfile( conftest=""" diff --git a/py/test/testing/test_runner_functional.py b/py/test/testing/test_runner_functional.py index 5b1116954..44370cb20 100644 --- a/py/test/testing/test_runner_functional.py +++ b/py/test/testing/test_runner_functional.py @@ -7,7 +7,7 @@ class BaseTests: def test_funcattr(self, testdir): ev = testdir.runitem(""" import py - @py.test.keywords(xfail="needs refactoring") + @py.test.mark(xfail="needs refactoring") def test_func(): raise Exit() """)