forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiscovery.py
More file actions
117 lines (98 loc) · 3.2 KB
/
discovery.py
File metadata and controls
117 lines (98 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
from __future__ import absolute_import, print_function
import re
from .util import fix_fileid, DIRNAME, NORMCASE
from .info import ParentInfo
FILE_ID_RE = re.compile(
r"""
^
(?:
( .* [.] (?: py | txt ) \b ) # .txt for doctest files
( [^.] .* )?
)
$
""",
re.VERBOSE,
)
def fix_nodeid(
nodeid,
kind,
rootdir=None,
# *,
_fix_fileid=fix_fileid,
):
if not nodeid:
raise ValueError("missing nodeid")
if nodeid == ".":
return nodeid
fileid = nodeid
remainder = ""
if kind not in ("folder", "file"):
m = FILE_ID_RE.match(nodeid)
if m:
fileid, remainder = m.groups()
elif len(nodeid) > 1:
fileid = nodeid[:2]
remainder = nodeid[2:]
fileid = _fix_fileid(fileid, rootdir)
return fileid + (remainder or "")
class DiscoveredTests(object):
"""A container for the discovered tests and their parents."""
def __init__(self):
self.reset()
def __len__(self):
return len(self._tests)
def __getitem__(self, index):
return self._tests[index]
@property
def parents(self):
return sorted(
self._parents.values(),
# Sort by (name, id).
key=lambda p: (NORMCASE(p.root or p.name), p.id),
)
def reset(self):
"""Clear out any previously discovered tests."""
self._parents = {}
self._tests = []
def add_test(self, test, parents):
"""Add the given test and its parents."""
parentid = self._ensure_parent(test.path, parents)
# Updating the parent ID and the test ID aren't necessary if the
# provided test and parents (from the test collector) are
# properly generated. However, we play it safe here.
test = test._replace(
# Clean up the ID.
id=fix_nodeid(test.id, "test", test.path.root),
parentid=parentid,
)
self._tests.append(test)
def _ensure_parent(
self,
path,
parents,
# *,
_dirname=DIRNAME,
):
rootdir = path.root
relpath = path.relfile
_parents = iter(parents)
nodeid, name, kind = next(_parents)
# As in add_test(), the node ID *should* already be correct.
nodeid = fix_nodeid(nodeid, kind, rootdir)
_parentid = nodeid
for parentid, parentname, parentkind in _parents:
# As in add_test(), the parent ID *should* already be correct.
parentid = fix_nodeid(parentid, kind, rootdir)
if kind in ("folder", "file"):
info = ParentInfo(nodeid, kind, name, rootdir, relpath, parentid)
relpath = _dirname(relpath)
else:
info = ParentInfo(nodeid, kind, name, rootdir, None, parentid)
self._parents[(rootdir, nodeid)] = info
nodeid, name, kind = parentid, parentname, parentkind
assert nodeid == "."
info = ParentInfo(nodeid, kind, name=rootdir)
self._parents[(rootdir, nodeid)] = info
return _parentid