mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 01:32:34 -05:00
Merge from vscode e3c4990c67c40213af168300d1cfeb71d680f877 (#16569)
This commit is contained in:
@@ -49,7 +49,7 @@ import 'vs/editor/contrib/parameterHints/provideSignatureHelp';
|
||||
import 'vs/editor/contrib/smartSelect/smartSelect';
|
||||
import 'vs/editor/contrib/suggest/suggest';
|
||||
import 'vs/editor/contrib/rename/rename';
|
||||
import 'vs/editor/contrib/inlineHints/inlineHintsController';
|
||||
import 'vs/editor/contrib/inlayHints/inlayHintsController';
|
||||
|
||||
const defaultSelector = { scheme: 'far' };
|
||||
const model: ITextModel = createTextModel(
|
||||
@@ -1204,85 +1204,74 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
// --- inline hints
|
||||
|
||||
test('Inline Hints, back and forth', async function () {
|
||||
disposables.push(extHost.registerInlineHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlineHintsProvider>{
|
||||
provideInlineHints() {
|
||||
return [new types.InlineHint('Foo', new types.Range(0, 1, 2, 3))];
|
||||
test('Inlay Hints, back and forth', async function () {
|
||||
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
|
||||
provideInlayHints() {
|
||||
return [new types.InlayHint('Foo', new types.Position(0, 1))];
|
||||
}
|
||||
}));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
|
||||
const value = await commands.executeCommand<vscode.InlineHint[]>('vscode.executeInlineHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
const value = await commands.executeCommand<vscode.InlayHint[]>('vscode.executeInlayHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
assert.strictEqual(value.length, 1);
|
||||
|
||||
const [first] = value;
|
||||
assert.strictEqual(first.text, 'Foo');
|
||||
assert.strictEqual(first.range.start.line, 0);
|
||||
assert.strictEqual(first.range.start.character, 1);
|
||||
assert.strictEqual(first.range.end.line, 2);
|
||||
assert.strictEqual(first.range.end.character, 3);
|
||||
assert.strictEqual(first.position.line, 0);
|
||||
assert.strictEqual(first.position.character, 1);
|
||||
});
|
||||
|
||||
test('Inline Hints, merge', async function () {
|
||||
disposables.push(extHost.registerInlineHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlineHintsProvider>{
|
||||
provideInlineHints() {
|
||||
return [new types.InlineHint('Bar', new types.Range(10, 11, 12, 13))];
|
||||
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
|
||||
provideInlayHints() {
|
||||
return [new types.InlayHint('Bar', new types.Position(10, 11))];
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerInlineHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlineHintsProvider>{
|
||||
provideInlineHints() {
|
||||
const hint = new types.InlineHint('Foo', new types.Range(0, 1, 2, 3), types.InlineHintKind.Parameter);
|
||||
hint.description = new types.MarkdownString('**Hello**');
|
||||
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
|
||||
provideInlayHints() {
|
||||
const hint = new types.InlayHint('Foo', new types.Position(0, 1), types.InlayHintKind.Parameter);
|
||||
return [hint];
|
||||
}
|
||||
}));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
|
||||
const value = await commands.executeCommand<vscode.InlineHint[]>('vscode.executeInlineHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
const value = await commands.executeCommand<vscode.InlayHint[]>('vscode.executeInlayHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
assert.strictEqual(value.length, 2);
|
||||
|
||||
const [first, second] = value;
|
||||
assert.strictEqual(first.text, 'Foo');
|
||||
assert.strictEqual(first.range.start.line, 0);
|
||||
assert.strictEqual(first.range.start.character, 1);
|
||||
assert.strictEqual(first.range.end.line, 2);
|
||||
assert.strictEqual(first.range.end.character, 3);
|
||||
assert.ok(first.description instanceof types.MarkdownString);
|
||||
assert.strictEqual((<types.MarkdownString>first.description).value, '**Hello**');
|
||||
assert.strictEqual(first.position.line, 0);
|
||||
assert.strictEqual(first.position.character, 1);
|
||||
|
||||
assert.strictEqual(second.text, 'Bar');
|
||||
assert.strictEqual(second.range.start.line, 10);
|
||||
assert.strictEqual(second.range.start.character, 11);
|
||||
assert.strictEqual(second.range.end.line, 12);
|
||||
assert.strictEqual(second.range.end.character, 13);
|
||||
assert.strictEqual(second.position.line, 10);
|
||||
assert.strictEqual(second.position.character, 11);
|
||||
});
|
||||
|
||||
test('Inline Hints, bad provider', async function () {
|
||||
disposables.push(extHost.registerInlineHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlineHintsProvider>{
|
||||
provideInlineHints() {
|
||||
return [new types.InlineHint('Foo', new types.Range(0, 1, 2, 3))];
|
||||
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
|
||||
provideInlayHints() {
|
||||
return [new types.InlayHint('Foo', new types.Position(0, 1))];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerInlineHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlineHintsProvider>{
|
||||
provideInlineHints() {
|
||||
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
|
||||
provideInlayHints() {
|
||||
throw new Error();
|
||||
}
|
||||
}));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
|
||||
const value = await commands.executeCommand<vscode.InlineHint[]>('vscode.executeInlineHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
const value = await commands.executeCommand<vscode.InlayHint[]>('vscode.executeInlayHintProvider', model.uri, new types.Range(0, 0, 20, 20));
|
||||
assert.strictEqual(value.length, 1);
|
||||
|
||||
const [first] = value;
|
||||
assert.strictEqual(first.text, 'Foo');
|
||||
assert.strictEqual(first.range.start.line, 0);
|
||||
assert.strictEqual(first.range.start.character, 1);
|
||||
assert.strictEqual(first.range.end.line, 2);
|
||||
assert.strictEqual(first.range.end.character, 3);
|
||||
assert.strictEqual(first.position.line, 0);
|
||||
assert.strictEqual(first.position.character, 1);
|
||||
});
|
||||
|
||||
// --- selection ranges
|
||||
|
||||
@@ -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, NotebookCellExecutionState, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, CellUri, 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';
|
||||
@@ -22,6 +22,7 @@ import { isEqual } from 'vs/base/common/resources';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
|
||||
|
||||
suite('NotebookCell#Document', function () {
|
||||
|
||||
@@ -31,6 +32,8 @@ suite('NotebookCell#Document', function () {
|
||||
let extHostDocumentsAndEditors: ExtHostDocumentsAndEditors;
|
||||
let extHostDocuments: ExtHostDocuments;
|
||||
let extHostNotebooks: ExtHostNotebookController;
|
||||
let extHostNotebookDocuments: ExtHostNotebookDocuments;
|
||||
|
||||
const notebookUri = URI.parse('test:///notebook.file');
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
@@ -54,7 +57,9 @@ suite('NotebookCell#Document', function () {
|
||||
return URI.from({ scheme: 'test', path: generateUuid() });
|
||||
}
|
||||
};
|
||||
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, new NullLogService(), extHostStoragePaths);
|
||||
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, extHostStoragePaths);
|
||||
extHostNotebookDocuments = new ExtHostNotebookDocuments(new NullLogService(), extHostNotebooks);
|
||||
|
||||
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
|
||||
// async openNotebook() { }
|
||||
});
|
||||
@@ -69,7 +74,7 @@ suite('NotebookCell#Document', function () {
|
||||
source: ['### Heading'],
|
||||
eol: '\n',
|
||||
language: 'markdown',
|
||||
cellKind: CellKind.Markdown,
|
||||
cellKind: CellKind.Markup,
|
||||
outputs: [],
|
||||
}, {
|
||||
handle: 1,
|
||||
@@ -162,7 +167,7 @@ suite('NotebookCell#Document', function () {
|
||||
});
|
||||
});
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -238,7 +243,7 @@ suite('NotebookCell#Document', function () {
|
||||
assert.strictEqual(notebook.apiNotebook.cellCount, 2);
|
||||
const [cell1, cell2] = notebook.apiNotebook.getCells();
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebook.uri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebook.uri, {
|
||||
versionId: 2,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -269,7 +274,7 @@ suite('NotebookCell#Document', function () {
|
||||
assert.strictEqual(second.index, 1);
|
||||
|
||||
// remove first cell
|
||||
extHostNotebooks.$acceptModelChanged(notebook.uri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebook.uri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
@@ -280,7 +285,7 @@ suite('NotebookCell#Document', function () {
|
||||
assert.strictEqual(notebook.apiNotebook.cellCount, 1);
|
||||
assert.strictEqual(second.index, 0);
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
@@ -315,7 +320,7 @@ suite('NotebookCell#Document', function () {
|
||||
// DON'T call this, make sure the cell-documents have not been created yet
|
||||
// assert.strictEqual(notebook.notebookDocument.cellCount, 2);
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebook.uri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebook.uri, {
|
||||
versionId: 100,
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
@@ -325,7 +330,7 @@ suite('NotebookCell#Document', function () {
|
||||
source: ['### Heading'],
|
||||
eol: '\n',
|
||||
language: 'markdown',
|
||||
cellKind: CellKind.Markdown,
|
||||
cellKind: CellKind.Markup,
|
||||
outputs: [],
|
||||
}, {
|
||||
handle: 4,
|
||||
@@ -398,7 +403,7 @@ suite('NotebookCell#Document', function () {
|
||||
const removed = Event.toPromise(extHostDocuments.onDidRemoveDocument);
|
||||
const added = Event.toPromise(extHostDocuments.onDidAddDocument);
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebook.uri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebook.uri, {
|
||||
versionId: 12, rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ChangeLanguage,
|
||||
index: 0,
|
||||
@@ -412,30 +417,4 @@ suite('NotebookCell#Document', function () {
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ import { MainContext, MainThreadCommandsShape, MainThreadNotebookShape } from 'v
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
|
||||
|
||||
suite('NotebookConcatDocument', function () {
|
||||
|
||||
@@ -30,6 +31,8 @@ suite('NotebookConcatDocument', function () {
|
||||
let extHostDocumentsAndEditors: ExtHostDocumentsAndEditors;
|
||||
let extHostDocuments: ExtHostDocuments;
|
||||
let extHostNotebooks: ExtHostNotebookController;
|
||||
let extHostNotebookDocuments: ExtHostNotebookDocuments;
|
||||
|
||||
const notebookUri = URI.parse('test:///notebook.file');
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
@@ -51,7 +54,9 @@ suite('NotebookConcatDocument', function () {
|
||||
return URI.from({ scheme: 'test', path: generateUuid() });
|
||||
}
|
||||
};
|
||||
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, new NullLogService(), extHostStoragePaths);
|
||||
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, extHostStoragePaths);
|
||||
extHostNotebookDocuments = new ExtHostNotebookDocuments(new NullLogService(), extHostNotebooks);
|
||||
|
||||
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
|
||||
// async openNotebook() { }
|
||||
});
|
||||
@@ -65,7 +70,7 @@ suite('NotebookConcatDocument', function () {
|
||||
source: ['### Heading'],
|
||||
eol: '\n',
|
||||
language: 'markdown',
|
||||
cellKind: CellKind.Markdown,
|
||||
cellKind: CellKind.Markup,
|
||||
outputs: [],
|
||||
}],
|
||||
versionId: 0
|
||||
@@ -122,7 +127,7 @@ suite('NotebookConcatDocument', function () {
|
||||
const cellUri1 = CellUri.generate(notebook.uri, 1);
|
||||
const cellUri2 = CellUri.generate(notebook.uri, 2);
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
@@ -159,7 +164,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('location, position mapping', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -204,7 +209,7 @@ suite('NotebookConcatDocument', function () {
|
||||
let doc = new ExtHostNotebookConcatDocument(extHostNotebooks, extHostDocuments, notebook.apiNotebook, undefined);
|
||||
|
||||
// UPDATE 1
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -231,7 +236,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
|
||||
// UPDATE 2
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -259,7 +264,7 @@ suite('NotebookConcatDocument', function () {
|
||||
assertLocation(doc, new Position(5, 12), new Location(notebook.apiNotebook.cellAt(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, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -281,7 +286,7 @@ suite('NotebookConcatDocument', function () {
|
||||
let doc = new ExtHostNotebookConcatDocument(extHostNotebooks, extHostDocuments, notebook.apiNotebook, undefined);
|
||||
|
||||
// UPDATE 1
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -340,7 +345,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('selector', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -374,7 +379,7 @@ suite('NotebookConcatDocument', function () {
|
||||
assertLines(fooLangDoc, 'fooLang-document');
|
||||
assertLines(barLangDoc, 'barLang-document');
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -412,7 +417,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('offsetAt(position) <-> positionAt(offset)', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -469,7 +474,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('locationAt(position) <-> positionAt(location)', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -510,7 +515,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('getText(range)', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
@@ -548,7 +553,7 @@ suite('NotebookConcatDocument', function () {
|
||||
|
||||
test('validateRange/Position', function () {
|
||||
|
||||
extHostNotebooks.$acceptModelChanged(notebookUri, {
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebookUri, {
|
||||
versionId: notebook.apiNotebook.version + 1,
|
||||
rawEvents: [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
@@ -8,18 +8,39 @@ import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
|
||||
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
|
||||
import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { mock } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { INotebookKernelDto2, MainContext, MainThreadCommandsShape, MainThreadNotebookKernelsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { INotebookKernelDto2, MainContext, MainThreadCommandsShape, MainThreadNotebookDocumentsShape, MainThreadNotebookKernelsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ExtHostNotebookKernels } from 'vs/workbench/api/common/extHostNotebookKernels';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||
import { ExtHostNotebookDocument } from 'vs/workbench/api/common/extHostNotebookDocument';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { CellKind, CellUri, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
|
||||
|
||||
suite('NotebookKernel', function () {
|
||||
|
||||
let rpcProtocol: TestRPCProtocol;
|
||||
let extHostNotebookKernels: ExtHostNotebookKernels;
|
||||
let notebook: ExtHostNotebookDocument;
|
||||
let extHostDocumentsAndEditors: ExtHostDocumentsAndEditors;
|
||||
let extHostDocuments: ExtHostDocuments;
|
||||
let extHostNotebooks: ExtHostNotebookController;
|
||||
let extHostNotebookDocuments: ExtHostNotebookDocuments;
|
||||
|
||||
const notebookUri = URI.parse('test:///notebook.file');
|
||||
const kernelData = new Map<number, INotebookKernelDto2>();
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
teardown(function () {
|
||||
disposables.clear();
|
||||
});
|
||||
setup(async function () {
|
||||
|
||||
kernelData.clear();
|
||||
@@ -40,11 +61,67 @@ suite('NotebookKernel', function () {
|
||||
kernelData.set(handle, { ...kernelData.get(handle)!, ...data, });
|
||||
}
|
||||
});
|
||||
rpcProtocol.set(MainContext.MainThreadNotebookDocuments, new class extends mock<MainThreadNotebookDocumentsShape>() {
|
||||
override async $applyEdits() { }
|
||||
});
|
||||
rpcProtocol.set(MainContext.MainThreadNotebook, new class extends mock<MainThreadNotebookShape>() {
|
||||
override async $registerNotebookProvider() { }
|
||||
override async $unregisterNotebookProvider() { }
|
||||
});
|
||||
extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol, new NullLogService());
|
||||
extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors);
|
||||
const extHostStoragePaths = new class extends mock<IExtensionStoragePaths>() {
|
||||
override workspaceValue() {
|
||||
return URI.from({ scheme: 'test', path: generateUuid() });
|
||||
}
|
||||
};
|
||||
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, extHostStoragePaths);
|
||||
|
||||
extHostNotebookDocuments = new ExtHostNotebookDocuments(new NullLogService(), extHostNotebooks);
|
||||
|
||||
extHostNotebooks.$acceptDocumentAndEditorsDelta({
|
||||
addedDocuments: [{
|
||||
uri: notebookUri,
|
||||
viewType: 'test',
|
||||
versionId: 0,
|
||||
cells: [{
|
||||
handle: 0,
|
||||
uri: CellUri.generate(notebookUri, 0),
|
||||
source: ['### Heading'],
|
||||
eol: '\n',
|
||||
language: 'markdown',
|
||||
cellKind: CellKind.Markup,
|
||||
outputs: [],
|
||||
}, {
|
||||
handle: 1,
|
||||
uri: CellUri.generate(notebookUri, 1),
|
||||
source: ['console.log("aaa")', 'console.log("bbb")'],
|
||||
eol: '\n',
|
||||
language: 'javascript',
|
||||
cellKind: CellKind.Code,
|
||||
outputs: [],
|
||||
}],
|
||||
}],
|
||||
addedEditors: [{
|
||||
documentUri: notebookUri,
|
||||
id: '_notebook_editor_0',
|
||||
selections: [{ start: 0, end: 1 }],
|
||||
visibleRanges: []
|
||||
}]
|
||||
});
|
||||
extHostNotebooks.$acceptDocumentAndEditorsDelta({ newActiveEditor: '_notebook_editor_0' });
|
||||
|
||||
notebook = extHostNotebooks.notebookDocuments[0]!;
|
||||
|
||||
disposables.add(notebook);
|
||||
disposables.add(extHostDocuments);
|
||||
|
||||
|
||||
extHostNotebookKernels = new ExtHostNotebookKernels(
|
||||
rpcProtocol,
|
||||
new class extends mock<IExtHostInitDataService>() { },
|
||||
new class extends mock<ExtHostNotebookController>() { }
|
||||
extHostNotebooks,
|
||||
new NullLogService()
|
||||
);
|
||||
});
|
||||
|
||||
@@ -53,12 +130,12 @@ suite('NotebookKernel', function () {
|
||||
const kernel = extHostNotebookKernels.createNotebookController(nullExtensionDescription, 'foo', '*', 'Foo');
|
||||
|
||||
assert.throws(() => (<any>kernel).id = 'dd');
|
||||
assert.throws(() => (<any>kernel).viewType = 'dd');
|
||||
assert.throws(() => (<any>kernel).notebookType = 'dd');
|
||||
|
||||
assert.ok(kernel);
|
||||
assert.strictEqual(kernel.id, 'foo');
|
||||
assert.strictEqual(kernel.label, 'Foo');
|
||||
assert.strictEqual(kernel.viewType, '*');
|
||||
assert.strictEqual(kernel.notebookType, '*');
|
||||
|
||||
await rpcProtocol.sync();
|
||||
assert.strictEqual(kernelData.size, 1);
|
||||
@@ -67,7 +144,7 @@ suite('NotebookKernel', function () {
|
||||
assert.strictEqual(first.id, 'nullExtensionDescription/foo');
|
||||
assert.strictEqual(ExtensionIdentifier.equals(first.extensionId, nullExtensionDescription.identifier), true);
|
||||
assert.strictEqual(first.label, 'Foo');
|
||||
assert.strictEqual(first.viewType, '*');
|
||||
assert.strictEqual(first.notebookType, '*');
|
||||
|
||||
kernel.dispose();
|
||||
await rpcProtocol.sync();
|
||||
@@ -93,4 +170,69 @@ suite('NotebookKernel', function () {
|
||||
assert.strictEqual(first.id, 'nullExtensionDescription/foo');
|
||||
assert.strictEqual(first.label, 'Far');
|
||||
});
|
||||
|
||||
test('execute - simple createNotebookCellExecution', function () {
|
||||
const kernel = extHostNotebookKernels.createNotebookController(nullExtensionDescription, 'foo', '*', 'Foo');
|
||||
|
||||
extHostNotebookKernels.$acceptNotebookAssociation(0, notebook.uri, true);
|
||||
|
||||
const cell1 = notebook.apiNotebook.cellAt(0);
|
||||
const task = kernel.createNotebookCellExecution(cell1);
|
||||
task.start();
|
||||
task.end(undefined);
|
||||
});
|
||||
|
||||
test('createNotebookCellExecution, must be selected/associated', function () {
|
||||
const kernel = extHostNotebookKernels.createNotebookController(nullExtensionDescription, 'foo', '*', 'Foo');
|
||||
assert.throws(() => {
|
||||
kernel.createNotebookCellExecution(notebook.apiNotebook.cellAt(0));
|
||||
});
|
||||
|
||||
extHostNotebookKernels.$acceptNotebookAssociation(0, notebook.uri, true);
|
||||
kernel.createNotebookCellExecution(notebook.apiNotebook.cellAt(0));
|
||||
});
|
||||
|
||||
test('createNotebookCellExecution, cell must be alive', function () {
|
||||
const kernel = extHostNotebookKernels.createNotebookController(nullExtensionDescription, 'foo', '*', 'Foo');
|
||||
|
||||
const cell1 = notebook.apiNotebook.cellAt(0);
|
||||
|
||||
extHostNotebookKernels.$acceptNotebookAssociation(0, notebook.uri, true);
|
||||
extHostNotebookDocuments.$acceptModelChanged(notebook.uri, {
|
||||
versionId: 12,
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
changes: [[0, notebook.apiNotebook.cellCount, []]]
|
||||
}]
|
||||
}, true);
|
||||
|
||||
assert.strictEqual(cell1.index, -1);
|
||||
|
||||
assert.throws(() => {
|
||||
kernel.createNotebookCellExecution(cell1);
|
||||
});
|
||||
});
|
||||
|
||||
test('interrupt handler, cancellation', async function () {
|
||||
|
||||
let interruptCallCount = 0;
|
||||
let tokenCancelCount = 0;
|
||||
|
||||
const kernel = extHostNotebookKernels.createNotebookController(nullExtensionDescription, 'foo', '*', 'Foo');
|
||||
kernel.interruptHandler = () => { interruptCallCount += 1; };
|
||||
extHostNotebookKernels.$acceptNotebookAssociation(0, notebook.uri, true);
|
||||
|
||||
const cell1 = notebook.apiNotebook.cellAt(0);
|
||||
|
||||
const task = kernel.createNotebookCellExecution(cell1);
|
||||
task.token.onCancellationRequested(() => tokenCancelCount += 1);
|
||||
|
||||
await extHostNotebookKernels.$cancelCells(0, notebook.uri, [0]);
|
||||
assert.strictEqual(interruptCallCount, 1);
|
||||
assert.strictEqual(tokenCancelCount, 0);
|
||||
|
||||
await extHostNotebookKernels.$cancelCells(0, notebook.uri, [0]);
|
||||
assert.strictEqual(interruptCallCount, 2);
|
||||
assert.strictEqual(tokenCancelCount, 0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,12 +15,12 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
|
||||
import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { mock } from 'vs/base/test/common/mock';
|
||||
import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views';
|
||||
import { TreeItemCollapsibleState, ITreeItem, IRevealOptions } from 'vs/workbench/common/views';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import type { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
suite.skip('ExtHostTreeView', function () {
|
||||
suite.skip('ExtHostTreeView', function () { // {{SQL CARBON EDIT}} Skip suite
|
||||
|
||||
class RecordingShape extends mock<MainThreadTreeViewsShape>() {
|
||||
|
||||
@@ -35,7 +35,7 @@ suite.skip('ExtHostTreeView', function () {
|
||||
});
|
||||
}
|
||||
|
||||
override $reveal(): Promise<void> {
|
||||
override $reveal(treeViewId: string, itemInfo: { item: ITreeItem, parentChain: ITreeItem[] } | undefined, options: IRevealOptions): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -515,8 +515,8 @@ suite.skip('ExtHostTreeView', function () {
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepStrictEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1]!.item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1]!.parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
|
||||
});
|
||||
});
|
||||
@@ -534,8 +534,8 @@ suite.skip('ExtHostTreeView', function () {
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepStrictEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1]!.item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1]!.parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
|
||||
}));
|
||||
});
|
||||
@@ -561,8 +561,8 @@ suite.skip('ExtHostTreeView', function () {
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepStrictEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1]!.item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1]!.parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ select: false, focus: false, expand: false }, revealTarget.args[0][2]);
|
||||
});
|
||||
});
|
||||
@@ -592,8 +592,8 @@ suite.skip('ExtHostTreeView', function () {
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepStrictEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1]!.item));
|
||||
assert.deepStrictEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1]!.parentChain)).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
|
||||
});
|
||||
});
|
||||
@@ -633,8 +633,8 @@ suite.skip('ExtHostTreeView', function () {
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepStrictEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepStrictEqual({ handle: '0/0:b/0:bc', label: { label: 'bc' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b' }, removeUnsetKeys(revealTarget.args[0][1].item));
|
||||
assert.deepStrictEqual([{ handle: '0/0:b', label: { label: 'b' }, collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][1].parentChain).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ handle: '0/0:b/0:bc', label: { label: 'bc' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b' }, removeUnsetKeys(revealTarget.args[0][1]!.item));
|
||||
assert.deepStrictEqual([{ handle: '0/0:b', label: { label: 'b' }, collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][1]!.parentChain).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepStrictEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { MarkdownString, NotebookCellOutputItem, NotebookData } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { isEmptyObject } from 'vs/base/common/types';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
|
||||
@@ -81,4 +82,33 @@ suite('ExtHostTypeConverter', function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('Notebook metadata is ignored when using Notebook Serializer #125716', function () {
|
||||
|
||||
const d = new extHostTypes.NotebookData([]);
|
||||
d.cells.push(new extHostTypes.NotebookCellData(extHostTypes.NotebookCellKind.Code, 'hello', 'fooLang'));
|
||||
d.metadata = { custom: { foo: 'bar', bar: 123 } };
|
||||
|
||||
const dto = NotebookData.from(d);
|
||||
|
||||
assert.strictEqual(dto.cells.length, 1);
|
||||
assert.strictEqual(dto.cells[0].language, 'fooLang');
|
||||
assert.strictEqual(dto.cells[0].source, 'hello');
|
||||
assert.deepStrictEqual(dto.metadata, d.metadata);
|
||||
});
|
||||
|
||||
test('NotebookCellOutputItem', function () {
|
||||
|
||||
const item = extHostTypes.NotebookCellOutputItem.text('Hello', 'foo/bar');
|
||||
|
||||
const dto = NotebookCellOutputItem.from(item);
|
||||
|
||||
assert.strictEqual(dto.mime, 'foo/bar');
|
||||
assert.deepStrictEqual(dto.valueBytes, Array.from(new TextEncoder().encode('Hello')));
|
||||
|
||||
const item2 = NotebookCellOutputItem.to(dto);
|
||||
|
||||
assert.strictEqual(item2.mime, item.mime);
|
||||
assert.deepStrictEqual(item2.data, item.data);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ import { URI } from 'vs/base/common/uri';
|
||||
import * as types from 'vs/workbench/api/common/extHostTypes';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { assertType } from 'vs/base/common/types';
|
||||
import { notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
function assertToJSON(a: any, expected: any) {
|
||||
const raw = JSON.stringify(a);
|
||||
@@ -649,57 +648,46 @@ suite('ExtHostTypes', function () {
|
||||
assert.deepStrictEqual(md.value, '\n```html\n<img src=0 onerror="alert(1)">\n```\n');
|
||||
});
|
||||
|
||||
test('NotebookMetadata - defaults', function () {
|
||||
const obj = new types.NotebookDocumentMetadata();
|
||||
assert.strictEqual(obj.trusted, notebookDocumentMetadataDefaults.trusted);
|
||||
});
|
||||
test('NotebookCellOutputItem - factories', function () {
|
||||
|
||||
test('NotebookMetadata - with', function () {
|
||||
const obj = new types.NotebookDocumentMetadata();
|
||||
const newObj = obj.with({ trusted: false });
|
||||
assert.ok(obj !== newObj);
|
||||
const sameObj = newObj.with({ trusted: false });
|
||||
assert.ok(newObj === sameObj);
|
||||
assert.strictEqual(obj.trusted, true);
|
||||
assert.strictEqual(newObj.trusted, false);
|
||||
});
|
||||
assert.throws(() => {
|
||||
// invalid mime type
|
||||
new types.NotebookCellOutputItem(new Uint8Array(), 'invalid');
|
||||
});
|
||||
|
||||
test('NotebookMetadata - with custom', function () {
|
||||
const obj = new types.NotebookDocumentMetadata();
|
||||
const newObj = obj.with({ trusted: false, mycustom: { display: 'hello' } });
|
||||
assert.ok(obj !== newObj);
|
||||
const sameObj = newObj.with({ trusted: false });
|
||||
assert.ok(newObj === sameObj);
|
||||
assert.strictEqual(obj.trusted, true);
|
||||
assert.strictEqual(newObj.trusted, false);
|
||||
assert.deepStrictEqual(newObj.mycustom, { display: 'hello' });
|
||||
});
|
||||
// --- err
|
||||
|
||||
test('NotebookCellMetadata - with', function () {
|
||||
const obj = new types.NotebookCellMetadata(true, true);
|
||||
let item = types.NotebookCellOutputItem.error(new Error());
|
||||
assert.strictEqual(item.mime, 'application/vnd.code.notebook.error');
|
||||
item = types.NotebookCellOutputItem.error({ name: 'Hello' });
|
||||
assert.strictEqual(item.mime, 'application/vnd.code.notebook.error');
|
||||
|
||||
const newObj = obj.with({ inputCollapsed: false });
|
||||
assert.ok(obj !== newObj);
|
||||
assert.strictEqual(obj.inputCollapsed, true);
|
||||
assert.strictEqual(obj.custom, undefined);
|
||||
// --- JSON
|
||||
|
||||
assert.strictEqual(newObj.inputCollapsed, false);
|
||||
assert.strictEqual(newObj.custom, undefined);
|
||||
});
|
||||
item = types.NotebookCellOutputItem.json(1);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(1)));
|
||||
|
||||
test('NotebookCellMetadata - with custom', function () {
|
||||
const obj = new types.NotebookCellMetadata(true, true);
|
||||
const newObj = obj.with({ inputCollapsed: false, custom: { display: 'hello' } });
|
||||
assert.ok(obj !== newObj);
|
||||
const sameObj = newObj.with({ inputCollapsed: false });
|
||||
assert.ok(newObj === sameObj);
|
||||
assert.strictEqual(obj.inputCollapsed, true);
|
||||
assert.strictEqual(newObj.inputCollapsed, false);
|
||||
assert.deepStrictEqual(newObj.custom, { display: 'hello' });
|
||||
item = types.NotebookCellOutputItem.json(1, 'foo/bar');
|
||||
assert.strictEqual(item.mime, 'foo/bar');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(1)));
|
||||
|
||||
const newCustom = newObj.with({ anotherCustom: { display: 'hello2' } });
|
||||
assert.strictEqual(newCustom.inputCollapsed, false);
|
||||
assert.deepStrictEqual(newCustom.mycustom, undefined);
|
||||
assert.deepStrictEqual(newCustom.anotherCustom, { display: 'hello2' });
|
||||
item = types.NotebookCellOutputItem.json(true);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(true)));
|
||||
|
||||
item = types.NotebookCellOutputItem.json([true, 1, 'ddd']);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify([true, 1, 'ddd'], undefined, '\t')));
|
||||
|
||||
// --- text
|
||||
|
||||
item = types.NotebookCellOutputItem.text('Hęłlö');
|
||||
assert.strictEqual(item.mime, 'text/plain');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode('Hęłlö'));
|
||||
|
||||
item = types.NotebookCellOutputItem.text('Hęłlö', 'foo/bar');
|
||||
assert.strictEqual(item.mime, 'foo/bar');
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode('Hęłlö'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { mock } from 'vs/base/test/common/mock';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
@@ -14,6 +15,7 @@ import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDep
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
|
||||
import { ExtHostWebviewPanels } from 'vs/workbench/api/common/extHostWebviewPanels';
|
||||
import { webviewResourceBaseHost } from 'vs/workbench/api/common/shared/webview';
|
||||
import { EditorGroupColumn } from 'vs/workbench/common/editor';
|
||||
import type * as vscode from 'vscode';
|
||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||
@@ -30,11 +32,7 @@ suite('ExtHostWebview', () => {
|
||||
test('Cannot register multiple serializers for the same view type', async () => {
|
||||
const viewType = 'view.type';
|
||||
|
||||
const extHostWebviews = new ExtHostWebviews(rpcProtocol!, {
|
||||
webviewCspSource: '',
|
||||
webviewResourceRoot: '',
|
||||
isExtensionDevelopmentDebug: false,
|
||||
}, undefined, new NullLogService(), NullApiDeprecationService);
|
||||
const extHostWebviews = new ExtHostWebviews(rpcProtocol!, { remote: { authority: undefined, isRemote: false } }, undefined, new NullLogService(), NullApiDeprecationService);
|
||||
|
||||
const extHostWebviewPanels = new ExtHostWebviewPanels(rpcProtocol!, extHostWebviews, undefined);
|
||||
|
||||
@@ -78,95 +76,71 @@ suite('ExtHostWebview', () => {
|
||||
assert.strictEqual(lastInvokedDeserializer, serializerB);
|
||||
});
|
||||
|
||||
test('asWebviewUri for desktop vscode-resource scheme', () => {
|
||||
const extHostWebviews = new ExtHostWebviews(rpcProtocol!, {
|
||||
webviewCspSource: '',
|
||||
webviewResourceRoot: 'vscode-resource://{{resource}}',
|
||||
isExtensionDevelopmentDebug: false,
|
||||
}, undefined, new NullLogService(), NullApiDeprecationService);
|
||||
|
||||
const extHostWebviewPanels = new ExtHostWebviewPanels(rpcProtocol!, extHostWebviews, undefined);
|
||||
|
||||
const webview = extHostWebviewPanels.createWebviewPanel({} as any, 'type', 'title', 1, {});
|
||||
test('asWebviewUri for local file paths', () => {
|
||||
const webview = createWebview(rpcProtocol, /* remoteAuthority */undefined);
|
||||
|
||||
assert.strictEqual(
|
||||
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString(),
|
||||
'vscode-resource://file///Users/codey/file.html',
|
||||
(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString()),
|
||||
`https://file%2B.vscode-resource.${webviewResourceBaseHost}/Users/codey/file.html`,
|
||||
'Unix basic'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString(),
|
||||
'vscode-resource://file///Users/codey/file.html#frag',
|
||||
(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString()),
|
||||
`https://file%2B.vscode-resource.${webviewResourceBaseHost}/Users/codey/file.html#frag`,
|
||||
'Unix should preserve fragment'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString(),
|
||||
'vscode-resource://file///Users/codey/f%20ile.html',
|
||||
(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString()),
|
||||
`https://file%2B.vscode-resource.${webviewResourceBaseHost}/Users/codey/f%20ile.html`,
|
||||
'Unix with encoding'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString(),
|
||||
'vscode-resource://file//localhost/Users/codey/file.html',
|
||||
(webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString()),
|
||||
`https://file%2Blocalhost.vscode-resource.${webviewResourceBaseHost}/Users/codey/file.html`,
|
||||
'Unix should preserve authority'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString(),
|
||||
'vscode-resource://file///c%3A/codey/file.txt',
|
||||
(webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString()),
|
||||
`https://file%2B.vscode-resource.${webviewResourceBaseHost}/c%3A/codey/file.txt`,
|
||||
'Windows C drive'
|
||||
);
|
||||
});
|
||||
|
||||
test('asWebviewUri for web endpoint', () => {
|
||||
const extHostWebviews = new ExtHostWebviews(rpcProtocol!, {
|
||||
webviewCspSource: '',
|
||||
webviewResourceRoot: `https://{{uuid}}.webview.contoso.com/commit/{{resource}}`,
|
||||
isExtensionDevelopmentDebug: false,
|
||||
}, undefined, new NullLogService(), NullApiDeprecationService);
|
||||
|
||||
const extHostWebviewPanels = new ExtHostWebviewPanels(rpcProtocol!, extHostWebviews, undefined);
|
||||
|
||||
const webview = extHostWebviewPanels.createWebviewPanel({} as any, 'type', 'title', 1, {});
|
||||
|
||||
function stripEndpointUuid(input: string) {
|
||||
return input.replace(/^https:\/\/[^\.]+?\./, '');
|
||||
}
|
||||
test('asWebviewUri for remote file paths', () => {
|
||||
const webview = createWebview(rpcProtocol, /* remoteAuthority */ 'remote');
|
||||
|
||||
assert.strictEqual(
|
||||
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString()),
|
||||
'webview.contoso.com/commit/file///Users/codey/file.html',
|
||||
(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString()),
|
||||
`https://vscode-remote%2Bremote.vscode-resource.${webviewResourceBaseHost}/Users/codey/file.html`,
|
||||
'Unix basic'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString()),
|
||||
'webview.contoso.com/commit/file///Users/codey/file.html#frag',
|
||||
'Unix should preserve fragment'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString()),
|
||||
'webview.contoso.com/commit/file///Users/codey/f%20ile.html',
|
||||
'Unix with encoding'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString()),
|
||||
'webview.contoso.com/commit/file//localhost/Users/codey/file.html',
|
||||
'Unix should preserve authority'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString()),
|
||||
'webview.contoso.com/commit/file///c%3A/codey/file.txt',
|
||||
'Windows C drive'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function createWebview(rpcProtocol: (IExtHostRpcService & IExtHostContext) | undefined, remoteAuthority: string | undefined) {
|
||||
const extHostWebviews = new ExtHostWebviews(rpcProtocol!, {
|
||||
remote: {
|
||||
authority: remoteAuthority,
|
||||
isRemote: !!remoteAuthority,
|
||||
},
|
||||
}, undefined, new NullLogService(), NullApiDeprecationService);
|
||||
|
||||
const extHostWebviewPanels = new ExtHostWebviewPanels(rpcProtocol!, extHostWebviews, undefined);
|
||||
|
||||
const webview = extHostWebviewPanels.createWebviewPanel({
|
||||
extensionLocation: URI.from({
|
||||
scheme: remoteAuthority ? Schemas.vscodeRemote : Schemas.file,
|
||||
authority: remoteAuthority,
|
||||
path: '/ext/path',
|
||||
})
|
||||
} as IExtensionDescription, 'type', 'title', 1, {});
|
||||
return webview;
|
||||
}
|
||||
|
||||
|
||||
function createNoopMainThreadWebviews() {
|
||||
return new class extends mock<MainThreadWebviewManager>() {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
|
||||
suite('Diff editor input', () => {
|
||||
|
||||
class MyEditorInput extends EditorInput {
|
||||
readonly resource = undefined;
|
||||
|
||||
override get typeId(): string { return 'myEditorInput'; }
|
||||
override resolve(): any { return null; }
|
||||
}
|
||||
|
||||
test('basics', () => {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
|
||||
let counter = 0;
|
||||
let input = new MyEditorInput();
|
||||
input.onWillDispose(() => {
|
||||
assert(true);
|
||||
counter++;
|
||||
});
|
||||
|
||||
let otherInput = new MyEditorInput();
|
||||
otherInput.onWillDispose(() => {
|
||||
assert(true);
|
||||
counter++;
|
||||
});
|
||||
|
||||
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
|
||||
assert.strictEqual(diffInput.originalInput, input);
|
||||
assert.strictEqual(diffInput.modifiedInput, otherInput);
|
||||
assert(diffInput.matches(diffInput));
|
||||
assert(!diffInput.matches(otherInput));
|
||||
assert(!diffInput.matches(null));
|
||||
|
||||
diffInput.dispose();
|
||||
assert.strictEqual(counter, 0);
|
||||
});
|
||||
|
||||
test('disposes when input inside disposes', function () {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
|
||||
let counter = 0;
|
||||
let input = new MyEditorInput();
|
||||
let otherInput = new MyEditorInput();
|
||||
|
||||
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
diffInput.onWillDispose(() => {
|
||||
counter++;
|
||||
assert(true);
|
||||
});
|
||||
|
||||
input.dispose();
|
||||
|
||||
input = new MyEditorInput();
|
||||
otherInput = new MyEditorInput();
|
||||
|
||||
let diffInput2 = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
diffInput2.onWillDispose(() => {
|
||||
counter++;
|
||||
assert(true);
|
||||
});
|
||||
|
||||
otherInput.dispose();
|
||||
assert.strictEqual(counter, 2);
|
||||
});
|
||||
});
|
||||
@@ -4,15 +4,23 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorResourceAccessor, SideBySideEditor, IEditorInputWithPreferredResource } from 'vs/workbench/common/editor';
|
||||
import { EditorResourceAccessor, SideBySideEditor, IEditorInputWithPreferredResource, EditorInputCapabilities, isEditorIdentifier } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { workbenchInstantiationService, TestServiceAccessor, TestEditorInput } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { workbenchInstantiationService, TestServiceAccessor, TestEditorInput, registerTestEditor, registerTestFileEditor, registerTestResourceEditor, TestFileEditorInput, createEditorPart, registerTestSideBySideEditor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { toResource } from 'vs/base/test/common/utils';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { whenEditorClosed } from 'vs/workbench/browser/editor';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
|
||||
suite('Workbench editor', () => {
|
||||
suite('Workbench editor utils', () => {
|
||||
|
||||
class TestEditorInputWithPreferredResource extends TestEditorInput implements IEditorInputWithPreferredResource {
|
||||
|
||||
@@ -21,16 +29,93 @@ suite('Workbench editor', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const TEST_EDITOR_ID = 'MyTestEditorForEditors';
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let accessor: TestServiceAccessor;
|
||||
|
||||
async function createServices(): Promise<TestServiceAccessor> {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
|
||||
const part = await createEditorPart(instantiationService, disposables);
|
||||
|
||||
instantiationService.stub(IEditorGroupsService, part);
|
||||
|
||||
const editorService = instantiationService.createInstance(EditorService);
|
||||
instantiationService.stub(IEditorService, editorService);
|
||||
|
||||
return instantiationService.createInstance(TestServiceAccessor);
|
||||
}
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService();
|
||||
accessor = instantiationService.createInstance(TestServiceAccessor);
|
||||
|
||||
disposables.add(registerTestFileEditor());
|
||||
disposables.add(registerTestSideBySideEditor());
|
||||
disposables.add(registerTestResourceEditor());
|
||||
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)]));
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
accessor.untitledTextEditorService.dispose();
|
||||
|
||||
disposables.clear();
|
||||
});
|
||||
|
||||
test('EditorInputCapabilities', () => {
|
||||
const testInput1 = new TestFileEditorInput(URI.file('resource1'), 'testTypeId');
|
||||
const testInput2 = new TestFileEditorInput(URI.file('resource2'), 'testTypeId');
|
||||
|
||||
testInput1.capabilities = EditorInputCapabilities.None;
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.None), true);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Readonly), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Untitled), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.RequiresTrust), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Singleton), false);
|
||||
|
||||
testInput1.capabilities |= EditorInputCapabilities.Readonly;
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Readonly), true);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.None), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Untitled), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.RequiresTrust), false);
|
||||
assert.strictEqual(testInput1.hasCapability(EditorInputCapabilities.Singleton), false);
|
||||
|
||||
testInput1.capabilities = EditorInputCapabilities.None;
|
||||
testInput2.capabilities = EditorInputCapabilities.None;
|
||||
|
||||
const sideBySideInput = new SideBySideEditorInput('name', undefined, testInput1, testInput2);
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.None), true);
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Readonly), false);
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Untitled), false);
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.RequiresTrust), false);
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Singleton), false);
|
||||
|
||||
testInput1.capabilities |= EditorInputCapabilities.Readonly;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Readonly), false);
|
||||
|
||||
testInput2.capabilities |= EditorInputCapabilities.Readonly;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Readonly), true);
|
||||
|
||||
testInput1.capabilities |= EditorInputCapabilities.Untitled;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Untitled), false);
|
||||
|
||||
testInput2.capabilities |= EditorInputCapabilities.Untitled;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Untitled), true);
|
||||
|
||||
testInput1.capabilities |= EditorInputCapabilities.RequiresTrust;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.RequiresTrust), true);
|
||||
|
||||
testInput2.capabilities |= EditorInputCapabilities.RequiresTrust;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.RequiresTrust), true);
|
||||
|
||||
testInput1.capabilities |= EditorInputCapabilities.Singleton;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Singleton), true);
|
||||
|
||||
testInput2.capabilities |= EditorInputCapabilities.Singleton;
|
||||
assert.strictEqual(sideBySideInput.hasCapability(EditorInputCapabilities.Singleton), true);
|
||||
});
|
||||
|
||||
test('EditorResourceAccessor', () => {
|
||||
@@ -123,4 +208,57 @@ suite('Workbench editor', () => {
|
||||
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(fileWithPreferredResource)?.toString(), resource.toString());
|
||||
assert.strictEqual(EditorResourceAccessor.getOriginalUri(fileWithPreferredResource)?.toString(), preferredResource.toString());
|
||||
});
|
||||
|
||||
test('isEditorIdentifier', () => {
|
||||
assert.strictEqual(isEditorIdentifier(undefined), false);
|
||||
assert.strictEqual(isEditorIdentifier('undefined'), false);
|
||||
|
||||
const testInput1 = new TestFileEditorInput(URI.file('resource1'), 'testTypeId');
|
||||
assert.strictEqual(isEditorIdentifier(testInput1), false);
|
||||
assert.strictEqual(isEditorIdentifier({ editor: testInput1, groupId: 3 }), true);
|
||||
});
|
||||
|
||||
test('whenEditorClosed (single editor)', async function () {
|
||||
return testWhenEditorClosed(false, false, toResource.call(this, '/path/index.txt'));
|
||||
});
|
||||
|
||||
test('whenEditorClosed (multiple editor)', async function () {
|
||||
return testWhenEditorClosed(false, false, toResource.call(this, '/path/index.txt'), toResource.call(this, '/test.html'));
|
||||
});
|
||||
|
||||
test('whenEditorClosed (single editor, diff editor)', async function () {
|
||||
return testWhenEditorClosed(true, false, toResource.call(this, '/path/index.txt'));
|
||||
});
|
||||
|
||||
test('whenEditorClosed (multiple editor, diff editor)', async function () {
|
||||
return testWhenEditorClosed(true, false, toResource.call(this, '/path/index.txt'), toResource.call(this, '/test.html'));
|
||||
});
|
||||
|
||||
test('whenEditorClosed (single custom editor)', async function () {
|
||||
return testWhenEditorClosed(false, true, toResource.call(this, '/path/index.txt'));
|
||||
});
|
||||
|
||||
test('whenEditorClosed (multiple custom editor)', async function () {
|
||||
return testWhenEditorClosed(false, true, toResource.call(this, '/path/index.txt'), toResource.call(this, '/test.html'));
|
||||
});
|
||||
|
||||
async function testWhenEditorClosed(sideBySide: boolean, custom: boolean, ...resources: URI[]): Promise<void> {
|
||||
const accessor = await createServices();
|
||||
|
||||
for (const resource of resources) {
|
||||
if (custom) {
|
||||
await accessor.editorService.openEditor(new TestFileEditorInput(resource, 'testTypeId'), { pinned: true });
|
||||
} else if (sideBySide) {
|
||||
await accessor.editorService.openEditor(new SideBySideEditorInput('testSideBySideEditor', undefined, new TestFileEditorInput(resource, 'testTypeId'), new TestFileEditorInput(resource, 'testTypeId')), { pinned: true });
|
||||
} else {
|
||||
await accessor.editorService.openEditor({ resource, options: { pinned: true } });
|
||||
}
|
||||
}
|
||||
|
||||
const closedPromise = accessor.instantitionService.invokeFunction(accessor => whenEditorClosed(accessor, resources));
|
||||
|
||||
accessor.editorGroupService.activeGroup.closeAllEditors();
|
||||
|
||||
await closedPromise;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import * as assert from 'assert';
|
||||
import { TextDiffEditorModel } from 'vs/workbench/common/editor/textDiffEditorModel';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
suite('Workbench editor model', () => {
|
||||
suite('TextDiffEditorModel', () => {
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let accessor: TestServiceAccessor;
|
||||
@@ -22,7 +22,7 @@ suite('Workbench editor model', () => {
|
||||
accessor = instantiationService.createInstance(TestServiceAccessor);
|
||||
});
|
||||
|
||||
test('TextDiffEditorModel', async () => {
|
||||
test('basics', async () => {
|
||||
const dispose = accessor.textModelResolverService.registerTextModelContentProvider('test', {
|
||||
provideTextContent: async function (resource: URI): Promise<ITextModel | null> {
|
||||
if (resource.scheme === 'test') {
|
||||
@@ -36,8 +36,8 @@ suite('Workbench editor model', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let input = instantiationService.createInstance(ResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name', 'description', undefined);
|
||||
let otherInput = instantiationService.createInstance(ResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name2', 'description', undefined);
|
||||
let input = instantiationService.createInstance(TextResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name', 'description', undefined, undefined);
|
||||
let otherInput = instantiationService.createInstance(TextResourceEditorInput, URI.from({ scheme: 'test', authority: null!, path: 'thePath' }), 'name2', 'description', undefined, undefined);
|
||||
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
|
||||
let model = await diffInput.resolve() as TextDiffEditorModel;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorGroupModel, ISerializedEditorGroupModel, EditorCloseEvent } from 'vs/workbench/common/editor/editorGroupModel';
|
||||
import { EditorExtensions, IEditorInputFactoryRegistry, EditorInput, IFileEditorInput, IEditorInputSerializer, CloseDirection, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { EditorExtensions, IEditorInputFactoryRegistry, IFileEditorInput, IEditorInputSerializer, CloseDirection, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TestLifecycleService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
@@ -22,8 +22,9 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { TestContextService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
|
||||
suite('Workbench editor group model', () => {
|
||||
suite('EditorGroupModel', () => {
|
||||
|
||||
function inst(): IInstantiationService {
|
||||
let inst = new TestInstantiationService();
|
||||
@@ -166,6 +167,7 @@ suite('Workbench editor group model', () => {
|
||||
getEncoding() { return undefined; }
|
||||
setPreferredEncoding(encoding: string) { }
|
||||
setForceOpenAsBinary(): void { }
|
||||
setPreferredContents(contents: string): void { }
|
||||
setMode(mode: string) { }
|
||||
setPreferredMode(mode: string) { }
|
||||
isResolved(): boolean { return false; }
|
||||
@@ -256,7 +258,7 @@ suite('Workbench editor group model', () => {
|
||||
assert.strictEqual(clone.count, 3);
|
||||
|
||||
let didEditorLabelChange = false;
|
||||
const toDispose = clone.onDidEditorLabelChange(() => didEditorLabelChange = true);
|
||||
const toDispose = clone.onDidChangeEditorLabel(() => didEditorLabelChange = true);
|
||||
input1.setLabel();
|
||||
assert.ok(didEditorLabelChange);
|
||||
|
||||
@@ -1558,12 +1560,12 @@ suite('Workbench editor group model', () => {
|
||||
});
|
||||
|
||||
let label1ChangeCounter = 0;
|
||||
group1.onDidEditorLabelChange(() => {
|
||||
group1.onDidChangeEditorLabel(() => {
|
||||
label1ChangeCounter++;
|
||||
});
|
||||
|
||||
let label2ChangeCounter = 0;
|
||||
group2.onDidEditorLabelChange(() => {
|
||||
group2.onDidChangeEditorLabel(() => {
|
||||
label2ChangeCounter++;
|
||||
});
|
||||
|
||||
|
||||
@@ -4,11 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
|
||||
suite('Workbench editor input', () => {
|
||||
suite('EditorInput', () => {
|
||||
|
||||
class MyEditorInput extends EditorInput {
|
||||
readonly resource = undefined;
|
||||
@@ -17,7 +15,7 @@ suite('Workbench editor input', () => {
|
||||
override resolve(): any { return null; }
|
||||
}
|
||||
|
||||
test('EditorInput', () => {
|
||||
test('basics', () => {
|
||||
let counter = 0;
|
||||
let input = new MyEditorInput();
|
||||
let otherInput = new MyEditorInput();
|
||||
@@ -35,60 +33,4 @@ suite('Workbench editor input', () => {
|
||||
input.dispose();
|
||||
assert.strictEqual(counter, 1);
|
||||
});
|
||||
|
||||
test('DiffEditorInput', () => {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
|
||||
let counter = 0;
|
||||
let input = new MyEditorInput();
|
||||
input.onWillDispose(() => {
|
||||
assert(true);
|
||||
counter++;
|
||||
});
|
||||
|
||||
let otherInput = new MyEditorInput();
|
||||
otherInput.onWillDispose(() => {
|
||||
assert(true);
|
||||
counter++;
|
||||
});
|
||||
|
||||
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
|
||||
assert.strictEqual(diffInput.originalInput, input);
|
||||
assert.strictEqual(diffInput.modifiedInput, otherInput);
|
||||
assert(diffInput.matches(diffInput));
|
||||
assert(!diffInput.matches(otherInput));
|
||||
assert(!diffInput.matches(null));
|
||||
|
||||
diffInput.dispose();
|
||||
assert.strictEqual(counter, 0);
|
||||
});
|
||||
|
||||
test('DiffEditorInput disposes when input inside disposes', function () {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
|
||||
let counter = 0;
|
||||
let input = new MyEditorInput();
|
||||
let otherInput = new MyEditorInput();
|
||||
|
||||
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
diffInput.onWillDispose(() => {
|
||||
counter++;
|
||||
assert(true);
|
||||
});
|
||||
|
||||
input.dispose();
|
||||
|
||||
input = new MyEditorInput();
|
||||
otherInput = new MyEditorInput();
|
||||
|
||||
let diffInput2 = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
|
||||
diffInput2.onWillDispose(() => {
|
||||
counter++;
|
||||
assert(true);
|
||||
});
|
||||
|
||||
otherInput.dispose();
|
||||
assert.strictEqual(counter, 2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { EditorModel } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
@@ -26,8 +25,9 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
|
||||
suite('Workbench editor model', () => {
|
||||
suite('EditorModel', () => {
|
||||
|
||||
class MyEditorModel extends EditorModel { }
|
||||
class MyTextEditorModel extends BaseTextEditorModel {
|
||||
@@ -62,7 +62,7 @@ suite('Workbench editor model', () => {
|
||||
modeService = instantiationService.stub(IModeService, ModeServiceImpl);
|
||||
});
|
||||
|
||||
test('EditorModel', async () => {
|
||||
test('basics', async () => {
|
||||
let counter = 0;
|
||||
|
||||
const model = new MyEditorModel();
|
||||
|
||||
@@ -5,27 +5,34 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorPane, EditorMemento } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { EditorInput, EditorOptions, IEditorInputSerializer, IEditorInputFactoryRegistry, EditorExtensions } from 'vs/workbench/common/editor';
|
||||
import { WorkspaceTrustRequiredEditor } from 'vs/workbench/browser/parts/editor/workspaceTrustRequiredEditor';
|
||||
import { IEditorInputSerializer, IEditorInputFactoryRegistry, EditorExtensions, EditorInputCapabilities, IEditorDescriptor, IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService, registerTestResourceEditor, TestEditorInput } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService, registerTestResourceEditor, TestEditorInput, createEditorPart } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEditorRegistry, EditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { EditorDescriptor, EditorRegistry } from 'vs/workbench/browser/editor';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { extUri } from 'vs/base/common/resources';
|
||||
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { TestWorkspaceTrustManagementService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
|
||||
const NullThemeService = new TestThemeService();
|
||||
|
||||
let EditorRegistry: IEditorRegistry = Registry.as(EditorExtensions.Editors);
|
||||
let EditorInputRegistry: IEditorInputFactoryRegistry = Registry.as(EditorExtensions.EditorInputFactories);
|
||||
const editorRegistry: EditorRegistry = Registry.as(EditorExtensions.Editors);
|
||||
const editorInputRegistry: IEditorInputFactoryRegistry = Registry.as(EditorExtensions.EditorInputFactories);
|
||||
|
||||
class TestEditor extends EditorPane {
|
||||
|
||||
@@ -69,8 +76,8 @@ class TestInput extends EditorInput {
|
||||
|
||||
readonly resource = undefined;
|
||||
|
||||
override getPreferredEditorId(ids: string[]) {
|
||||
return ids[1];
|
||||
override prefersEditor<T extends IEditorDescriptor<IEditorPane>>(editors: T[]): T | undefined {
|
||||
return editors[1];
|
||||
}
|
||||
|
||||
override get typeId(): string {
|
||||
@@ -94,90 +101,90 @@ class OtherTestInput extends EditorInput {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
class TestResourceEditorInput extends ResourceEditorInput { }
|
||||
class TestResourceEditorInput extends TextResourceEditorInput { }
|
||||
|
||||
suite('Workbench EditorPane', () => {
|
||||
suite('EditorPane', () => {
|
||||
|
||||
test('EditorPane API', async () => {
|
||||
let e = new TestEditor(NullTelemetryService);
|
||||
let input = new OtherTestInput();
|
||||
let options = new EditorOptions();
|
||||
const editor = new TestEditor(NullTelemetryService);
|
||||
const input = new OtherTestInput();
|
||||
const options = {};
|
||||
|
||||
assert(!e.isVisible());
|
||||
assert(!e.input);
|
||||
assert(!editor.isVisible());
|
||||
assert(!editor.input);
|
||||
|
||||
await e.setInput(input, options, Object.create(null), CancellationToken.None);
|
||||
assert.strictEqual(<any>input, e.input);
|
||||
await editor.setInput(input, options, Object.create(null), CancellationToken.None);
|
||||
assert.strictEqual(<any>input, editor.input);
|
||||
const group = new TestEditorGroupView(1);
|
||||
e.setVisible(true, group);
|
||||
assert(e.isVisible());
|
||||
assert.strictEqual(e.group, group);
|
||||
editor.setVisible(true, group);
|
||||
assert(editor.isVisible());
|
||||
assert.strictEqual(editor.group, group);
|
||||
input.onWillDispose(() => {
|
||||
assert(false);
|
||||
});
|
||||
e.dispose();
|
||||
e.clearInput();
|
||||
e.setVisible(false, group);
|
||||
assert(!e.isVisible());
|
||||
assert(!e.input);
|
||||
assert(!e.getControl());
|
||||
editor.dispose();
|
||||
editor.clearInput();
|
||||
editor.setVisible(false, group);
|
||||
assert(!editor.isVisible());
|
||||
assert(!editor.input);
|
||||
assert(!editor.getControl());
|
||||
});
|
||||
|
||||
test('EditorDescriptor', () => {
|
||||
let d = EditorDescriptor.create(TestEditor, 'id', 'name');
|
||||
assert.strictEqual(d.getId(), 'id');
|
||||
assert.strictEqual(d.getName(), 'name');
|
||||
const editorDescriptor = EditorDescriptor.create(TestEditor, 'id', 'name');
|
||||
assert.strictEqual(editorDescriptor.typeId, 'id');
|
||||
assert.strictEqual(editorDescriptor.name, 'name');
|
||||
});
|
||||
|
||||
test('Editor Registration', function () {
|
||||
let d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
let d2 = EditorDescriptor.create(OtherTestEditor, 'id2', 'name');
|
||||
const editorDescriptor1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
const editorDescriptor2 = EditorDescriptor.create(OtherTestEditor, 'id2', 'name');
|
||||
|
||||
let oldEditorsCnt = EditorRegistry.getEditors().length;
|
||||
let oldInputCnt = (<any>EditorRegistry).getEditorInputs().length;
|
||||
const oldEditorsCnt = editorRegistry.getEditors().length;
|
||||
const oldInputCnt = editorRegistry.getEditorInputs().length;
|
||||
|
||||
const dispose1 = EditorRegistry.registerEditor(d1, [new SyncDescriptor(TestInput)]);
|
||||
const dispose2 = EditorRegistry.registerEditor(d2, [new SyncDescriptor(TestInput), new SyncDescriptor(OtherTestInput)]);
|
||||
const dispose1 = editorRegistry.registerEditor(editorDescriptor1, [new SyncDescriptor(TestInput)]);
|
||||
const dispose2 = editorRegistry.registerEditor(editorDescriptor2, [new SyncDescriptor(TestInput), new SyncDescriptor(OtherTestInput)]);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditors().length, oldEditorsCnt + 2);
|
||||
assert.strictEqual((<any>EditorRegistry).getEditorInputs().length, oldInputCnt + 3);
|
||||
assert.strictEqual(editorRegistry.getEditors().length, oldEditorsCnt + 2);
|
||||
assert.strictEqual(editorRegistry.getEditorInputs().length, oldInputCnt + 3);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditor(new TestInput()), d2);
|
||||
assert.strictEqual(EditorRegistry.getEditor(new OtherTestInput()), d2);
|
||||
assert.strictEqual(editorRegistry.getEditor(new TestInput()), editorDescriptor2);
|
||||
assert.strictEqual(editorRegistry.getEditor(new OtherTestInput()), editorDescriptor2);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditorById('id1'), d1);
|
||||
assert.strictEqual(EditorRegistry.getEditorById('id2'), d2);
|
||||
assert(!EditorRegistry.getEditorById('id3'));
|
||||
assert.strictEqual(editorRegistry.getEditorByType('id1'), editorDescriptor1);
|
||||
assert.strictEqual(editorRegistry.getEditorByType('id2'), editorDescriptor2);
|
||||
assert(!editorRegistry.getEditorByType('id3'));
|
||||
|
||||
dispose([dispose1, dispose2]);
|
||||
});
|
||||
|
||||
test('Editor Lookup favors specific class over superclass (match on specific class)', function () {
|
||||
let d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
const d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registerTestResourceEditor());
|
||||
disposables.add(EditorRegistry.registerEditor(d1, [new SyncDescriptor(TestResourceEditorInput)]));
|
||||
disposables.add(editorRegistry.registerEditor(d1, [new SyncDescriptor(TestResourceEditorInput)]));
|
||||
|
||||
let inst = workbenchInstantiationService();
|
||||
const inst = workbenchInstantiationService();
|
||||
|
||||
const editor = EditorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const editor = editorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined, undefined))!.instantiate(inst);
|
||||
assert.strictEqual(editor.getId(), 'testEditor');
|
||||
|
||||
const otherEditor = EditorRegistry.getEditor(inst.createInstance(ResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const otherEditor = editorRegistry.getEditor(inst.createInstance(TextResourceEditorInput, URI.file('/fake'), 'fake', '', undefined, undefined))!.instantiate(inst);
|
||||
assert.strictEqual(otherEditor.getId(), 'workbench.editors.textResourceEditor');
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Editor Lookup favors specific class over superclass (match on super class)', function () {
|
||||
let inst = workbenchInstantiationService();
|
||||
const inst = workbenchInstantiationService();
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registerTestResourceEditor());
|
||||
const editor = EditorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const editor = editorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined, undefined))!.instantiate(inst);
|
||||
|
||||
assert.strictEqual('workbench.editors.textResourceEditor', editor.getId());
|
||||
|
||||
@@ -186,17 +193,17 @@ suite('Workbench EditorPane', () => {
|
||||
|
||||
test('Editor Input Serializer', function () {
|
||||
const testInput = new TestEditorInput(URI.file('/fake'), 'testTypeId');
|
||||
workbenchInstantiationService().invokeFunction(accessor => EditorInputRegistry.start(accessor));
|
||||
const disposable = EditorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer);
|
||||
workbenchInstantiationService().invokeFunction(accessor => editorInputRegistry.start(accessor));
|
||||
const disposable = editorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer);
|
||||
|
||||
let factory = EditorInputRegistry.getEditorInputSerializer('testTypeId');
|
||||
let factory = editorInputRegistry.getEditorInputSerializer('testTypeId');
|
||||
assert(factory);
|
||||
|
||||
factory = EditorInputRegistry.getEditorInputSerializer(testInput);
|
||||
factory = editorInputRegistry.getEditorInputSerializer(testInput);
|
||||
assert(factory);
|
||||
|
||||
// throws when registering serializer for same type
|
||||
assert.throws(() => EditorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer));
|
||||
assert.throws(() => editorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer));
|
||||
|
||||
disposable.dispose();
|
||||
});
|
||||
@@ -277,7 +284,7 @@ suite('Workbench EditorPane', () => {
|
||||
interface TestViewState { line: number; }
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, editorGroupService);
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, editorGroupService);
|
||||
|
||||
memento.saveEditorState(testGroup0, URI.file('/some/folder/file-1.txt'), { line: 1 });
|
||||
memento.saveEditorState(testGroup0, URI.file('/some/folder/file-2.txt'), { line: 2 });
|
||||
@@ -320,7 +327,7 @@ suite('Workbench EditorPane', () => {
|
||||
}
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
|
||||
const testInputA = new TestEditorInput(URI.file('/A'));
|
||||
|
||||
@@ -358,7 +365,7 @@ suite('Workbench EditorPane', () => {
|
||||
}
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
|
||||
const testInputA = new TestEditorInput(URI.file('/A'));
|
||||
|
||||
@@ -393,4 +400,72 @@ suite('Workbench EditorPane', () => {
|
||||
res = memento.loadEditorState(testGroup0, testInputB);
|
||||
assert.ok(!res);
|
||||
});
|
||||
|
||||
test('WorkspaceTrustRequiredEditor', async function () {
|
||||
|
||||
class TrustRequiredTestEditor extends EditorPane {
|
||||
constructor(@ITelemetryService telemetryService: ITelemetryService) {
|
||||
super('TestEditor', NullTelemetryService, NullThemeService, new TestStorageService());
|
||||
}
|
||||
|
||||
override getId(): string { return 'trustRequiredTestEditor'; }
|
||||
layout(): void { }
|
||||
createEditor(): any { }
|
||||
}
|
||||
|
||||
class TrustRequiredTestInput extends EditorInput {
|
||||
|
||||
readonly resource = undefined;
|
||||
|
||||
override get typeId(): string {
|
||||
return 'trustRequiredTestInput';
|
||||
}
|
||||
|
||||
override get capabilities(): EditorInputCapabilities {
|
||||
return EditorInputCapabilities.RequiresTrust;
|
||||
}
|
||||
|
||||
override resolve(): any {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
const workspaceTrustService = instantiationService.createInstance(TestWorkspaceTrustManagementService);
|
||||
instantiationService.stub(IWorkspaceTrustManagementService, workspaceTrustService);
|
||||
workspaceTrustService.setWorkspaceTrust(false);
|
||||
|
||||
const editorPart = await createEditorPart(instantiationService, disposables);
|
||||
instantiationService.stub(IEditorGroupsService, editorPart);
|
||||
|
||||
const editorService = instantiationService.createInstance(EditorService);
|
||||
instantiationService.stub(IEditorService, editorService);
|
||||
|
||||
const group = editorPart.activeGroup;
|
||||
|
||||
const editorDescriptor = EditorDescriptor.create(TrustRequiredTestEditor, 'id1', 'name');
|
||||
disposables.add(editorRegistry.registerEditor(editorDescriptor, [new SyncDescriptor(TrustRequiredTestInput)]));
|
||||
|
||||
const testInput = new TrustRequiredTestInput();
|
||||
|
||||
await group.openEditor(testInput);
|
||||
assert.strictEqual(group.activeEditorPane?.getId(), WorkspaceTrustRequiredEditor.ID);
|
||||
|
||||
const getEditorPaneIdAsync = () => new Promise(resolve => {
|
||||
disposables.add(editorService.onDidActiveEditorChange(event => {
|
||||
resolve(group.activeEditorPane?.getId());
|
||||
}));
|
||||
});
|
||||
|
||||
workspaceTrustService.setWorkspaceTrust(true);
|
||||
|
||||
assert.strictEqual(await getEditorPaneIdAsync(), 'trustRequiredTestEditor');
|
||||
|
||||
workspaceTrustService.setWorkspaceTrust(false);
|
||||
assert.strictEqual(await getEditorPaneIdAsync(), WorkspaceTrustRequiredEditor.ID);
|
||||
|
||||
dispose(disposables);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,50 +5,51 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { AbstractResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { EditorInputCapabilities, Verbosity } from 'vs/workbench/common/editor';
|
||||
|
||||
suite('Resource text editors', () => {
|
||||
suite('ResourceEditorInput', () => {
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let accessor: TestServiceAccessor;
|
||||
|
||||
class TestResourceEditorInput extends AbstractResourceEditorInput {
|
||||
|
||||
readonly typeId = 'test.typeId';
|
||||
|
||||
constructor(
|
||||
resource: URI,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IFileService fileService: IFileService
|
||||
) {
|
||||
super(resource, resource, labelService, fileService);
|
||||
}
|
||||
}
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService();
|
||||
accessor = instantiationService.createInstance(TestServiceAccessor);
|
||||
});
|
||||
|
||||
test('basics', async () => {
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
const resource = URI.from({ scheme: 'testResource', path: 'thePath/of/the/resource.txt' });
|
||||
|
||||
const input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, resource, 'The Name', 'The Description', undefined);
|
||||
const input = instantiationService.createInstance(TestResourceEditorInput, resource);
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(input.getName().length > 0);
|
||||
|
||||
assert.ok(model);
|
||||
assert.strictEqual(snapshotToString(((model as ResourceEditorModel).createSnapshot()!)), 'function test() {}');
|
||||
});
|
||||
assert.ok(input.getDescription(Verbosity.SHORT)!.length > 0);
|
||||
assert.ok(input.getDescription(Verbosity.MEDIUM)!.length > 0);
|
||||
assert.ok(input.getDescription(Verbosity.LONG)!.length > 0);
|
||||
|
||||
test('custom mode', async () => {
|
||||
ModesRegistry.registerLanguage({
|
||||
id: 'resource-input-test',
|
||||
});
|
||||
assert.ok(input.getTitle(Verbosity.SHORT).length > 0);
|
||||
assert.ok(input.getTitle(Verbosity.MEDIUM).length > 0);
|
||||
assert.ok(input.getTitle(Verbosity.LONG).length > 0);
|
||||
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, resource, 'The Name', 'The Description', 'resource-input-test');
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(model);
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), 'resource-input-test');
|
||||
|
||||
input.setMode('text');
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), PLAINTEXT_MODE_ID);
|
||||
assert.strictEqual(input.hasCapability(EditorInputCapabilities.Readonly), false);
|
||||
assert.strictEqual(input.hasCapability(EditorInputCapabilities.Untitled), true);
|
||||
assert.strictEqual(input.isOrphaned(), false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
|
||||
suite('SideBySideEditorInput', () => {
|
||||
|
||||
class MyEditorInput extends EditorInput {
|
||||
readonly resource = undefined;
|
||||
|
||||
override get typeId(): string { return 'myEditorInput'; }
|
||||
override resolve(): any { return null; }
|
||||
|
||||
fireCapabilitiesChangeEvent(): void {
|
||||
this._onDidChangeCapabilities.fire();
|
||||
}
|
||||
|
||||
fireDirtyChangeEvent(): void {
|
||||
this._onDidChangeDirty.fire();
|
||||
}
|
||||
|
||||
fireLabelChangeEvent(): void {
|
||||
this._onDidChangeLabel.fire();
|
||||
}
|
||||
}
|
||||
|
||||
test('events dispatching', () => {
|
||||
let input = new MyEditorInput();
|
||||
let otherInput = new MyEditorInput();
|
||||
|
||||
const sideBySideInut = new SideBySideEditorInput('name', 'description', otherInput, input);
|
||||
|
||||
let capabilitiesChangeCounter = 0;
|
||||
sideBySideInut.onDidChangeCapabilities(() => capabilitiesChangeCounter++);
|
||||
|
||||
let dirtyChangeCounter = 0;
|
||||
sideBySideInut.onDidChangeDirty(() => dirtyChangeCounter++);
|
||||
|
||||
let labelChangeCounter = 0;
|
||||
sideBySideInut.onDidChangeLabel(() => labelChangeCounter++);
|
||||
|
||||
input.fireCapabilitiesChangeEvent();
|
||||
assert.strictEqual(capabilitiesChangeCounter, 1);
|
||||
|
||||
otherInput.fireCapabilitiesChangeEvent();
|
||||
assert.strictEqual(capabilitiesChangeCounter, 2);
|
||||
|
||||
input.fireDirtyChangeEvent();
|
||||
otherInput.fireDirtyChangeEvent();
|
||||
assert.strictEqual(dirtyChangeCounter, 1);
|
||||
|
||||
input.fireLabelChangeEvent();
|
||||
otherInput.fireLabelChangeEvent();
|
||||
assert.strictEqual(labelChangeCounter, 1);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
|
||||
|
||||
suite('TextResourceEditorInput', () => {
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let accessor: TestServiceAccessor;
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService();
|
||||
accessor = instantiationService.createInstance(TestServiceAccessor);
|
||||
});
|
||||
|
||||
test('basics', async () => {
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined, undefined);
|
||||
|
||||
const model = await input.resolve();
|
||||
|
||||
assert.ok(model);
|
||||
assert.strictEqual(snapshotToString(((model as TextResourceEditorModel).createSnapshot()!)), 'function test() {}');
|
||||
});
|
||||
|
||||
test('preferred mode (via ctor)', async () => {
|
||||
ModesRegistry.registerLanguage({
|
||||
id: 'resource-input-test',
|
||||
});
|
||||
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', 'resource-input-test', undefined);
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(model);
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), 'resource-input-test');
|
||||
|
||||
input.setMode('text');
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), PLAINTEXT_MODE_ID);
|
||||
|
||||
await input.resolve();
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), PLAINTEXT_MODE_ID);
|
||||
});
|
||||
|
||||
test('preferred mode (via setPreferredMode)', async () => {
|
||||
ModesRegistry.registerLanguage({
|
||||
id: 'resource-input-test',
|
||||
});
|
||||
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined, undefined);
|
||||
input.setPreferredMode('resource-input-test');
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(model);
|
||||
assert.strictEqual(model.textEditorModel?.getModeId(), 'resource-input-test');
|
||||
});
|
||||
|
||||
test('preferred contents (via ctor)', async () => {
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined, 'My Resource Input Contents');
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(model);
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'My Resource Input Contents');
|
||||
|
||||
model.textEditorModel.setValue('Some other contents');
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'Some other contents');
|
||||
|
||||
await input.resolve();
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'Some other contents'); // preferred contents only used once
|
||||
});
|
||||
|
||||
test('preferred contents (via setPreferredContents)', async () => {
|
||||
const resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' });
|
||||
accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource);
|
||||
|
||||
const input = instantiationService.createInstance(TextResourceEditorInput, resource, 'The Name', 'The Description', undefined, undefined);
|
||||
input.setPreferredContents('My Resource Input Contents');
|
||||
|
||||
const model = await input.resolve();
|
||||
assert.ok(model);
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'My Resource Input Contents');
|
||||
|
||||
model.textEditorModel.setValue('Some other contents');
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'Some other contents');
|
||||
|
||||
await input.resolve();
|
||||
assert.strictEqual(model.textEditorModel?.getValue(), 'Some other contents'); // preferred contents only used once
|
||||
});
|
||||
});
|
||||
331
src/vs/workbench/test/browser/quickAccess.test.ts
Normal file
331
src/vs/workbench/test/browser/quickAccess.test.ts
Normal file
@@ -0,0 +1,331 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IQuickAccessRegistry, Extensions, IQuickAccessProvider, QuickAccessRegistry } from 'vs/platform/quickinput/common/quickAccess';
|
||||
import { IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { DisposableStore, toDisposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { PickerQuickAccessProvider, FastAndSlowPicks } from 'vs/platform/quickinput/browser/pickerQuickAccess';
|
||||
|
||||
suite('QuickAccess', () => {
|
||||
|
||||
let instantiationService: IInstantiationService;
|
||||
let accessor: TestServiceAccessor;
|
||||
|
||||
let providerDefaultCalled = false;
|
||||
let providerDefaultCanceled = false;
|
||||
let providerDefaultDisposed = false;
|
||||
|
||||
let provider1Called = false;
|
||||
let provider1Canceled = false;
|
||||
let provider1Disposed = false;
|
||||
|
||||
let provider2Called = false;
|
||||
let provider2Canceled = false;
|
||||
let provider2Disposed = false;
|
||||
|
||||
let provider3Called = false;
|
||||
let provider3Canceled = false;
|
||||
let provider3Disposed = false;
|
||||
|
||||
class TestProviderDefault implements IQuickAccessProvider {
|
||||
|
||||
constructor(@IQuickInputService private readonly quickInputService: IQuickInputService, disposables: DisposableStore) { }
|
||||
|
||||
provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): IDisposable {
|
||||
assert.ok(picker);
|
||||
providerDefaultCalled = true;
|
||||
token.onCancellationRequested(() => providerDefaultCanceled = true);
|
||||
|
||||
// bring up provider #3
|
||||
setTimeout(() => this.quickInputService.quickAccess.show(providerDescriptor3.prefix));
|
||||
|
||||
return toDisposable(() => providerDefaultDisposed = true);
|
||||
}
|
||||
}
|
||||
|
||||
class TestProvider1 implements IQuickAccessProvider {
|
||||
provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): IDisposable {
|
||||
assert.ok(picker);
|
||||
provider1Called = true;
|
||||
token.onCancellationRequested(() => provider1Canceled = true);
|
||||
|
||||
return toDisposable(() => provider1Disposed = true);
|
||||
}
|
||||
}
|
||||
|
||||
class TestProvider2 implements IQuickAccessProvider {
|
||||
provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): IDisposable {
|
||||
assert.ok(picker);
|
||||
provider2Called = true;
|
||||
token.onCancellationRequested(() => provider2Canceled = true);
|
||||
|
||||
return toDisposable(() => provider2Disposed = true);
|
||||
}
|
||||
}
|
||||
|
||||
class TestProvider3 implements IQuickAccessProvider {
|
||||
provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): IDisposable {
|
||||
assert.ok(picker);
|
||||
provider3Called = true;
|
||||
token.onCancellationRequested(() => provider3Canceled = true);
|
||||
|
||||
// hide without picking
|
||||
setTimeout(() => picker.hide());
|
||||
|
||||
return toDisposable(() => provider3Disposed = true);
|
||||
}
|
||||
}
|
||||
|
||||
const providerDescriptorDefault = { ctor: TestProviderDefault, prefix: '', helpEntries: [] };
|
||||
const providerDescriptor1 = { ctor: TestProvider1, prefix: 'test', helpEntries: [] };
|
||||
const providerDescriptor2 = { ctor: TestProvider2, prefix: 'test something', helpEntries: [] };
|
||||
const providerDescriptor3 = { ctor: TestProvider3, prefix: 'changed', helpEntries: [] };
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService();
|
||||
accessor = instantiationService.createInstance(TestServiceAccessor);
|
||||
});
|
||||
|
||||
test('registry', () => {
|
||||
const registry = (Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess));
|
||||
const restore = (registry as QuickAccessRegistry).clear();
|
||||
|
||||
assert.ok(!registry.getQuickAccessProvider('test'));
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registry.registerQuickAccessProvider(providerDescriptorDefault));
|
||||
assert(registry.getQuickAccessProvider('') === providerDescriptorDefault);
|
||||
assert(registry.getQuickAccessProvider('test') === providerDescriptorDefault);
|
||||
|
||||
const disposable = disposables.add(registry.registerQuickAccessProvider(providerDescriptor1));
|
||||
assert(registry.getQuickAccessProvider('test') === providerDescriptor1);
|
||||
|
||||
const providers = registry.getQuickAccessProviders();
|
||||
assert(providers.some(provider => provider.prefix === 'test'));
|
||||
|
||||
disposable.dispose();
|
||||
assert(registry.getQuickAccessProvider('test') === providerDescriptorDefault);
|
||||
|
||||
disposables.dispose();
|
||||
assert.ok(!registry.getQuickAccessProvider('test'));
|
||||
|
||||
restore();
|
||||
});
|
||||
|
||||
test('provider', async () => {
|
||||
const registry = (Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess));
|
||||
const restore = (registry as QuickAccessRegistry).clear();
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registry.registerQuickAccessProvider(providerDescriptorDefault));
|
||||
disposables.add(registry.registerQuickAccessProvider(providerDescriptor1));
|
||||
disposables.add(registry.registerQuickAccessProvider(providerDescriptor2));
|
||||
disposables.add(registry.registerQuickAccessProvider(providerDescriptor3));
|
||||
|
||||
accessor.quickInputService.quickAccess.show('test');
|
||||
assert.strictEqual(providerDefaultCalled, false);
|
||||
assert.strictEqual(provider1Called, true);
|
||||
assert.strictEqual(provider2Called, false);
|
||||
assert.strictEqual(provider3Called, false);
|
||||
assert.strictEqual(providerDefaultCanceled, false);
|
||||
assert.strictEqual(provider1Canceled, false);
|
||||
assert.strictEqual(provider2Canceled, false);
|
||||
assert.strictEqual(provider3Canceled, false);
|
||||
assert.strictEqual(providerDefaultDisposed, false);
|
||||
assert.strictEqual(provider1Disposed, false);
|
||||
assert.strictEqual(provider2Disposed, false);
|
||||
assert.strictEqual(provider3Disposed, false);
|
||||
provider1Called = false;
|
||||
|
||||
accessor.quickInputService.quickAccess.show('test something');
|
||||
assert.strictEqual(providerDefaultCalled, false);
|
||||
assert.strictEqual(provider1Called, false);
|
||||
assert.strictEqual(provider2Called, true);
|
||||
assert.strictEqual(provider3Called, false);
|
||||
assert.strictEqual(providerDefaultCanceled, false);
|
||||
assert.strictEqual(provider1Canceled, true);
|
||||
assert.strictEqual(provider2Canceled, false);
|
||||
assert.strictEqual(provider3Canceled, false);
|
||||
assert.strictEqual(providerDefaultDisposed, false);
|
||||
assert.strictEqual(provider1Disposed, true);
|
||||
assert.strictEqual(provider2Disposed, false);
|
||||
assert.strictEqual(provider3Disposed, false);
|
||||
provider2Called = false;
|
||||
provider1Canceled = false;
|
||||
provider1Disposed = false;
|
||||
|
||||
accessor.quickInputService.quickAccess.show('usedefault');
|
||||
assert.strictEqual(providerDefaultCalled, true);
|
||||
assert.strictEqual(provider1Called, false);
|
||||
assert.strictEqual(provider2Called, false);
|
||||
assert.strictEqual(provider3Called, false);
|
||||
assert.strictEqual(providerDefaultCanceled, false);
|
||||
assert.strictEqual(provider1Canceled, false);
|
||||
assert.strictEqual(provider2Canceled, true);
|
||||
assert.strictEqual(provider3Canceled, false);
|
||||
assert.strictEqual(providerDefaultDisposed, false);
|
||||
assert.strictEqual(provider1Disposed, false);
|
||||
assert.strictEqual(provider2Disposed, true);
|
||||
assert.strictEqual(provider3Disposed, false);
|
||||
|
||||
await timeout(1);
|
||||
|
||||
assert.strictEqual(providerDefaultCanceled, true);
|
||||
assert.strictEqual(providerDefaultDisposed, true);
|
||||
assert.strictEqual(provider3Called, true);
|
||||
|
||||
await timeout(1);
|
||||
|
||||
assert.strictEqual(provider3Canceled, true);
|
||||
assert.strictEqual(provider3Disposed, true);
|
||||
|
||||
disposables.dispose();
|
||||
|
||||
restore();
|
||||
});
|
||||
|
||||
let fastProviderCalled = false;
|
||||
let slowProviderCalled = false;
|
||||
let fastAndSlowProviderCalled = false;
|
||||
|
||||
let slowProviderCanceled = false;
|
||||
let fastAndSlowProviderCanceled = false;
|
||||
|
||||
class FastTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
|
||||
|
||||
constructor() {
|
||||
super('fast');
|
||||
}
|
||||
|
||||
protected _getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Array<IQuickPickItem> {
|
||||
fastProviderCalled = true;
|
||||
|
||||
return [{ label: 'Fast Pick' }];
|
||||
}
|
||||
}
|
||||
|
||||
class SlowTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
|
||||
|
||||
constructor() {
|
||||
super('slow');
|
||||
}
|
||||
|
||||
protected async _getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IQuickPickItem>> {
|
||||
slowProviderCalled = true;
|
||||
|
||||
await timeout(1);
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
slowProviderCanceled = true;
|
||||
}
|
||||
|
||||
return [{ label: 'Slow Pick' }];
|
||||
}
|
||||
}
|
||||
|
||||
class FastAndSlowTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
|
||||
|
||||
constructor() {
|
||||
super('bothFastAndSlow');
|
||||
}
|
||||
|
||||
protected _getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): FastAndSlowPicks<IQuickPickItem> {
|
||||
fastAndSlowProviderCalled = true;
|
||||
|
||||
return {
|
||||
picks: [{ label: 'Fast Pick' }],
|
||||
additionalPicks: (async () => {
|
||||
await timeout(1);
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
fastAndSlowProviderCanceled = true;
|
||||
}
|
||||
|
||||
return [{ label: 'Slow Pick' }];
|
||||
})()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const fastProviderDescriptor = { ctor: FastTestQuickPickProvider, prefix: 'fast', helpEntries: [] };
|
||||
const slowProviderDescriptor = { ctor: SlowTestQuickPickProvider, prefix: 'slow', helpEntries: [] };
|
||||
const fastAndSlowProviderDescriptor = { ctor: FastAndSlowTestQuickPickProvider, prefix: 'bothFastAndSlow', helpEntries: [] };
|
||||
|
||||
test('quick pick access - show()', async () => {
|
||||
const registry = (Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess));
|
||||
const restore = (registry as QuickAccessRegistry).clear();
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registry.registerQuickAccessProvider(fastProviderDescriptor));
|
||||
disposables.add(registry.registerQuickAccessProvider(slowProviderDescriptor));
|
||||
disposables.add(registry.registerQuickAccessProvider(fastAndSlowProviderDescriptor));
|
||||
|
||||
accessor.quickInputService.quickAccess.show('fast');
|
||||
assert.strictEqual(fastProviderCalled, true);
|
||||
assert.strictEqual(slowProviderCalled, false);
|
||||
assert.strictEqual(fastAndSlowProviderCalled, false);
|
||||
fastProviderCalled = false;
|
||||
|
||||
accessor.quickInputService.quickAccess.show('slow');
|
||||
await timeout(2);
|
||||
|
||||
assert.strictEqual(fastProviderCalled, false);
|
||||
assert.strictEqual(slowProviderCalled, true);
|
||||
assert.strictEqual(slowProviderCanceled, false);
|
||||
assert.strictEqual(fastAndSlowProviderCalled, false);
|
||||
slowProviderCalled = false;
|
||||
|
||||
accessor.quickInputService.quickAccess.show('bothFastAndSlow');
|
||||
await timeout(2);
|
||||
|
||||
assert.strictEqual(fastProviderCalled, false);
|
||||
assert.strictEqual(slowProviderCalled, false);
|
||||
assert.strictEqual(fastAndSlowProviderCalled, true);
|
||||
assert.strictEqual(fastAndSlowProviderCanceled, false);
|
||||
fastAndSlowProviderCalled = false;
|
||||
|
||||
accessor.quickInputService.quickAccess.show('slow');
|
||||
accessor.quickInputService.quickAccess.show('bothFastAndSlow');
|
||||
accessor.quickInputService.quickAccess.show('fast');
|
||||
|
||||
assert.strictEqual(fastProviderCalled, true);
|
||||
assert.strictEqual(slowProviderCalled, true);
|
||||
assert.strictEqual(fastAndSlowProviderCalled, true);
|
||||
|
||||
await timeout(2);
|
||||
assert.strictEqual(slowProviderCanceled, true);
|
||||
assert.strictEqual(fastAndSlowProviderCanceled, true);
|
||||
|
||||
disposables.dispose();
|
||||
|
||||
restore();
|
||||
});
|
||||
|
||||
test('quick pick access - pick()', async () => {
|
||||
const registry = (Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess));
|
||||
const restore = (registry as QuickAccessRegistry).clear();
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registry.registerQuickAccessProvider(fastProviderDescriptor));
|
||||
|
||||
const result = accessor.quickInputService.quickAccess.pick('fast');
|
||||
assert.strictEqual(fastProviderCalled, true);
|
||||
assert.ok(result instanceof Promise);
|
||||
|
||||
disposables.dispose();
|
||||
|
||||
restore();
|
||||
});
|
||||
});
|
||||
@@ -3,26 +3,27 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||
import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { basename } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorInput, EditorOptions, EditorsOrder, IFileEditorInput, IEditorInputFactoryRegistry, IEditorInputSerializer, EditorExtensions, ISaveOptions, IMoveResult, ITextEditorPane, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, SideBySideEditorInput, IEditorMoveEvent, EditorExtensions as Extensions } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorsOrder, IFileEditorInput, IEditorInputFactoryRegistry, IEditorInputSerializer, EditorExtensions, ISaveOptions, IMoveResult, ITextEditorPane, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, IEditorMoveEvent, EditorExtensions as Extensions, EditorInputCapabilities, IEditorOpenEvent } from 'vs/workbench/common/editor';
|
||||
import { EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor, IEditorGroupTitleHeight } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup';
|
||||
import { IResolvedWorkingCopyBackup, IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchLayoutService, Parts, Position as PartPosition } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IEditorOptions, IResourceEditorInput, IEditorModel, ITextEditorOptions, IResourceEditorInputIdentifier } from 'vs/platform/editor/common/editor';
|
||||
import { IEditorOptions, IResourceEditorInput, IEditorModel, IResourceEditorInputIdentifier } from 'vs/platform/editor/common/editor';
|
||||
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
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, IReadFileStreamOptions } 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, IFileSystemProviderCapabilitiesChangeEvent } 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';
|
||||
@@ -42,7 +43,7 @@ import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||
import { ITextBufferFactory, DefaultEndOfLine, EndOfLinePreference, ITextSnapshot } from 'vs/editor/common/model';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { IDialogService, IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||
@@ -51,7 +52,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/browser/decorations';
|
||||
import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IEditorReplacement, IGroupChangeEvent, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService, IOpenEditorOverrideHandler, ISaveEditorsOptions, IRevertAllEditorsOptions, IResourceEditorInputType, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE, IOpenEditorOverrideEntry } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, IResourceEditorInputType, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { IEditorRegistry, EditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { Dimension, IDimension } from 'vs/base/browser/dom';
|
||||
@@ -74,7 +75,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IWorkingCopyService, WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy';
|
||||
import { IWorkingCopyBackupMeta, IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy';
|
||||
import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
@@ -83,7 +84,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
|
||||
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
import { Direction } from 'vs/base/browser/ui/grid/grid';
|
||||
import { IProgressService, IProgressOptions, IProgressWindowOptions, IProgressNotificationOptions, IProgressCompositeOptions, IProgress, IProgressStep, Progress } from 'vs/platform/progress/common/progress';
|
||||
import { IProgressService, IProgressOptions, IProgressWindowOptions, IProgressNotificationOptions, IProgressCompositeOptions, IProgress, IProgressStep, Progress, IProgressDialogOptions } from 'vs/platform/progress/common/progress';
|
||||
import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
|
||||
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
@@ -96,7 +97,7 @@ import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogSer
|
||||
import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService';
|
||||
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 { IChange, IDiffEditor, IEditor } from 'vs/editor/common/editorCommon';
|
||||
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';
|
||||
@@ -119,34 +120,38 @@ import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { TextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor';
|
||||
import { TestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
|
||||
import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEditor';
|
||||
import { IEnterWorkspaceResult, IRecent, IRecentlyOpened, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { TestWorkspaceTrustManagementService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
|
||||
import { ILocalTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalsLayoutInfo, ITerminalsLayoutInfoById } from 'vs/platform/terminal/common/terminal';
|
||||
import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
|
||||
import { ILocalTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalShellType } 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';
|
||||
import { IShellLaunchConfigResolveOptions, ITerminalProfile, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IShellLaunchConfigResolveOptions, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { EditorOverrideService } from 'vs/workbench/services/editor/browser/editorOverrideService';
|
||||
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
|
||||
import { IEditorOverrideService } from 'vs/workbench/services/editor/common/editorOverrideService';
|
||||
import { IWorkingCopyEditorService, WorkingCopyEditorService } from 'vs/workbench/services/workingCopy/common/workingCopyEditorService';
|
||||
import { IElevatedFileService } from 'vs/workbench/services/files/common/elevatedFileService';
|
||||
import { BrowserElevatedFileService } from 'vs/workbench/services/files/browser/elevatedFileService';
|
||||
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/modes';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
|
||||
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
|
||||
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined);
|
||||
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined);
|
||||
}
|
||||
|
||||
Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerFileEditorInputFactory({
|
||||
|
||||
typeId: FILE_EDITOR_INPUT_ID,
|
||||
|
||||
createFileEditorInput: (resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode, instantiationService): IFileEditorInput => {
|
||||
return instantiationService.createInstance(FileEditorInput, resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode);
|
||||
createFileEditorInput: (resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode, preferredContents, instantiationService): IFileEditorInput => {
|
||||
return instantiationService.createInstance(FileEditorInput, resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode, preferredContents);
|
||||
},
|
||||
|
||||
isFileEditorInput: (obj): obj is IFileEditorInput => {
|
||||
@@ -183,6 +188,7 @@ export function workbenchInstantiationService(
|
||||
): ITestInstantiationService {
|
||||
const instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()]));
|
||||
|
||||
instantiationService.stub(IEditorWorkerService, new TestEditorWorkerService());
|
||||
instantiationService.stub(IWorkingCopyService, disposables.add(new WorkingCopyService()));
|
||||
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
|
||||
instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService);
|
||||
@@ -223,7 +229,6 @@ export function workbenchInstantiationService(
|
||||
instantiationService.stub(IKeybindingService, keybindingService);
|
||||
instantiationService.stub(IDecorationsService, new TestDecorationsService());
|
||||
instantiationService.stub(IExtensionService, new TestExtensionService());
|
||||
instantiationService.stub(IWorkingCopyEditorService, disposables.add(instantiationService.createInstance(WorkingCopyEditorService)));
|
||||
instantiationService.stub(IWorkingCopyFileService, disposables.add(instantiationService.createInstance(WorkingCopyFileService)));
|
||||
instantiationService.stub(ITextFileService, overrides?.textFileService ? overrides.textFileService(instantiationService) : disposables.add(<ITextFileService>instantiationService.createInstance(TestTextFileService)));
|
||||
instantiationService.stub(IHostService, <IHostService>instantiationService.createInstance(TestHostService));
|
||||
@@ -234,6 +239,7 @@ export function workbenchInstantiationService(
|
||||
instantiationService.stub(ILabelService, <ILabelService>disposables.add(instantiationService.createInstance(LabelService)));
|
||||
const editorService = overrides?.editorService ? overrides.editorService(instantiationService) : new TestEditorService(editorGroupService);
|
||||
instantiationService.stub(IEditorService, editorService);
|
||||
instantiationService.stub(IWorkingCopyEditorService, disposables.add(instantiationService.createInstance(WorkingCopyEditorService)));
|
||||
instantiationService.stub(IEditorOverrideService, disposables.add(instantiationService.createInstance(EditorOverrideService)));
|
||||
instantiationService.stub(ICodeEditorService, disposables.add(new CodeEditorService(editorService, themeService, configService)));
|
||||
instantiationService.stub(IViewletService, new TestViewletService());
|
||||
@@ -258,9 +264,13 @@ export class TestServiceAccessor {
|
||||
@IModelService public modelService: ModelServiceImpl,
|
||||
@IFileService public fileService: TestFileService,
|
||||
@IFileDialogService public fileDialogService: TestFileDialogService,
|
||||
@IDialogService public dialogService: TestDialogService,
|
||||
@IWorkingCopyService public workingCopyService: IWorkingCopyService,
|
||||
@IEditorService public editorService: TestEditorService,
|
||||
@IWorkbenchEnvironmentService public environmentService: IWorkbenchEnvironmentService,
|
||||
@IPathService public pathService: IPathService,
|
||||
@IEditorGroupsService public editorGroupService: IEditorGroupsService,
|
||||
@IEditorOverrideService public editorOverrideService: IEditorOverrideService,
|
||||
@IModeService public modeService: IModeService,
|
||||
@ITextModelService public textModelResolverService: ITextModelService,
|
||||
@IUntitledTextEditorService public untitledTextEditorService: UntitledTextEditorService,
|
||||
@@ -275,7 +285,8 @@ export class TestServiceAccessor {
|
||||
@INotificationService public notificationService: INotificationService,
|
||||
@IWorkingCopyEditorService public workingCopyEditorService: IWorkingCopyEditorService,
|
||||
@IInstantiationService public instantiationService: IInstantiationService,
|
||||
@IElevatedFileService public elevatedFileService: IElevatedFileService
|
||||
@IElevatedFileService public elevatedFileService: IElevatedFileService,
|
||||
@IWorkspaceTrustRequestService public workspaceTrustRequestService: TestWorkspaceTrustRequestService
|
||||
) { }
|
||||
}
|
||||
|
||||
@@ -321,8 +332,8 @@ export class TestTextFileService extends BrowserTextFileService {
|
||||
workingCopyFileService,
|
||||
uriIdentityService,
|
||||
modeService,
|
||||
logService,
|
||||
elevatedFileService
|
||||
elevatedFileService,
|
||||
logService
|
||||
);
|
||||
}
|
||||
|
||||
@@ -347,7 +358,8 @@ export class TestTextFileService extends BrowserTextFileService {
|
||||
etag: content.etag,
|
||||
encoding: 'utf8',
|
||||
value: await createTextBufferFactoryFromStream(content.value),
|
||||
size: 10
|
||||
size: 10,
|
||||
readonly: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -405,7 +417,7 @@ export class TestProgressService implements IProgressService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
withProgress(
|
||||
options: IProgressOptions | IProgressWindowOptions | IProgressNotificationOptions | IProgressCompositeOptions,
|
||||
options: IProgressOptions | IProgressDialogOptions | IProgressWindowOptions | IProgressNotificationOptions | IProgressCompositeOptions,
|
||||
task: (progress: IProgress<IProgressStep>) => Promise<any>,
|
||||
onDidCancel?: ((choice?: number | undefined) => void) | undefined
|
||||
): Promise<any> {
|
||||
@@ -532,6 +544,7 @@ export class TestLayoutService implements IWorkbenchLayoutService {
|
||||
isStatusBarHidden(): boolean { return false; }
|
||||
isActivityBarHidden(): boolean { return false; }
|
||||
setActivityBarHidden(_hidden: boolean): void { }
|
||||
setBannerHidden(_hidden: boolean): void { }
|
||||
isSideBarHidden(): boolean { return false; }
|
||||
async setEditorHidden(_hidden: boolean): Promise<void> { }
|
||||
async setSideBarHidden(_hidden: boolean): Promise<void> { }
|
||||
@@ -650,7 +663,6 @@ export class TestEditorGroupsService implements IEditorGroupsService {
|
||||
get activeGroup(): IEditorGroup { return this.groups[0]; }
|
||||
get count(): number { return this.groups.length; }
|
||||
|
||||
isRestored(): boolean { return true; }
|
||||
getGroups(_order?: GroupsOrder): readonly IEditorGroup[] { return this.groups; }
|
||||
getGroup(identifier: number): IEditorGroup | undefined { return this.groups.find(group => group.id === identifier); }
|
||||
getLabel(_identifier: number): string { return 'Group 1'; }
|
||||
@@ -709,6 +721,7 @@ export class TestEditorGroupView implements IEditorGroupView {
|
||||
onDidFocus: Event<void> = Event.None;
|
||||
onDidChange: Event<{ width: number; height: number; }> = Event.None;
|
||||
onWillMoveEditor: Event<IEditorMoveEvent> = Event.None;
|
||||
onWillOpenEditor: Event<IEditorOpenEvent> = Event.None;
|
||||
|
||||
getEditors(_order?: EditorsOrder): readonly IEditorInput[] { return []; }
|
||||
findEditors(_resource: URI): readonly IEditorInput[] { return []; }
|
||||
@@ -720,8 +733,8 @@ export class TestEditorGroupView implements IEditorGroupView {
|
||||
isSticky(_editor: IEditorInput): boolean { return false; }
|
||||
isActive(_editor: IEditorInput): boolean { return false; }
|
||||
contains(candidate: IEditorInput): boolean { return false; }
|
||||
moveEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IEditorOptions | ITextEditorOptions): void { }
|
||||
copyEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IEditorOptions | ITextEditorOptions): void { }
|
||||
moveEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IEditorOptions): void { }
|
||||
copyEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IEditorOptions): void { }
|
||||
async closeEditor(_editor?: IEditorInput, options?: ICloseEditorOptions): Promise<void> { }
|
||||
async closeEditors(_editors: IEditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise<void> { }
|
||||
async closeAllEditors(options?: ICloseAllEditorsOptions): Promise<void> { }
|
||||
@@ -792,15 +805,13 @@ export class TestEditorService implements EditorServiceImpl {
|
||||
constructor(private editorGroupService?: IEditorGroupsService) { }
|
||||
getEditors() { return []; }
|
||||
findEditors() { return [] as any; }
|
||||
getEditorOverrides(resource: URI, options: IEditorOptions | undefined, group: IEditorGroup | undefined): [IOpenEditorOverrideHandler, IOpenEditorOverrideEntry][] { return []; }
|
||||
overrideOpenEditor(_handler: IOpenEditorOverrideHandler): IDisposable { return toDisposable(() => undefined); }
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IResourceEditorInput | IUntitledTextResourceEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<ITextEditorPane | undefined>;
|
||||
openEditor(editor: IResourceDiffEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<ITextDiffEditorPane | undefined>;
|
||||
async openEditor(editor: IEditorInput | IResourceEditorInputType, optionsOrGroup?: IEditorOptions | ITextEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined> {
|
||||
async openEditor(editor: IEditorInput | IResourceEditorInputType, optionsOrGroup?: IEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined> {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
doResolveEditorOpenRequest(editor: IEditorInput | IResourceEditorInputType): [IEditorGroup, EditorInput, EditorOptions | undefined] | undefined {
|
||||
doResolveEditorOpenRequest(editor: IEditorInput | IResourceEditorInputType): [IEditorGroup, EditorInput, IEditorOptions | undefined] | undefined {
|
||||
if (!this.editorGroupService) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -822,24 +833,31 @@ export class TestFileService implements IFileService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _onDidFilesChange = new Emitter<FileChangesEvent>();
|
||||
get onDidFilesChange(): Event<FileChangesEvent> { return this._onDidFilesChange.event; }
|
||||
fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); }
|
||||
|
||||
private readonly _onDidRunOperation = new Emitter<FileOperationEvent>();
|
||||
get onDidRunOperation(): Event<FileOperationEvent> { return this._onDidRunOperation.event; }
|
||||
fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); }
|
||||
|
||||
private readonly _onDidChangeFileSystemProviderCapabilities = new Emitter<IFileSystemProviderCapabilitiesChangeEvent>();
|
||||
get onDidChangeFileSystemProviderCapabilities(): Event<IFileSystemProviderCapabilitiesChangeEvent> { return this._onDidChangeFileSystemProviderCapabilities.event; }
|
||||
fireFileSystemProviderCapabilitiesChangeEvent(event: IFileSystemProviderCapabilitiesChangeEvent): void { this._onDidChangeFileSystemProviderCapabilities.fire(event); }
|
||||
|
||||
readonly onWillActivateFileSystemProvider = Event.None;
|
||||
readonly onDidChangeFileSystemProviderCapabilities = Event.None;
|
||||
readonly onError: Event<Error> = Event.None;
|
||||
|
||||
private content = 'Hello Html';
|
||||
private lastReadFileUri!: URI;
|
||||
|
||||
readonly = false;
|
||||
|
||||
setContent(content: string): void { this.content = content; }
|
||||
getContent(): string { return this.content; }
|
||||
getLastReadFileUri(): URI { return this.lastReadFileUri; }
|
||||
get onDidFilesChange(): Event<FileChangesEvent> { return this._onDidFilesChange.event; }
|
||||
fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); }
|
||||
get onDidRunOperation(): Event<FileOperationEvent> { return this._onDidRunOperation.event; }
|
||||
fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); }
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat>;
|
||||
|
||||
resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise<IFileStatWithMetadata>;
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat>;
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat> {
|
||||
return Promise.resolve({
|
||||
resource,
|
||||
@@ -850,6 +868,7 @@ export class TestFileService implements IFileService {
|
||||
isFile: true,
|
||||
isDirectory: false,
|
||||
isSymbolicLink: false,
|
||||
readonly: this.readonly,
|
||||
name: basename(resource)
|
||||
});
|
||||
}
|
||||
@@ -860,7 +879,7 @@ export class TestFileService implements IFileService {
|
||||
return stats.map(stat => ({ stat, success: true }));
|
||||
}
|
||||
|
||||
readonly notExistsSet = new Set<URI>();
|
||||
readonly notExistsSet = new ResourceMap<boolean>();
|
||||
|
||||
async exists(_resource: URI): Promise<boolean> { return !this.notExistsSet.has(_resource); }
|
||||
|
||||
@@ -881,6 +900,7 @@ export class TestFileService implements IFileService {
|
||||
mtime: Date.now(),
|
||||
ctime: Date.now(),
|
||||
name: basename(resource),
|
||||
readonly: this.readonly,
|
||||
size: 1
|
||||
});
|
||||
}
|
||||
@@ -900,6 +920,7 @@ export class TestFileService implements IFileService {
|
||||
mtime: Date.now(),
|
||||
ctime: Date.now(),
|
||||
size: 1,
|
||||
readonly: this.readonly,
|
||||
name: basename(resource)
|
||||
});
|
||||
}
|
||||
@@ -922,6 +943,7 @@ export class TestFileService implements IFileService {
|
||||
isFile: true,
|
||||
isDirectory: false,
|
||||
isSymbolicLink: false,
|
||||
readonly: this.readonly,
|
||||
name: basename(resource)
|
||||
});
|
||||
}
|
||||
@@ -958,7 +980,9 @@ export class TestFileService implements IFileService {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
const provider = this.getProvider(resource.scheme);
|
||||
|
||||
return !!(provider && (provider.capabilities & capability));
|
||||
}
|
||||
|
||||
async del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean; }): Promise<void> { }
|
||||
@@ -981,6 +1005,8 @@ export class TestFileService implements IFileService {
|
||||
|
||||
export class TestWorkingCopyBackupService extends InMemoryWorkingCopyBackupService {
|
||||
|
||||
readonly resolved: Set<IWorkingCopyIdentifier> = new Set();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
@@ -992,6 +1018,12 @@ export class TestWorkingCopyBackupService extends InMemoryWorkingCopyBackupServi
|
||||
|
||||
return textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined);
|
||||
}
|
||||
|
||||
override async resolve<T extends IWorkingCopyBackupMeta>(identifier: IWorkingCopyIdentifier): Promise<IResolvedWorkingCopyBackup<T> | undefined> {
|
||||
this.resolved.add(identifier);
|
||||
|
||||
return super.resolve(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
export function toUntypedWorkingCopyId(resource: URI): IWorkingCopyIdentifier {
|
||||
@@ -1183,7 +1215,6 @@ export class TestInMemoryFileSystemProvider extends InMemoryFileSystemProvider i
|
||||
| FileSystemProviderCapabilities.PathCaseSensitive
|
||||
| FileSystemProviderCapabilities.FileReadStream;
|
||||
|
||||
|
||||
readFileStream(resource: URI): ReadableStreamEvents<Uint8Array> {
|
||||
const BUFFER_SIZE = 64 * 1024;
|
||||
const stream = newWriteableStream<Uint8Array>(data => VSBuffer.concat(data.map(data => VSBuffer.wrap(data))).buffer);
|
||||
@@ -1281,7 +1312,7 @@ export function registerTestEditor(id: string, inputs: SyncDescriptor<EditorInpu
|
||||
this._scopedContextKeyService = new MockContextKeyService();
|
||||
}
|
||||
|
||||
override async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
override async setInput(input: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
super.setInput(input, options, context, token);
|
||||
|
||||
await input.resolve();
|
||||
@@ -1343,7 +1374,7 @@ export function registerTestFileEditor(): IDisposable {
|
||||
TestTextFileEditor.ID,
|
||||
'Text File Editor'
|
||||
),
|
||||
[new SyncDescriptor<EditorInput>(FileEditorInput)]
|
||||
[new SyncDescriptor(FileEditorInput)]
|
||||
));
|
||||
|
||||
return disposables;
|
||||
@@ -1359,8 +1390,8 @@ export function registerTestResourceEditor(): IDisposable {
|
||||
'Text Editor'
|
||||
),
|
||||
[
|
||||
new SyncDescriptor<EditorInput>(UntitledTextEditorInput),
|
||||
new SyncDescriptor<EditorInput>(ResourceEditorInput)
|
||||
new SyncDescriptor(UntitledTextEditorInput),
|
||||
new SyncDescriptor(TextResourceEditorInput)
|
||||
]
|
||||
));
|
||||
|
||||
@@ -1403,6 +1434,16 @@ export class TestFileEditorInput extends EditorInput implements IFileEditorInput
|
||||
}
|
||||
|
||||
override get typeId() { return this._typeId; }
|
||||
|
||||
private _capabilities: EditorInputCapabilities = EditorInputCapabilities.None;
|
||||
override get capabilities(): EditorInputCapabilities { return this._capabilities; }
|
||||
override set capabilities(capabilities: EditorInputCapabilities) {
|
||||
if (this._capabilities !== capabilities) {
|
||||
this._capabilities = capabilities;
|
||||
this._onDidChangeCapabilities.fire();
|
||||
}
|
||||
}
|
||||
|
||||
override resolve(): Promise<IEditorModel | null> { return !this.fails ? Promise.resolve(null) : Promise.reject(new Error('fails')); }
|
||||
override matches(other: EditorInput): boolean { return !!(other?.resource && this.resource.toString() === other.resource.toString() && other instanceof TestFileEditorInput && other.typeId === this.typeId); }
|
||||
setPreferredResource(resource: URI): void { }
|
||||
@@ -1411,6 +1452,7 @@ export class TestFileEditorInput extends EditorInput implements IFileEditorInput
|
||||
setPreferredName(name: string): void { }
|
||||
setPreferredDescription(description: string): void { }
|
||||
setPreferredEncoding(encoding: string) { }
|
||||
setPreferredContents(contents: string): void { }
|
||||
setMode(mode: string) { }
|
||||
setPreferredMode(mode: string) { }
|
||||
setForceOpenAsBinary(): void { }
|
||||
@@ -1436,9 +1478,6 @@ export class TestFileEditorInput extends EditorInput implements IFileEditorInput
|
||||
override isDirty(): boolean {
|
||||
return this.dirty;
|
||||
}
|
||||
override isReadonly(): boolean {
|
||||
return false;
|
||||
}
|
||||
isResolved(): boolean { return false; }
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
@@ -1538,40 +1577,32 @@ export class TestWorkspacesService implements IWorkspacesService {
|
||||
async clearRecentlyOpened(): Promise<void> { }
|
||||
async getRecentlyOpened(): Promise<IRecentlyOpened> { return { files: [], workspaces: [] }; }
|
||||
async getDirtyWorkspaces(): Promise<(URI | IWorkspaceIdentifier)[]> { return []; }
|
||||
async enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null> { throw new Error('Method not implemented.'); }
|
||||
async enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | undefined> { 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.'); }
|
||||
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string, shellType: TerminalShellType, isRemote: boolean): Promise<string> { throw new Error('Method not implemented.'); }
|
||||
}
|
||||
|
||||
export class TestTerminalProfileResolverService implements ITerminalProfileResolverService {
|
||||
_serviceBrand: undefined;
|
||||
defaultProfileName = '';
|
||||
resolveIcon(shellLaunchConfig: IShellLaunchConfig): void { }
|
||||
async resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise<void> { }
|
||||
async getDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> { return { path: '/default', profileName: 'Default' }; }
|
||||
async getDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> { return { path: '/default', profileName: 'Default', isDefault: true }; }
|
||||
async getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise<string> { return '/default'; }
|
||||
async getDefaultShellArgs(options: IShellLaunchConfigResolveOptions): Promise<string | string[]> { return []; }
|
||||
async getShellEnvironment(): Promise<IProcessEnvironment> { return process.env; }
|
||||
async getEnvironment(): Promise<IProcessEnvironment> { return process.env; }
|
||||
getSafeConfigValue(key: string, os: OperatingSystem): unknown | undefined { return undefined; }
|
||||
getSafeConfigValueFullKey(key: string): unknown | undefined { return undefined; }
|
||||
createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise<string | ITerminalProfile> { throw new Error('Method not implemented.'); }
|
||||
}
|
||||
|
||||
export class TestLocalTerminalService implements ILocalTerminalService {
|
||||
@@ -1588,11 +1619,16 @@ export class TestLocalTerminalService implements ILocalTerminalService {
|
||||
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { throw new Error('Method not implemented.'); }
|
||||
async listProcesses(): Promise<IProcessDetails[]> { throw new Error('Method not implemented.'); }
|
||||
getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> { throw new Error('Method not implemented.'); }
|
||||
getShellEnvironment(): Promise<IProcessEnvironment> { throw new Error('Method not implemented.'); }
|
||||
getProfiles(isWorkspaceTrusted: boolean, includeDetectedProfiles?: boolean): Promise<ITerminalProfile[]> { throw new Error('Method not implemented.'); }
|
||||
getEnvironment(): Promise<IProcessEnvironment> { throw new Error('Method not implemented.'); }
|
||||
getShellEnvironment(): Promise<IProcessEnvironment | undefined> { throw new Error('Method not implemented.'); }
|
||||
getWslPath(original: string): Promise<string> { 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.'); }
|
||||
async reduceConnectionGraceTime(): Promise<void> { throw new Error('Method not implemented.'); }
|
||||
processBinary(id: number, data: string): Promise<void> { throw new Error('Method not implemented.'); }
|
||||
updateTitle(id: number, title: string): Promise<void> { throw new Error('Method not implemented.'); }
|
||||
updateIcon(id: number, icon: URI | { light: URI; dark: URI } | { id: string, color?: { id: string } }, color?: string): Promise<void> { throw new Error('Method not implemented.'); }
|
||||
}
|
||||
|
||||
class TestTerminalChildProcess implements ITerminalChildProcess {
|
||||
@@ -1650,3 +1686,18 @@ export class TestQuickInputService implements IQuickInputService {
|
||||
back(): Promise<void> { throw new Error('not implemented.'); }
|
||||
cancel(): Promise<void> { throw new Error('not implemented.'); }
|
||||
}
|
||||
|
||||
export class TestEditorWorkerService implements IEditorWorkerService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
canComputeDiff(original: URI, modified: URI): boolean { return false; }
|
||||
async computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise<IDiffComputationResult | null> { return null; }
|
||||
canComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }
|
||||
async computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null> { return null; }
|
||||
async computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | undefined> { return undefined; }
|
||||
canComputeWordRanges(resource: URI): boolean { return false; }
|
||||
async computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[]; } | null> { return null; }
|
||||
canNavigateValueSet(resource: URI): boolean { return false; }
|
||||
async navigateValueSet(resource: URI, range: IRange, up: boolean): Promise<IInplaceReplaceSupportResult | null> { return null; }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { INotification, Severity, NotificationsFilter } from 'vs/platform/notifi
|
||||
import { createErrorWithActions } from 'vs/base/common/errors';
|
||||
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
|
||||
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
suite('Notifications', () => {
|
||||
|
||||
@@ -143,6 +144,23 @@ suite('Notifications', () => {
|
||||
assert.strictEqual(item11.silent, true);
|
||||
});
|
||||
|
||||
test('Items - does not fire changed when message did not change (content, severity)', async () => {
|
||||
const item1 = NotificationViewItem.create({ severity: Severity.Error, message: 'Error Message' })!;
|
||||
|
||||
let fired = false;
|
||||
item1.onDidChangeContent(() => {
|
||||
fired = true;
|
||||
});
|
||||
|
||||
item1.updateMessage('Error Message');
|
||||
await timeout(0);
|
||||
assert.ok(!fired, 'Expected onDidChangeContent to not be fired');
|
||||
|
||||
item1.updateSeverity(Severity.Error);
|
||||
await timeout(0);
|
||||
assert.ok(!fired, 'Expected onDidChangeContent to not be fired');
|
||||
});
|
||||
|
||||
test('Model', () => {
|
||||
const model = new NotificationsModel();
|
||||
|
||||
@@ -167,11 +185,11 @@ suite('Notifications', () => {
|
||||
assert.strictEqual(lastNotificationEvent.index, 0);
|
||||
assert.strictEqual(lastNotificationEvent.kind, NotificationChangeType.ADD);
|
||||
|
||||
item1Handle.updateMessage('Error Message');
|
||||
item1Handle.updateMessage('Different Error Message');
|
||||
assert.strictEqual(lastNotificationEvent.kind, NotificationChangeType.CHANGE);
|
||||
assert.strictEqual(lastNotificationEvent.detail, NotificationViewItemContentChangeKind.MESSAGE);
|
||||
|
||||
item1Handle.updateSeverity(Severity.Error);
|
||||
item1Handle.updateSeverity(Severity.Warning);
|
||||
assert.strictEqual(lastNotificationEvent.kind, NotificationChangeType.CHANGE);
|
||||
assert.strictEqual(lastNotificationEvent.detail, NotificationViewItemContentChangeKind.SEVERITY);
|
||||
|
||||
@@ -205,8 +223,8 @@ suite('Notifications', () => {
|
||||
item1Handle.close();
|
||||
assert.strictEqual(called, 1);
|
||||
assert.strictEqual(model.notifications.length, 2);
|
||||
assert.strictEqual(lastNotificationEvent.item.severity, item1.severity);
|
||||
assert.strictEqual(lastNotificationEvent.item.message.linkedText.toString(), item1.message);
|
||||
assert.strictEqual(lastNotificationEvent.item.severity, Severity.Warning);
|
||||
assert.strictEqual(lastNotificationEvent.item.message.linkedText.toString(), 'Different Error Message');
|
||||
assert.strictEqual(lastNotificationEvent.index, 2);
|
||||
assert.strictEqual(lastNotificationEvent.kind, NotificationChangeType.REMOVE);
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ export class TestWorkingCopy extends Disposable implements IWorkingCopy {
|
||||
|
||||
private dirty = false;
|
||||
|
||||
constructor(public readonly resource: URI, isDirty = false, public readonly typeId = 'testWorkingCopyType') {
|
||||
constructor(readonly resource: URI, isDirty = false, readonly typeId = 'testWorkingCopyType') {
|
||||
super();
|
||||
|
||||
this.dirty = isDirty;
|
||||
|
||||
@@ -883,14 +883,16 @@ suite('ExtHostSearch', () => {
|
||||
});
|
||||
|
||||
test('basic sibling clause', async () => {
|
||||
mockPFS.readdir = (_path: string): any => {
|
||||
if (_path === rootFolderA.fsPath) {
|
||||
return Promise.resolve([
|
||||
'file1.js',
|
||||
'file1.ts'
|
||||
]);
|
||||
} else {
|
||||
return Promise.reject(new Error('Wrong path'));
|
||||
(mockPFS as any).Promises = {
|
||||
readdir: (_path: string): any => {
|
||||
if (_path === rootFolderA.fsPath) {
|
||||
return Promise.resolve([
|
||||
'file1.js',
|
||||
'file1.ts'
|
||||
]);
|
||||
} else {
|
||||
return Promise.reject(new Error('Wrong path'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -926,21 +928,23 @@ suite('ExtHostSearch', () => {
|
||||
});
|
||||
|
||||
test('multiroot sibling clause', async () => {
|
||||
mockPFS.readdir = (_path: string): any => {
|
||||
if (_path === joinPath(rootFolderA, 'folder').fsPath) {
|
||||
return Promise.resolve([
|
||||
'fileA.scss',
|
||||
'fileA.css',
|
||||
'file2.css'
|
||||
]);
|
||||
} else if (_path === rootFolderB.fsPath) {
|
||||
return Promise.resolve([
|
||||
'fileB.ts',
|
||||
'fileB.js',
|
||||
'file3.js'
|
||||
]);
|
||||
} else {
|
||||
return Promise.reject(new Error('Wrong path'));
|
||||
(mockPFS as any).Promises = {
|
||||
readdir: (_path: string): any => {
|
||||
if (_path === joinPath(rootFolderA, 'folder').fsPath) {
|
||||
return Promise.resolve([
|
||||
'fileA.scss',
|
||||
'fileA.css',
|
||||
'file2.css'
|
||||
]);
|
||||
} else if (_path === rootFolderB.fsPath) {
|
||||
return Promise.resolve([
|
||||
'fileB.ts',
|
||||
'fileB.js',
|
||||
'file3.js'
|
||||
]);
|
||||
} else {
|
||||
return Promise.reject(new Error('Wrong path'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ suite('MainThreadWorkspace', () => {
|
||||
assert.strictEqual(query.folderQueries.length, 1);
|
||||
assert.strictEqual(query.folderQueries[0].disregardIgnoreFiles, true);
|
||||
|
||||
assert.deepEqual(query.includePattern, { 'foo': true });
|
||||
assert.deepStrictEqual({ ...query.includePattern }, { 'foo': true });
|
||||
assert.strictEqual(query.maxResults, 10);
|
||||
|
||||
return Promise.resolve({ results: [], messages: [] });
|
||||
@@ -89,7 +89,7 @@ suite('MainThreadWorkspace', () => {
|
||||
instantiationService.stub(ISearchService, {
|
||||
fileSearch(query: IFileQuery) {
|
||||
assert.strictEqual(query.folderQueries[0].excludePattern, undefined);
|
||||
assert.deepEqual(query.excludePattern, { 'exclude/**': true });
|
||||
assert.deepStrictEqual({ ...query.excludePattern }, { 'exclude/**': true });
|
||||
|
||||
return Promise.resolve({ results: [], messages: [] });
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IColorRegistry, Extensions, ColorContribution } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { asText } from 'vs/platform/request/common/request';
|
||||
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';
|
||||
@@ -102,11 +101,11 @@ function getDescription(color: ColorContribution) {
|
||||
|
||||
async function getColorsFromExtension(): Promise<{ [id: string]: string }> {
|
||||
let extPath = getPathFromAmdModule(require, '../../../../../extensions');
|
||||
let extFolders = await pfs.readDirsInDir(extPath);
|
||||
let extFolders = await pfs.Promises.readDirsInDir(extPath);
|
||||
let result: { [id: string]: string } = Object.create(null);
|
||||
for (let folder of extFolders) {
|
||||
try {
|
||||
let packageJSON = JSON.parse((await fs.promises.readFile(path.join(extPath, folder, 'package.json'))).toString());
|
||||
let packageJSON = JSON.parse((await pfs.Promises.readFile(path.join(extPath, folder, 'package.json'))).toString());
|
||||
let contributes = packageJSON['contributes'];
|
||||
if (contributes) {
|
||||
let colors = contributes['colors'];
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions, IColorRegistry } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
suite('ColorRegistry', () => {
|
||||
if (process.env.VSCODE_COLOR_REGISTRY_EXPORT) {
|
||||
test('exports', () => {
|
||||
const themingRegistry = Registry.as<IColorRegistry>(Extensions.ColorContribution);
|
||||
const colors = themingRegistry.getColors();
|
||||
const replacer = (_key: string, value: unknown) =>
|
||||
value instanceof Color ? Color.Format.CSS.formatHexA(value) : value;
|
||||
console.log(`#colors:${JSON.stringify(colors, replacer)}\n`);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -23,7 +23,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IReadTextFileOptions, ITextFileStreamContent, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
|
||||
import { IOpenEmptyWindowOptions, IWindowOpenable, IOpenWindowOptions, IOpenedWindow } from 'vs/platform/windows/common/windows';
|
||||
import { IOpenEmptyWindowOptions, IWindowOpenable, IOpenWindowOptions, IOpenedWindow, IPartsSplash } from 'vs/platform/windows/common/windows';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { LogLevel, ILogService } from 'vs/platform/log/common/log';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
@@ -53,7 +53,6 @@ export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
|
||||
machineId: 'testMachineId',
|
||||
logLevel: LogLevel.Error,
|
||||
mainPid: 0,
|
||||
partsSplashPath: '',
|
||||
appRoot: '',
|
||||
userEnv: {},
|
||||
execPath: process.execPath,
|
||||
@@ -136,7 +135,8 @@ export class TestTextFileService extends NativeTextFileService {
|
||||
etag: content.etag,
|
||||
encoding: 'utf8',
|
||||
value: await createTextBufferFactoryFromStream(content.value),
|
||||
size: 10
|
||||
size: 10,
|
||||
readonly: false
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -197,6 +197,7 @@ export class TestNativeHostService implements INativeHostService {
|
||||
async unmaximizeWindow(): Promise<void> { }
|
||||
async minimizeWindow(): Promise<void> { }
|
||||
async setMinimumSize(width: number | undefined, height: number | undefined): Promise<void> { }
|
||||
async saveWindowSplash(value: IPartsSplash): Promise<void> { }
|
||||
async focusWindow(options?: { windowId?: number | undefined; } | undefined): Promise<void> { }
|
||||
async showMessageBox(options: Electron.MessageBoxOptions): Promise<Electron.MessageBoxReturnValue> { throw new Error('Method not implemented.'); }
|
||||
async showSaveDialog(options: Electron.SaveDialogOptions): Promise<Electron.SaveDialogReturnValue> { throw new Error('Method not implemented.'); }
|
||||
@@ -216,13 +217,15 @@ export class TestNativeHostService implements INativeHostService {
|
||||
async setDocumentEdited(edited: boolean): Promise<void> { }
|
||||
async openExternal(url: string): Promise<boolean> { return false; }
|
||||
async updateTouchBar(): Promise<void> { }
|
||||
async moveItemToTrash(): Promise<boolean> { return false; }
|
||||
async moveItemToTrash(): Promise<void> { }
|
||||
async newWindowTab(): Promise<void> { }
|
||||
async showPreviousWindowTab(): Promise<void> { }
|
||||
async showNextWindowTab(): Promise<void> { }
|
||||
async moveWindowTabToNewWindow(): Promise<void> { }
|
||||
async mergeAllWindowTabs(): Promise<void> { }
|
||||
async toggleWindowTabsBar(): Promise<void> { }
|
||||
async installShellCommand(): Promise<void> { }
|
||||
async uninstallShellCommand(): Promise<void> { }
|
||||
async notifyReady(): Promise<void> { }
|
||||
async relaunch(options?: { addArgs?: string[] | undefined; removeArgs?: string[] | undefined; } | undefined): Promise<void> { }
|
||||
async reload(): Promise<void> { }
|
||||
|
||||
Reference in New Issue
Block a user