testing: some api polishing

Fixes #119793
Fixes #119831
Fixes #117602
This commit is contained in:
Connor Peet
2021-04-01 14:26:08 -07:00
parent 788d62f10f
commit ade3e6e683
23 changed files with 274 additions and 260 deletions

View File

@@ -9,7 +9,8 @@ import { isDefined } from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { Range } from 'vs/editor/common/core/range';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { getTestSubscriptionKey, ISerializedTestResults, ITestState, RunTestsRequest, TestDiffOpType, TestsDiff } from 'vs/workbench/contrib/testing/common/testCollection';
import { TestResultState } from 'vs/workbench/api/common/extHostTypes';
import { getTestSubscriptionKey, ISerializedTestResults, ITestMessage, RunTestsRequest, TestDiffOpType, TestsDiff } from 'vs/workbench/contrib/testing/common/testCollection';
import { HydratedTestResult, ITestResultService, LiveTestResult } from 'vs/workbench/contrib/testing/common/testResultService';
import { ITestRootProvider, ITestService } from 'vs/workbench/contrib/testing/common/testService';
import { ExtHostContext, ExtHostTestingResource, ExtHostTestingShape, IExtHostContext, MainContext, MainThreadTestingShape } from '../common/extHost.protocol';
@@ -75,17 +76,25 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh
/**
* @inheritdoc
*/
public $updateTestStateInRun(runId: string, testId: string, state: ITestState): void {
public $updateTestStateInRun(runId: string, testId: string, state: TestResultState, duration?: number): void {
const r = this.resultService.getResult(runId);
if (r && r instanceof LiveTestResult) {
for (const message of state.messages) {
if (message.location) {
message.location.uri = URI.revive(message.location.uri);
message.location.range = Range.lift(message.location.range);
}
r.updateState(testId, state, duration);
}
}
/**
* @inheritdoc
*/
public $appendTestMessageInRun(runId: string, testId: string, message: ITestMessage): void {
const r = this.resultService.getResult(runId);
if (r && r instanceof LiveTestResult) {
if (message.location) {
message.location.uri = URI.revive(message.location.uri);
message.location.range = Range.lift(message.location.range);
}
r.updateState(testId, state);
r.appendMessage(testId, message);
}
}

View File

@@ -1251,8 +1251,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
NotebookCellOutputItem: extHostTypes.NotebookCellOutputItem,
LinkedEditingRanges: extHostTypes.LinkedEditingRanges,
TestItem: extHostTypes.TestItem,
TestState: extHostTypes.TestState,
TestResult: extHostTypes.TestResult,
TestResultState: extHostTypes.TestResultState,
TestMessage: extHostTypes.TestMessage,
TestMessageSeverity: extHostTypes.TestMessageSeverity,
WorkspaceTrustState: extHostTypes.WorkspaceTrustState

View File

@@ -53,10 +53,10 @@ import { revive } from 'vs/base/common/marshalling';
import { NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEventDto, NotebookDataDto, IMainCellDto, INotebookDocumentFilter, TransientMetadata, INotebookCellStatusBarEntry, ICellRange, INotebookDecorationRenderOptions, INotebookExclusiveDocumentFilter, IOutputDto, TransientOptions, IImmediateCellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import { Dto } from 'vs/base/common/types';
import { DebugConfigurationProviderTriggerKind, WorkspaceTrustState } from 'vs/workbench/api/common/extHostTypes';
import { DebugConfigurationProviderTriggerKind, TestResultState, WorkspaceTrustState } from 'vs/workbench/api/common/extHostTypes';
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
import { IExtensionIdWithVersion } from 'vs/platform/userDataSync/common/extensionsStorageSync';
import { InternalTestItem, ITestState, RunTestForProviderRequest, RunTestsRequest, TestIdWithSrc, TestsDiff, ISerializedTestResults } from 'vs/workbench/contrib/testing/common/testCollection';
import { InternalTestItem, RunTestForProviderRequest, RunTestsRequest, TestIdWithSrc, TestsDiff, ISerializedTestResults, ITestMessage } from 'vs/workbench/contrib/testing/common/testCollection';
import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { WorkspaceTrustRequestOptions, WorkspaceTrustStateChangeEvent } from 'vs/platform/workspace/common/workspaceTrust';
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
@@ -1970,7 +1970,8 @@ export interface MainThreadTestingShape {
$subscribeToDiffs(resource: ExtHostTestingResource, uri: UriComponents): void;
$unsubscribeFromDiffs(resource: ExtHostTestingResource, uri: UriComponents): void;
$publishDiff(resource: ExtHostTestingResource, uri: UriComponents, diff: TestsDiff): void;
$updateTestStateInRun(runId: string, testId: string, state: ITestState): void;
$updateTestStateInRun(runId: string, testId: string, state: TestResultState, duration?: number): void;
$appendTestMessageInRun(runId: string, testId: string, message: ITestMessage): void;
$runTests(req: RunTestsRequest, token: CancellationToken): Promise<string>;
$publishExtensionProvidedResults(results: ISerializedTestResults, persist: boolean): void;
}

View File

@@ -41,7 +41,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
private textDocumentObservers: TextDocumentTestObserverFactory;
public onResultsChanged = this.resultsChangedEmitter.event;
public results: ReadonlyArray<vscode.TestResults> = [];
public results: ReadonlyArray<vscode.TestRunResult> = [];
constructor(@IExtHostRpcService rpc: IExtHostRpcService, @IExtHostDocumentsAndEditors private readonly documents: IExtHostDocumentsAndEditors, @IExtHostWorkspace private readonly workspace: IExtHostWorkspace) {
this.proxy = rpc.getProxy(MainContext.MainThreadTesting);
@@ -88,7 +88,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
/**
* Implements vscode.test.runTests
*/
public async runTests(req: vscode.TestRunOptions<vscode.TestItem>, token = CancellationToken.None) {
public async runTests(req: vscode.TestRunRequest<vscode.TestItem>, token = CancellationToken.None) {
const testListToProviders = (tests: ReadonlyArray<vscode.TestItem>) =>
tests
.map(this.getInternalTestForReference, this)
@@ -105,7 +105,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
/**
* Implements vscode.test.publishTestResults
*/
public publishExtensionProvidedResults(results: vscode.TestResults, persist: boolean): void {
public publishExtensionProvidedResults(results: vscode.TestRunResult, persist: boolean): void {
this.proxy.$publishExtensionProvidedResults(Convert.TestResults.from(generateUuid(), results), persist);
}
@@ -259,20 +259,35 @@ export class ExtHostTesting implements ExtHostTestingShape {
return;
}
const isExcluded = (test: vscode.TestItem) => {
// for test providers that don't support excluding natively,
// make sure not to report excluded result otherwise summaries will be off.
for (const [tree, exclude] of excludeTests) {
const e = tree.comparePositions(exclude, test.id);
if (e === TestPosition.IsChild || e === TestPosition.IsSame) {
return true;
}
}
return false;
};
try {
await provider.runTests({
setState: (test, state) => {
// for test providers that don't support excluding natively,
// make sure not to report excluded result otherwise summaries will be off.
for (const [tree, exclude] of excludeTests) {
const e = tree.comparePositions(exclude, test.id);
if (e === TestPosition.IsChild || e === TestPosition.IsSame) {
return;
}
appendOutput() {
// todo
},
appendMessage: (test, message) => {
if (!isExcluded(test)) {
this.flushCollectionDiffs();
this.proxy.$appendTestMessageInRun(req.runId, test.id, Convert.TestMessage.from(message));
}
},
setState: (test, state, duration) => {
if (!isExcluded(test)) {
this.flushCollectionDiffs();
this.proxy.$updateTestStateInRun(req.runId, test.id, state, duration);
}
this.flushCollectionDiffs();
this.proxy.$updateTestStateInRun(req.runId, test.id, Convert.TestState.from(state));
},
tests: includeTests.map(t => TestItemFilteredWrapper.unwrap(t.actual)),
exclude: excludeTests.map(([, t]) => TestItemFilteredWrapper.unwrap(t.actual)),
@@ -464,7 +479,7 @@ class MirroredChangeCollector extends IncrementalChangeCollector<MirroredCollect
return this.added.size === 0 && this.removed.size === 0 && this.updated.size === 0;
}
constructor(private readonly emitter: Emitter<vscode.TestChangeEvent>) {
constructor(private readonly emitter: Emitter<vscode.TestsChangeEvent>) {
super();
}
@@ -507,7 +522,7 @@ class MirroredChangeCollector extends IncrementalChangeCollector<MirroredCollect
/**
* @override
*/
public getChangeEvent(): vscode.TestChangeEvent {
public getChangeEvent(): vscode.TestsChangeEvent {
const { added, updated, removed } = this;
return {
get added() { return [...added].map(n => n.revived); },
@@ -528,7 +543,7 @@ class MirroredChangeCollector extends IncrementalChangeCollector<MirroredCollect
* @private
*/
export class MirroredTestCollection extends AbstractIncrementalTestCollection<MirroredCollectionTestItem> {
private changeEmitter = new Emitter<vscode.TestChangeEvent>();
private changeEmitter = new Emitter<vscode.TestsChangeEvent>();
/**
* Change emitter that fires with the same sematics as `TestObserver.onDidChangeTests`.

View File

@@ -28,7 +28,7 @@ import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebo
import { EditorGroupColumn, SaveReason } from 'vs/workbench/common/editor';
import * as notebooks from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as search from 'vs/workbench/contrib/search/common/search';
import { ISerializedTestResults, ITestItem, ITestMessage, ITestState, SerializedTestResultItem, TestItemExpandState } from 'vs/workbench/contrib/testing/common/testCollection';
import { ISerializedTestResults, ITestItem, ITestMessage, SerializedTestResultItem, TestItemExpandState } from 'vs/workbench/contrib/testing/common/testCollection';
import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import type * as vscode from 'vscode';
import * as types from './extHostTypes';
@@ -1630,23 +1630,6 @@ export namespace NotebookDocumentContentOptions {
}
}
export namespace TestState {
export function from(item: vscode.TestState): ITestState {
return {
state: item.state,
duration: item.duration,
messages: item.messages.map(TestMessage.from),
};
}
export function to(item: ITestState): vscode.TestState {
const ts = new types.TestState(item.state);
ts.duration = item.duration;
ts.messages = item.messages.map(TestMessage.to);
return ts;
}
}
export namespace TestMessage {
export function from(message: vscode.TestMessage): ITestMessage {
return {
@@ -1720,7 +1703,7 @@ export namespace TestItem {
}
export namespace TestResults {
export function from(id: string, results: vscode.TestResults): ISerializedTestResults {
export function from(id: string, results: vscode.TestRunResult): ISerializedTestResults {
const serialized: ISerializedTestResults = {
completedAt: results.completedAt,
id,
@@ -1736,9 +1719,13 @@ export namespace TestResults {
for (const item of children) {
const serializedItem: SerializedTestResultItem = {
children: item.children?.map(c => c.id) ?? [],
computedState: item.result.state,
computedState: item.state,
item: TestItem.fromResultSnapshot(item),
state: TestState.from(item.result),
state: {
state: item.state,
duration: item.duration,
messages: item.messages.map(TestMessage.from),
},
retired: undefined,
expand: TestItemExpandState.Expanded,
parent: parent?.item.extId ?? null,
@@ -1758,14 +1745,16 @@ export namespace TestResults {
const convertTestResultItem = (item: SerializedTestResultItem, byInternalId: Map<string, SerializedTestResultItem>): vscode.TestResultSnapshot => ({
...TestItem.toPlain(item.item),
result: TestState.to(item.state),
state: item.state.state,
duration: item.state.duration,
messages: item.state.messages.map(TestMessage.to),
children: item.children
.map(c => byInternalId.get(c))
.filter(isDefined)
.map(c => convertTestResultItem(c, byInternalId)),
});
export function to(serialized: ISerializedTestResults): vscode.TestResults {
export function to(serialized: ISerializedTestResults): vscode.TestRunResult {
const roots: SerializedTestResultItem[] = [];
const byInternalId = new Map<string, SerializedTestResultItem>();
for (const item of serialized.items) {

View File

@@ -3239,7 +3239,7 @@ export class LinkedEditingRanges {
}
//#region Testing
export enum TestResult {
export enum TestResultState {
Unset = 0,
Queued = 1,
Running = 2,
@@ -3384,13 +3384,6 @@ export class TestItem implements vscode.TestItem {
}
}
export class TestState implements vscode.TestState {
public messages: TestMessage[] = [];
public duration?: number;
constructor(public state: TestResult) { }
}
export class TestMessage implements vscode.TestMessage {
public severity = TestMessageSeverity.Error;
public expectedOutput?: string;