[pypy-commit] pypy py3k: add the possibility to write applevel tests inside the docstring (only if the body of the method is empty. This way we can write tests using py3k only syntax and still run them on top of cpython 2

antocuni noreply at buildbot.pypy.org
Wed Jan 25 17:12:16 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: py3k
Changeset: r51759:def902951d4f
Date: 2012-01-25 16:02 +0100
http://bitbucket.org/pypy/pypy/changeset/def902951d4f/

Log:	add the possibility to write applevel tests inside the docstring
	(only if the body of the method is empty. This way we can write
	tests using py3k only syntax and still run them on top of cpython 2

diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -473,10 +473,24 @@
             return target()
         space = target.im_self.space
         filename = self._getdynfilename(target)
-        func = app2interp_temp(target.im_func, filename=filename)
+        src = extract_docstring_if_empty_function(target.im_func)
+        func = app2interp_temp(src, filename=filename)
         w_instance = self.parent.w_instance
         self.execute_appex(space, func, space, w_instance)
 
+def extract_docstring_if_empty_function(fn):
+    def empty_func():
+        ""
+        pass
+    co_code = fn.func_code.co_code
+    if co_code == empty_func.func_code.co_code and fn.__doc__ is not None:
+        head = '%s(self):' % fn.func_name
+        body = py.code.Source(fn.__doc__)
+        return head + str(body.indent())
+    else:
+        return fn
+
+
 class PyPyClassCollector(py.test.collect.Class):
     def setup(self):
         cls = self.obj
diff --git a/pypy/tool/pytest/test/conftest1_innertest.py b/pypy/tool/pytest/test/conftest1_innertest.py
--- a/pypy/tool/pytest/test/conftest1_innertest.py
+++ b/pypy/tool/pytest/test/conftest1_innertest.py
@@ -7,7 +7,20 @@
 
 class AppTestSomething: 
     def test_method_app(self): 
-        assert 23 == 23 
+        assert 23 == 23
+
+    def test_code_in_docstring_failing(self):
+        """
+        assert False # failing test
+        """
+
+    def test_code_in_docstring_ignored(self):
+        """
+        this docstring is not parsed as code because the function body is not
+        empty
+        """
+        assert True
+
     
 class TestSomething:
     def test_method(self): 
diff --git a/pypy/tool/pytest/test/test_conftest1.py b/pypy/tool/pytest/test/test_conftest1.py
--- a/pypy/tool/pytest/test/test_conftest1.py
+++ b/pypy/tool/pytest/test/test_conftest1.py
@@ -17,15 +17,18 @@
     def test_selection_by_keyword_app(self, testdir): 
         sorter = testdir.inline_run("-k", "applevel", innertest)
         passed, skipped, failed = sorter.listoutcomes()
-        assert len(passed) == 2
-        assert not skipped and not failed 
+        assert len(passed) == 3
+        assert len(failed) == 1
+        assert skipped == []
         assert "app_test_something" in passed[0].nodeid
         assert "test_method_app" in passed[1].nodeid
-
+        assert "test_code_in_docstring_ignored" in passed[2].nodeid
+        assert "test_code_in_docstring_failing" in failed[0].nodeid
+        
     def test_runappdirect(self, testdir):
         sorter = testdir.inline_run(innertest, '-k', 'applevel', '--runappdirect')
         passed, skipped, failed = sorter.listoutcomes()
-        assert len(passed) == 2
+        assert len(passed) == 3
         print passed
         assert "app_test_something" in passed[0].nodeid
         assert "test_method_app" in passed[1].nodeid
@@ -34,8 +37,16 @@
         sorter = testdir.inline_run(innertest, '-k', 'applevel',
                                     '--appdirect=%s' % (sys.executable,))
         passed, skipped, failed = sorter.listoutcomes()
-        assert len(passed) == 2
+        assert len(passed) == 3
         print passed
         assert "app_test_something" in passed[0].nodeid
         assert "test_method_app" in passed[1].nodeid
         
+    def test_docstrings(self, testdir): 
+        sorter = testdir.inline_run("-k", "test_code_in_docstring", innertest)
+        passed, skipped, failed = sorter.listoutcomes()
+        assert len(passed) == 1
+        assert len(failed) == 1
+        assert skipped == []
+        assert "test_code_in_docstring_ignored" in passed[0].nodeid
+        assert "test_code_in_docstring_failing" in failed[0].nodeid


More information about the pypy-commit mailing list