[svn r57754] * introduce py.test.collect.File (File for py or non-py files)
* introduce py.test.collect.Collector.collect_by_name and special case it for Directories to allow specifying files that would otherwise be ignored because of filters. * fix py/doc/conftest to work with new API * refactor py/doc/test_conftest.py to use suptest helper * avoid old APIs in some more places. --HG-- branch : trunk
This commit is contained in:
parent
494ea31042
commit
561a14054c
|
@ -26,8 +26,8 @@ version = "1.0.0a1"
|
||||||
|
|
||||||
initpkg(__name__,
|
initpkg(__name__,
|
||||||
description = "pylib and py.test: agile development and test support library",
|
description = "pylib and py.test: agile development and test support library",
|
||||||
revision = int('$LastChangedRevision: 57551 $'.split(':')[1][:-1]),
|
revision = int('$LastChangedRevision: 57754 $'.split(':')[1][:-1]),
|
||||||
lastchangedate = '$LastChangedDate: 2008-08-21 15:25:29 +0200 (Thu, 21 Aug 2008) $',
|
lastchangedate = '$LastChangedDate: 2008-09-02 14:24:15 +0200 (Tue, 02 Sep 2008) $',
|
||||||
version = version,
|
version = version,
|
||||||
url = "http://pylib.org",
|
url = "http://pylib.org",
|
||||||
download_url = "http://codespeak.net/py/0.9.2/download.html",
|
download_url = "http://codespeak.net/py/0.9.2/download.html",
|
||||||
|
@ -78,12 +78,13 @@ initpkg(__name__,
|
||||||
# for customization of collecting/running tests
|
# for customization of collecting/running tests
|
||||||
'test.collect.Collector' : ('./test/collect.py', 'Collector'),
|
'test.collect.Collector' : ('./test/collect.py', 'Collector'),
|
||||||
'test.collect.Directory' : ('./test/collect.py', 'Directory'),
|
'test.collect.Directory' : ('./test/collect.py', 'Directory'),
|
||||||
|
'test.collect.File' : ('./test/collect.py', 'File'),
|
||||||
|
'test.collect.Item' : ('./test/collect.py', 'Item'),
|
||||||
'test.collect.Module' : ('./test/pycollect.py', 'Module'),
|
'test.collect.Module' : ('./test/pycollect.py', 'Module'),
|
||||||
'test.collect.DoctestFile' : ('./test/pycollect.py', 'DoctestFile'),
|
'test.collect.DoctestFile' : ('./test/pycollect.py', 'DoctestFile'),
|
||||||
'test.collect.Class' : ('./test/pycollect.py', 'Class'),
|
'test.collect.Class' : ('./test/pycollect.py', 'Class'),
|
||||||
'test.collect.Instance' : ('./test/pycollect.py', 'Instance'),
|
'test.collect.Instance' : ('./test/pycollect.py', 'Instance'),
|
||||||
'test.collect.Generator' : ('./test/pycollect.py', 'Generator'),
|
'test.collect.Generator' : ('./test/pycollect.py', 'Generator'),
|
||||||
'test.collect.Item' : ('./test/collect.py', 'Item'),
|
|
||||||
'test.collect.Function' : ('./test/pycollect.py', 'Function'),
|
'test.collect.Function' : ('./test/pycollect.py', 'Function'),
|
||||||
|
|
||||||
# thread related API (still in early design phase)
|
# thread related API (still in early design phase)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import py
|
import py
|
||||||
|
|
||||||
class Directory(py.test.collect.Directory):
|
class Directory(py.test.collect.Directory):
|
||||||
def listdir(self):
|
def collect(self):
|
||||||
py.test.skip("compat tests currently need to be run manually")
|
py.test.skip("compat tests need to be run manually")
|
||||||
|
|
|
@ -43,15 +43,13 @@ py.apigen
|
||||||
|
|
||||||
- make it work again
|
- make it work again
|
||||||
|
|
||||||
- py.apigen tool -> separate runtime-data collection and
|
see apigen_refactorings.txt
|
||||||
web page generation. (see M750), provide "py.apigen" tool
|
|
||||||
|
|
||||||
- refactor html renderer to work on intermediate
|
|
||||||
data/files rather than on the live data
|
|
||||||
|
|
||||||
- check out CodeInvestigator
|
- check out CodeInvestigator
|
||||||
http://codeinvestigator.googlepages.com/main
|
http://codeinvestigator.googlepages.com/main
|
||||||
|
|
||||||
|
or other code that collects data from running a program
|
||||||
|
(in our case running the tests)
|
||||||
|
|
||||||
ld (review and shift to above)
|
ld (review and shift to above)
|
||||||
=================================
|
=================================
|
||||||
|
|
|
@ -110,12 +110,12 @@ def _checkskip(lpath, htmlpath=None):
|
||||||
#return [] # no need to rebuild
|
#return [] # no need to rebuild
|
||||||
|
|
||||||
class ReSTSyntaxTest(py.test.collect.Item):
|
class ReSTSyntaxTest(py.test.collect.Item):
|
||||||
def execute(self):
|
def runtest(self):
|
||||||
mypath = self.fspath
|
mypath = self.fspath
|
||||||
restcheck(py.path.svnwc(mypath))
|
restcheck(py.path.svnwc(mypath))
|
||||||
|
|
||||||
class DoctestText(py.test.collect.Item):
|
class DoctestText(py.test.collect.Item):
|
||||||
def execute(self):
|
def runtest(self):
|
||||||
s = self._normalize_linesep()
|
s = self._normalize_linesep()
|
||||||
l = []
|
l = []
|
||||||
prefix = '.. >>> '
|
prefix = '.. >>> '
|
||||||
|
@ -158,20 +158,15 @@ class DoctestText(py.test.collect.Item):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
class LinkCheckerMaker(py.test.collect.Collector):
|
class LinkCheckerMaker(py.test.collect.Collector):
|
||||||
def listdir(self):
|
def collect(self):
|
||||||
l = []
|
l = []
|
||||||
for call, tryfn, path, lineno in genlinkchecks(self.fspath):
|
for call, tryfn, path, lineno in genlinkchecks(self.fspath):
|
||||||
l.append("%s:%d" %(tryfn, lineno))
|
name = "%s:%d" %(tryfn, lineno)
|
||||||
|
l.append(
|
||||||
|
CheckLink(name, parent=self, args=(tryfn, path, lineno), callobj=call)
|
||||||
|
)
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def join(self, name):
|
|
||||||
i = name.rfind(':')
|
|
||||||
assert i != -1
|
|
||||||
jname, jlineno = name[:i], int(name[i+1:])
|
|
||||||
for call, tryfn, path, lineno in genlinkchecks(self.fspath):
|
|
||||||
if tryfn == jname and lineno == jlineno:
|
|
||||||
return CheckLink(name, parent=self, args=(tryfn, path, lineno), callobj=call)
|
|
||||||
|
|
||||||
class CheckLink(py.test.collect.Function):
|
class CheckLink(py.test.collect.Function):
|
||||||
def repr_metainfo(self):
|
def repr_metainfo(self):
|
||||||
return self.ReprMetaInfo(fspath=self.fspath, lineno=self._args[2],
|
return self.ReprMetaInfo(fspath=self.fspath, lineno=self._args[2],
|
||||||
|
@ -181,26 +176,17 @@ class CheckLink(py.test.collect.Function):
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class ReSTChecker(py.test.collect.Module):
|
class DocfileTests(py.test.collect.File):
|
||||||
DoctestText = DoctestText
|
DoctestText = DoctestText
|
||||||
ReSTSyntaxTest = ReSTSyntaxTest
|
ReSTSyntaxTest = ReSTSyntaxTest
|
||||||
|
LinkCheckerMaker = LinkCheckerMaker
|
||||||
|
|
||||||
def __repr__(self):
|
def collect(self):
|
||||||
return py.test.collect.Collector.__repr__(self)
|
return [
|
||||||
|
self.ReSTSyntaxTest(self.fspath.basename, parent=self),
|
||||||
def setup(self):
|
self.LinkCheckerMaker("checklinks", self),
|
||||||
pass
|
self.DoctestText("doctest", self),
|
||||||
def teardown(self):
|
]
|
||||||
pass
|
|
||||||
def listdir(self):
|
|
||||||
return [self.fspath.basename, 'checklinks', 'doctest']
|
|
||||||
def join(self, name):
|
|
||||||
if name == self.fspath.basename:
|
|
||||||
return self.ReSTSyntaxTest(name, parent=self)
|
|
||||||
elif name == 'checklinks':
|
|
||||||
return LinkCheckerMaker(name, self)
|
|
||||||
elif name == 'doctest':
|
|
||||||
return self.DoctestText(name, self)
|
|
||||||
|
|
||||||
# generating functions + args as single tests
|
# generating functions + args as single tests
|
||||||
def genlinkchecks(path):
|
def genlinkchecks(path):
|
||||||
|
@ -286,20 +272,13 @@ def localrefcheck(tryfn, path, lineno):
|
||||||
# hooking into py.test Directory collector's chain ...
|
# hooking into py.test Directory collector's chain ...
|
||||||
|
|
||||||
class DocDirectory(py.test.collect.Directory):
|
class DocDirectory(py.test.collect.Directory):
|
||||||
ReSTChecker = ReSTChecker
|
DocfileTests = DocfileTests
|
||||||
|
def collect(self):
|
||||||
def listdir(self):
|
results = super(DocDirectory, self).collect()
|
||||||
results = super(DocDirectory, self).listdir()
|
|
||||||
for x in self.fspath.listdir('*.txt', sort=True):
|
for x in self.fspath.listdir('*.txt', sort=True):
|
||||||
results.append(x.basename)
|
results.append(self.DocfileTests(x, parent=self))
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def join(self, name):
|
|
||||||
if not name.endswith('.txt'):
|
|
||||||
return super(DocDirectory, self).join(name)
|
|
||||||
p = self.fspath.join(name)
|
|
||||||
if p.check(file=1):
|
|
||||||
return self.ReSTChecker(p, parent=self)
|
|
||||||
Directory = DocDirectory
|
Directory = DocDirectory
|
||||||
|
|
||||||
def resolve_linkrole(name, text, check=True):
|
def resolve_linkrole(name, text, check=True):
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
|
|
||||||
import py
|
import py
|
||||||
failure_demo = py.magic.autopath().dirpath('failure_demo.py')
|
failure_demo = py.magic.autopath().dirpath('failure_demo.py')
|
||||||
from py.__.doc.test_conftest import countoutcomes
|
|
||||||
|
from py.__.test.testing import suptest
|
||||||
|
from py.__.test import event
|
||||||
|
|
||||||
def test_failure_demo_fails_properly():
|
def test_failure_demo_fails_properly():
|
||||||
config = py.test.config._reparse([failure_demo])
|
sorter = suptest.events_from_cmdline([failure_demo])
|
||||||
session = config.initsession()
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
failed, passed, skipped = countoutcomes(session)
|
|
||||||
assert failed == 21
|
|
||||||
assert passed == 0
|
assert passed == 0
|
||||||
|
assert failed == 20, failed
|
||||||
|
colreports = sorter.get(event.CollectionReport)
|
||||||
|
failed = len([x.failed for x in colreports])
|
||||||
|
assert failed == 5
|
||||||
|
|
|
@ -1,74 +1,80 @@
|
||||||
|
|
||||||
import py
|
import py
|
||||||
from py.__.test import event
|
from py.__.test import event
|
||||||
|
from py.__.test.testing import suptest
|
||||||
|
from py.__.doc import conftest as doc_conftest
|
||||||
|
|
||||||
def setup_module(mod):
|
|
||||||
mod.tmpdir = py.test.ensuretemp('docdoctest')
|
|
||||||
|
|
||||||
def countoutcomes(session):
|
class TestDoctest(suptest.InlineCollection):
|
||||||
l = []
|
def setup_method(self, method):
|
||||||
session.bus.subscribe(l.append)
|
super(TestDoctest, self).setup_method(method)
|
||||||
session.main()
|
p = py.path.local(doc_conftest.__file__)
|
||||||
session.bus.unsubscribe(l.append)
|
if p.ext == ".pyc":
|
||||||
passed = failed = skipped = 0
|
p = p.new(ext=".py")
|
||||||
for ev in l:
|
p.copy(self.tmpdir.join("conftest.py"))
|
||||||
if isinstance(ev, event.ItemTestReport):
|
|
||||||
if ev.passed:
|
def test_doctest_extra_exec(self):
|
||||||
passed += 1
|
xtxt = self.maketxtfile(x="""
|
||||||
elif ev.skipped:
|
hello::
|
||||||
skipped += 1
|
.. >>> raise ValueError
|
||||||
else:
|
>>> None
|
||||||
failed += 1
|
""")
|
||||||
elif isinstance(ev, event.CollectionReport):
|
sorter = suptest.events_from_cmdline([xtxt])
|
||||||
if ev.failed:
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
failed += 1
|
assert failed == 1
|
||||||
return failed, passed, skipped
|
|
||||||
|
|
||||||
def test_doctest_extra_exec():
|
def test_doctest_basic(self):
|
||||||
# XXX get rid of the next line:
|
xtxt = self.maketxtfile(x="""
|
||||||
py.magic.autopath().dirpath('conftest.py').copy(tmpdir.join('conftest.py'))
|
..
|
||||||
xtxt = tmpdir.join('y.txt')
|
>>> from os.path import abspath
|
||||||
xtxt.write(py.code.Source("""
|
|
||||||
hello::
|
|
||||||
.. >>> raise ValueError
|
|
||||||
>>> None
|
|
||||||
"""))
|
|
||||||
config = py.test.config._reparse([xtxt])
|
|
||||||
session = config.initsession()
|
|
||||||
failed, passed, skipped = countoutcomes(session)
|
|
||||||
assert failed == 1
|
|
||||||
|
|
||||||
def test_doctest_basic():
|
hello world
|
||||||
# XXX get rid of the next line:
|
|
||||||
py.magic.autopath().dirpath('conftest.py').copy(tmpdir.join('conftest.py'))
|
|
||||||
|
|
||||||
xtxt = tmpdir.join('x.txt')
|
>>> assert abspath
|
||||||
xtxt.write(py.code.Source("""
|
>>> i=3
|
||||||
..
|
>>> print i
|
||||||
>>> from os.path import abspath
|
3
|
||||||
|
|
||||||
hello world
|
yes yes
|
||||||
|
|
||||||
>>> assert abspath
|
>>> i
|
||||||
>>> i=3
|
3
|
||||||
>>> print i
|
|
||||||
3
|
|
||||||
|
|
||||||
yes yes
|
end
|
||||||
|
""")
|
||||||
|
sorter = suptest.events_from_cmdline([xtxt])
|
||||||
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
|
assert failed == 0
|
||||||
|
assert passed + skipped == 2
|
||||||
|
|
||||||
>>> i
|
def test_doctest_eol(self):
|
||||||
3
|
ytxt = self.maketxtfile(y=".. >>> 1 + 1\r\n 2\r\n\r\n")
|
||||||
|
sorter = suptest.events_from_cmdline([ytxt])
|
||||||
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
|
assert failed == 0
|
||||||
|
assert passed + skipped == 2
|
||||||
|
|
||||||
end
|
def test_doctest_indentation(self):
|
||||||
"""))
|
footxt = self.maketxtfile(foo=
|
||||||
config = py.test.config._reparse([xtxt])
|
'..\n >>> print "foo\\n bar"\n foo\n bar\n')
|
||||||
session = config.initsession()
|
sorter = suptest.events_from_cmdline([footxt])
|
||||||
failed, passed, skipped = countoutcomes(session)
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
assert failed == 0
|
assert failed == 0
|
||||||
assert passed + skipped == 2
|
assert skipped + passed == 2
|
||||||
|
|
||||||
|
def test_js_ignore(self):
|
||||||
|
xtxt = self.maketxtfile(xtxt="""
|
||||||
|
`blah`_
|
||||||
|
|
||||||
|
.. _`blah`: javascript:some_function()
|
||||||
|
""")
|
||||||
|
sorter = suptest.events_from_cmdline([xtxt])
|
||||||
|
passed, skipped, failed = sorter.countoutcomes()
|
||||||
|
assert failed == 0
|
||||||
|
assert skipped + passed == 3
|
||||||
|
|
||||||
def test_deindent():
|
def test_deindent():
|
||||||
from py.__.doc.conftest import deindent
|
deindent = doc_conftest.deindent
|
||||||
assert deindent('foo') == 'foo'
|
assert deindent('foo') == 'foo'
|
||||||
assert deindent('foo\n bar') == 'foo\n bar'
|
assert deindent('foo\n bar') == 'foo\n bar'
|
||||||
assert deindent(' foo\n bar\n') == 'foo\nbar\n'
|
assert deindent(' foo\n bar\n') == 'foo\nbar\n'
|
||||||
|
@ -76,45 +82,6 @@ def test_deindent():
|
||||||
assert deindent(' foo\n bar\n') == 'foo\n bar\n'
|
assert deindent(' foo\n bar\n') == 'foo\n bar\n'
|
||||||
assert deindent(' foo\n bar\n') == ' foo\nbar\n'
|
assert deindent(' foo\n bar\n') == ' foo\nbar\n'
|
||||||
|
|
||||||
def test_doctest_eol():
|
|
||||||
# XXX get rid of the next line:
|
|
||||||
py.magic.autopath().dirpath('conftest.py').copy(tmpdir.join('conftest.py'))
|
|
||||||
|
|
||||||
ytxt = tmpdir.join('y.txt')
|
|
||||||
ytxt.write(py.code.Source(".. >>> 1 + 1\r\n 2\r\n\r\n"))
|
|
||||||
config = py.test.config._reparse([ytxt])
|
|
||||||
session = config.initsession()
|
|
||||||
failed, passed, skipped = countoutcomes(session)
|
|
||||||
assert failed == 0
|
|
||||||
assert passed + skipped == 2
|
|
||||||
|
|
||||||
def test_doctest_indentation():
|
|
||||||
# XXX get rid of the next line:
|
|
||||||
py.magic.autopath().dirpath('conftest.py').copy(tmpdir.join('conftest.py'))
|
|
||||||
|
|
||||||
txt = tmpdir.join('foo.txt')
|
|
||||||
txt.write('..\n >>> print "foo\\n bar"\n foo\n bar\n')
|
|
||||||
config = py.test.config._reparse([txt])
|
|
||||||
session = config.initsession()
|
|
||||||
failed, passed, skipped = countoutcomes(session)
|
|
||||||
assert failed == 0
|
|
||||||
assert skipped + passed == 2
|
|
||||||
|
|
||||||
def test_js_ignore():
|
|
||||||
py.magic.autopath().dirpath('conftest.py').copy(tmpdir.join('conftest.py'))
|
|
||||||
tmpdir.ensure('__init__.py')
|
|
||||||
xtxt = tmpdir.join('x.txt')
|
|
||||||
xtxt.write(py.code.Source("""
|
|
||||||
`blah`_
|
|
||||||
|
|
||||||
.. _`blah`: javascript:some_function()
|
|
||||||
"""))
|
|
||||||
config = py.test.config._reparse([xtxt])
|
|
||||||
session = config.initsession()
|
|
||||||
|
|
||||||
failed, passed, skipped = countoutcomes(session)
|
|
||||||
assert failed == 0
|
|
||||||
assert skipped + passed == 3
|
|
||||||
|
|
||||||
def test_resolve_linkrole():
|
def test_resolve_linkrole():
|
||||||
from py.__.doc.conftest import get_apigen_relpath
|
from py.__.doc.conftest import get_apigen_relpath
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import py, os
|
import py, os
|
||||||
|
|
||||||
class Directory(py.test.collect.Directory):
|
class Directory(py.test.collect.Directory):
|
||||||
def listdir(self):
|
def collect(self):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
py.test.skip("Cannot test green layer on windows")
|
py.test.skip("Cannot test green layer on windows")
|
||||||
else:
|
else:
|
||||||
return super(Directory, self).listdir()
|
return super(Directory, self).run()
|
||||||
|
|
|
@ -189,7 +189,7 @@ class Node(object):
|
||||||
cur = self
|
cur = self
|
||||||
for name in namelist:
|
for name in namelist:
|
||||||
if name:
|
if name:
|
||||||
next = cur.join(name)
|
next = cur.collect_by_name(name)
|
||||||
if next is None:
|
if next is None:
|
||||||
existingnames = [x.name for x in self._memocollect()]
|
existingnames = [x.name for x in self._memocollect()]
|
||||||
msg = ("Collector %r does not have name %r "
|
msg = ("Collector %r does not have name %r "
|
||||||
|
@ -297,6 +297,12 @@ class Collector(Node):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError("abstract")
|
raise NotImplementedError("abstract")
|
||||||
|
|
||||||
|
def collect_by_name(self, name):
|
||||||
|
""" return a child matching the given name, else None. """
|
||||||
|
for colitem in self._memocollect():
|
||||||
|
if colitem.name == name:
|
||||||
|
return colitem
|
||||||
|
|
||||||
def repr_failure(self, excinfo, outerr):
|
def repr_failure(self, excinfo, outerr):
|
||||||
""" represent a failure. """
|
""" represent a failure. """
|
||||||
return self._repr_failure_py(excinfo, outerr)
|
return self._repr_failure_py(excinfo, outerr)
|
||||||
|
@ -336,12 +342,10 @@ class Collector(Node):
|
||||||
If the return value is None there is no such child.
|
If the return value is None there is no such child.
|
||||||
"""
|
"""
|
||||||
warnoldcollect()
|
warnoldcollect()
|
||||||
for colitem in self._memocollect():
|
return self.collect_by_name(name)
|
||||||
if colitem.name == name:
|
|
||||||
return colitem
|
|
||||||
|
|
||||||
def multijoin(self, namelist):
|
def multijoin(self, namelist):
|
||||||
""" DEPRECATED: return a list of colitems for the given namelist. """
|
""" DEPRECATED: return a list of child items matching the given namelist. """
|
||||||
warnoldcollect()
|
warnoldcollect()
|
||||||
return [self.join(name) for name in namelist]
|
return [self.join(name) for name in namelist]
|
||||||
|
|
||||||
|
@ -380,6 +384,8 @@ class FSCollector(Collector):
|
||||||
name, parent = picklestate
|
name, parent = picklestate
|
||||||
self.__init__(parent.fspath.join(name), parent=parent)
|
self.__init__(parent.fspath.join(name), parent=parent)
|
||||||
|
|
||||||
|
class File(FSCollector):
|
||||||
|
""" base class for collecting tests from a file. """
|
||||||
|
|
||||||
class Directory(FSCollector):
|
class Directory(FSCollector):
|
||||||
def recfilter(self, path):
|
def recfilter(self, path):
|
||||||
|
@ -398,7 +404,6 @@ class Directory(FSCollector):
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def consider(self, path, usefilters=True):
|
def consider(self, path, usefilters=True):
|
||||||
print "checking", path
|
|
||||||
if path.check(file=1):
|
if path.check(file=1):
|
||||||
return self.consider_file(path, usefilters=usefilters)
|
return self.consider_file(path, usefilters=usefilters)
|
||||||
elif path.check(dir=1):
|
elif path.check(dir=1):
|
||||||
|
@ -421,14 +426,13 @@ class Directory(FSCollector):
|
||||||
Directory = self._config.getvalue('Directory', path)
|
Directory = self._config.getvalue('Directory', path)
|
||||||
return Directory(path, parent=self)
|
return Directory(path, parent=self)
|
||||||
|
|
||||||
# **********************************************************************
|
def collect_by_name(self, name):
|
||||||
# DEPRECATED METHODS
|
""" get a child with the given name. """
|
||||||
# **********************************************************************
|
res = super(Directory, self).collect_by_name(name)
|
||||||
|
if res is None:
|
||||||
def join(self, name):
|
p = self.fspath.join(name)
|
||||||
""" get a child collector or item without using filters. """
|
res = self.consider(p, usefilters=False)
|
||||||
p = self.fspath.join(name)
|
return res
|
||||||
return self.consider(p, usefilters=False)
|
|
||||||
|
|
||||||
from py.__.test.runner import basic_run_report, forked_run_report
|
from py.__.test.runner import basic_run_report, forked_run_report
|
||||||
class Item(Node):
|
class Item(Node):
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Python related collection nodes. Here is an example of
|
Python related collection nodes. Here is an example of
|
||||||
a tree of collectors and test items that this modules provides::
|
a tree of collectors and test items that this modules provides::
|
||||||
|
|
||||||
Module # FSCollector
|
Module # File
|
||||||
Class
|
Class
|
||||||
Instance
|
Instance
|
||||||
Function
|
Function
|
||||||
|
@ -12,13 +12,12 @@ a tree of collectors and test items that this modules provides::
|
||||||
Generator
|
Generator
|
||||||
Function
|
Function
|
||||||
|
|
||||||
DoctestFile # FSCollector
|
DoctestFile # File
|
||||||
DoctestFileContent # acts as Item
|
DoctestFileContent # acts as Item
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import py
|
import py
|
||||||
from py.__.test.collect import Collector, FSCollector, Item, configproperty
|
from py.__.test.collect import configproperty, warnoldcollect
|
||||||
from py.__.test.collect import warnoldcollect
|
|
||||||
|
|
||||||
class PyobjMixin(object):
|
class PyobjMixin(object):
|
||||||
def obj():
|
def obj():
|
||||||
|
@ -86,7 +85,7 @@ class PyobjMixin(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PyCollectorMixin(PyobjMixin, Collector):
|
class PyCollectorMixin(PyobjMixin, py.test.collect.Collector):
|
||||||
Class = configproperty('Class')
|
Class = configproperty('Class')
|
||||||
Instance = configproperty('Instance')
|
Instance = configproperty('Instance')
|
||||||
Function = configproperty('Function')
|
Function = configproperty('Function')
|
||||||
|
@ -144,9 +143,7 @@ class PyCollectorMixin(PyobjMixin, Collector):
|
||||||
else:
|
else:
|
||||||
return self.Function(name, parent=self)
|
return self.Function(name, parent=self)
|
||||||
|
|
||||||
class Module(FSCollector, PyCollectorMixin):
|
class Module(py.test.collect.File, PyCollectorMixin):
|
||||||
_stickyfailure = None
|
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
if getattr(self.obj, 'disabled', 0):
|
if getattr(self.obj, 'disabled', 0):
|
||||||
return []
|
return []
|
||||||
|
@ -169,7 +166,7 @@ class Module(FSCollector, PyCollectorMixin):
|
||||||
#print "*" * 20, "revoke assertion", self
|
#print "*" * 20, "revoke assertion", self
|
||||||
py.magic.revoke(assertion=1)
|
py.magic.revoke(assertion=1)
|
||||||
|
|
||||||
class Class(PyCollectorMixin, Collector):
|
class Class(PyCollectorMixin, py.test.collect.Collector):
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
if getattr(self.obj, 'disabled', 0):
|
if getattr(self.obj, 'disabled', 0):
|
||||||
|
@ -194,7 +191,7 @@ class Class(PyCollectorMixin, Collector):
|
||||||
def _getsortvalue(self):
|
def _getsortvalue(self):
|
||||||
return self.getfslineno()
|
return self.getfslineno()
|
||||||
|
|
||||||
class Instance(PyCollectorMixin, Collector):
|
class Instance(PyCollectorMixin, py.test.collect.Collector):
|
||||||
def _getobj(self):
|
def _getobj(self):
|
||||||
return self.parent.obj()
|
return self.parent.obj()
|
||||||
def Function(self):
|
def Function(self):
|
||||||
|
@ -259,7 +256,7 @@ class FunctionMixin(PyobjMixin):
|
||||||
|
|
||||||
shortfailurerepr = "F"
|
shortfailurerepr = "F"
|
||||||
|
|
||||||
class Generator(FunctionMixin, PyCollectorMixin, Collector):
|
class Generator(FunctionMixin, PyCollectorMixin, py.test.collect.Collector):
|
||||||
def collect(self):
|
def collect(self):
|
||||||
# test generators are collectors yet participate in
|
# test generators are collectors yet participate in
|
||||||
# the test-item setup and teardown protocol.
|
# the test-item setup and teardown protocol.
|
||||||
|
@ -285,7 +282,7 @@ class Generator(FunctionMixin, PyCollectorMixin, Collector):
|
||||||
# Test Items
|
# Test Items
|
||||||
#
|
#
|
||||||
_dummy = object()
|
_dummy = object()
|
||||||
class Function(FunctionMixin, Item):
|
class Function(FunctionMixin, py.test.collect.Item):
|
||||||
""" a Function Item is responsible for setting up
|
""" a Function Item is responsible for setting up
|
||||||
and executing a Python callable test object.
|
and executing a Python callable test object.
|
||||||
"""
|
"""
|
||||||
|
@ -312,7 +309,7 @@ class Function(FunctionMixin, Item):
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return not self == other
|
return not self == other
|
||||||
|
|
||||||
class DoctestFile(FSCollector):
|
class DoctestFile(py.test.collect.File):
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
return [DoctestFileContent(self.fspath.basename, parent=self)]
|
return [DoctestFileContent(self.fspath.basename, parent=self)]
|
||||||
|
@ -328,7 +325,7 @@ class ReprFailDoctest(Repr):
|
||||||
tw.line(line)
|
tw.line(line)
|
||||||
self.reprlocation.toterminal(tw)
|
self.reprlocation.toterminal(tw)
|
||||||
|
|
||||||
class DoctestFileContent(Item):
|
class DoctestFileContent(py.test.collect.Item):
|
||||||
def repr_failure(self, excinfo, outerr):
|
def repr_failure(self, excinfo, outerr):
|
||||||
if excinfo.errisinstance(py.compat.doctest.DocTestFailure):
|
if excinfo.errisinstance(py.compat.doctest.DocTestFailure):
|
||||||
doctestfailure = excinfo.value
|
doctestfailure = excinfo.value
|
||||||
|
|
|
@ -59,11 +59,31 @@ class TestCollect(suptest.InlineCollection):
|
||||||
def test_listnames_and__getitembynames(self):
|
def test_listnames_and__getitembynames(self):
|
||||||
modcol = self.getmodulecol("pass")
|
modcol = self.getmodulecol("pass")
|
||||||
names = modcol.listnames()
|
names = modcol.listnames()
|
||||||
dircol = py.test.collect.Directory(modcol._config.topdir, config=modcol._config)
|
dircol = modcol._config.getfsnode(modcol._config.topdir)
|
||||||
x = dircol._getitembynames(names)
|
x = dircol._getitembynames(names)
|
||||||
assert modcol.name == x.name
|
assert modcol.name == x.name
|
||||||
assert modcol.name == x.name
|
assert modcol.name == x.name
|
||||||
|
|
||||||
|
def test_listnames_getitembynames_custom(self):
|
||||||
|
hello = self._makefile(".xxx", hello="world")
|
||||||
|
self.makepyfile(conftest="""
|
||||||
|
import py
|
||||||
|
class CustomFile(py.test.collect.File):
|
||||||
|
pass
|
||||||
|
class MyDirectory(py.test.collect.Directory):
|
||||||
|
def collect(self):
|
||||||
|
return [CustomFile(self.fspath.join("hello.xxx"), parent=self)]
|
||||||
|
Directory = MyDirectory
|
||||||
|
""")
|
||||||
|
config = self.parseconfig(hello)
|
||||||
|
node = config.getfsnode(hello)
|
||||||
|
assert isinstance(node, py.test.collect.File)
|
||||||
|
assert node.name == "hello.xxx"
|
||||||
|
names = node.listnames()[1:]
|
||||||
|
dircol = config.getfsnode(config.topdir)
|
||||||
|
node = dircol._getitembynames(names)
|
||||||
|
assert isinstance(node, py.test.collect.File)
|
||||||
|
|
||||||
def test_found_certain_testfiles(self):
|
def test_found_certain_testfiles(self):
|
||||||
p1 = self.makepyfile(test_found = "pass", found_test="pass")
|
p1 = self.makepyfile(test_found = "pass", found_test="pass")
|
||||||
col = py.test.collect.Directory(p1.dirpath(), config=dummyconfig)
|
col = py.test.collect.Directory(p1.dirpath(), config=dummyconfig)
|
||||||
|
@ -156,9 +176,9 @@ class TestCollect(suptest.InlineCollection):
|
||||||
def test_pass(): pass
|
def test_pass(): pass
|
||||||
def test_fail(): assert 0
|
def test_fail(): assert 0
|
||||||
""")
|
""")
|
||||||
fn1 = modcol.join("test_pass")
|
fn1 = modcol.collect_by_name("test_pass")
|
||||||
assert isinstance(fn1, py.test.collect.Function)
|
assert isinstance(fn1, py.test.collect.Function)
|
||||||
fn2 = modcol.join("test_pass")
|
fn2 = modcol.collect_by_name("test_pass")
|
||||||
assert isinstance(fn2, py.test.collect.Function)
|
assert isinstance(fn2, py.test.collect.Function)
|
||||||
|
|
||||||
assert fn1 == fn2
|
assert fn1 == fn2
|
||||||
|
@ -166,7 +186,7 @@ class TestCollect(suptest.InlineCollection):
|
||||||
assert cmp(fn1, fn2) == 0
|
assert cmp(fn1, fn2) == 0
|
||||||
assert hash(fn1) == hash(fn2)
|
assert hash(fn1) == hash(fn2)
|
||||||
|
|
||||||
fn3 = modcol.join("test_fail")
|
fn3 = modcol.collect_by_name("test_fail")
|
||||||
assert isinstance(fn3, py.test.collect.Function)
|
assert isinstance(fn3, py.test.collect.Function)
|
||||||
assert not (fn1 == fn3)
|
assert not (fn1 == fn3)
|
||||||
assert fn1 != fn3
|
assert fn1 != fn3
|
||||||
|
@ -274,7 +294,6 @@ class TestCustomConftests(suptest.InlineCollection):
|
||||||
assert item.name == "hello.xxx"
|
assert item.name == "hello.xxx"
|
||||||
assert item.__class__.__name__ == "CustomItem"
|
assert item.__class__.__name__ == "CustomItem"
|
||||||
|
|
||||||
|
|
||||||
def test_module_file_not_found():
|
def test_module_file_not_found():
|
||||||
fn = tmpdir.join('nada','no')
|
fn = tmpdir.join('nada','no')
|
||||||
col = py.test.collect.Module(fn, config=dummyconfig)
|
col = py.test.collect.Module(fn, config=dummyconfig)
|
||||||
|
@ -513,7 +532,7 @@ class TestCollectorReprs(suptest.InlineCollection):
|
||||||
class TestClass:
|
class TestClass:
|
||||||
def test_hello(self): pass
|
def test_hello(self): pass
|
||||||
""")
|
""")
|
||||||
classcol = modcol.join("TestClass")
|
classcol = modcol.collect_by_name("TestClass")
|
||||||
info = classcol.repr_metainfo()
|
info = classcol.repr_metainfo()
|
||||||
assert info.fspath == modcol.fspath
|
assert info.fspath == modcol.fspath
|
||||||
assert info.lineno == 1
|
assert info.lineno == 1
|
||||||
|
@ -527,7 +546,7 @@ class TestCollectorReprs(suptest.InlineCollection):
|
||||||
assert x
|
assert x
|
||||||
yield check, 3
|
yield check, 3
|
||||||
""")
|
""")
|
||||||
gencol = modcol.join("test_gen")
|
gencol = modcol.collect_by_name("test_gen")
|
||||||
info = gencol.repr_metainfo()
|
info = gencol.repr_metainfo()
|
||||||
assert info.fspath == modcol.fspath
|
assert info.fspath == modcol.fspath
|
||||||
assert info.lineno == 1
|
assert info.lineno == 1
|
||||||
|
@ -595,7 +614,7 @@ class TestPickling(suptest.InlineCollection):
|
||||||
def test_pickle_func(self):
|
def test_pickle_func(self):
|
||||||
modcol1 = self.getmodulecol("def test_one(): pass")
|
modcol1 = self.getmodulecol("def test_one(): pass")
|
||||||
self.unifyconfig(modcol1._config)
|
self.unifyconfig(modcol1._config)
|
||||||
item = modcol1.join("test_one")
|
item = modcol1.collect_by_name("test_one")
|
||||||
item2a = self.p1_to_p2(item)
|
item2a = self.p1_to_p2(item)
|
||||||
assert item is not item2a # of course
|
assert item is not item2a # of course
|
||||||
assert item2a.name == item.name
|
assert item2a.name == item.name
|
||||||
|
|
Loading…
Reference in New Issue