chore(vscode): update to 1.55.2

This commit is contained in:
Akash Satheesan
2021-04-09 11:32:27 +05:30
1102 changed files with 39988 additions and 23544 deletions

View File

@@ -280,15 +280,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
disposables.push(extHost.registerDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.DefinitionProvider>{
provideDefinition(doc: any): any {
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.DefinitionProvider>{
provideDefinition(doc: any): any {
// duplicate result will get removed
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.DefinitionProvider>{
provideDefinition(doc: any): any {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(2, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(3, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(4, 0, 0, 0)),
];
}
}));
@@ -309,7 +315,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
provideDefinition(doc: any): (vscode.Location | vscode.LocationLink)[] {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
{ targetUri: doc.uri, targetRange: new types.Range(0, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
{ targetUri: doc.uri, targetRange: new types.Range(1, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
];
}
}));
@@ -338,15 +344,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
disposables.push(extHost.registerDeclarationProvider(nullExtensionDescription, defaultSelector, <vscode.DeclarationProvider>{
provideDeclaration(doc: any): any {
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerDeclarationProvider(nullExtensionDescription, defaultSelector, <vscode.DeclarationProvider>{
provideDeclaration(doc: any): any {
// duplicate result will get removed
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerDeclarationProvider(nullExtensionDescription, defaultSelector, <vscode.DeclarationProvider>{
provideDeclaration(doc: any): any {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(2, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(3, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(4, 0, 0, 0)),
];
}
}));
@@ -367,7 +379,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
provideDeclaration(doc: any): (vscode.Location | vscode.LocationLink)[] {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
{ targetUri: doc.uri, targetRange: new types.Range(0, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
{ targetUri: doc.uri, targetRange: new types.Range(1, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
];
}
}));
@@ -407,15 +419,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
disposables.push(extHost.registerTypeDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.TypeDefinitionProvider>{
provideTypeDefinition(doc: any): any {
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerTypeDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.TypeDefinitionProvider>{
provideTypeDefinition(doc: any): any {
// duplicate result will get removed
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerTypeDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.TypeDefinitionProvider>{
provideTypeDefinition(doc: any): any {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(2, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(3, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(4, 0, 0, 0)),
];
}
}));
@@ -436,7 +454,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
provideTypeDefinition(doc: any): (vscode.Location | vscode.LocationLink)[] {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
{ targetUri: doc.uri, targetRange: new types.Range(0, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
{ targetUri: doc.uri, targetRange: new types.Range(1, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
];
}
}));
@@ -476,15 +494,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
disposables.push(extHost.registerImplementationProvider(nullExtensionDescription, defaultSelector, <vscode.ImplementationProvider>{
provideImplementation(doc: any): any {
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerImplementationProvider(nullExtensionDescription, defaultSelector, <vscode.ImplementationProvider>{
provideImplementation(doc: any): any {
// duplicate result will get removed
return new types.Location(doc.uri, new types.Range(1, 0, 0, 0));
}
}));
disposables.push(extHost.registerImplementationProvider(nullExtensionDescription, defaultSelector, <vscode.ImplementationProvider>{
provideImplementation(doc: any): any {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(2, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(3, 0, 0, 0)),
new types.Location(doc.uri, new types.Range(4, 0, 0, 0)),
];
}
}));
@@ -505,7 +529,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
provideImplementation(doc: any): (vscode.Location | vscode.LocationLink)[] {
return [
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
{ targetUri: doc.uri, targetRange: new types.Range(0, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
{ targetUri: doc.uri, targetRange: new types.Range(1, 0, 0, 0), targetSelectionRange: new types.Range(1, 1, 1, 1), originSelectionRange: new types.Range(2, 2, 2, 2) }
];
}
}));

View File

@@ -40,7 +40,7 @@ suite('ExtHostBulkEdits.applyWorkspaceEdit', () => {
EOL: '\n',
}]
});
bulkEdits = new ExtHostBulkEdits(rpcProtocol, documentsAndEditors, null!);
bulkEdits = new ExtHostBulkEdits(rpcProtocol, documentsAndEditors);
});
test('uses version id if document available', async () => {

View File

@@ -259,7 +259,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider {
provideDefinition(): any {
return new types.Location(model.uri, new types.Range(1, 1, 1, 1));
return new types.Location(model.uri, new types.Range(2, 1, 1, 1));
}
}));
@@ -268,7 +268,7 @@ suite('ExtHostLanguageFeatures', function () {
assert.strictEqual(value.length, 2);
});
test('Definition, registration order', async () => {
test('Definition, registration order ignored (results are sorted)', async () => {
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider {
provideDefinition(): any {
@@ -286,8 +286,8 @@ suite('ExtHostLanguageFeatures', function () {
const value = await getDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None);
assert.strictEqual(value.length, 2);
// let [first, second] = value;
assert.strictEqual(value[0].uri.authority, 'second');
assert.strictEqual(value[1].uri.authority, 'first');
assert.strictEqual(value[0].uri.authority, 'first');
assert.strictEqual(value[1].uri.authority, 'second');
});
test('Definition, evil provider', async () => {
@@ -521,7 +521,7 @@ suite('ExtHostLanguageFeatures', function () {
// --- references
test('References, registration order', async () => {
test('References, registration order ignored (results are sorted)', async () => {
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider {
provideReferences(): any {
@@ -539,8 +539,8 @@ suite('ExtHostLanguageFeatures', function () {
let value = await getReferencesAtPosition(model, new EditorPosition(1, 2), false, CancellationToken.None);
assert.strictEqual(value.length, 2);
let [first, second] = value;
assert.strictEqual(first.uri.path, '/second');
assert.strictEqual(second.uri.path, '/first');
assert.strictEqual(first.uri.path, '/first');
assert.strictEqual(second.uri.path, '/second');
});
test('References, data conversion', async () => {
@@ -591,7 +591,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Invoke }, Progress.None, CancellationToken.None);
assert.strictEqual(actions.length, 2);
const [first, second] = actions;
assert.strictEqual(first.action.title, 'Testing1');
@@ -615,7 +615,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Invoke }, Progress.None, CancellationToken.None);
assert.strictEqual(actions.length, 1);
const [first] = actions;
assert.strictEqual(first.action.title, 'Testing1');
@@ -638,7 +638,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Invoke }, Progress.None, CancellationToken.None);
assert.strictEqual(actions.length, 1);
});
@@ -656,7 +656,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Invoke }, Progress.None, CancellationToken.None);
assert.strictEqual(actions.length, 1);
});

View File

@@ -11,6 +11,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { mock } from 'vs/base/test/common/mock';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { Event } from 'vs/base/common/event';
const emptyDialogService = new class implements IDialogService {
declare readonly _serviceBrand: undefined;
@@ -42,6 +43,8 @@ const emptyCommandService: ICommandService = {
const emptyNotificationService = new class implements INotificationService {
declare readonly _serviceBrand: undefined;
onDidAddNotification: Event<INotification> = Event.None;
onDidRemoveNotification: Event<INotification> = Event.None;
notify(...args: any[]): never {
throw new Error('not implemented');
}
@@ -71,6 +74,8 @@ class EmptyNotificationService implements INotificationService {
constructor(private withNotify: (notification: INotification) => void) {
}
onDidAddNotification: Event<INotification> = Event.None;
onDidRemoveNotification: Event<INotification> = Event.None;
notify(notification: INotification): INotificationHandle {
this.withNotify(notification);

View File

@@ -13,7 +13,7 @@ import { mock } from 'vs/base/test/common/mock';
import { IModelAddedData, MainContext, MainThreadCommandsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { ExtHostNotebookDocument } from 'vs/workbench/api/common/extHostNotebookDocument';
import { CellKind, CellUri, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, CellUri, NotebookCellExecutionState, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
@@ -54,7 +54,7 @@ suite('NotebookCell#Document', function () {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
@@ -80,7 +80,6 @@ suite('NotebookCell#Document', function () {
cellKind: CellKind.Code,
outputs: [],
}],
contentOptions: { transientMetadata: {}, transientOutputs: false }
}],
addedEditors: [{
documentUri: notebookUri,
@@ -104,16 +103,16 @@ suite('NotebookCell#Document', function () {
assert.strictEqual(notebook.notebookDocument.cells.length, 2);
const [c1, c2] = notebook.notebookDocument.cells;
const d1 = extHostDocuments.getDocument(c1.uri);
const d1 = extHostDocuments.getDocument(c1.document.uri);
assert.ok(d1);
assert.strictEqual(d1.languageId, c1.language);
assert.strictEqual(d1.languageId, c1.document.languageId);
assert.strictEqual(d1.version, 1);
assert.ok(d1.notebook === notebook.notebookDocument);
const d2 = extHostDocuments.getDocument(c2.uri);
const d2 = extHostDocuments.getDocument(c2.document.uri);
assert.ok(d2);
assert.strictEqual(d2.languageId, c2.language);
assert.strictEqual(d2.languageId, c2.document.languageId);
assert.strictEqual(d2.version, 1);
assert.ok(d2.notebook === notebook.notebookDocument);
});
@@ -121,8 +120,8 @@ suite('NotebookCell#Document', function () {
test('cell document goes when notebook closes', async function () {
const cellUris: string[] = [];
for (let cell of notebook.notebookDocument.cells) {
assert.ok(extHostDocuments.getDocument(cell.uri));
cellUris.push(cell.uri.toString());
assert.ok(extHostDocuments.getDocument(cell.document.uri));
cellUris.push(cell.document.uri.toString());
}
const removedCellUris: string[] = [];
@@ -147,11 +146,11 @@ suite('NotebookCell#Document', function () {
const [first, second] = e.changes[0].items;
const doc1 = extHostDocuments.getAllDocumentData().find(data => isEqual(data.document.uri, first.uri));
const doc1 = extHostDocuments.getAllDocumentData().find(data => isEqual(data.document.uri, first.document.uri));
assert.ok(doc1);
assert.strictEqual(doc1?.document === first.document, true);
const doc2 = extHostDocuments.getAllDocumentData().find(data => isEqual(data.document.uri, second.uri));
const doc2 = extHostDocuments.getAllDocumentData().find(data => isEqual(data.document.uri, second.document.uri));
assert.ok(doc2);
assert.strictEqual(doc2?.document === second.document, true);
@@ -198,9 +197,9 @@ suite('NotebookCell#Document', function () {
const docs: vscode.TextDocument[] = [];
const addData: IModelAddedData[] = [];
for (let cell of notebook.notebookDocument.cells) {
const doc = extHostDocuments.getDocument(cell.uri);
const doc = extHostDocuments.getDocument(cell.document.uri);
assert.ok(doc);
assert.strictEqual(extHostDocuments.getDocument(cell.uri).isClosed, false);
assert.strictEqual(extHostDocuments.getDocument(cell.document.uri).isClosed, false);
docs.push(doc);
addData.push({
EOL: '\n',
@@ -220,14 +219,14 @@ suite('NotebookCell#Document', function () {
// notebook is still open -> cell documents stay open
for (let cell of notebook.notebookDocument.cells) {
assert.ok(extHostDocuments.getDocument(cell.uri));
assert.strictEqual(extHostDocuments.getDocument(cell.uri).isClosed, false);
assert.ok(extHostDocuments.getDocument(cell.document.uri));
assert.strictEqual(extHostDocuments.getDocument(cell.document.uri).isClosed, false);
}
// close notebook -> docs are closed
extHostNotebooks.$acceptDocumentAndEditorsDelta({ removedDocuments: [notebook.uri] });
for (let cell of notebook.notebookDocument.cells) {
assert.throws(() => extHostDocuments.getDocument(cell.uri));
assert.throws(() => extHostDocuments.getDocument(cell.document.uri));
}
for (let doc of docs) {
assert.strictEqual(doc.isClosed, true);
@@ -253,7 +252,7 @@ suite('NotebookCell#Document', function () {
assert.strictEqual(cell1.document.isClosed, true); // ref still alive!
assert.strictEqual(cell2.document.isClosed, false);
assert.throws(() => extHostDocuments.getDocument(cell1.uri));
assert.throws(() => extHostDocuments.getDocument(cell1.document.uri));
});
test('cell document knows notebook', function () {
@@ -353,4 +352,90 @@ suite('NotebookCell#Document', function () {
assert.strictEqual(event.changes[0].items[0].document.isClosed, false);
assert.strictEqual(event.changes[0].items[1].document.isClosed, false);
});
test('Opening a notebook results in VS Code firing the event onDidChangeActiveNotebookEditor twice #118470', function () {
let count = 0;
extHostNotebooks.onDidChangeActiveNotebookEditor(() => count += 1);
extHostNotebooks.$acceptDocumentAndEditorsDelta({
addedEditors: [{
documentUri: notebookUri,
id: '_notebook_editor_2',
selections: [{ start: 0, end: 1 }],
visibleRanges: []
}]
});
extHostNotebooks.$acceptDocumentAndEditorsDelta({
newActiveEditor: '_notebook_editor_2'
});
assert.strictEqual(count, 1);
});
test('unset active notebook editor', function () {
const editor = extHostNotebooks.activeNotebookEditor;
assert.ok(editor !== undefined);
extHostNotebooks.$acceptDocumentAndEditorsDelta({ newActiveEditor: undefined });
assert.ok(extHostNotebooks.activeNotebookEditor === editor);
extHostNotebooks.$acceptDocumentAndEditorsDelta({});
assert.ok(extHostNotebooks.activeNotebookEditor === editor);
extHostNotebooks.$acceptDocumentAndEditorsDelta({ newActiveEditor: null });
assert.ok(extHostNotebooks.activeNotebookEditor === undefined);
});
test('change cell language triggers onDidChange events', async function () {
const [first] = notebook.notebookDocument.cells;
assert.strictEqual(first.document.languageId, 'markdown');
const removed = Event.toPromise(extHostDocuments.onDidRemoveDocument);
const added = Event.toPromise(extHostDocuments.onDidAddDocument);
extHostNotebooks.$acceptModelChanged(notebook.uri, {
versionId: 12, rawEvents: [{
kind: NotebookCellsChangeType.ChangeLanguage,
index: 0,
language: 'fooLang'
}]
}, false);
const removedDoc = await removed;
const addedDoc = await added;
assert.strictEqual(first.document.languageId, 'fooLang');
assert.ok(removedDoc === addedDoc);
});
test('change cell execution state does not trigger onDidChangeMetadata event', async function () {
let didFireOnDidChangeMetadata = false;
let e = extHostNotebooks.onDidChangeCellMetadata(() => {
didFireOnDidChangeMetadata = true;
});
const changeExeState = Event.toPromise(extHostNotebooks.onDidChangeNotebookCellExecutionState);
extHostNotebooks.$acceptModelChanged(notebook.uri, {
versionId: 12, rawEvents: [{
kind: NotebookCellsChangeType.ChangeCellMetadata,
index: 0,
metadata: {
...notebook.getCellFromIndex(0)?.internalMetadata,
...{
runState: NotebookCellExecutionState.Executing
}
}
}]
}, false);
await changeExeState;
assert.strictEqual(didFireOnDidChangeMetadata, false);
e.dispose();
});
});

View File

@@ -51,7 +51,7 @@ suite('NotebookConcatDocument', function () {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
@@ -68,7 +68,6 @@ suite('NotebookConcatDocument', function () {
cellKind: CellKind.Markdown,
outputs: [],
}],
contentOptions: { transientOutputs: false, transientMetadata: {} },
versionId: 0
}],
addedEditors: [
@@ -194,11 +193,11 @@ suite('NotebookConcatDocument', function () {
let doc = new ExtHostNotebookConcatDocument(extHostNotebooks, extHostDocuments, notebook.notebookDocument, undefined);
assertLines(doc, 'Hello', 'World', 'Hello World!', 'Hallo', 'Welt', 'Hallo Welt!');
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(0, 0)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 3)));
assertLocation(doc, new Position(5, 11), new Location(notebook.notebookDocument.cells[1].uri, new Position(2, 11)));
assertLocation(doc, new Position(5, 12), new Location(notebook.notebookDocument.cells[1].uri, new Position(2, 11)), false); // don't check identity because position will be clamped
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(0, 0)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 3)));
assertLocation(doc, new Position(5, 11), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(2, 11)));
assertLocation(doc, new Position(5, 12), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(2, 11)), false); // don't check identity because position will be clamped
});
@@ -228,9 +227,9 @@ suite('NotebookConcatDocument', function () {
assert.strictEqual(doc.version, 1);
assertLines(doc, 'Hello', 'World', 'Hello World!');
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 2)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 12)), false); // clamped
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 2)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 12)), false); // clamped
// UPDATE 2
@@ -255,11 +254,11 @@ suite('NotebookConcatDocument', function () {
assert.strictEqual(notebook.notebookDocument.cells.length, 1 + 2);
assert.strictEqual(doc.version, 2);
assertLines(doc, 'Hello', 'World', 'Hello World!', 'Hallo', 'Welt', 'Hallo Welt!');
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(0, 0)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 3)));
assertLocation(doc, new Position(5, 11), new Location(notebook.notebookDocument.cells[1].uri, new Position(2, 11)));
assertLocation(doc, new Position(5, 12), new Location(notebook.notebookDocument.cells[1].uri, new Position(2, 11)), false); // don't check identity because position will be clamped
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(0, 0)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 3)));
assertLocation(doc, new Position(5, 11), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(2, 11)));
assertLocation(doc, new Position(5, 12), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(2, 11)), false); // don't check identity because position will be clamped
// UPDATE 3 (remove cell #2 again)
extHostNotebooks.$acceptModelChanged(notebookUri, {
@@ -274,9 +273,9 @@ suite('NotebookConcatDocument', function () {
assert.strictEqual(notebook.notebookDocument.cells.length, 1 + 1);
assert.strictEqual(doc.version, 3);
assertLines(doc, 'Hello', 'World', 'Hello World!');
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 2)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 12)), false); // clamped
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 2)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 12)), false); // clamped
});
test('location, position mapping, cell-document changes', function () {
@@ -314,17 +313,17 @@ suite('NotebookConcatDocument', function () {
assert.strictEqual(doc.version, 1);
assertLines(doc, 'Hello', 'World', 'Hello World!', 'Hallo', 'Welt', 'Hallo Welt!');
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 2)));
assertLocation(doc, new Position(2, 12), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 12)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].uri, new Position(1, 3)));
assertLocation(doc, new Position(0, 0), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(0, 0)));
assertLocation(doc, new Position(2, 2), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 2)));
assertLocation(doc, new Position(2, 12), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 12)));
assertLocation(doc, new Position(4, 0), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 0)));
assertLocation(doc, new Position(4, 3), new Location(notebook.notebookDocument.cells[1].document.uri, new Position(1, 3)));
// offset math
let cell1End = doc.offsetAt(new Position(2, 12));
assert.strictEqual(doc.positionAt(cell1End).isEqual(new Position(2, 12)), true);
extHostDocuments.$acceptModelChanged(notebook.notebookDocument.cells[0].uri, {
extHostDocuments.$acceptModelChanged(notebook.notebookDocument.cells[0].document.uri, {
versionId: 0,
eol: '\n',
changes: [{
@@ -335,7 +334,7 @@ suite('NotebookConcatDocument', function () {
}]
}, false);
assertLines(doc, 'Hello', 'World', 'Hi World!', 'Hallo', 'Welt', 'Hallo Welt!');
assertLocation(doc, new Position(2, 12), new Location(notebook.notebookDocument.cells[0].uri, new Position(2, 9)), false);
assertLocation(doc, new Position(2, 12), new Location(notebook.notebookDocument.cells[0].document.uri, new Position(2, 9)), false);
assert.strictEqual(doc.positionAt(cell1End).isEqual(new Position(3, 2)), true);
@@ -503,12 +502,12 @@ suite('NotebookConcatDocument', function () {
let doc = new ExtHostNotebookConcatDocument(extHostNotebooks, extHostDocuments, notebook.notebookDocument, undefined);
assertLines(doc, 'Hello', 'World', 'Hello World!', 'Hallo', 'Welt', 'Hallo Welt!');
assertLocationAtPosition(doc, { line: 0, character: 0 }, { uri: notebook.notebookDocument.cells[0].uri, line: 0, character: 0 });
assertLocationAtPosition(doc, { line: 2, character: 0 }, { uri: notebook.notebookDocument.cells[0].uri, line: 2, character: 0 });
assertLocationAtPosition(doc, { line: 2, character: 12 }, { uri: notebook.notebookDocument.cells[0].uri, line: 2, character: 12 });
assertLocationAtPosition(doc, { line: 3, character: 0 }, { uri: notebook.notebookDocument.cells[1].uri, line: 0, character: 0 });
assertLocationAtPosition(doc, { line: 5, character: 0 }, { uri: notebook.notebookDocument.cells[1].uri, line: 2, character: 0 });
assertLocationAtPosition(doc, { line: 5, character: 11 }, { uri: notebook.notebookDocument.cells[1].uri, line: 2, character: 11 });
assertLocationAtPosition(doc, { line: 0, character: 0 }, { uri: notebook.notebookDocument.cells[0].document.uri, line: 0, character: 0 });
assertLocationAtPosition(doc, { line: 2, character: 0 }, { uri: notebook.notebookDocument.cells[0].document.uri, line: 2, character: 0 });
assertLocationAtPosition(doc, { line: 2, character: 12 }, { uri: notebook.notebookDocument.cells[0].document.uri, line: 2, character: 12 });
assertLocationAtPosition(doc, { line: 3, character: 0 }, { uri: notebook.notebookDocument.cells[1].document.uri, line: 0, character: 0 });
assertLocationAtPosition(doc, { line: 5, character: 0 }, { uri: notebook.notebookDocument.cells[1].document.uri, line: 2, character: 0 });
assertLocationAtPosition(doc, { line: 5, character: 11 }, { uri: notebook.notebookDocument.cells[1].document.uri, line: 2, character: 11 });
});
test('getText(range)', function () {

View File

@@ -52,7 +52,7 @@ suite('NotebookKernel', function () {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
@@ -81,7 +81,6 @@ suite('NotebookKernel', function () {
cellKind: CellKind.Code,
outputs: [],
}],
contentOptions: { transientOutputs: false, transientMetadata: {} },
versionId: 0
}],
addedEditors: [

View File

@@ -4,52 +4,47 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { MirroredTestCollection, TestItemFilteredWrapper } from 'vs/workbench/api/common/extHostTesting';
import * as convert from 'vs/workbench/api/common/extHostTypeConverters';
import { TestDiffOpType } from 'vs/workbench/contrib/testing/common/testCollection';
import { TestDiffOpType, TestItemExpandState } from 'vs/workbench/contrib/testing/common/testCollection';
import { stubTest, testStubs } from 'vs/workbench/contrib/testing/common/testStubs';
import { TestOwnedTestCollection, TestSingleUseCollection } from 'vs/workbench/contrib/testing/test/common/ownedTestCollection';
import { TestChangeEvent, TestItem, TextDocument } from 'vscode';
import { URI } from 'vs/base/common/uri';
import { Location } from 'vs/editor/common/modes';
import { Range } from 'vs/editor/common/core/range';
import { TestItem } from 'vscode';
const simplify = (item: TestItem) => {
if ('toJSON' in item) {
item = (item as any).toJSON();
delete (item as any).providerId;
delete (item as any).testId;
}
const simplify = (item: TestItem) => ({
id: item.id,
label: item.label,
uri: item.uri,
range: item.range,
runnable: item.runnable,
debuggable: item.debuggable,
});
return { ...item, children: undefined };
};
const assertTreesEqual = (a: Readonly<TestItem>, b: Readonly<TestItem>) => {
const assertTreesEqual = (a: TestItem, b: TestItem) => {
assert.deepStrictEqual(simplify(a), simplify(b));
const aChildren = (a.children ?? []).sort();
const bChildren = (b.children ?? []).sort();
const aChildren = [...a.children].slice().sort();
const bChildren = [...b.children].slice().sort();
assert.strictEqual(aChildren.length, bChildren.length, `expected ${a.label}.children.length == ${b.label}.children.length`);
aChildren.forEach((_, i) => assertTreesEqual(aChildren[i], bChildren[i]));
};
const assertTreeListEqual = (a: ReadonlyArray<Readonly<TestItem>>, b: ReadonlyArray<Readonly<TestItem>>) => {
assert.strictEqual(a.length, b.length, `expected a.length == n.length`);
a.forEach((_, i) => assertTreesEqual(a[i], b[i]));
};
// const assertTreeListEqual = (a: ReadonlyArray<TestItem>, b: ReadonlyArray<TestItem>) => {
// assert.strictEqual(a.length, b.length, `expected a.length == n.length`);
// a.forEach((_, i) => assertTreesEqual(a[i], b[i]));
// };
class TestMirroredCollection extends MirroredTestCollection {
public changeEvent!: TestChangeEvent;
// class TestMirroredCollection extends MirroredTestCollection {
// public changeEvent!: TestChangeEvent;
constructor() {
super();
this.onDidChangeTests(evt => this.changeEvent = evt);
}
// constructor() {
// super();
// this.onDidChangeTests(evt => this.changeEvent = evt);
// }
public get length() {
return this.items.size;
}
}
// public get length() {
// return this.items.size;
// }
// }
suite('ExtHost Testing', () => {
let single: TestSingleUseCollection;
@@ -68,12 +63,40 @@ suite('ExtHost Testing', () => {
test('adds a root recursively', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
single.expand('id-root', Infinity);
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Add, { providerId: 'pid', parent: null, item: convert.TestItem.from(stubTest('root')) }],
[TestDiffOpType.Add, { providerId: 'pid', parent: 'id-root', item: convert.TestItem.from(stubTest('a')) }],
[TestDiffOpType.Add, { providerId: 'pid', parent: 'id-a', item: convert.TestItem.from(stubTest('aa')) }],
[TestDiffOpType.Add, { providerId: 'pid', parent: 'id-a', item: convert.TestItem.from(stubTest('ab')) }],
[TestDiffOpType.Add, { providerId: 'pid', parent: 'id-root', item: convert.TestItem.from(stubTest('b')) }],
[
TestDiffOpType.Add,
{ src: { tree: 0, provider: 'pid' }, parent: null, expand: TestItemExpandState.BusyExpanding, item: { ...convert.TestItem.from(stubTest('root')), expandable: true } }
],
[
TestDiffOpType.Add,
{ src: { tree: 0, provider: 'pid' }, parent: 'id-root', expand: TestItemExpandState.Expandable, item: { ...convert.TestItem.from(stubTest('a')), expandable: true } }
],
[
TestDiffOpType.Add,
{ src: { tree: 0, provider: 'pid' }, parent: 'id-root', expand: TestItemExpandState.NotExpandable, item: convert.TestItem.from(stubTest('b')) }
],
[
TestDiffOpType.Update,
{ extId: 'id-root', expand: TestItemExpandState.Expanded }
],
[
TestDiffOpType.Update,
{ extId: 'id-a', expand: TestItemExpandState.BusyExpanding }
],
[
TestDiffOpType.Add,
{ src: { tree: 0, provider: 'pid' }, parent: 'id-a', expand: TestItemExpandState.NotExpandable, item: convert.TestItem.from(stubTest('aa')) }
],
[
TestDiffOpType.Add,
{ src: { tree: 0, provider: 'pid' }, parent: 'id-a', expand: TestItemExpandState.NotExpandable, item: convert.TestItem.from(stubTest('ab')) }
],
[
TestDiffOpType.Update,
{ extId: 'id-a', expand: TestItemExpandState.Expanded }
],
]);
});
@@ -87,23 +110,23 @@ suite('ExtHost Testing', () => {
test('watches property mutations', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
single.expand('id-root', Infinity);
single.collectDiff();
tests.children![0].description = 'Hello world'; /* item a */
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Update, { parent: 'id-root', providerId: 'pid', item: convert.TestItem.from({ ...stubTest('a'), description: 'Hello world' }) }],
]);
tests.children.get('id-a')!.description = 'Hello world'; /* item a */
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), []);
assert.deepStrictEqual(single.collectDiff(), [
[
TestDiffOpType.Update,
{ extId: 'id-a', item: { description: 'Hello world' } }],
]);
});
test('removes children', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
single.expand('id-root', Infinity);
single.collectDiff();
tests.children!.splice(0, 1);
single.onItemChange(tests, 'pid');
tests.children.delete('id-a');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Remove, 'id-a'],
@@ -115,13 +138,18 @@ suite('ExtHost Testing', () => {
test('adds new children', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
single.expand('id-root', Infinity);
single.collectDiff();
const child = stubTest('ac');
tests.children![0].children!.push(child);
single.onItemChange(tests, 'pid');
tests.children.get('id-a')!.children!.add(child);
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Add, { providerId: 'pid', parent: 'id-a', item: convert.TestItem.from(child) }],
[TestDiffOpType.Add, {
src: { tree: 0, provider: 'pid' },
parent: 'id-a',
expand: TestItemExpandState.NotExpandable,
item: convert.TestItem.from(child),
}],
]);
assert.deepStrictEqual(
[...owned.idToInternal].map(n => n.item.extId).sort(),
@@ -131,277 +159,285 @@ suite('ExtHost Testing', () => {
});
});
suite('MirroredTestCollection', () => {
let m: TestMirroredCollection;
setup(() => m = new TestMirroredCollection());
test('mirrors creation of the root', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
// todo@connor4312: re-renable when we figure out what observing looks like we async children
// suite('MirroredTestCollection', () => {
// let m: TestMirroredCollection;
// setup(() => m = new TestMirroredCollection());
test('mirrors node deletion', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children!.splice(0, 1);
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// test('mirrors creation of the root', () => {
// const tests = testStubs.nested();
// single.addRoot(tests, 'pid');
// single.expand('id-root', Infinity);
// m.apply(single.collectDiff());
// assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
// assert.strictEqual(m.length, single.itemToInternal.size);
// });
assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
// test('mirrors node deletion', () => {
// const tests = testStubs.nested();
// single.addRoot(tests, 'pid');
// m.apply(single.collectDiff());
// single.expand('id-root', Infinity);
// tests.children!.splice(0, 1);
// single.onItemChange(tests, 'pid');
// single.expand('id-root', Infinity);
// m.apply(single.collectDiff());
test('mirrors node addition', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children![0].children!.push(stubTest('ac'));
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
// assert.strictEqual(m.length, single.itemToInternal.size);
// });
assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
// test('mirrors node addition', () => {
// const tests = testStubs.nested();
// single.addRoot(tests, 'pid');
// m.apply(single.collectDiff());
// tests.children![0].children!.push(stubTest('ac'));
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
test('mirrors node update', () => {
const tests = testStubs.nested();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children![0].description = 'Hello world'; /* item a */
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
// assert.strictEqual(m.length, single.itemToInternal.size);
// });
assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
});
// test('mirrors node update', () => {
// const tests = testStubs.nested();
// single.addRoot(tests, 'pid');
// m.apply(single.collectDiff());
// tests.children![0].description = 'Hello world'; /* item a */
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
suite('MirroredChangeCollector', () => {
let tests = testStubs.nested();
setup(() => {
tests = testStubs.nested();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
});
// assertTreesEqual(m.rootTestItems[0], owned.getTestById('id-root')![1].actual);
// });
test('creates change for root', () => {
assert.deepStrictEqual(m.changeEvent.commonChangeAncestor, null);
assertTreeListEqual(m.changeEvent.added, [
tests,
tests.children[0],
tests.children![0].children![0],
tests.children![0].children![1],
tests.children[1],
]);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, []);
});
// suite('MirroredChangeCollector', () => {
// let tests = testStubs.nested();
// setup(() => {
// tests = testStubs.nested();
// single.addRoot(tests, 'pid');
// m.apply(single.collectDiff());
// });
test('creates change for delete', () => {
const rm = tests.children.shift()!;
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// test('creates change for root', () => {
// assertTreeListEqual(m.changeEvent.added, [
// tests,
// tests.children[0],
// tests.children![0].children![0],
// tests.children![0].children![1],
// tests.children[1],
// ]);
// assertTreeListEqual(m.changeEvent.removed, []);
// assertTreeListEqual(m.changeEvent.updated, []);
// });
assertTreesEqual(m.changeEvent.commonChangeAncestor!, tests);
assertTreeListEqual(m.changeEvent.added, []);
assertTreeListEqual(m.changeEvent.removed, [
{ ...rm, children: [] },
{ ...rm.children![0], children: [] },
{ ...rm.children![1], children: [] },
]);
assertTreeListEqual(m.changeEvent.updated, []);
});
// test('creates change for delete', () => {
// const rm = tests.children.shift()!;
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
test('creates change for update', () => {
tests.children[0].label = 'updated!';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// assertTreeListEqual(m.changeEvent.added, []);
// assertTreeListEqual(m.changeEvent.removed, [
// { ...rm },
// { ...rm.children![0] },
// { ...rm.children![1] },
// ]);
// assertTreeListEqual(m.changeEvent.updated, []);
// });
assert.deepStrictEqual(m.changeEvent.commonChangeAncestor?.label, 'updated!');
assertTreeListEqual(m.changeEvent.added, []);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, [tests.children[0]]);
});
// test('creates change for update', () => {
// tests.children[0].label = 'updated!';
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
test('is a no-op if a node is added and removed', () => {
const nested = testStubs.nested('id2-');
tests.children.push(nested);
single.onItemChange(tests, 'pid');
tests.children.pop();
single.onItemChange(tests, 'pid');
const previousEvent = m.changeEvent;
m.apply(single.collectDiff());
assert.strictEqual(m.changeEvent, previousEvent);
});
// assertTreeListEqual(m.changeEvent.added, []);
// assertTreeListEqual(m.changeEvent.removed, []);
// assertTreeListEqual(m.changeEvent.updated, [tests.children[0]]);
// });
test('is a single-op if a node is added and changed', () => {
const child = stubTest('c');
tests.children.push(child);
single.onItemChange(tests, 'pid');
child.label = 'd';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// test('is a no-op if a node is added and removed', () => {
// const nested = testStubs.nested('id2-');
// tests.children.push(nested);
// single.onItemChange(tests, 'pid');
// tests.children.pop();
// single.onItemChange(tests, 'pid');
// const previousEvent = m.changeEvent;
// m.apply(single.collectDiff());
// assert.strictEqual(m.changeEvent, previousEvent);
// });
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'root');
assertTreeListEqual(m.changeEvent.added, [child]);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, []);
});
// test('is a single-op if a node is added and changed', () => {
// const child = stubTest('c');
// tests.children.push(child);
// single.onItemChange(tests, 'pid');
// child.label = 'd';
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
test('gets the common ancestor (1)', () => {
tests.children![0].children![0].label = 'za';
tests.children![0].children![1].label = 'zb';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// assertTreeListEqual(m.changeEvent.added, [child]);
// assertTreeListEqual(m.changeEvent.removed, []);
// assertTreeListEqual(m.changeEvent.updated, []);
// });
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'a');
});
// test('gets the common ancestor (1)', () => {
// tests.children![0].children![0].label = 'za';
// tests.children![0].children![1].label = 'zb';
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
test('gets the common ancestor (2)', () => {
tests.children![0].children![0].label = 'za';
tests.children![1].label = 'ab';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
// });
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'root');
});
});
// test('gets the common ancestor (2)', () => {
// tests.children![0].children![0].label = 'za';
// tests.children![1].label = 'ab';
// single.onItemChange(tests, 'pid');
// m.apply(single.collectDiff());
// });
// });
suite('TestItemFilteredWrapper', () => {
const stubTestWithLocation = (label: string, location: Location): TestItem => {
const t = stubTest(label);
t.location = location as any;
return t;
};
// suite('TestItemFilteredWrapper', () => {
// const stubTestWithLocation = (label: string, location: Location, children: StubTestItem[] = []) => {
// const t = stubTest(label, undefined, children);
// t.location = location as any;
// return t;
// };
const location1: Location = {
range: new Range(0, 0, 0, 0),
uri: URI.parse('file:///foo.ts')
};
// const location1: Location = {
// range: new Range(0, 0, 0, 0),
// uri: URI.parse('file:///foo.ts')
// };
const location2: Location = {
range: new Range(0, 0, 0, 0),
uri: URI.parse('file:///bar.ts')
};
// const location2: Location = {
// range: new Range(0, 0, 0, 0),
// uri: URI.parse('file:///bar.ts')
// };
const location3: Location = {
range: new Range(0, 0, 0, 0),
uri: URI.parse('file:///baz.ts')
};
// const location3: Location = {
// range: new Range(0, 0, 0, 0),
// uri: URI.parse('file:///baz.ts')
// };
const textDocumentFilter = {
uri: location1.uri
} as TextDocument;
// const textDocumentFilter = {
// uri: location1.uri
// } as TextDocument;
let testsWithLocation: TestItem;
setup(() => {
testsWithLocation = {
...stubTest('root'),
children: [
{
...stubTestWithLocation('a', location1),
children: [stubTestWithLocation('aa', location1), stubTestWithLocation('ab', location1)]
},
{
...stubTestWithLocation('b', location2),
children: [stubTestWithLocation('ba', location2), stubTestWithLocation('bb', location2)]
},
{
...stubTestWithLocation('b', location3),
}
],
};
});
// let testsWithLocation: StubTestItem;
// let hierarchy: TestHierarchy<TestItemFilteredWrapper>;
// setup(async () => {
// testsWithLocation =
// stubTest('root', undefined, [
// stubTestWithLocation('a', location1, [stubTestWithLocation('aa', location1), stubTestWithLocation('ab', location1)]),
// stubTestWithLocation('b', location2, [stubTestWithLocation('ba', location2), stubTestWithLocation('bb', location2)]),
// stubTestWithLocation('b', location3),
// ]);
teardown(() => {
TestItemFilteredWrapper.removeFilter(textDocumentFilter);
});
// hierarchy = (await createDefaultDocumentTestHierarchy<StubTestItem>(
// {
// provideWorkspaceTestHierarchy: () => ({
// getChildren.getChildren,
// getParent.getParent,
// onDidChangeTest: new Emitter<StubTestItem>().event,
// root: testsWithLocation
// }),
// runTests() {
// throw new Error('no implemented');
// }
// },
// textDocumentFilter,
// undefined,
// CancellationToken.None
// ))!;
// });
test('gets all actual properties', () => {
const testItem: TestItem = stubTest('test1');
const wrapper: TestItemFilteredWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testItem, textDocumentFilter);
// teardown(() => {
// TestItemFilteredWrapper.removeFilter(textDocumentFilter);
// });
assert.strictEqual(testItem.debuggable, wrapper.debuggable);
assert.strictEqual(testItem.description, wrapper.description);
assert.strictEqual(testItem.label, wrapper.label);
assert.strictEqual(testItem.location, wrapper.location);
assert.strictEqual(testItem.runnable, wrapper.runnable);
});
// test('gets all actual properties', () => {
// const testItem: TestItem = stubTest('test1');
// const wrapper: TestItemFilteredWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testItem, textDocumentFilter);
test('gets no children if nothing matches Uri filter', () => {
let tests: TestItem = testStubs.nested();
const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(tests, textDocumentFilter);
assert.strictEqual(wrapper.children.length, 0);
});
// assert.strictEqual(testItem.debuggable, wrapper.debuggable);
// assert.strictEqual(testItem.description, wrapper.description);
// assert.strictEqual(testItem.label, wrapper.label);
// assert.strictEqual(testItem.location, wrapper.location);
// assert.strictEqual(testItem.runnable, wrapper.runnable);
// });
test('filter is applied to children', () => {
const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
assert.strictEqual(wrapper.label, 'root');
assert.strictEqual(wrapper.children.length, 1);
assert.strictEqual(wrapper.children[0] instanceof TestItemFilteredWrapper, true);
assert.strictEqual(wrapper.children[0].label, 'a');
});
// test('gets no children if nothing matches Uri filter', () => {
// let tests: TestItem = testStubs.nested();
// const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(tests, textDocumentFilter);
// const children = hierarchy.getChildren(wrapper, CancellationToken.None) as TestItemFilteredWrapper[];
// assert.strictEqual(children.length, 0);
// });
test('can get if node has matching filter', () => {
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// test('filter is applied to children', () => {
// const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// assert.strictEqual(wrapper.label, 'root');
// const children = hierarchy.getChildren(wrapper, CancellationToken.None) as TestItemFilteredWrapper[];
// assert.strictEqual(children.length, 1);
// assert.strictEqual(children[0] instanceof TestItemFilteredWrapper, true);
// assert.strictEqual(children[0].label, 'a');
// });
const invisible = testsWithLocation.children![1];
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
const visible = testsWithLocation.children![0];
const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
// test('can get if node has matching filter', () => {
// const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// The root is always visible
assert.strictEqual(rootWrapper.hasNodeMatchingFilter, true);
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
assert.strictEqual(visibleWrapper.hasNodeMatchingFilter, true);
});
// const invisible = testsWithLocation.children![1];
// const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
// const visible = testsWithLocation.children![0];
// const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
test('can get visible parent', () => {
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// // The root is always visible
// assert.strictEqual(rootWrapper.hasNodeMatchingFilter, true);
// assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
// assert.strictEqual(visibleWrapper.hasNodeMatchingFilter, true);
// });
const invisible = testsWithLocation.children![1];
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
const visible = testsWithLocation.children![0];
const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
// test('can get visible parent', () => {
// const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// The root is always visible
assert.strictEqual(rootWrapper.visibleParent, rootWrapper);
assert.strictEqual(invisibleWrapper.visibleParent, rootWrapper);
assert.strictEqual(visibleWrapper.visibleParent, visibleWrapper);
});
// const invisible = testsWithLocation.children![1];
// const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
// const visible = testsWithLocation.children![0];
// const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
test('can reset cached value of hasNodeMatchingFilter', () => {
TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// // The root is always visible
// assert.strictEqual(rootWrapper.visibleParent, rootWrapper);
// assert.strictEqual(invisibleWrapper.visibleParent, rootWrapper);
// assert.strictEqual(visibleWrapper.visibleParent, visibleWrapper);
// });
const invisible = testsWithLocation.children![1];
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
// test('can reset cached value of hasNodeMatchingFilter', () => {
// TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
invisible.location = location1 as any;
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
invisibleWrapper.reset();
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, true);
});
// const invisible = testsWithLocation.children![1];
// const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
test('can reset cached value of hasNodeMatchingFilter of parents up to visible parent', () => {
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
// assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
// invisible.location = location1 as any;
// assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
// invisibleWrapper.reset();
// assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, true);
// });
const invisibleParent = testsWithLocation.children![1];
const invisibleParentWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisibleParent, textDocumentFilter);
const invisible = invisibleParent.children![1];
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
// test('can reset cached value of hasNodeMatchingFilter of parents up to visible parent', () => {
// const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
invisible.location = location1 as any;
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
invisibleWrapper.reset();
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, true);
// const invisibleParent = testsWithLocation.children![1];
// const invisibleParentWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisibleParent, textDocumentFilter);
// const invisible = invisibleParent.children![1];
// const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
// the root should be undefined due to the reset.
assert.strictEqual((rootWrapper as any).matchesFilter, undefined);
});
});
});
// assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
// invisible.location = location1 as any;
// assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
// invisibleWrapper.reset();
// assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, true);
// // the root should be undefined due to the reset.
// assert.strictEqual((rootWrapper as any).matchesFilter, undefined);
// });
// });
// });
});

View File

@@ -653,12 +653,8 @@ suite('ExtHostTypes', function () {
const obj = new types.NotebookDocumentMetadata();
assert.strictEqual(obj.cellEditable, notebookDocumentMetadataDefaults.cellEditable);
assert.strictEqual(obj.cellHasExecutionOrder, notebookDocumentMetadataDefaults.cellHasExecutionOrder);
assert.strictEqual(obj.cellRunnable, notebookDocumentMetadataDefaults.cellRunnable);
assert.deepStrictEqual(obj.custom, notebookDocumentMetadataDefaults.custom);
assert.deepStrictEqual(obj.displayOrder, notebookDocumentMetadataDefaults.displayOrder);
assert.strictEqual(obj.editable, notebookDocumentMetadataDefaults.editable);
assert.strictEqual(obj.runState, notebookDocumentMetadataDefaults.runState);
assert.strictEqual(obj.runnable, notebookDocumentMetadataDefaults.runnable);
assert.strictEqual(obj.trusted, notebookDocumentMetadataDefaults.trusted);
});
@@ -686,22 +682,4 @@ suite('ExtHostTypes', function () {
assert.strictEqual(newObj.custom, undefined);
});
test('Unable to reset executionOrder of cells #116956', function () {
let obj = new types.NotebookCellMetadata();
assert.strictEqual(obj.executionOrder, undefined);
obj = obj.with({ executionOrder: 23 });
assert.strictEqual(obj.executionOrder, 23);
obj = obj.with({ executionOrder: undefined });
assert.strictEqual(obj.executionOrder, 23);
obj = obj.with({});
assert.strictEqual(obj.executionOrder, 23);
obj = obj.with({ executionOrder: null });
assert.strictEqual(obj.executionOrder, undefined);
});
});

View File

@@ -53,7 +53,12 @@ suite('ExtHostWebview', () => {
const serializerARegistration = extHostWebviewPanels.registerWebviewPanelSerializer(extension, viewType, serializerA);
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorGroupColumn, {});
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, {
title: 'title',
state: {},
panelOptions: {},
webviewOptions: {}
}, 0 as EditorGroupColumn);
assert.strictEqual(lastInvokedDeserializer, serializerA);
assert.throws(
@@ -64,7 +69,12 @@ suite('ExtHostWebview', () => {
extHostWebviewPanels.registerWebviewPanelSerializer(extension, viewType, serializerB);
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorGroupColumn, {});
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, {
title: 'title',
state: {},
panelOptions: {},
webviewOptions: {}
}, 0 as EditorGroupColumn);
assert.strictEqual(lastInvokedDeserializer, serializerB);
});

View File

@@ -40,6 +40,7 @@ suite('MainThreadDocumentsAndEditors', () => {
function myCreateTestCodeEditor(model: ITextModel | undefined): ITestCodeEditor {
return createTestCodeEditor({
model: model,
hasTextFocus: false,
serviceCollection: new ServiceCollection(
[ICodeEditorService, codeEditorService]
)

View File

@@ -53,6 +53,7 @@ import { extUri } from 'vs/base/common/resources';
import { ITextSnapshot } from 'vs/editor/common/model';
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
suite('MainThreadEditors', () => {
@@ -86,6 +87,7 @@ suite('MainThreadEditors', () => {
services.set(ILabelService, new SyncDescriptor(LabelService));
services.set(ILogService, new NullLogService());
services.set(IWorkspaceContextService, new TestContextService());
services.set(IEnvironmentService, TestEnvironmentService);
services.set(IWorkbenchEnvironmentService, TestEnvironmentService);
services.set(IConfigurationService, configService);
services.set(IDialogService, dialogService);

View File

@@ -22,11 +22,11 @@ import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbe
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { FileOperationEvent, IFileService, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions, IReadFileOptions, IFileContent, IFileStreamContent, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, FileReadStreamOptions } from 'vs/platform/files/common/files';
import { FileOperationEvent, IFileService, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, ICreateFileOptions, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions, IReadFileOptions, IFileContent, IFileStreamContent, FileOperationError, IFileSystemProviderWithFileReadStreamCapability, FileReadStreamOptions, IReadFileStreamOptions } from 'vs/platform/files/common/files';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent } from 'vs/workbench/services/textfile/common/textfiles';
import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent, IWriteTextFileOptions, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
@@ -63,7 +63,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { isLinux, isWindows } from 'vs/base/common/platform';
import { IProcessEnvironment, isLinux, isWindows } from 'vs/base/common/platform';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { Part } from 'vs/workbench/browser/part';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
@@ -97,7 +97,7 @@ import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEdit
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IDiffEditor, IEditor } from 'vs/editor/common/editorCommon';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IInputBox, IInputOptions, IPickOptions, IQuickInputButton, IQuickInputService, IQuickNavigateConfiguration, IQuickPick, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService';
import { IListService } from 'vs/platform/list/browser/listService';
import { win32, posix } from 'vs/base/common/path';
@@ -126,6 +126,10 @@ import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEd
import { IEnterWorkspaceResult, IRecent, IRecentlyOpened, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceTrustService } from 'vs/platform/workspace/common/workspaceTrust';
import { TestWorkspaceTrustService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
import { ILocalTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalsLayoutInfo, ITerminalsLayoutInfoById } from 'vs/platform/terminal/common/terminal';
import { IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { isArray } from 'vs/base/common/types';
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined);
@@ -173,6 +177,7 @@ export function workbenchInstantiationService(
instantiationService.stub(IWorkingCopyService, disposables.add(new TestWorkingCopyService()));
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService);
const contextKeyService = overrides?.contextKeyService ? overrides.contextKeyService(instantiationService) : instantiationService.createInstance(MockContextKeyService);
instantiationService.stub(IContextKeyService, contextKeyService);
instantiationService.stub(IProgressService, new TestProgressService());
@@ -226,6 +231,8 @@ export function workbenchInstantiationService(
instantiationService.stub(IQuickInputService, disposables.add(new QuickInputService(configService, instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService)));
instantiationService.stub(IWorkspacesService, new TestWorkspacesService());
instantiationService.stub(IWorkspaceTrustService, new TestWorkspaceTrustService());
instantiationService.stub(ITerminalInstanceService, new TestTerminalInstanceService());
instantiationService.stub(ILocalTerminalService, new TestLocalTerminalService());
return instantiationService;
}
@@ -249,12 +256,16 @@ export class TestServiceAccessor {
@IConfigurationService public testConfigurationService: TestConfigurationService,
@IBackupFileService public backupFileService: TestBackupFileService,
@IHostService public hostService: TestHostService,
@IQuickInputService public quickInputService: IQuickInputService
@IQuickInputService public quickInputService: IQuickInputService,
@ILabelService public labelService: ILabelService,
@ILogService public logService: ILogService,
@IUriIdentityService public uriIdentityService: IUriIdentityService
) { }
}
export class TestTextFileService extends BrowserTextFileService {
private resolveTextContentError!: FileOperationError | null;
private readStreamError: FileOperationError | undefined = undefined;
private writeError: FileOperationError | undefined = undefined;
constructor(
@IFileService protected fileService: IFileService,
@@ -297,14 +308,14 @@ export class TestTextFileService extends BrowserTextFileService {
);
}
setResolveTextContentErrorOnce(error: FileOperationError): void {
this.resolveTextContentError = error;
setReadStreamErrorOnce(error: FileOperationError): void {
this.readStreamError = error;
}
async readStream(resource: URI, options?: IReadTextFileOptions): Promise<ITextFileStreamContent> {
if (this.resolveTextContentError) {
const error = this.resolveTextContentError;
this.resolveTextContentError = null;
if (this.readStreamError) {
const error = this.readStreamError;
this.readStreamError = undefined;
throw error;
}
@@ -321,6 +332,21 @@ export class TestTextFileService extends BrowserTextFileService {
size: 10
};
}
setWriteErrorOnce(error: FileOperationError): void {
this.writeError = error;
}
async write(resource: URI, value: string | ITextSnapshot, options?: IWriteTextFileOptions): Promise<IFileStatWithMetadata> {
if (this.writeError) {
const error = this.writeError;
this.writeError = undefined;
throw error;
}
return super.write(resource, value, options);
}
}
export class TestBrowserTextFileServiceWithEncodingOverrides extends BrowserTextFileService {
@@ -501,7 +527,6 @@ export class TestLayoutService implements IWorkbenchLayoutService {
addClass(_clazz: string): void { }
removeClass(_clazz: string): void { }
getMaximumEditorDimensions(): Dimension { throw new Error('not implemented'); }
getWorkbenchContainer(): HTMLElement { throw new Error('not implemented'); }
toggleZenMode(): void { }
isEditorLayoutCentered(): boolean { return false; }
centerEditorLayout(_active: boolean): void { }
@@ -619,6 +644,7 @@ export class TestEditorGroupsService implements IEditorGroupsService {
removeGroup(_group: number | IEditorGroup): void { }
moveGroup(_group: number | IEditorGroup, _location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); }
mergeGroup(_group: number | IEditorGroup, _target: number | IEditorGroup, _options?: IMergeGroupOptions): IEditorGroup { throw new Error('not implemented'); }
mergeAllGroups(): IEditorGroup { throw new Error('not implemented'); }
copyGroup(_group: number | IEditorGroup, _location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); }
centerLayout(active: boolean): void { }
isLayoutCentered(): boolean { return false; }
@@ -813,9 +839,17 @@ export class TestFileService implements IFileService {
return stats.map(stat => ({ stat, success: true }));
}
async exists(_resource: URI): Promise<boolean> { return true; }
readonly notExistsSet = new Set<URI>();
async exists(_resource: URI): Promise<boolean> { return !this.notExistsSet.has(_resource); }
readShouldThrowError: Error | undefined = undefined;
readFile(resource: URI, options?: IReadFileOptions | undefined): Promise<IFileContent> {
if (this.readShouldThrowError) {
throw this.readShouldThrowError;
}
this.lastReadFileUri = resource;
return Promise.resolve({
@@ -830,7 +864,11 @@ export class TestFileService implements IFileService {
});
}
readFileStream(resource: URI, options?: IReadFileOptions | undefined): Promise<IFileStreamContent> {
readFileStream(resource: URI, options?: IReadFileStreamOptions | undefined): Promise<IFileStreamContent> {
if (this.readShouldThrowError) {
throw this.readShouldThrowError;
}
this.lastReadFileUri = resource;
return Promise.resolve({
@@ -1373,6 +1411,14 @@ export class TestEditorPart extends EditorPart {
}
}
export function createEditorPart(instantiationService: IInstantiationService, disposables: DisposableStore): TestEditorPart {
const part = disposables.add(instantiationService.createInstance(TestEditorPart));
part.create(document.createElement('div'));
part.layout(1080, 800);
return part;
}
export class TestListService implements IListService {
declare readonly _serviceBrand: undefined;
@@ -1412,6 +1458,16 @@ export class TestTextFileEditorModelManager extends TextFileEditorModelManager {
}
}
interface ITestTextFileEditorModel extends ITextFileEditorModel {
readonly lastResolvedFileStat: IFileStatWithMetadata | undefined;
}
export function getLastResolvedFileStat(model: unknown): IFileStatWithMetadata | undefined {
const candidate = model as ITestTextFileEditorModel | undefined;
return candidate?.lastResolvedFileStat;
}
export class TestWorkspacesService implements IWorkspacesService {
_serviceBrand: undefined;
@@ -1427,3 +1483,95 @@ export class TestWorkspacesService implements IWorkspacesService {
async enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null> { throw new Error('Method not implemented.'); }
async getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier> { throw new Error('Method not implemented.'); }
}
export class TestTerminalInstanceService implements ITerminalInstanceService {
declare readonly _serviceBrand: undefined;
async getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> {
return {
shell: 'bash',
args: undefined
};
}
async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
return {};
}
async getXtermConstructor(): Promise<any> { throw new Error('Method not implemented.'); }
async getXtermSearchConstructor(): Promise<any> { throw new Error('Method not implemented.'); }
async getXtermUnicode11Constructor(): Promise<any> { throw new Error('Method not implemented.'); }
async getXtermWebglConstructor(): Promise<any> { throw new Error('Method not implemented.'); }
createWindowsShellHelper(shellProcessId: number, xterm: any): any { throw new Error('Method not implemented.'); }
}
export class TestLocalTerminalService implements ILocalTerminalService {
declare readonly _serviceBrand: undefined;
onPtyHostExit = Event.None;
onPtyHostUnresponsive = Event.None;
onPtyHostResponsive = Event.None;
onPtyHostRestart = Event.None;
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess> {
return new TestTerminalChildProcess(shouldPersist);
}
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { throw new Error('Method not implemented.'); }
async listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> { throw new Error('Method not implemented.'); }
async setTerminalLayoutInfo(argsOrLayout?: ISetTerminalLayoutInfoArgs | ITerminalsLayoutInfoById) { throw new Error('Method not implemented.'); }
async getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined> { throw new Error('Method not implemented.'); }
}
class TestTerminalChildProcess implements ITerminalChildProcess {
id: number = 0;
constructor(
readonly shouldPersist: boolean
) {
}
onProcessData = Event.None;
onProcessExit = Event.None;
onProcessReady = Event.None;
onProcessTitleChanged = Event.None;
onProcessShellTypeChanged = Event.None;
async start(): Promise<undefined> { return undefined; }
shutdown(immediate: boolean): void { }
input(data: string): void { }
resize(cols: number, rows: number): void { }
acknowledgeDataEvent(charCount: number): void { }
async getInitialCwd(): Promise<string> { return ''; }
async getCwd(): Promise<string> { return ''; }
async getLatency(): Promise<number> { return 0; }
}
export class TestQuickInputService implements IQuickInputService {
declare readonly _serviceBrand: undefined;
readonly onShow = Event.None;
readonly onHide = Event.None;
readonly quickAccess = undefined!;
backButton!: IQuickInputButton;
pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: IPickOptions<T> & { canPickMany: true }, token?: CancellationToken): Promise<T[]>;
pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: IPickOptions<T> & { canPickMany: false }, token?: CancellationToken): Promise<T>;
async pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: Omit<IPickOptions<T>, 'canPickMany'>, token?: CancellationToken): Promise<T | undefined> {
if (isArray(picks)) {
return <any>{ label: 'selectedPick', description: 'pick description', value: 'selectedPick' };
} else {
return undefined;
}
}
async input(options?: IInputOptions, token?: CancellationToken): Promise<string> { return options ? 'resolved' + options.prompt : 'resolved'; }
createQuickPick<T extends IQuickPickItem>(): IQuickPick<T> { throw new Error('not implemented.'); }
createInputBox(): IInputBox { throw new Error('not implemented.'); }
focus(): void { throw new Error('not implemented.'); }
toggle(): void { throw new Error('not implemented.'); }
navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration): void { throw new Error('not implemented.'); }
accept(): Promise<void> { throw new Error('not implemented.'); }
back(): Promise<void> { throw new Error('not implemented.'); }
cancel(): Promise<void> { throw new Error('not implemented.'); }
}

View File

@@ -8,6 +8,8 @@ import { NotificationsModel, NotificationViewItem, INotificationChangeEvent, Not
import { Action } from 'vs/base/common/actions';
import { INotification, Severity, NotificationsFilter } from 'vs/platform/notification/common/notification';
import { createErrorWithActions } from 'vs/base/common/errors';
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
suite('Notifications', () => {
@@ -241,4 +243,41 @@ suite('Notifications', () => {
disposable3.dispose();
assert.ok(!model.statusMessage);
});
test('Service', async () => {
const service = new NotificationService(new TestStorageService());
let addNotificationCount = 0;
let notification!: INotification;
service.onDidAddNotification(n => {
addNotificationCount++;
notification = n;
});
service.info('hello there');
assert.strictEqual(addNotificationCount, 1);
assert.strictEqual(notification.message, 'hello there');
assert.strictEqual(notification.silent, false);
assert.strictEqual(notification.source, undefined);
let notificationHandle = service.notify({ message: 'important message', severity: Severity.Warning });
assert.strictEqual(addNotificationCount, 2);
assert.strictEqual(notification.message, 'important message');
assert.strictEqual(notification.severity, Severity.Warning);
let removeNotificationCount = 0;
service.onDidRemoveNotification(n => {
removeNotificationCount++;
notification = n;
});
notificationHandle.close();
assert.strictEqual(removeNotificationCount, 1);
assert.strictEqual(notification.message, 'important message');
notificationHandle = service.notify({ silent: true, message: 'test', severity: Severity.Ignore });
assert.strictEqual(addNotificationCount, 3);
assert.strictEqual(notification.message, 'test');
assert.strictEqual(notification.silent, true);
notificationHandle.close();
assert.strictEqual(removeNotificationCount, 2);
});
});

View File

@@ -10,12 +10,13 @@ import * as fs from 'fs';
import * as pfs from 'vs/base/node/pfs';
import * as path from 'vs/base/common/path';
import * as assert from 'assert';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
import { CancellationToken } from 'vs/base/common/cancellation';
import { RequestService } from 'vs/platform/request/node/requestService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import 'vs/workbench/workbench.desktop.main';
import { NullLogService } from 'vs/platform/log/common/log';
import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
interface ColorInfo {
description: string;
@@ -33,7 +34,7 @@ export const experimental: string[] = []; // 'settings.modifiedItemForeground',
suite('Color Registry', function () {
test('all colors documented in theme-color.md', async function () {
const reqContext = await new RequestService(new TestConfigurationService(), new NullLogService()).request({ url: 'https://raw.githubusercontent.com/microsoft/vscode-docs/vnext/api/references/theme-color.md' }, CancellationToken.None);
const reqContext = await new RequestService(new TestConfigurationService(), TestEnvironmentService, new NullLogService()).request({ url: 'https://raw.githubusercontent.com/microsoft/vscode-docs/vnext/api/references/theme-color.md' }, CancellationToken.None);
const content = (await asText(reqContext))!;
const expression = /\-\s*\`([\w\.]+)\`: (.*)/g;

View File

@@ -3,46 +3,46 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/workbench/contrib/search/browser/search.contribution'; // load contributions
import * as assert from 'assert';
import * as fs from 'fs';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { createSyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ISearchService } from 'vs/workbench/services/search/common/search';
import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import * as minimist from 'minimist';
import { Emitter, Event } from 'vs/base/common/event';
import * as path from 'vs/base/common/path';
import { LocalSearchService } from 'vs/workbench/services/search/electron-browser/searchService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { TestEditorService, TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { IModelService } from 'vs/editor/common/services/modelService';
import { SearchModel } from 'vs/workbench/contrib/search/common/searchModel';
import { QueryBuilder, ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import { Event, Emitter } from 'vs/base/common/event';
import { testWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { NullLogService, ILogService } from 'vs/platform/log/common/log';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestTextResourcePropertiesService, TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { testWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import 'vs/workbench/contrib/search/browser/search.contribution'; // load contributions
import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
import { SearchModel } from 'vs/workbench/contrib/search/common/searchModel';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ISearchService } from 'vs/workbench/services/search/common/search';
import { LocalSearchService } from 'vs/workbench/services/search/electron-browser/searchService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices';
import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
// declare var __dirname: string;
@@ -84,8 +84,8 @@ suite.skip('TextSearch performance (integration)', () => {
[IEditorService, new TestEditorService()],
[IEditorGroupsService, new TestEditorGroupsService()],
[IEnvironmentService, TestEnvironmentService],
[IUntitledTextEditorService, createSyncDescriptor(UntitledTextEditorService)],
[ISearchService, createSyncDescriptor(LocalSearchService)],
[IUntitledTextEditorService, new SyncDescriptor(UntitledTextEditorService)],
[ISearchService, new SyncDescriptor(LocalSearchService)],
[ILogService, logService]
));

View File

@@ -6,15 +6,14 @@
import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestFileService, TestFileDialogService, TestPathService, TestEncodingOracle, TestProductService } from 'vs/workbench/test/browser/workbenchTestServices';
import { Event } from 'vs/base/common/event';
import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services';
import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { NativeTextFileService, } from 'vs/workbench/services/textfile/electron-browser/nativeTextFileService';
import { NativeTextFileService, } from 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService';
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
import { FileOperationError, IFileService } from 'vs/platform/files/common/files';
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IModelService } from 'vs/editor/common/services/modelService';
import { INativeWorkbenchConfiguration, INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
import { INativeWorkbenchConfiguration, INativeWorkbenchEnvironmentService, NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
import { IDialogService, IFileDialogService, INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { IProductService } from 'vs/platform/product/common/productService';
@@ -40,7 +39,11 @@ import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/ur
import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IOSProperties, IOSStatistics } from 'vs/platform/native/common/native';
import { homedir, release } from 'os';
import { homedir, release, tmpdir } from 'os';
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { getUserDataPath } from 'vs/platform/environment/node/userDataPath';
import { INativeEnvironmentPaths } from 'vs/platform/environment/common/environmentService';
export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
windowId: 0,
@@ -55,11 +58,12 @@ export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
perfMarks: [],
colorScheme: { dark: true, highContrast: false },
os: { release: release() },
enableExperimentalMainProcessWorkspaceStorage: false,
...parseArgs(process.argv, OPTIONS)
};
export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(TestWorkbenchConfiguration, TestProductService);
export const TestEnvironmentPaths: INativeEnvironmentPaths = { homeDir: homedir(), tmpDir: tmpdir(), userDataDir: getUserDataPath(TestWorkbenchConfiguration) };
export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(TestWorkbenchConfiguration, TestEnvironmentPaths, TestProductService);
export class TestTextFileService extends NativeTextFileService {
private resolveTextContentError!: FileOperationError | null;
@@ -168,6 +172,7 @@ export class TestNativeHostService implements INativeHostService {
onDidResumeOS: Event<unknown> = Event.None;
onDidChangeColorScheme = Event.None;
onDidChangePassword = Event.None;
onDidChangeDisplay = Event.None;
windowCount = Promise.resolve(1);
getWindowCount(): Promise<number> { return this.windowCount; }
@@ -199,7 +204,7 @@ export class TestNativeHostService implements INativeHostService {
async showItemInFolder(path: string): Promise<void> { }
async setRepresentedFilename(path: string): Promise<void> { }
async isAdmin(): Promise<boolean> { return false; }
async writeElevated(source: URI, target: URI, options?: { overwriteReadonly?: boolean | undefined; }): Promise<void> { }
async writeElevated(source: URI, target: URI): Promise<void> { }
async getOSProperties(): Promise<IOSProperties> { return Object.create(null); }
async getOSStatistics(): Promise<IOSStatistics> { return Object.create(null); }
async getOSVirtualMachineHint(): Promise<number> { return 0; }
@@ -248,6 +253,9 @@ export function workbenchInstantiationService(): ITestInstantiationService {
});
instantiationService.stub(INativeHostService, new TestNativeHostService());
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
instantiationService.stub(INativeEnvironmentService, TestEnvironmentService);
instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService);
instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService);
return instantiationService;

View File

@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as platform from 'vs/base/common/platform';
import { findPorts, getSockets, loadConnectionTable, loadListeningPorts } from 'vs/workbench/api/node/extHostTunnelService';
import { findPorts, getRootProcesses, getSockets, loadConnectionTable, loadListeningPorts, tryFindRootPorts } from 'vs/workbench/api/node/extHostTunnelService';
const tcp =
` sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
@@ -215,52 +214,68 @@ const processes: { pid: number, cwd: string, cmd: string }[] = [
}
];
if (platform.isLinux) {
suite('ExtHostTunnelService', () => {
test('getSockets', function () {
const result = getSockets(procSockets);
assert.equal(result.length, 78);
// 4412 is the pid fo the http-server in the test data
assert.notEqual(result.find(value => value.pid === 4412), undefined);
});
const psStdOut =
`4 S root 1 0 0 80 0 - 596 - 1440 2 14:41 ? 00:00:00 /bin/sh -c echo Container started ; trap "exit 0" 15; while sleep 1 & wait $!; do :; done
4 S root 14 0 0 80 0 - 596 - 764 4 14:41 ? 00:00:00 /bin/sh
4 S root 40 0 0 80 0 - 596 - 700 4 14:41 ? 00:00:00 /bin/sh
4 S root 513 380 0 80 0 - 2476 - 3404 1 14:41 pts/1 00:00:00 sudo npx http-server -p 5000
4 S root 514 513 0 80 0 - 165439 - 41380 5 14:41 pts/1 00:00:00 http-server
0 S root 1052 1 0 80 0 - 573 - 752 5 14:43 ? 00:00:00 sleep 1
0 S node 1056 329 0 80 0 - 596 do_wai 764 10 14:43 ? 00:00:00 /bin/sh -c ps -F -A -l | grep root
0 S node 1058 1056 0 80 0 - 770 pipe_w 888 9 14:43 ? 00:00:00 grep root`;
test('loadConnectionTable', function () {
const result = loadConnectionTable(tcp);
assert.equal(result.length, 6);
assert.deepEqual(result[0], {
10: '1',
11: '0000000010173312',
12: '100',
13: '0',
14: '0',
15: '10',
16: '0',
inode: '2335214',
local_address: '00000000:0BBA',
rem_address: '00000000:0000',
retrnsmt: '00000000',
sl: '0:',
st: '0A',
timeout: '0',
tr: '00:00000000',
tx_queue: '00000000:00000000',
uid: '1000'
});
});
suite('ExtHostTunnelService', () => {
test('getSockets', function () {
const result = getSockets(procSockets);
assert.strictEqual(Object.keys(result).length, 75);
// 4412 is the pid of the http-server in the test data
assert.notStrictEqual(Object.keys(result).find(key => result[key].pid === 4412), undefined);
});
test('loadListeningPorts', function () {
const result = loadListeningPorts(tcp, tcp6);
// There should be 7 based on the input data. One of them should be 3002.
assert.equal(result.length, 7);
assert.notEqual(result.find(value => value.port === 3002), undefined);
});
test('findPorts', async function () {
const result = await findPorts(tcp, tcp6, procSockets, processes);
assert.equal(result.length, 1);
assert.equal(result[0].host, '0.0.0.0');
assert.equal(result[0].port, 3002);
assert.equal(result[0].detail, 'http-server');
test('loadConnectionTable', function () {
const result = loadConnectionTable(tcp);
assert.strictEqual(result.length, 6);
assert.deepStrictEqual(result[0], {
10: '1',
11: '0000000010173312',
12: '100',
13: '0',
14: '0',
15: '10',
16: '0',
inode: '2335214',
local_address: '00000000:0BBA',
rem_address: '00000000:0000',
retrnsmt: '00000000',
sl: '0:',
st: '0A',
timeout: '0',
tr: '00:00000000',
tx_queue: '00000000:00000000',
uid: '1000'
});
});
}
test('loadListeningPorts', function () {
const result = loadListeningPorts(tcp, tcp6);
// There should be 7 based on the input data. One of them should be 3002.
assert.strictEqual(result.length, 7);
assert.notStrictEqual(result.find(value => value.port === 3002), undefined);
});
test('tryFindRootPorts', function () {
const rootProcesses = getRootProcesses(psStdOut);
assert.strictEqual(rootProcesses.length, 6);
const result = tryFindRootPorts([{ socket: 1000, ip: '127.0.0.1', port: 5000 }], psStdOut, new Map());
assert.strictEqual(result.size, 1);
assert.strictEqual(result.get(5000)?.pid, 514);
});
test('findPorts', async function () {
const result = await findPorts(loadListeningPorts(tcp, tcp6), getSockets(procSockets), processes);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].host, '0.0.0.0');
assert.strictEqual(result[0].port, 3002);
assert.strictEqual(result[0].detail, 'http-server');
});
});