@opensumi/ide-testing 2.21.13 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/components/testing.explorer.tree.d.ts.map +1 -1
- package/lib/browser/components/testing.explorer.tree.js +7 -5
- package/lib/browser/components/testing.explorer.tree.js.map +1 -1
- package/lib/browser/components/testing.view.js +1 -1
- package/lib/browser/components/testing.view.js.map +1 -1
- package/lib/browser/icons/icons.d.ts +1 -0
- package/lib/browser/icons/icons.d.ts.map +1 -1
- package/lib/browser/icons/icons.js +15 -14
- package/lib/browser/icons/icons.js.map +1 -1
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/outputPeek/test-output-peek.js +9 -9
- package/lib/browser/outputPeek/test-output-peek.js.map +1 -1
- package/lib/browser/outputPeek/test-peek-message.service.js.map +1 -1
- package/lib/browser/outputPeek/test-peek-opener.service.js +1 -1
- package/lib/browser/outputPeek/test-peek-opener.service.js.map +1 -1
- package/lib/browser/outputPeek/test-peek-widget.js +1 -1
- package/lib/browser/outputPeek/test-peek-widget.js.map +1 -1
- package/lib/browser/outputPeek/test-tree-container.js +2 -2
- package/lib/browser/outputPeek/test-tree-container.js.map +1 -1
- package/lib/browser/test-contextkey.service.js.map +1 -1
- package/lib/browser/test-decorations.js +19 -19
- package/lib/browser/test-decorations.js.map +1 -1
- package/lib/browser/test-profile.service.js.map +1 -1
- package/lib/browser/test-tree-view.model.d.ts +1 -0
- package/lib/browser/test-tree-view.model.d.ts.map +1 -1
- package/lib/browser/test-tree-view.model.js +13 -10
- package/lib/browser/test-tree-view.model.js.map +1 -1
- package/lib/browser/test.result.service.d.ts +1 -1
- package/lib/browser/test.result.service.d.ts.map +1 -1
- package/lib/browser/test.result.service.js +5 -5
- package/lib/browser/test.result.service.js.map +1 -1
- package/lib/browser/test.service.d.ts +4 -0
- package/lib/browser/test.service.d.ts.map +1 -1
- package/lib/browser/test.service.js +31 -4
- package/lib/browser/test.service.js.map +1 -1
- package/lib/browser/testing.contribution.d.ts.map +1 -1
- package/lib/browser/testing.contribution.js +21 -10
- package/lib/browser/testing.contribution.js.map +1 -1
- package/lib/common/commands.d.ts +1 -0
- package/lib/common/commands.d.ts.map +1 -1
- package/lib/common/commands.js +6 -1
- package/lib/common/commands.js.map +1 -1
- package/lib/common/constants.js +12 -12
- package/lib/common/constants.js.map +1 -1
- package/lib/common/getComputedState.d.ts +1 -1
- package/lib/common/getComputedState.d.ts.map +1 -1
- package/lib/common/getComputedState.js +1 -1
- package/lib/common/getComputedState.js.map +1 -1
- package/lib/common/index.d.ts +5 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/observableValue.d.ts +14 -0
- package/lib/common/observableValue.d.ts.map +1 -0
- package/lib/common/observableValue.js +23 -0
- package/lib/common/observableValue.js.map +1 -0
- package/lib/common/test-result.d.ts +2 -2
- package/lib/common/test-result.d.ts.map +1 -1
- package/lib/common/test-result.js +19 -19
- package/lib/common/test-result.js.map +1 -1
- package/lib/common/testCollection.d.ts +9 -8
- package/lib/common/testCollection.d.ts.map +1 -1
- package/lib/common/testCollection.js +27 -27
- package/lib/common/testCollection.js.map +1 -1
- package/lib/common/testId.js +21 -21
- package/lib/common/testId.js.map +1 -1
- package/lib/common/testingStates.js +11 -11
- package/lib/common/testingStates.js.map +1 -1
- package/lib/common/testingUri.d.ts +1 -1
- package/lib/common/testingUri.d.ts.map +1 -1
- package/lib/common/testingUri.js +16 -16
- package/lib/common/testingUri.js.map +1 -1
- package/package.json +14 -13
- package/src/browser/components/testing.explorer.tree.tsx +129 -0
- package/src/browser/components/testing.module.less +26 -0
- package/src/browser/components/testing.view.tsx +35 -0
- package/src/browser/icons/icons.less +31 -0
- package/src/browser/icons/icons.ts +31 -0
- package/src/browser/index.ts +51 -0
- package/src/browser/outputPeek/test-message-container.tsx +183 -0
- package/src/browser/outputPeek/test-output-peek.ts +282 -0
- package/src/browser/outputPeek/test-peek-message.service.ts +15 -0
- package/src/browser/outputPeek/test-peek-opener.service.ts +131 -0
- package/src/browser/outputPeek/test-peek-widget.less +86 -0
- package/src/browser/outputPeek/test-peek-widget.tsx +127 -0
- package/src/browser/outputPeek/test-tree-container.tsx +171 -0
- package/src/browser/test-contextkey.service.ts +24 -0
- package/src/browser/test-decorations.ts +567 -0
- package/src/browser/test-profile.service.ts +66 -0
- package/src/browser/test-tree-view.model.ts +304 -0
- package/src/browser/test.result.service.ts +193 -0
- package/src/browser/test.service.ts +190 -0
- package/src/browser/testing.contribution.ts +471 -0
- package/src/browser/theme.less +6 -0
- package/src/common/commands.ts +78 -0
- package/src/common/constants.ts +57 -0
- package/src/common/contextKeys.ts +0 -0
- package/src/common/getComputedState.ts +136 -0
- package/src/common/index.ts +55 -0
- package/src/common/observableValue.ts +27 -0
- package/src/common/test-profile.ts +25 -0
- package/src/common/test-result.ts +328 -0
- package/src/common/testCollection.ts +680 -0
- package/src/common/testId.ts +191 -0
- package/src/common/testing-view.ts +28 -0
- package/src/common/testingPeekOpener.ts +31 -0
- package/src/common/testingStates.ts +92 -0
- package/src/common/testingUri.ts +101 -0
- package/src/common/tree-view.model.ts +41 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
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
|
+
export interface TestItemLike {
|
|
27
|
+
id: string;
|
|
28
|
+
parent?: TestItemLike;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The test ID is a stringifiable client that
|
|
33
|
+
*/
|
|
34
|
+
export class TestId {
|
|
35
|
+
private stringifed?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a test ID from an ext host test item.
|
|
39
|
+
*/
|
|
40
|
+
public static fromExtHostTestItem(item: TestItemLike, rootId: string, parent = item.parent) {
|
|
41
|
+
if (item.id === rootId) {
|
|
42
|
+
return new TestId([rootId]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const path = [item.id];
|
|
46
|
+
for (let i = parent; i && i.id !== rootId; i = i.parent) {
|
|
47
|
+
path.push(i.id);
|
|
48
|
+
}
|
|
49
|
+
path.push(rootId);
|
|
50
|
+
|
|
51
|
+
return new TestId(path.reverse());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Cheaply ets whether the ID refers to the root .
|
|
56
|
+
*/
|
|
57
|
+
public static isRoot(idString: string) {
|
|
58
|
+
return !idString.includes(TestIdPathParts.Delimiter);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a test ID from a serialized TestId instance.
|
|
63
|
+
*/
|
|
64
|
+
public static fromString(idString: string) {
|
|
65
|
+
return new TestId(idString.split(TestIdPathParts.Delimiter));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gets the ID resulting from adding b to the base ID.
|
|
70
|
+
*/
|
|
71
|
+
public static join(base: TestId, b: string) {
|
|
72
|
+
return new TestId([...base.path, b]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Gets the string ID resulting from adding b to the base ID.
|
|
77
|
+
*/
|
|
78
|
+
public static joinToString(base: string | TestId, b: string) {
|
|
79
|
+
return base.toString() + TestIdPathParts.Delimiter + b;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Compares the position of the two ID strings.
|
|
84
|
+
*/
|
|
85
|
+
public static compare(a: string, b: string) {
|
|
86
|
+
if (a === b) {
|
|
87
|
+
return TestPosition.IsSame;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (b.startsWith(a + TestIdPathParts.Delimiter)) {
|
|
91
|
+
return TestPosition.IsChild;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (a.startsWith(b + TestIdPathParts.Delimiter)) {
|
|
95
|
+
return TestPosition.IsParent;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return TestPosition.Disconnected;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
constructor(public readonly path: readonly string[], private readonly viewEnd = path.length) {
|
|
102
|
+
if (path.length === 0 || viewEnd < 1) {
|
|
103
|
+
throw new Error('cannot create test with empty path');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Gets the ID of the parent test.
|
|
109
|
+
*/
|
|
110
|
+
public get parentId(): TestId {
|
|
111
|
+
return this.viewEnd > 1 ? new TestId(this.path, this.viewEnd - 1) : this;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Gets the local ID of the current full test ID.
|
|
116
|
+
*/
|
|
117
|
+
public get localId() {
|
|
118
|
+
return this.path[this.viewEnd - 1];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Gets whether this ID refers to the root.
|
|
123
|
+
*/
|
|
124
|
+
public get controllerId() {
|
|
125
|
+
return this.path[0];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Gets whether this ID refers to the root.
|
|
130
|
+
*/
|
|
131
|
+
public get isRoot() {
|
|
132
|
+
return this.viewEnd === 1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Returns an iterable that yields IDs of all parent items down to and
|
|
137
|
+
* including the current item.
|
|
138
|
+
*/
|
|
139
|
+
public *idsFromRoot() {
|
|
140
|
+
for (let i = 1; i <= this.viewEnd; i++) {
|
|
141
|
+
yield new TestId(this.path, i);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Compares the other test ID with this one.
|
|
147
|
+
*/
|
|
148
|
+
public compare(other: TestId | string) {
|
|
149
|
+
if (typeof other === 'string') {
|
|
150
|
+
return TestId.compare(this.toString(), other);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
for (let i = 0; i < other.viewEnd && i < this.viewEnd; i++) {
|
|
154
|
+
if (other.path[i] !== this.path[i]) {
|
|
155
|
+
return TestPosition.Disconnected;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (other.viewEnd > this.viewEnd) {
|
|
160
|
+
return TestPosition.IsChild;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (other.viewEnd < this.viewEnd) {
|
|
164
|
+
return TestPosition.IsParent;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return TestPosition.IsSame;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Serializes the ID.
|
|
172
|
+
*/
|
|
173
|
+
public toJSON() {
|
|
174
|
+
return this.toString();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Serializes the ID to a string.
|
|
179
|
+
*/
|
|
180
|
+
public toString() {
|
|
181
|
+
if (!this.stringifed) {
|
|
182
|
+
this.stringifed = this.path[0];
|
|
183
|
+
for (let i = 1; i < this.viewEnd; i++) {
|
|
184
|
+
this.stringifed += TestIdPathParts.Delimiter;
|
|
185
|
+
this.stringifed += this.path[i];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return this.stringifed;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IBasicInlineMenu, IBasicInlineMenuPosition } from '@opensumi/ide-components';
|
|
2
|
+
|
|
3
|
+
import { DebugTestCommand, GoToTestCommand, RuntTestCommand } from './commands';
|
|
4
|
+
|
|
5
|
+
export const TestingViewId = '@opensumi/ide-testing';
|
|
6
|
+
|
|
7
|
+
export const TestingContainerId = 'testing';
|
|
8
|
+
|
|
9
|
+
export const TestingExplorerInlineMenus: IBasicInlineMenu[] = [
|
|
10
|
+
{
|
|
11
|
+
icon: 'start',
|
|
12
|
+
title: 'Run Test',
|
|
13
|
+
command: RuntTestCommand.id,
|
|
14
|
+
position: IBasicInlineMenuPosition.TREE_CONTAINER,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
icon: 'debug-alt-small',
|
|
18
|
+
title: 'Debug Test',
|
|
19
|
+
command: DebugTestCommand.id,
|
|
20
|
+
position: IBasicInlineMenuPosition.TREE_CONTAINER,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
icon: 'openfile',
|
|
24
|
+
title: 'Go To Test',
|
|
25
|
+
command: GoToTestCommand.id,
|
|
26
|
+
position: IBasicInlineMenuPosition.TREE_CONTAINER,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
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
|
+
import type { ITextEditorOptions } from '@opensumi/monaco-editor-core/esm/vs/platform/editor/common/editor';
|
|
7
|
+
|
|
8
|
+
import { ITestResult } from './test-result';
|
|
9
|
+
import { TestResultItem } from './testCollection';
|
|
10
|
+
|
|
11
|
+
export const TestingPeekOpenerServiceToken = Symbol('TestingPeekOpenerService');
|
|
12
|
+
|
|
13
|
+
export interface ITestingPeekOpenerService {
|
|
14
|
+
_serviceBrand: undefined;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Tries to peek the first test error, if the item is in a failed state.
|
|
18
|
+
* @returns a boolean indicating whether a peek was opened
|
|
19
|
+
*/
|
|
20
|
+
tryPeekFirstError(result: ITestResult, test: TestResultItem, options?: Partial<ITextEditorOptions>): boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Opens the peek. Shows any available message.
|
|
24
|
+
*/
|
|
25
|
+
open(): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Closes peeks for all visible editors.
|
|
29
|
+
*/
|
|
30
|
+
closeAllPeeks(): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
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
|
+
import { parseMarkdown } from '@opensumi/ide-components/lib/utils';
|
|
7
|
+
import { strings } from '@opensumi/ide-core-common';
|
|
8
|
+
|
|
9
|
+
import { ITestErrorMessage, TestResultState } from './testCollection';
|
|
10
|
+
|
|
11
|
+
const { count } = strings;
|
|
12
|
+
|
|
13
|
+
export interface TreeStateNode {
|
|
14
|
+
statusNode: true;
|
|
15
|
+
state: TestResultState;
|
|
16
|
+
priority: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* List of display priorities for different run states. When tests update,
|
|
21
|
+
* the highest-priority state from any of their children will be the state
|
|
22
|
+
* reflected in the parent node.
|
|
23
|
+
*/
|
|
24
|
+
export const statePriority: { [K in TestResultState]: number } = {
|
|
25
|
+
[TestResultState.Running]: 6,
|
|
26
|
+
[TestResultState.Errored]: 5,
|
|
27
|
+
[TestResultState.Failed]: 4,
|
|
28
|
+
[TestResultState.Queued]: 3,
|
|
29
|
+
[TestResultState.Passed]: 2,
|
|
30
|
+
[TestResultState.Unset]: 1,
|
|
31
|
+
[TestResultState.Skipped]: 0,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const isFailedState = (s: TestResultState) => s === TestResultState.Errored || s === TestResultState.Failed;
|
|
35
|
+
export const isStateWithResult = (s: TestResultState) =>
|
|
36
|
+
s === TestResultState.Errored || s === TestResultState.Failed || s === TestResultState.Passed;
|
|
37
|
+
|
|
38
|
+
export const stateNodes = Object.entries(statePriority).reduce((acc, [stateStr, priority]) => {
|
|
39
|
+
const state = Number(stateStr) as TestResultState;
|
|
40
|
+
acc[state] = { statusNode: true, state, priority };
|
|
41
|
+
return acc;
|
|
42
|
+
}, {} as { [K in TestResultState]: TreeStateNode });
|
|
43
|
+
|
|
44
|
+
export const cmpPriority = (a: TestResultState, b: TestResultState) => statePriority[b] - statePriority[a];
|
|
45
|
+
|
|
46
|
+
export const maxPriority = (...states: TestResultState[]) => {
|
|
47
|
+
switch (states.length) {
|
|
48
|
+
case 0:
|
|
49
|
+
return TestResultState.Unset;
|
|
50
|
+
case 1:
|
|
51
|
+
return states[0];
|
|
52
|
+
case 2:
|
|
53
|
+
return statePriority[states[0]] > statePriority[states[1]] ? states[0] : states[1];
|
|
54
|
+
default: {
|
|
55
|
+
let max = states[0];
|
|
56
|
+
for (let i = 1; i < states.length; i++) {
|
|
57
|
+
if (statePriority[max] < statePriority[states[i]]) {
|
|
58
|
+
max = states[i];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return max;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const statesInOrder = Object.keys(statePriority)
|
|
67
|
+
.map((s) => Number(s) as TestResultState)
|
|
68
|
+
.sort(cmpPriority);
|
|
69
|
+
|
|
70
|
+
export const isRunningState = (s: TestResultState) => s === TestResultState.Queued || s === TestResultState.Running;
|
|
71
|
+
|
|
72
|
+
export const firstLine = (str: string) => {
|
|
73
|
+
const index = str.indexOf('\n');
|
|
74
|
+
return index === -1 ? str : str.slice(0, index);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const domParser = new DOMParser();
|
|
78
|
+
|
|
79
|
+
export const parseMarkdownText = (value: string) =>
|
|
80
|
+
domParser.parseFromString(parseMarkdown(value) || '', 'text/html').documentElement.outerText;
|
|
81
|
+
|
|
82
|
+
export const isDiffable = (
|
|
83
|
+
message: ITestErrorMessage,
|
|
84
|
+
): message is ITestErrorMessage & { actualOutput: string; expectedOutput: string } =>
|
|
85
|
+
message.actual !== undefined && message.expected !== undefined;
|
|
86
|
+
|
|
87
|
+
const hintPeekStrHeight = (str: string | undefined) => Math.min(Math.max(count(str || '', '\n') + 3, 8), 20);
|
|
88
|
+
|
|
89
|
+
export const hintMessagePeekHeight = (msg: ITestErrorMessage) =>
|
|
90
|
+
isDiffable(msg)
|
|
91
|
+
? Math.max(hintPeekStrHeight(msg.actual), hintPeekStrHeight(msg.expected))
|
|
92
|
+
: hintPeekStrHeight(typeof msg.message === 'string' ? msg.message : msg.message.value);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
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
|
+
import { URI } from '@opensumi/ide-core-common';
|
|
7
|
+
|
|
8
|
+
export const TEST_DATA_SCHEME = 'opensumi-test-data';
|
|
9
|
+
|
|
10
|
+
export const enum TestUriType {
|
|
11
|
+
ResultMessage,
|
|
12
|
+
ResultActualOutput,
|
|
13
|
+
ResultExpectedOutput,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface IResultTestUri {
|
|
17
|
+
resultId: string;
|
|
18
|
+
taskIndex: number;
|
|
19
|
+
testExtId: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface IResultTestMessageReference extends IResultTestUri {
|
|
23
|
+
type: TestUriType.ResultMessage;
|
|
24
|
+
messageIndex: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface IResultTestOutputReference extends IResultTestUri {
|
|
28
|
+
type: TestUriType.ResultActualOutput | TestUriType.ResultExpectedOutput;
|
|
29
|
+
messageIndex: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ParsedTestUri = IResultTestMessageReference | IResultTestOutputReference;
|
|
33
|
+
|
|
34
|
+
const enum TestUriParts {
|
|
35
|
+
Results = 'results',
|
|
36
|
+
|
|
37
|
+
Messages = 'message',
|
|
38
|
+
Text = 'TestFailureMessage',
|
|
39
|
+
ActualOutput = 'ActualOutput',
|
|
40
|
+
ExpectedOutput = 'ExpectedOutput',
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const parseTestUri = (uri: URI): ParsedTestUri | undefined => {
|
|
44
|
+
const type = uri.authority;
|
|
45
|
+
const [locationId, ...request] = uri.path.toString().slice(1).split('/');
|
|
46
|
+
|
|
47
|
+
if (request[0] === TestUriParts.Messages) {
|
|
48
|
+
const taskIndex = Number(request[1]);
|
|
49
|
+
const index = Number(request[2]);
|
|
50
|
+
const part = request[3];
|
|
51
|
+
const testExtId = uri.query;
|
|
52
|
+
if (type === TestUriParts.Results) {
|
|
53
|
+
switch (part) {
|
|
54
|
+
case TestUriParts.Text:
|
|
55
|
+
return { resultId: locationId, taskIndex, testExtId, messageIndex: index, type: TestUriType.ResultMessage };
|
|
56
|
+
case TestUriParts.ActualOutput:
|
|
57
|
+
return {
|
|
58
|
+
resultId: locationId,
|
|
59
|
+
taskIndex,
|
|
60
|
+
testExtId,
|
|
61
|
+
messageIndex: index,
|
|
62
|
+
type: TestUriType.ResultActualOutput,
|
|
63
|
+
};
|
|
64
|
+
case TestUriParts.ExpectedOutput:
|
|
65
|
+
return {
|
|
66
|
+
resultId: locationId,
|
|
67
|
+
taskIndex,
|
|
68
|
+
testExtId,
|
|
69
|
+
messageIndex: index,
|
|
70
|
+
type: TestUriType.ResultExpectedOutput,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return undefined;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const buildTestUri = (parsed: ParsedTestUri): URI => {
|
|
80
|
+
const uriParts = {
|
|
81
|
+
scheme: TEST_DATA_SCHEME,
|
|
82
|
+
authority: TestUriParts.Results,
|
|
83
|
+
};
|
|
84
|
+
const msgRef = (locationId: string, ...remaining: (string | number)[]) =>
|
|
85
|
+
URI.from({
|
|
86
|
+
...uriParts,
|
|
87
|
+
query: parsed.testExtId,
|
|
88
|
+
path: ['', locationId, TestUriParts.Messages, ...remaining].join('/'),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
switch (parsed.type) {
|
|
92
|
+
case TestUriType.ResultActualOutput:
|
|
93
|
+
return msgRef(parsed.resultId, parsed.taskIndex, parsed.messageIndex, TestUriParts.ActualOutput);
|
|
94
|
+
case TestUriType.ResultExpectedOutput:
|
|
95
|
+
return msgRef(parsed.resultId, parsed.taskIndex, parsed.messageIndex, TestUriParts.ExpectedOutput);
|
|
96
|
+
case TestUriType.ResultMessage:
|
|
97
|
+
return msgRef(parsed.resultId, parsed.taskIndex, parsed.messageIndex, TestUriParts.Text);
|
|
98
|
+
default:
|
|
99
|
+
throw new Error('Invalid test uri');
|
|
100
|
+
}
|
|
101
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IBasicTreeData, IRecycleTreeHandle } from '@opensumi/ide-components';
|
|
2
|
+
import { Event } from '@opensumi/ide-core-browser';
|
|
3
|
+
|
|
4
|
+
import { InternalTestItem, TestResultState, IncrementalTestCollectionItem } from './testCollection';
|
|
5
|
+
|
|
6
|
+
export const TestTreeViewModelToken = Symbol('TestTreeViewModel');
|
|
7
|
+
|
|
8
|
+
export interface ITestTreeViewModel {
|
|
9
|
+
roots: Iterable<ITestTreeItem>;
|
|
10
|
+
onUpdate: Event<void>;
|
|
11
|
+
|
|
12
|
+
initTreeModel(): Promise<void>;
|
|
13
|
+
|
|
14
|
+
expandElement(element: ITestTreeItem, depth: number): void;
|
|
15
|
+
|
|
16
|
+
setTreeHandlerApi(handle: IRecycleTreeHandle): void;
|
|
17
|
+
|
|
18
|
+
getTestItem(extId: string): IncrementalTestCollectionItem | undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ITestTreeItem {
|
|
22
|
+
state: TestResultState;
|
|
23
|
+
|
|
24
|
+
test: InternalTestItem;
|
|
25
|
+
|
|
26
|
+
parent: ITestTreeItem | undefined;
|
|
27
|
+
|
|
28
|
+
children: Set<ITestTreeItem>;
|
|
29
|
+
|
|
30
|
+
depth: number;
|
|
31
|
+
|
|
32
|
+
tests: InternalTestItem[];
|
|
33
|
+
|
|
34
|
+
duration: number | undefined;
|
|
35
|
+
|
|
36
|
+
label: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ITestTreeData<T = ITestTreeItem> extends IBasicTreeData {
|
|
40
|
+
rawItem: T;
|
|
41
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './common';
|