fix a collection bug where a:🅱️:c could not be resolved properly if
there are multiple 'b' nodes. --HG-- branch : trunk
This commit is contained in:
parent
f779d3f863
commit
a60e470573
|
@ -4,6 +4,8 @@ tags: bug 1.4 core xdist
|
|||
|
||||
* reportinfo -> location in hooks and items
|
||||
* check oejskit plugin compatibility
|
||||
* terminal reporting - dot-printing
|
||||
* some simple profiling
|
||||
|
||||
refine session initialization / fix custom collect crash
|
||||
---------------------------------------------------------------
|
||||
|
|
|
@ -138,15 +138,14 @@ class Collection:
|
|||
|
||||
def getbyid(self, id):
|
||||
""" return one or more nodes matching the id. """
|
||||
matching = [self._topcollector]
|
||||
if not id:
|
||||
return matching
|
||||
names = id.split("::")
|
||||
names = filter(None, id.split("::"))
|
||||
if names and '/' in names[0]:
|
||||
names[:1] = names[0].split("/")
|
||||
return self._match([self._topcollector], names)
|
||||
|
||||
def _match(self, matching, names):
|
||||
while names:
|
||||
name = names.pop(0)
|
||||
newnames = name.split("/")
|
||||
name = newnames[0]
|
||||
names[:0] = newnames[1:]
|
||||
l = []
|
||||
for current in matching:
|
||||
for x in current._memocollect():
|
||||
|
@ -169,22 +168,28 @@ class Collection:
|
|||
return nodes
|
||||
|
||||
def perform_collect(self):
|
||||
idlist = [self._parsearg(arg) for arg in self.config.args]
|
||||
nodes = []
|
||||
for names in idlist:
|
||||
for arg in self.config.args:
|
||||
names = self._parsearg(arg)
|
||||
try:
|
||||
self.genitems([self._topcollector], names, nodes)
|
||||
except NoMatch:
|
||||
raise self.config.Error("can't collect: %s" % (arg,))
|
||||
return nodes
|
||||
|
||||
def genitems(self, matching, names, result):
|
||||
if not matching:
|
||||
assert not names
|
||||
return result
|
||||
names = list(names)
|
||||
name = names and names.pop(0) or None
|
||||
return
|
||||
if names:
|
||||
name = names[0]
|
||||
names = names[1:]
|
||||
else:
|
||||
name = None
|
||||
for node in matching:
|
||||
if isinstance(node, py.test.collect.Item):
|
||||
if name is None:
|
||||
self.config.hook.pytest_log_itemcollect(item=node)
|
||||
node.ihook.pytest_log_itemcollect(item=node)
|
||||
result.append(node)
|
||||
continue
|
||||
assert isinstance(node, py.test.collect.Collector)
|
||||
|
@ -192,27 +197,31 @@ class Collection:
|
|||
rep = node.ihook.pytest_make_collect_report(collector=node)
|
||||
#print "matching", rep.result, "against name", name
|
||||
if rep.passed:
|
||||
if name:
|
||||
matched = False
|
||||
for subcol in rep.result:
|
||||
if subcol.name != name and subcol.name == "()":
|
||||
names.insert(0, name)
|
||||
name = "()"
|
||||
# see doctests/custom naming XXX
|
||||
if subcol.name == name or subcol.fspath.basename == name:
|
||||
self.genitems([subcol], names, result)
|
||||
matched = True
|
||||
if not matched:
|
||||
raise self.config.Error(
|
||||
"can't collect: %s" % (name,))
|
||||
|
||||
else:
|
||||
if not name:
|
||||
self.genitems(rep.result, [], result)
|
||||
else:
|
||||
matched = False
|
||||
for x in rep.result:
|
||||
try:
|
||||
if x.name == name or x.fspath.basename == name:
|
||||
self.genitems([x], names, result)
|
||||
matched = True
|
||||
elif x.name == "()": # XXX special Instance() case
|
||||
self.genitems([x], [name] + names, result)
|
||||
matched = True
|
||||
except NoMatch:
|
||||
pass
|
||||
if not matched:
|
||||
node.ihook.pytest_collectreport(report=rep)
|
||||
raise NoMatch(name)
|
||||
node.ihook.pytest_collectreport(report=rep)
|
||||
x = getattr(self, 'shouldstop', None)
|
||||
if x:
|
||||
raise Session.Interrupted(x)
|
||||
|
||||
class NoMatch(Exception):
|
||||
""" raised if genitems cannot locate a matching names. """
|
||||
|
||||
def gettopdir(args):
|
||||
""" return the top directory for the given paths.
|
||||
if the common base dir resides in a python package
|
||||
|
|
|
@ -191,3 +191,23 @@ class TestGeneralUsage:
|
|||
for dirname, other_dirname in [('a', 'b'), ('b', 'a')]:
|
||||
result = testdir.runpytest(dirname)
|
||||
assert result.ret == 0, "test_sibling_conftest: py.test run for '%s', but '%s/conftest.py' loaded." % (dirname, other_dirname)
|
||||
|
||||
def test_multiple_items_per_collector_byid(self, testdir):
|
||||
c = testdir.makeconftest("""
|
||||
import py
|
||||
class MyItem(py.test.collect.Item):
|
||||
def runtest(self):
|
||||
pass
|
||||
class MyCollector(py.test.collect.File):
|
||||
def collect(self):
|
||||
return [MyItem(name="xyz", parent=self)]
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.basename.startswith("conftest"):
|
||||
return MyCollector(path, parent)
|
||||
""")
|
||||
result = testdir.runpytest(c.basename+"::"+"xyz")
|
||||
assert result.ret == 0
|
||||
result.stdout.fnmatch_lines([
|
||||
"*1 pass*",
|
||||
])
|
||||
|
||||
|
|
Loading…
Reference in New Issue