src/vs/workbench/contrib/testing/common/testId.ts

269 LOC · 158 covered · 111 uncovered · 23 ranges · 154 concepts · 1 introducers · 103 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- extHostTypes.ts ×270
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > export const enum TestIdPathParts {
7 > /** Delimiter for path parts in test IDs */
8 > Delimiter = '\0',
9 > }
10 >
11 > /**
12 > * Enum for describing relative positions of tests. Similar to
13 > * `node.compareDocumentPosition` in the DOM.
14 > */
15 > export const enum TestPosition {
16 > /** a === b */
17 > IsSame,
18 > /** Neither a nor b are a child of one another. They may share a common parent, though. */
19 > Disconnected,
20 > /** b is a child of a */
21 > IsChild,
22 > /** b is a parent of a */
23 > IsParent,
24 > }
25 >
26 > type TestItemLike = { id: string; parent?: TestItemLike; _isRoot?: boolean };
27 >
28 > /**
29 > * The test ID is a stringifiable client that
30 > */
31 > export class TestId {
32 > private stringifed?: string;
33 >
34 > /**
35 > * Creates a test ID from an ext host test item.
36 > */
37 > public static fromExtHostTestItem(item: TestItemLike, rootId: string, parent = item.parent) {
38 > if (item._isRoot) {
39 > return new TestId([rootId]);
40 > }
41 >
42 > const path = [item.id];
43 > for (let i = parent; i && i.id !== rootId; i = i.parent) {
44 > path.push(i.id);
45 > }
46 > path.push(rootId);
47 >
48 > return new TestId(path.reverse());
49 > }
50 >
51 > /**
52 > * Cheaply ets whether the ID refers to the root .
53 > */
54 > public static isRoot(idString: string) {
55 return !idString.includes(TestIdPathParts.Delimiter);
56 }
58 > /**
59 > * Cheaply gets whether the ID refers to the root .
60 > */
61 > public static root(idString: string) {
62 const idx = idString.indexOf(TestIdPathParts.Delimiter);
63 return idx === -1 ? idString : idString.slice(0, idx);
64 }
66 > /**
67 > * Creates a test ID from a serialized TestId instance.
68 > */
69 > public static fromString(idString: string) {
70 return new TestId(idString.split(TestIdPathParts.Delimiter));
71 }
73 > /**
74 > * Gets the ID resulting from adding b to the base ID.
75 > */
76 > public static join(base: TestId, b: string) {
77 return new TestId([...base.path, b]);
78 }
80 > /**
81 > * Splits a test ID into its parts.
82 > */
83 > public static split(idString: string) {
84 return idString.split(TestIdPathParts.Delimiter);
85 }
87 > /**
88 > * Gets the string ID resulting from adding b to the base ID.
89 > */
90 > public static joinToString(base: string | TestId, b: string) {
91 return base.toString() + TestIdPathParts.Delimiter + b;
92 }
94 > /**
95 > * Cheaply gets the parent ID of a test identified with the string.
96 > */
97 > public static parentId(idString: string) {
98 const idx = idString.lastIndexOf(TestIdPathParts.Delimiter);
99 return idx === -1 ? undefined : idString.slice(0, idx);
100 }
102 > /**
103 > * Cheaply gets the local ID of a test identified with the string.
104 > */
105 > public static localId(idString: string) {
106 const idx = idString.lastIndexOf(TestIdPathParts.Delimiter);
107 return idx === -1 ? idString : idString.slice(idx + TestIdPathParts.Delimiter.length);
108 }
110 > /**
111 > * Gets whether maybeChild is a child of maybeParent.
112 > * todo@connor4312: review usages of this to see if using the WellDefinedPrefixTree is better
113 > */
114 > public static isChild(maybeParent: string, maybeChild: string) {
115 return maybeChild[maybeParent.length] === TestIdPathParts.Delimiter && maybeChild.startsWith(maybeParent);
116 }
118 > /**
119 > * Compares the position of the two ID strings.
120 > * todo@connor4312: review usages of this to see if using the WellDefinedPrefixTree is better
121 > */
122 > public static compare(a: string, b: string) {
123 if (a === b) {
124 return TestPosition.IsSame;
125 }
126
127 if (TestId.isChild(a, b)) {
128 return TestPosition.IsChild;
129 }
130
131 if (TestId.isChild(b, a)) {
132 return TestPosition.IsParent;
133 }
134
135 return TestPosition.Disconnected;
136 }
138 > public static getLengthOfCommonPrefix(length: number, getId: (i: number) => TestId): number {
139 if (length === 0) {
140 return 0;
141 }
142
143 let commonPrefix = 0;
144 while (commonPrefix < length - 1) {
145 for (let i = 1; i < length; i++) {
146 const a = getId(i - 1);
147 const b = getId(i);
148 if (a.path[commonPrefix] !== b.path[commonPrefix]) {
149 return commonPrefix;
150 }
151 }
152
153 commonPrefix++;
154 }
155
156 return commonPrefix;
157 }
159 > constructor(
160 public readonly path: readonly string[],
161 private readonly viewEnd = path.length,
162 ) {
163 if (path.length === 0 || viewEnd < 1) {
164 throw new Error('cannot create test with empty path');
165 }
166 }
168 > /**
169 > * Gets the ID of the parent test.
170 > */
171 > public get rootId(): TestId {
172 return new TestId(this.path, 1);
173 }
175 > /**
176 > * Gets the ID of the parent test.
177 > */
178 > public get parentId(): TestId | undefined {
179 return this.viewEnd > 1 ? new TestId(this.path, this.viewEnd - 1) : undefined;
180 }
182 > /**
183 > * Gets the local ID of the current full test ID.
184 > */
185 > public get localId() {
186 return this.path[this.viewEnd - 1];
187 }
189 > /**
190 > * Gets whether this ID refers to the root.
191 > */
192 > public get controllerId() {
193 return this.path[0];
194 }
196 > /**
197 > * Gets whether this ID refers to the root.
198 > */
199 > public get isRoot() {
200 return this.viewEnd === 1;
201 }
203 > /**
204 > * Returns an iterable that yields IDs of all parent items down to and
205 > * including the current item.
206 > */
207 > public *idsFromRoot() {
208 for (let i = 1; i <= this.viewEnd; i++) {
209 yield new TestId(this.path, i);
210 }
211 }
213 > /**
214 > * Returns an iterable that yields IDs of the current item up to the root
215 > * item.
216 > */
217 > public *idsToRoot() {
218 for (let i = this.viewEnd; i > 0; i--) {
219 yield new TestId(this.path, i);
220 }
221 }
223 > /**
224 > * Compares the other test ID with this one.
225 > */
226 > public compare(other: TestId | string) {
227 if (typeof other === 'string') {
228 return TestId.compare(this.toString(), other);
229 }
230
231 for (let i = 0; i < other.viewEnd && i < this.viewEnd; i++) {
232 if (other.path[i] !== this.path[i]) {
233 return TestPosition.Disconnected;
234 }
235 }
236
237 if (other.viewEnd > this.viewEnd) {
238 return TestPosition.IsChild;
239 }
240
241 if (other.viewEnd < this.viewEnd) {
242 return TestPosition.IsParent;
243 }
244
245 return TestPosition.IsSame;
246 }
248 > /**
249 > * Serializes the ID.
250 > */
251 > public toJSON() {
252 return this.toString();
253 }
255 > /**
256 > * Serializes the ID to a string.
257 > */
258 > public toString() {
259 if (!this.stringifed) {
260 this.stringifed = this.path[0];
261 for (let i = 1; i < this.viewEnd; i++) {
262 this.stringifed += TestIdPathParts.Delimiter;
263 this.stringifed += this.path[i];
264 }
265 }
266
267 return this.stringifed;
268 }