Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 (#14050)

* Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79

* Fix breaks

* Extension management fixes

* Fix breaks in windows bundling

* Fix/skip failing tests

* Update distro

* Add clear to nuget.config

* Add hygiene task

* Bump distro

* Fix hygiene issue

* Add build to hygiene exclusion

* Update distro

* Update hygiene

* Hygiene exclusions

* Update tsconfig

* Bump distro for server breaks

* Update build config

* Update darwin path

* Add done calls to notebook tests

* Skip failing tests

* Disable smoke tests
This commit is contained in:
Karl Burtram
2021-02-09 16:15:05 -08:00
committed by GitHub
parent 6f192f9af5
commit ce612a3d96
1929 changed files with 68012 additions and 34564 deletions

View File

@@ -28,7 +28,7 @@ import 'vs/workbench/contrib/search/browser/search.contribution';
import { NullLogService } from 'vs/platform/log/common/log';
import { ITextModel } from 'vs/editor/common/model';
import { nullExtensionDescription, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { dispose } from 'vs/base/common/lifecycle';
import { dispose, ImmortalReference } from 'vs/base/common/lifecycle';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { mock } from 'vs/base/test/common/mock';
import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
@@ -48,6 +48,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 { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
const defaultSelector = { scheme: 'far' };
const model: ITextModel = createTextModel(
@@ -108,6 +109,13 @@ suite('ExtHostLanguageFeatureCommands', function () {
services.set(IModelService, new class extends mock<IModelService>() {
getModel() { return model; }
});
services.set(ITextModelService, new class extends mock<ITextModelService>() {
async createModelReference() {
return new ImmortalReference<IResolvedTextEditorModel>(new class extends mock<IResolvedTextEditorModel>() {
textEditorModel = model;
});
}
});
services.set(IEditorWorkerService, new class extends mock<IEditorWorkerService>() {
async computeMoreMinimalEdits(_uri: any, edits: any) {
return edits || undefined;
@@ -925,6 +933,38 @@ suite('ExtHostLanguageFeatureCommands', function () {
});
});
test('resolving code action', async function () {
let didCallResolve = 0;
class MyAction extends types.CodeAction { }
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
provideCodeActions(document, rangeOrSelection): vscode.CodeAction[] {
return [new MyAction('title', types.CodeActionKind.Empty.append('foo'))];
},
resolveCodeAction(action): vscode.CodeAction {
assert.ok(action instanceof MyAction);
didCallResolve += 1;
action.title = 'resolved title';
action.edit = new types.WorkspaceEdit();
return action;
}
}));
const selection = new types.Selection(0, 0, 1, 1);
await rpcProtocol.sync();
const value = await commands.executeCommand<vscode.CodeAction[]>('vscode.executeCodeActionProvider', model.uri, selection, undefined, 1000);
assert.equal(didCallResolve, 1);
assert.equal(value.length, 1);
const [first] = value;
assert.equal(first.title, 'title'); // does NOT change
assert.ok(first.edit); // is set
});
// --- code lens
test('CodeLens, back and forth', function () {

View File

@@ -43,6 +43,16 @@ suite('ExtHostBulkEdits.applyWorkspaceEdit', () => {
bulkEdits = new ExtHostBulkEdits(rpcProtocol, documentsAndEditors, null!);
});
test('uses version id if document available', async () => {
let edit = new extHostTypes.WorkspaceEdit();
edit.replace(resource, new extHostTypes.Range(0, 0, 0, 0), 'hello');
await bulkEdits.applyWorkspaceEdit(edit);
assert.equal(workspaceResourceEdits.edits.length, 1);
const [first] = workspaceResourceEdits.edits;
assertType(first._type === WorkspaceEditType.Text);
assert.equal(first.modelVersionId, 1337);
});
test('does not use version id if document is not available', async () => {
let edit = new extHostTypes.WorkspaceEdit();
edit.replace(URI.parse('foo:bar2'), new extHostTypes.Range(0, 0, 0, 0), 'hello');

View File

@@ -15,6 +15,9 @@ import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/
import { ConfigurationTarget, IConfigurationModel, IConfigurationChange } from 'vs/platform/configuration/common/configuration';
import { NullLogService } from 'vs/platform/log/common/log';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo';
import { FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
import { isLinux } from 'vs/base/common/platform';
suite('ExtHostConfiguration', function () {
@@ -27,7 +30,7 @@ suite('ExtHostConfiguration', function () {
}
function createExtHostWorkspace(): ExtHostWorkspace {
return new ExtHostWorkspace(new TestRPCProtocol(), new class extends mock<IExtHostInitDataService>() { }, new NullLogService());
return new ExtHostWorkspace(new TestRPCProtocol(), new class extends mock<IExtHostInitDataService>() { }, new class extends mock<IExtHostFileSystemInfo>() { getCapabilities() { return isLinux ? FileSystemProviderCapabilities.PathCaseSensitive : undefined; } }, new NullLogService());
}
function createExtHostConfiguration(contents: any = Object.create(null), shape?: MainThreadConfigurationShape) {

View File

@@ -6,7 +6,6 @@
import * as assert from 'assert';
import { timeout } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { mock } from 'vs/base/test/common/mock';
import { NullLogService } from 'vs/platform/log/common/log';
@@ -47,20 +46,20 @@ suite('ExtHostDecorations', function () {
let calledB = false;
// never returns
extHostDecorations.registerDecorationProvider({
onDidChangeDecorations: Event.None,
provideDecoration() {
extHostDecorations.registerFileDecorationProvider({
provideFileDecoration() {
calledA = true;
return new Promise(() => { });
}
}, nullExtensionDescription.identifier);
// always returns
extHostDecorations.registerDecorationProvider({
onDidChangeDecorations: Event.None,
provideDecoration() {
extHostDecorations.registerFileDecorationProvider({
provideFileDecoration() {
calledB = true;
return new Promise(resolve => resolve({ letter: 'H', title: 'Hello' }));
return new Promise(resolve => resolve({ badge: 'H', tooltip: 'Hello' }));
}
}, nullExtensionDescription.identifier);

View File

@@ -331,6 +331,21 @@ suite('ExtHostDocumentData', () => {
assert.equal(range.start.character, 4);
assert.equal(range.end.character, 28);
});
test('Custom snippet $TM_SELECTED_TEXT not show suggestion #108892', function () {
data = new ExtHostDocumentData(undefined!, URI.file(''), [
` <p><span xml:lang="en">Sheldon</span>, soprannominato "<span xml:lang="en">Shelly</span> dalla madre e dalla sorella, è nato a <span xml:lang="en">Galveston</span>, in <span xml:lang="en">Texas</span>, il 26 febbraio 1980 in un supermercato. È stato un bambino prodigio, come testimoniato dal suo quoziente d'intelligenza (187, di molto superiore alla norma) e dalla sua rapida carriera scolastica: si è diplomato all'eta di 11 anni approdando alla stessa età alla formazione universitaria e all'età di 16 anni ha ottenuto il suo primo dottorato di ricerca. All'inizio della serie e per gran parte di essa vive con il coinquilino Leonard nell'appartamento 4A al 2311 <span xml:lang="en">North Los Robles Avenue</span> di <span xml:lang="en">Pasadena</span>, per poi trasferirsi nell'appartamento di <span xml:lang="en">Penny</span> con <span xml:lang="en">Amy</span> nella decima stagione. Come più volte afferma lui stesso possiede una memoria eidetica e un orecchio assoluto. È stato educato da una madre estremamente religiosa e, in più occasioni, questo aspetto contrasta con il rigore scientifico di <span xml:lang="en">Sheldon</span>; tuttavia la donna sembra essere l'unica persona in grado di comandarlo a bacchetta.</p>`
], '\n', 1, 'text', false);
const pos = new Position(0, 55);
const range = data.document.getWordRangeAtPosition(pos)!;
assert.equal(range.start.line, 0);
assert.equal(range.end.line, 0);
assert.equal(range.start.character, 47);
assert.equal(range.end.character, 61);
assert.equal(data.document.getText(range), 'soprannominato');
});
});
enum AssertDocumentLineMappingDirection {

View File

@@ -31,6 +31,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
engines: undefined!,
extensionLocation: undefined!,
isBuiltin: false,
isUserBuiltin: false,
isUnderDevelopment: false,
version: undefined!
};

View File

@@ -594,10 +594,10 @@ suite('ExtHostLanguageFeatures', function () {
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
assert.equal(actions.length, 2);
const [first, second] = actions;
assert.equal(first.title, 'Testing1');
assert.equal(first.command!.id, 'test1');
assert.equal(second.title, 'Testing2');
assert.equal(second.command!.id, 'test2');
assert.equal(first.action.title, 'Testing1');
assert.equal(first.action.command!.id, 'test1');
assert.equal(second.action.title, 'Testing2');
assert.equal(second.action.command!.id, 'test2');
});
test('Quick Fix, code action data conversion', async () => {
@@ -618,10 +618,10 @@ suite('ExtHostLanguageFeatures', function () {
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: modes.CodeActionTriggerType.Manual }, Progress.None, CancellationToken.None);
assert.equal(actions.length, 1);
const [first] = actions;
assert.equal(first.title, 'Testing1');
assert.equal(first.command!.title, 'Testing1Command');
assert.equal(first.command!.id, 'test1');
assert.equal(first.kind, 'test.scope');
assert.equal(first.action.title, 'Testing1');
assert.equal(first.action.command!.title, 'Testing1Command');
assert.equal(first.action.command!.id, 'test1');
assert.equal(first.action.kind, 'test.scope');
});
@@ -1170,7 +1170,7 @@ suite('ExtHostLanguageFeatures', function () {
await rpcProtocol.sync();
provideSelectionRanges(model, [new Position(1, 17)], CancellationToken.None).then(ranges => {
provideSelectionRanges(model, [new Position(1, 17)], { selectLeadingAndTrailingWhitespace: true }, CancellationToken.None).then(ranges => {
assert.equal(ranges.length, 1);
assert.ok(ranges[0].length >= 2);
});

View File

@@ -25,6 +25,10 @@ const emptyDialogService = new class implements IDialogService {
about(): never {
throw new Error('not implemented');
}
input(): never {
throw new Error('not implemented');
}
};
const emptyCommandService: ICommandService = {

View File

@@ -77,6 +77,7 @@ suite('NotebookCell#Document', function () {
cellKind: CellKind.Code,
outputs: [],
}],
contentOptions: { transientMetadata: {}, transientOutputs: false }
}],
addedEditors: [{
documentUri: notebookUri,

View File

@@ -68,6 +68,7 @@ suite('NotebookConcatDocument', function () {
cellKind: CellKind.Markdown,
outputs: [],
}],
contentOptions: { transientOutputs: false, transientMetadata: {} },
versionId: 0
}],
addedEditors: [

View File

@@ -0,0 +1,310 @@
/*---------------------------------------------------------------------------------------------
* 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 { MirroredTestCollection, OwnedTestCollection, SingleUseTestCollection } from 'vs/workbench/api/common/extHostTesting';
import * as convert from 'vs/workbench/api/common/extHostTypeConverters';
import { TestRunState, TestState } from 'vs/workbench/api/common/extHostTypes';
import { TestDiffOpType, TestsDiff } from 'vs/workbench/contrib/testing/common/testCollection';
import { TestChangeEvent, TestItem } from 'vscode';
const stubTest = (label: string): TestItem => ({
label,
location: undefined,
state: new TestState(TestRunState.Unset),
debuggable: true,
runnable: true,
description: ''
});
const simplify = (item: TestItem) => {
if ('toJSON' in item) {
item = (item as any).toJSON();
}
return { ...item, children: undefined };
};
const assertTreesEqual = (a: Readonly<TestItem>, b: Readonly<TestItem>) => {
assert.deepStrictEqual(simplify(a), simplify(b));
const aChildren = (a.children ?? []).sort();
const bChildren = (b.children ?? []).sort();
assert.strictEqual(aChildren.length, bChildren.length, `expected ${a.label}.children.length == ${b.label}.children.length`);
aChildren.forEach((_, i) => assertTreesEqual(aChildren[i], bChildren[i]));
};
const assertTreeListEqual = (a: ReadonlyArray<Readonly<TestItem>>, b: ReadonlyArray<Readonly<TestItem>>) => {
assert.strictEqual(a.length, b.length, `expected a.length == n.length`);
a.forEach((_, i) => assertTreesEqual(a[i], b[i]));
};
const stubNestedTests = () => ({
...stubTest('root'),
children: [
{ ...stubTest('a'), children: [stubTest('aa'), stubTest('ab')] },
stubTest('b'),
]
});
class TestOwnedTestCollection extends OwnedTestCollection {
public get idToInternal() {
return this.testIdToInternal;
}
public createForHierarchy(publishDiff: (diff: TestsDiff) => void = () => undefined) {
return new TestSingleUseCollection(this.testIdToInternal, publishDiff);
}
}
class TestSingleUseCollection extends SingleUseTestCollection {
private idCounter = 0;
public get itemToInternal() {
return this.testItemToInternal;
}
public get currentDiff() {
return this.diff;
}
protected getId() {
return String(this.idCounter++);
}
public setDiff(diff: TestsDiff) {
this.diff = diff;
}
}
class TestMirroredCollection extends MirroredTestCollection {
public changeEvent!: TestChangeEvent;
constructor() {
super();
this.onDidChangeTests(evt => this.changeEvent = evt);
}
public get length() {
return this.items.size;
}
}
suite('ExtHost Testing', () => {
let single: TestSingleUseCollection;
let owned: TestOwnedTestCollection;
setup(() => {
owned = new TestOwnedTestCollection();
single = owned.createForHierarchy(d => single.setDiff(d /* don't clear during testing */));
});
teardown(() => {
single.dispose();
assert.deepEqual(owned.idToInternal.size, 0, 'expected owned ids to be empty after dispose');
});
suite('OwnedTestCollection', () => {
test('adds a root recursively', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Add, { id: '0', providerId: 'pid', parent: null, item: convert.TestItem.from(stubTest('root')) }],
[TestDiffOpType.Add, { id: '1', providerId: 'pid', parent: '0', item: convert.TestItem.from(stubTest('a')) }],
[TestDiffOpType.Add, { id: '2', providerId: 'pid', parent: '1', item: convert.TestItem.from(stubTest('aa')) }],
[TestDiffOpType.Add, { id: '3', providerId: 'pid', parent: '1', item: convert.TestItem.from(stubTest('ab')) }],
[TestDiffOpType.Add, { id: '4', providerId: 'pid', parent: '0', item: convert.TestItem.from(stubTest('b')) }],
]);
});
test('no-ops if items not changed', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
single.collectDiff();
assert.deepStrictEqual(single.collectDiff(), []);
});
test('watches property mutations', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
single.collectDiff();
tests.children![0].description = 'Hello world'; /* item a */
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Update, { id: '1', parent: '0', providerId: 'pid', item: convert.TestItem.from({ ...stubTest('a'), description: 'Hello world' }) }],
]);
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), []);
});
test('removes children', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
single.collectDiff();
tests.children!.splice(0, 1);
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Remove, '1'],
]);
assert.deepStrictEqual([...owned.idToInternal.keys()].sort(), ['0', '4']);
assert.strictEqual(single.itemToInternal.size, 2);
});
test('adds new children', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
single.collectDiff();
const child = stubTest('ac');
tests.children![0].children!.push(child);
single.onItemChange(tests, 'pid');
assert.deepStrictEqual(single.collectDiff(), [
[TestDiffOpType.Add, { id: '5', providerId: 'pid', parent: '1', item: convert.TestItem.from(child) }],
]);
assert.deepStrictEqual([...owned.idToInternal.keys()].sort(), ['0', '1', '2', '3', '4', '5']);
assert.strictEqual(single.itemToInternal.size, 6);
});
});
suite('MirroredTestCollection', () => {
let m: TestMirroredCollection;
setup(() => m = new TestMirroredCollection());
test('mirrors creation of the root', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.rootTestItems[0], owned.getTestById('0')!.actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
test('mirrors node deletion', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children!.splice(0, 1);
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.rootTestItems[0], owned.getTestById('0')!.actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
test('mirrors node addition', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children![0].children!.push(stubTest('ac'));
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.rootTestItems[0], owned.getTestById('0')!.actual);
assert.strictEqual(m.length, single.itemToInternal.size);
});
test('mirrors node update', () => {
const tests = stubNestedTests();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
tests.children![0].description = 'Hello world'; /* item a */
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.rootTestItems[0], owned.getTestById('0')!.actual);
});
suite('MirroredChangeCollector', () => {
let tests = stubNestedTests();
setup(() => {
tests = stubNestedTests();
single.addRoot(tests, 'pid');
m.apply(single.collectDiff());
});
test('creates change for root', () => {
assert.deepStrictEqual(m.changeEvent.commonChangeAncestor, null);
assertTreeListEqual(m.changeEvent.added, [
tests,
tests.children[0],
tests.children![0].children![0],
tests.children![0].children![1],
tests.children[1],
]);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, []);
});
test('creates change for delete', () => {
const rm = tests.children.shift()!;
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assertTreesEqual(m.changeEvent.commonChangeAncestor!, tests);
assertTreeListEqual(m.changeEvent.added, []);
assertTreeListEqual(m.changeEvent.removed, [
{ ...rm, children: [] },
{ ...rm.children![0], children: [] },
{ ...rm.children![1], children: [] },
]);
assertTreeListEqual(m.changeEvent.updated, []);
});
test('creates change for update', () => {
tests.children[0].label = 'updated!';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assert.deepStrictEqual(m.changeEvent.commonChangeAncestor?.label, 'updated!');
assertTreeListEqual(m.changeEvent.added, []);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, [tests.children[0]]);
});
test('is a no-op if a node is added and removed', () => {
const nested = stubNestedTests();
tests.children.push(nested);
single.onItemChange(tests, 'pid');
tests.children.pop();
single.onItemChange(tests, 'pid');
const previousEvent = m.changeEvent;
m.apply(single.collectDiff());
assert.strictEqual(m.changeEvent, previousEvent);
});
test('is a single-op if a node is added and changed', () => {
const child = stubTest('c');
tests.children.push(child);
single.onItemChange(tests, 'pid');
child.label = 'd';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'root');
assertTreeListEqual(m.changeEvent.added, [child]);
assertTreeListEqual(m.changeEvent.removed, []);
assertTreeListEqual(m.changeEvent.updated, []);
});
test('gets the common ancestor (1)', () => {
tests.children![0].children![0].label = 'za';
tests.children![0].children![1].label = 'zb';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'a');
});
test('gets the common ancestor (2)', () => {
tests.children![0].children![0].label = 'za';
tests.children![1].label = 'ab';
single.onItemChange(tests, 'pid');
m.apply(single.collectDiff());
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'root');
});
});
});
});

View File

@@ -488,41 +488,53 @@ suite.skip('ExtHostTreeView', function () {
test('reveal will return empty array for root element', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
const expected = {
item:
{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed },
parentChain: []
};
return treeView.reveal({ key: 'a' })
.then(() => {
assert.ok(revealTarget.calledOnce);
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
assert.deepEqual({ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual([], revealTarget.args[0][2]);
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][3]);
assert.deepEqual(expected, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
});
});
test('reveal will return parents array for an element when hierarchy is not loaded', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
const expected = {
item: { handle: '0/0:a/0:aa', label: { label: 'aa' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' },
parentChain: [{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }]
};
return treeView.reveal({ key: 'aa' })
.then(() => {
assert.ok(revealTarget.calledOnce);
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
assert.deepEqual({ handle: '0/0:a/0:aa', label: { label: 'aa' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' }, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual([{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][3]);
assert.deepEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
assert.deepEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
});
});
test('reveal will return parents array for an element when hierarchy is loaded', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
const expected = {
item: { handle: '0/0:a/0:aa', label: { label: 'aa' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' },
parentChain: [{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }]
};
return testObject.$getChildren('treeDataProvider')
.then(() => testObject.$getChildren('treeDataProvider', '0/0:a'))
.then(() => treeView.reveal({ key: 'aa' })
.then(() => {
assert.ok(revealTarget.calledOnce);
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
assert.deepEqual({ handle: '0/0:a/0:aa', label: { label: 'aa' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' }, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual([{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][3]);
assert.deepEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
assert.deepEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
}));
});
@@ -536,22 +548,30 @@ suite.skip('ExtHostTreeView', function () {
};
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
const expected = {
item: { handle: '0/0:b/0:ba/0:bac', label: { label: 'bac' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b/0:ba' },
parentChain: [
{ handle: '0/0:b', label: { label: 'b' }, collapsibleState: TreeItemCollapsibleState.Collapsed },
{ handle: '0/0:b/0:ba', label: { label: 'ba' }, collapsibleState: TreeItemCollapsibleState.Collapsed, parentHandle: '0/0:b' }
]
};
return treeView.reveal({ key: 'bac' }, { select: false, focus: false, expand: false })
.then(() => {
assert.ok(revealTarget.calledOnce);
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
assert.deepEqual({ handle: '0/0:b/0:ba/0:bac', label: { label: 'bac' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b/0:ba' }, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual([
{ handle: '0/0:b', label: { label: 'b' }, collapsibleState: TreeItemCollapsibleState.Collapsed },
{ handle: '0/0:b/0:ba', label: { label: 'ba' }, collapsibleState: TreeItemCollapsibleState.Collapsed, parentHandle: '0/0:b' }
], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: false, focus: false, expand: false }, revealTarget.args[0][3]);
assert.deepEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
assert.deepEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: false, focus: false, expand: false }, revealTarget.args[0][2]);
});
});
test('reveal after first udpate', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
const expected = {
item: { handle: '0/0:a/0:ac', label: { label: 'ac' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' },
parentChain: [{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }]
};
return loadCompleteTree('treeDataProvider')
.then(() => {
tree = {
@@ -570,9 +590,9 @@ suite.skip('ExtHostTreeView', function () {
.then(() => {
assert.ok(revealTarget.calledOnce);
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
assert.deepEqual({ handle: '0/0:a/0:ac', label: { label: 'ac' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' }, removeUnsetKeys(revealTarget.args[0][1]));
assert.deepEqual([{ handle: '0/0:a', label: { label: 'a' }, collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][3]);
assert.deepEqual(expected.item, removeUnsetKeys(revealTarget.args[0][1].item));
assert.deepEqual(expected.parentChain, (<Array<any>>(revealTarget.args[0][1].parentChain)).map(arg => removeUnsetKeys(arg)));
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][2]);
});
});
});

View File

@@ -5,10 +5,9 @@
import * as assert from 'assert';
import { MarkdownString, LogLevel } from 'vs/workbench/api/common/extHostTypeConverters';
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
import { isEmptyObject } from 'vs/base/common/types';
import { forEach } from 'vs/base/common/collections';
import * as types from 'vs/workbench/api/common/extHostTypes';
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
@@ -82,14 +81,4 @@ suite('ExtHostTypeConverter', function () {
}
});
});
test('LogLevel', () => {
assert.equal(LogLevel.from(types.LogLevel.Error), _MainLogLevel.Error);
assert.equal(LogLevel.from(types.LogLevel.Info), _MainLogLevel.Info);
assert.equal(LogLevel.from(types.LogLevel.Off), _MainLogLevel.Off);
assert.equal(LogLevel.to(_MainLogLevel.Error), types.LogLevel.Error);
assert.equal(LogLevel.to(_MainLogLevel.Info), types.LogLevel.Info);
assert.equal(LogLevel.to(_MainLogLevel.Off), types.LogLevel.Off);
});
});

View File

@@ -524,6 +524,10 @@ suite('ExtHostTypes', function () {
string.appendChoice(['b', 'a', 'r']);
assert.equal(string.value, '${1|b,a,r|}');
string = new types.SnippetString();
string.appendChoice(['b,1', 'a,2', 'r,3']);
assert.equal(string.value, '${1|b\\,1,a\\,2,r\\,3|}');
string = new types.SnippetString();
string.appendChoice(['b', 'a', 'r'], 0);
assert.equal(string.value, '${0|b,a,r|}');

View File

@@ -14,7 +14,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 { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { EditorGroupColumn } from 'vs/workbench/common/editor';
import type * as vscode from 'vscode';
import { SingleProxyRPCProtocol } from './testRPCProtocol';
@@ -53,7 +53,7 @@ suite('ExtHostWebview', () => {
const serializerARegistration = extHostWebviewPanels.registerWebviewPanelSerializer(extension, viewType, serializerA);
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorGroupColumn, {});
assert.strictEqual(lastInvokedDeserializer, serializerA);
assert.throws(
@@ -64,7 +64,7 @@ suite('ExtHostWebview', () => {
extHostWebviewPanels.registerWebviewPanelSerializer(extension, viewType, serializerB);
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
await extHostWebviewPanels.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorGroupColumn, {});
assert.strictEqual(lastInvokedDeserializer, serializerB);
});

View File

@@ -20,13 +20,16 @@ import { ExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import { IPatternInfo } from 'vs/workbench/services/search/common/search';
import { isWindows } from 'vs/base/common/platform';
import { isLinux, isWindows } from 'vs/base/common/platform';
import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo';
import { FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace {
const result = new ExtHostWorkspace(
new ExtHostRpcService(mainContext),
new class extends mock<IExtHostInitDataService>() { workspace = data; },
logService
new class extends mock<IExtHostFileSystemInfo>() { getCapabilities() { return isLinux ? FileSystemProviderCapabilities.PathCaseSensitive : undefined; } },
logService,
);
result.$initializeWorkspace(data);
return result;
@@ -42,6 +45,7 @@ suite('ExtHostWorkspace', function () {
engines: undefined!,
extensionLocation: undefined!,
isBuiltin: false,
isUserBuiltin: false,
isUnderDevelopment: false,
version: undefined!
};
@@ -601,7 +605,7 @@ suite('ExtHostWorkspace', function () {
});
});
test('findFiles - RelativePattern include', () => {
function testFindFilesInclude(pattern: RelativePattern) {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
@@ -610,16 +614,24 @@ suite('ExtHostWorkspace', function () {
$startFileSearch(includePattern: string, _includeFolder: UriComponents | null, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.equal(includePattern, 'glob/**');
assert.deepEqual(_includeFolder, URI.file('/other/folder').toJSON());
assert.deepEqual(_includeFolder ? URI.from(_includeFolder).toJSON() : null, URI.file('/other/folder').toJSON());
assert.equal(excludePatternOrDisregardExcludes, null);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), undefined, 10, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles(pattern, undefined, 10, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
}
test('findFiles - RelativePattern include (string)', () => {
return testFindFilesInclude(new RelativePattern('/other/folder', 'glob/**'));
});
test('findFiles - RelativePattern include (URI)', () => {
return testFindFilesInclude(new RelativePattern(URI.file('/other/folder'), 'glob/**'));
});
test('findFiles - no excludes', () => {

View File

@@ -15,8 +15,8 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { CustomTreeView } from 'vs/workbench/contrib/views/browser/treeView';
import { ViewDescriptorService } from 'vs/workbench/services/views/browser/viewDescriptorService';
import { CustomTreeView } from 'vs/workbench/browser/parts/views/treeView';
suite('MainThreadHostTreeView', function () {
const testTreeViewId = 'testTreeView';

View File

@@ -9,7 +9,7 @@ import * as Types from 'vs/base/common/types';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { append, $, hide } from 'vs/base/browser/dom';
import { TestLayoutService } from 'vs/workbench/test/browser/workbenchTestServices';
import { StorageScope } from 'vs/platform/storage/common/storage';
import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
class SimplePart extends Part {
@@ -44,8 +44,8 @@ class MyPart extends SimplePart {
return super.createContentArea(parent)!;
}
getMemento(scope: StorageScope) {
return super.getMemento(scope);
getMemento(scope: StorageScope, target: StorageTarget) {
return super.getMemento(scope, target);
}
saveState(): void {
@@ -123,7 +123,7 @@ suite('Workbench parts', () => {
assert.strictEqual(part.getId(), 'myPart');
// Memento
let memento = part.getMemento(StorageScope.GLOBAL) as any;
let memento = part.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE) as any;
assert(memento);
memento.foo = 'bar';
memento.bar = [1, 2, 3];
@@ -133,7 +133,7 @@ suite('Workbench parts', () => {
// Re-Create to assert memento contents
part = new MyPart(b);
memento = part.getMemento(StorageScope.GLOBAL);
memento = part.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert(memento);
assert.strictEqual(memento.foo, 'bar');
assert.strictEqual(memento.bar.length, 3);
@@ -144,7 +144,7 @@ suite('Workbench parts', () => {
part.saveState();
part = new MyPart(b);
memento = part.getMemento(StorageScope.GLOBAL);
memento = part.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert(memento);
assert.strictEqual(Types.isEmptyObject(memento), true);
});

View File

@@ -5,11 +5,12 @@
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { FileKind } from 'vs/platform/files/common/files';
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
import { Workspace } from 'vs/platform/workspace/test/common/testWorkspace';
suite('Breadcrumb Model', function () {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { toResource, SideBySideEditor } from 'vs/workbench/common/editor';
import { EditorResourceAccessor, SideBySideEditor, IEditorInputWithPreferredResource } 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';
@@ -12,6 +12,13 @@ import { workbenchInstantiationService, TestServiceAccessor, TestEditorInput } f
import { Schemas } from 'vs/base/common/network';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
export class TestEditorInputWithPreferredResource extends TestEditorInput implements IEditorInputWithPreferredResource {
constructor(resource: URI, public preferredResource: URI, typeId: string) {
super(resource, typeId);
}
}
suite('Workbench editor', () => {
let instantiationService: IInstantiationService;
@@ -26,50 +33,94 @@ suite('Workbench editor', () => {
accessor.untitledTextEditorService.dispose();
});
test('toResource', () => {
test('EditorResourceAccessor', () => {
const service = accessor.untitledTextEditorService;
assert.ok(!toResource(null!));
assert.ok(!EditorResourceAccessor.getCanonicalUri(null!));
assert.ok(!EditorResourceAccessor.getOriginalUri(null!));
const untitled = instantiationService.createInstance(UntitledTextEditorInput, service.create());
assert.equal(toResource(untitled)!.toString(), untitled.resource.toString());
assert.equal(toResource(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource.toString());
assert.equal(toResource(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(toResource(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource.toString());
assert.equal(toResource(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(toResource(untitled, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.ok(!toResource(untitled, { filterByScheme: Schemas.file }));
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled)!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(untitled, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.ok(!EditorResourceAccessor.getCanonicalUri(untitled, { filterByScheme: Schemas.file }));
assert.equal(EditorResourceAccessor.getOriginalUri(untitled)!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(untitled, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.ok(!EditorResourceAccessor.getOriginalUri(untitled, { filterByScheme: Schemas.file }));
const file = new TestEditorInput(URI.file('/some/path.txt'), 'editorResourceFileTest');
assert.equal(toResource(file)!.toString(), file.resource.toString());
assert.equal(toResource(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(toResource(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.equal(toResource(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.equal(toResource(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(toResource(file, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.ok(!toResource(file, { filterByScheme: Schemas.untitled }));
assert.equal(EditorResourceAccessor.getCanonicalUri(file)!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(file, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.ok(!EditorResourceAccessor.getCanonicalUri(file, { filterByScheme: Schemas.untitled }));
const diffEditorInput = new DiffEditorInput('name', 'description', untitled, file);
assert.equal(EditorResourceAccessor.getOriginalUri(file)!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(file, { filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.ok(!EditorResourceAccessor.getOriginalUri(file, { filterByScheme: Schemas.untitled }));
assert.ok(!toResource(diffEditorInput));
assert.ok(!toResource(diffEditorInput, { filterByScheme: Schemas.file }));
const diffEditorInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', untitled, file, undefined);
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.ok(!EditorResourceAccessor.getCanonicalUri(diffEditorInput));
assert.ok(!EditorResourceAccessor.getCanonicalUri(diffEditorInput, { filterByScheme: Schemas.file }));
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.file }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.untitled }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((toResource(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.file }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.untitled }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getCanonicalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.ok(!EditorResourceAccessor.getOriginalUri(diffEditorInput));
assert.ok(!EditorResourceAccessor.getOriginalUri(diffEditorInput, { filterByScheme: Schemas.file }));
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: Schemas.file })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.SECONDARY, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.file }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).primary.toString(), file.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: Schemas.untitled }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
assert.equal((EditorResourceAccessor.getOriginalUri(diffEditorInput, { supportSideBySide: SideBySideEditor.BOTH, filterByScheme: [Schemas.file, Schemas.untitled] }) as { primary: URI, secondary: URI }).secondary.toString(), untitled.resource.toString());
const resource = URI.file('/some/path.txt');
const preferredResource = URI.file('/some/PATH.txt');
const fileWithPreferredResource = new TestEditorInputWithPreferredResource(URI.file('/some/path.txt'), URI.file('/some/PATH.txt'), 'editorResourceFileTest');
assert.equal(EditorResourceAccessor.getCanonicalUri(fileWithPreferredResource)?.toString(), resource.toString());
assert.equal(EditorResourceAccessor.getOriginalUri(fileWithPreferredResource)?.toString(), preferredResource.toString());
});
});

View File

@@ -37,7 +37,7 @@ 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 diffInput = new DiffEditorInput('name', 'description', input, otherInput);
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
let model = await diffInput.resolve() as TextDiffEditorModel;

View File

@@ -7,11 +7,11 @@ import * as assert from 'assert';
import { EditorGroup, ISerializedEditorGroup, EditorCloseEvent } from 'vs/workbench/common/editor/editorGroup';
import { Extensions as EditorExtensions, IEditorInputFactoryRegistry, EditorInput, IFileEditorInput, IEditorInputFactory, CloseDirection, EditorsOrder } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestLifecycleService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { Registry } from 'vs/platform/registry/common/platform';
import { IEditorModel } from 'vs/platform/editor/common/editor';
@@ -157,6 +157,8 @@ class TestFileEditorInput extends EditorInput implements IFileEditorInput {
}
getTypeId() { return 'testFileEditorInputForGroups'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
setPreferredName(name: string): void { }
setPreferredDescription(description: string): void { }
setPreferredResource(resource: URI): void { }
setEncoding(encoding: string) { }
getEncoding() { return undefined; }
@@ -269,12 +271,13 @@ suite('Workbench editor groups', () => {
test('contains()', function () {
const group = createGroup();
const instantiationService = workbenchInstantiationService();
const input1 = input();
const input2 = input();
const diffInput1 = new DiffEditorInput('name', 'description', input1, input2);
const diffInput2 = new DiffEditorInput('name', 'description', input2, input1);
const diffInput1 = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input1, input2, undefined);
const diffInput2 = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input2, input1, undefined);
group.openEditor(input1, { pinned: true, active: true });
@@ -1513,7 +1516,7 @@ suite('Workbench editor groups', () => {
assert.ok(group1Listener.disposed[1].matches(input3));
});
test('Preview tab does not have a stable position (https://github.com/Microsoft/vscode/issues/8245)', function () {
test('Preview tab does not have a stable position (https://github.com/microsoft/vscode/issues/8245)', function () {
const group1 = createGroup();
const input1 = input();

View File

@@ -6,6 +6,7 @@
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';
class MyEditorInput extends EditorInput {
readonly resource = undefined;
@@ -36,6 +37,8 @@ suite('Workbench editor input', () => {
});
test('DiffEditorInput', () => {
const instantiationService = workbenchInstantiationService();
let counter = 0;
let input = new MyEditorInput();
input.onDispose(() => {
@@ -49,7 +52,7 @@ suite('Workbench editor input', () => {
counter++;
});
let diffInput = new DiffEditorInput('name', 'description', input, otherInput);
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
assert.equal(diffInput.originalInput, input);
assert.equal(diffInput.modifiedInput, otherInput);
@@ -62,11 +65,13 @@ suite('Workbench editor input', () => {
});
test('DiffEditorInput disposes when input inside disposes', function () {
const instantiationService = workbenchInstantiationService();
let counter = 0;
let input = new MyEditorInput();
let otherInput = new MyEditorInput();
let diffInput = new DiffEditorInput('name', 'description', input, otherInput);
let diffInput = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
diffInput.onDispose(() => {
counter++;
assert(true);
@@ -77,7 +82,7 @@ suite('Workbench editor input', () => {
input = new MyEditorInput();
otherInput = new MyEditorInput();
let diffInput2 = new DiffEditorInput('name', 'description', input, otherInput);
let diffInput2 = instantiationService.createInstance(DiffEditorInput, 'name', 'description', input, otherInput, undefined);
diffInput2.onDispose(() => {
counter++;
assert(true);

View File

@@ -325,6 +325,62 @@ suite('Workbench EditorPane', () => {
assert.ok(!res);
});
test('EditoMemento - clear on editor dispose', function () {
const testGroup0 = new TestEditorGroupView(0);
interface TestViewState {
line: number;
}
class TestEditorInput extends EditorInput {
constructor(public resource: URI, private id = 'testEditorInputForMementoTest') {
super();
}
getTypeId() { return 'testEditorInputForMementoTest'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
matches(other: TestEditorInput): boolean {
return other && this.id === other.id && other instanceof TestEditorInput;
}
}
const rawMemento = Object.create(null);
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
const testInputA = new TestEditorInput(URI.file('/A'));
let res = memento.loadEditorState(testGroup0, testInputA);
assert.ok(!res);
memento.saveEditorState(testGroup0, testInputA.resource, { line: 3 });
res = memento.loadEditorState(testGroup0, testInputA);
assert.ok(res);
assert.equal(res!.line, 3);
// State not yet removed when input gets disposed
// because we used resource
testInputA.dispose();
res = memento.loadEditorState(testGroup0, testInputA);
assert.ok(res);
const testInputB = new TestEditorInput(URI.file('/B'));
res = memento.loadEditorState(testGroup0, testInputB);
assert.ok(!res);
memento.saveEditorState(testGroup0, testInputB.resource, { line: 3 });
res = memento.loadEditorState(testGroup0, testInputB);
assert.ok(res);
assert.equal(res!.line, 3);
memento.clearEditorStateOnDispose(testInputB.resource, testInputB);
// State removed when input gets disposed
testInputB.dispose();
res = memento.loadEditorState(testGroup0, testInputB);
assert.ok(!res);
});
return {
MyEditor: MyEditor,
MyOtherEditor: MyOtherEditor

View File

@@ -11,7 +11,7 @@ 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, IEditorInputFactory, Extensions as EditorExtensions, ISaveOptions, IMoveResult, ITextEditorPane, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext } from 'vs/workbench/common/editor';
import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor } from 'vs/workbench/browser/parts/editor/editor';
import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor, IEditorGroupTitleDimensions } from 'vs/workbench/browser/parts/editor/editor';
import { Event, Emitter } from 'vs/base/common/event';
import { IBackupFileService, IResolvedBackup } from 'vs/workbench/services/backup/common/backup';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
@@ -21,7 +21,7 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { IEditorOptions, IResourceEditorInput, IEditorModel, ITextEditorOptions } 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/platform/lifecycle/common/lifecycle';
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 } from 'vs/platform/files/common/files';
import { IModelService } from 'vs/editor/common/services/modelService';
@@ -30,7 +30,7 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { IResourceEncoding, ITextFileService, IReadTextFileOptions, ITextFileStreamContent } from 'vs/workbench/services/textfile/common/textfiles';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IInstantiationService, ServicesAccessor, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { MenuBarVisibility, IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
@@ -63,7 +63,7 @@ import { timeout } from 'vs/base/common/async';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { isLinux, isWindows } from 'vs/base/common/platform';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { Part } from 'vs/workbench/browser/part';
@@ -104,7 +104,6 @@ import { IListService } from 'vs/platform/list/browser/listService';
import { win32, posix } from 'vs/base/common/path';
import { TestWorkingCopyService, TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService } from 'vs/workbench/test/common/workbenchTestServices';
import { IViewsService, IView, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
import { IStorageKeysSyncRegistryService, StorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
@@ -114,9 +113,10 @@ import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream'
import { EncodingOracle, IEncodingOverride } from 'vs/workbench/services/textfile/browser/textFileService';
import { UTF16le, UTF16be, UTF8_with_bom } from 'vs/workbench/services/textfile/common/encoding';
import { ColorScheme } from 'vs/platform/theme/common/theme';
import { Iterable } from 'vs/base/common/iterator';
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined);
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined);
}
export interface ITestInstantiationService extends IInstantiationService {
@@ -126,13 +126,14 @@ export interface ITestInstantiationService extends IInstantiationService {
export function workbenchInstantiationService(overrides?: {
textFileService?: (instantiationService: IInstantiationService) => ITextFileService
pathService?: (instantiationService: IInstantiationService) => IPathService,
editorService?: (instantiationService: IInstantiationService) => IEditorService
editorService?: (instantiationService: IInstantiationService) => IEditorService,
contextKeyService?: (instantiationService: IInstantiationService) => IContextKeyService,
}): ITestInstantiationService {
const instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()]));
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
const contextKeyService = <IContextKeyService>instantiationService.createInstance(MockContextKeyService);
const contextKeyService = overrides?.contextKeyService ? overrides.contextKeyService(instantiationService) : instantiationService.createInstance(MockContextKeyService);
instantiationService.stub(IContextKeyService, contextKeyService);
instantiationService.stub(IProgressService, new TestProgressService());
const workspaceContextService = new TestContextService(TestWorkspace);
@@ -149,7 +150,7 @@ export function workbenchInstantiationService(overrides?: {
instantiationService.stub(IDialogService, new TestDialogService());
const accessibilityService = new TestAccessibilityService();
instantiationService.stub(IAccessibilityService, accessibilityService);
instantiationService.stub(IFileDialogService, new TestFileDialogService());
instantiationService.stub(IFileDialogService, instantiationService.createInstance(TestFileDialogService));
instantiationService.stub(IModeService, instantiationService.createInstance(ModeServiceImpl));
instantiationService.stub(IHistoryService, new TestHistoryService());
instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(configService));
@@ -183,7 +184,6 @@ export function workbenchInstantiationService(overrides?: {
instantiationService.stub(IViewletService, new TestViewletService());
instantiationService.stub(IListService, new TestListService());
instantiationService.stub(IQuickInputService, new QuickInputService(configService, instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService));
instantiationService.stub(IStorageKeysSyncRegistryService, new StorageKeysSyncRegistryService());
return instantiationService;
}
@@ -231,7 +231,8 @@ export class TestTextFileService extends BrowserTextFileService {
@IPathService pathService: IPathService,
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService,
@IUriIdentityService uriIdentityService: IUriIdentityService,
@IModeService modeService: IModeService
@IModeService modeService: IModeService,
@ILogService logService: ILogService
) {
super(
fileService,
@@ -249,7 +250,8 @@ export class TestTextFileService extends BrowserTextFileService {
pathService,
workingCopyFileService,
uriIdentityService,
modeService
modeService,
logService
);
}
@@ -308,7 +310,9 @@ class TestEnvironmentServiceWithArgs extends BrowserWorkbenchEnvironmentService
args = [];
}
export const TestEnvironmentService = new TestEnvironmentServiceWithArgs(Object.create(null));
export const TestProductService = { _serviceBrand: undefined, ...product };
export const TestEnvironmentService = new TestEnvironmentServiceWithArgs(Object.create(null), TestProductService);
export class TestProgressService implements IProgressService {
@@ -385,9 +389,12 @@ export class TestFileDialogService implements IFileDialogService {
private confirmResult!: ConfirmResult;
defaultFilePath(_schemeFilter?: string): URI | undefined { return undefined; }
defaultFolderPath(_schemeFilter?: string): URI | undefined { return undefined; }
defaultWorkspacePath(_schemeFilter?: string): URI | undefined { return undefined; }
constructor(
@IPathService private readonly pathService: IPathService
) { }
async defaultFilePath(_schemeFilter?: string): Promise<URI> { return this.pathService.userHome(); }
async defaultFolderPath(_schemeFilter?: string): Promise<URI> { return this.pathService.userHome(); }
async defaultWorkspacePath(_schemeFilter?: string): Promise<URI> { return this.pathService.userHome(); }
pickFileFolderAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
pickFileAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
pickFolderAndOpen(_options: IPickAndOpenOptions): Promise<any> { return Promise.resolve(0); }
@@ -456,7 +463,7 @@ export class TestLayoutService implements IWorkbenchLayoutService {
toggleZenMode(): void { }
isEditorLayoutCentered(): boolean { return false; }
centerEditorLayout(_active: boolean): void { }
resizePart(_part: Parts, _sizeChange: number): void { }
resizePart(_part: Parts, _sizeChangeWidth: number, _sizeChangeHeight: number): void { }
registerPart(part: Part): void { }
isWindowMaximized() { return false; }
updateWindowMaximizedState(maximized: boolean): void { }
@@ -599,6 +606,8 @@ export class TestEditorGroupView implements IEditorGroupView {
minimumHeight!: number;
maximumHeight!: number;
titleDimensions!: IEditorGroupTitleDimensions;
isEmpty = true;
isMinimized = false;
@@ -630,7 +639,7 @@ export class TestEditorGroupView implements IEditorGroupView {
stickEditor(editor?: IEditorInput | undefined): void { }
unstickEditor(editor?: IEditorInput | undefined): void { }
focus(): void { }
invokeWithinContext<T>(fn: (accessor: ServicesAccessor) => T): T { throw new Error('not implemented'); }
get scopedContextKeyService(): IContextKeyService { throw new Error('not implemented'); }
setActive(_isActive: boolean): void { }
notifyIndexChanged(_index: number): void { }
dispose(): void { }
@@ -712,7 +721,6 @@ export class TestEditorService implements EditorServiceImpl {
openEditors(_editors: any, _group?: any): Promise<IEditorPane[]> { throw new Error('not implemented'); }
isOpen(_editor: IEditorInput | IResourceEditorInput): boolean { return false; }
replaceEditors(_editors: any, _group: any) { return Promise.resolve(undefined); }
invokeWithinEditorContext<T>(fn: (accessor: ServicesAccessor) => T): T { throw new Error('not implemented'); }
createEditorInput(_input: IResourceEditorInput | IUntitledTextResourceEditorInput | IResourceDiffEditorInput): EditorInput { throw new Error('not implemented'); }
save(editors: IEditorIdentifier[], options?: ISaveEditorsOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
saveAll(options?: ISaveEditorsOptions): Promise<boolean> { throw new Error('Method not implemented.'); }
@@ -834,7 +842,7 @@ export class TestFileService implements IFileService {
move(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
copy(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
createFile(_resource: URI, _content?: VSBuffer | VSBufferReadable, _options?: ICreateFileOptions): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
createFolder(_resource: URI): Promise<IFileStatWithMetadata> { throw new Error('not implemented'); }
createFolder(_resource: URI): Promise<IFileStatWithMetadata> { return Promise.resolve(null!); }
onDidChangeFileSystemProviderRegistrations = Event.None;
@@ -847,7 +855,13 @@ export class TestFileService implements IFileService {
}
activateProvider(_scheme: string): Promise<void> { throw new Error('not implemented'); }
canHandleResource(resource: URI): boolean { return resource.scheme === 'file' || this.providers.has(resource.scheme); }
canHandleResource(resource: URI): boolean { return resource.scheme === Schemas.file || this.providers.has(resource.scheme); }
listCapabilities() {
return [
{ scheme: Schemas.file, capabilities: FileSystemProviderCapabilities.FileOpenReadWriteClose },
...Iterable.map(this.providers, ([scheme, p]) => { return { scheme, capabilities: p.capabilities }; })
];
}
hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean {
if (capability === FileSystemProviderCapabilities.PathCaseSensitive && isLinux) {
return true;
@@ -921,6 +935,10 @@ export class TestLifecycleService implements ILifecycleService {
}
fireWillShutdown(event: BeforeShutdownEvent): void { this._onBeforeShutdown.fire(event); }
shutdown(): void {
this.fireShutdown();
}
}
export class TestTextResourceConfigurationService implements ITextResourceConfigurationService {
@@ -1031,6 +1049,7 @@ export class TestHostService implements IHostService {
async restart(): Promise<void> { }
async reload(): Promise<void> { }
async close(): Promise<void> { }
async focus(options?: { force: boolean }): Promise<void> { }
@@ -1074,7 +1093,12 @@ export class TestEditorInput extends EditorInput {
export function registerTestEditor(id: string, inputs: SyncDescriptor<EditorInput>[], factoryInputId?: string): IDisposable {
class TestEditor extends EditorPane {
constructor() { super(id, NullTelemetryService, new TestThemeService(), new TestStorageService()); }
private _scopedContextKeyService: IContextKeyService;
constructor() {
super(id, NullTelemetryService, new TestThemeService(), new TestStorageService());
this._scopedContextKeyService = new MockContextKeyService();
}
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
super.setInput(input, options, context, token);
@@ -1085,6 +1109,10 @@ export function registerTestEditor(id: string, inputs: SyncDescriptor<EditorInpu
getId(): string { return id; }
layout(): void { }
createEditor(): void { }
get scopedContextKeyService() {
return this._scopedContextKeyService;
}
}
const disposables = new DisposableStore();
@@ -1149,6 +1177,8 @@ export class TestFileEditorInput extends EditorInput implements IFileEditorInput
setPreferredResource(resource: URI): void { }
setEncoding(encoding: string) { }
getEncoding() { return undefined; }
setPreferredName(name: string): void { }
setPreferredDescription(description: string): void { }
setPreferredEncoding(encoding: string) { }
setMode(mode: string) { }
setPreferredMode(mode: string) { }
@@ -1194,12 +1224,12 @@ export class TestEditorPart extends EditorPart {
}
clearState(): void {
const workspaceMemento = this.getMemento(StorageScope.WORKSPACE);
const workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
for (const key of Object.keys(workspaceMemento)) {
delete workspaceMemento[key];
}
const globalMemento = this.getMemento(StorageScope.GLOBAL);
const globalMemento = this.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
for (const key of Object.keys(globalMemento)) {
delete globalMemento[key];
}

View File

@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
import { StorageScope, IStorageService, StorageTarget } from 'vs/platform/storage/common/storage';
import { Memento } from 'vs/workbench/common/memento';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
@@ -21,26 +20,26 @@ suite('Memento', () => {
let myMemento = new Memento('memento.test', storage);
// Global
let memento = myMemento.getMemento(StorageScope.GLOBAL);
let memento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
memento.foo = [1, 2, 3];
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL);
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert(memento);
memento.foo = 'Hello World';
myMemento.saveMemento();
// Global
memento = myMemento.getMemento(StorageScope.GLOBAL);
memento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: [1, 2, 3] });
globalMemento = myMemento.getMemento(StorageScope.GLOBAL);
globalMemento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: 'Hello World' });
// Assert the Mementos are stored properly in storage
@@ -49,21 +48,21 @@ suite('Memento', () => {
assert.deepEqual(JSON.parse(storage.get('memento/memento.test', StorageScope.WORKSPACE)!), { foo: 'Hello World' });
// Delete Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
delete memento.foo;
// Delete Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
delete memento.foo;
myMemento.saveMemento();
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, {});
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, {});
// Assert the Mementos are also removed from storage
@@ -76,63 +75,63 @@ suite('Memento', () => {
let myMemento = new Memento('memento.test', storage);
// Global
let memento = myMemento.getMemento(context!);
let memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
memento.foo = [1, 2, 3];
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert(memento);
memento.foo = 'Hello World';
myMemento.saveMemento();
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: [1, 2, 3] });
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL);
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: 'Hello World' });
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
memento.foo = [4, 5, 6];
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert(memento);
memento.foo = 'World Hello';
myMemento.saveMemento();
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: [4, 5, 6] });
globalMemento = myMemento.getMemento(StorageScope.GLOBAL);
globalMemento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: 'World Hello' });
// Delete Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
delete memento.foo;
// Delete Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
delete memento.foo;
myMemento.saveMemento();
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, {});
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, {});
});
@@ -141,18 +140,18 @@ suite('Memento', () => {
let myMemento2 = new Memento('memento.test', storage);
// Global
let memento = myMemento.getMemento(context!);
let memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
memento.foo = [1, 2, 3];
memento = myMemento2.getMemento(context!);
memento = myMemento2.getMemento(context!, StorageTarget.MACHINE);
memento.bar = [1, 2, 3];
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert(memento);
memento.foo = 'Hello World';
memento = myMemento2.getMemento(StorageScope.WORKSPACE);
memento = myMemento2.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert(memento);
memento.bar = 'Hello World';
@@ -160,21 +159,21 @@ suite('Memento', () => {
myMemento2.saveMemento();
// Global
memento = myMemento.getMemento(context!);
memento = myMemento.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: [1, 2, 3], bar: [1, 2, 3] });
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL);
let globalMemento = myMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
memento = myMemento2.getMemento(context!);
memento = myMemento2.getMemento(context!, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: [1, 2, 3], bar: [1, 2, 3] });
globalMemento = myMemento2.getMemento(StorageScope.GLOBAL);
globalMemento = myMemento2.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert.deepEqual(globalMemento, memento);
// Workspace
memento = myMemento.getMemento(StorageScope.WORKSPACE);
memento = myMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: 'Hello World', bar: 'Hello World' });
memento = myMemento2.getMemento(StorageScope.WORKSPACE);
memento = myMemento2.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
assert.deepEqual(memento, { foo: 'Hello World', bar: 'Hello World' });
});
});

View File

@@ -8,18 +8,20 @@ import * as resources from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace } from 'vs/platform/workspace/common/workspace';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { InMemoryStorageService, IWillSaveStateEvent } from 'vs/platform/storage/common/storage';
import { WorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { InMemoryStorageService, WillSaveStateReason } from 'vs/platform/storage/common/storage';
import { WorkingCopyService, IWorkingCopy, IWorkingCopyBackup, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { NullExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IWorkingCopyFileService, IWorkingCopyFileOperationParticipant, WorkingCopyFileEvent } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IFileStatWithMetadata } from 'vs/platform/files/common/files';
import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
import { ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor';
import { CancellationToken } from 'vs/base/common/cancellation';
export class TestTextResourcePropertiesService implements ITextResourcePropertiesService {
@@ -79,11 +81,11 @@ export class TestContextService implements IWorkspaceContextService {
return WorkbenchState.EMPTY;
}
getCompleteWorkspace(): Promise<IWorkbenchWorkspace> {
getCompleteWorkspace(): Promise<IWorkspace> {
return Promise.resolve(this.getWorkspace());
}
getWorkspace(): IWorkbenchWorkspace {
getWorkspace(): IWorkspace {
return this.workspace;
}
@@ -119,12 +121,71 @@ export class TestContextService implements IWorkspaceContextService {
}
export class TestStorageService extends InMemoryStorageService {
readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
readonly onWillSaveState = this._onWillSaveState.event;
emitWillSaveState(reason: WillSaveStateReason): void {
super.emitWillSaveState(reason);
}
}
export class TestWorkingCopyService extends WorkingCopyService { }
export class TestWorkingCopy extends Disposable implements IWorkingCopy {
private readonly _onDidChangeDirty = this._register(new Emitter<void>());
readonly onDidChangeDirty = this._onDidChangeDirty.event;
private readonly _onDidChangeContent = this._register(new Emitter<void>());
readonly onDidChangeContent = this._onDidChangeContent.event;
private readonly _onDispose = this._register(new Emitter<void>());
readonly onDispose = this._onDispose.event;
readonly capabilities = WorkingCopyCapabilities.None;
readonly name = resources.basename(this.resource);
private dirty = false;
constructor(public readonly resource: URI, isDirty = false) {
super();
this.dirty = isDirty;
}
setDirty(dirty: boolean): void {
if (this.dirty !== dirty) {
this.dirty = dirty;
this._onDidChangeDirty.fire();
}
}
setContent(content: string): void {
this._onDidChangeContent.fire();
}
isDirty(): boolean {
return this.dirty;
}
async save(options?: ISaveOptions): Promise<boolean> {
return true;
}
async revert(options?: IRevertOptions): Promise<void> {
this.setDirty(false);
}
async backup(token: CancellationToken): Promise<IWorkingCopyBackup> {
return {};
}
dispose(): void {
this._onDispose.fire();
super.dispose();
}
}
export class TestWorkingCopyFileService implements IWorkingCopyFileService {
declare readonly _serviceBrand: undefined;
@@ -142,6 +203,7 @@ export class TestWorkingCopyFileService implements IWorkingCopyFileService {
getDirty(resource: URI): IWorkingCopy[] { return []; }
create(resource: URI, contents?: VSBuffer | VSBufferReadable | VSBufferReadableStream, options?: { overwrite?: boolean | undefined; } | undefined): Promise<IFileStatWithMetadata> { throw new Error('Method not implemented.'); }
createFolder(resource: URI): Promise<IFileStatWithMetadata> { throw new Error('Method not implemented.'); }
move(files: { source: URI; target: URI; }[], options?: { overwrite?: boolean }): Promise<IFileStatWithMetadata[]> { throw new Error('Method not implemented.'); }

View File

@@ -3,18 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestFileService, TestFileDialogService, TestPathService, TestEncodingOracle } from 'vs/workbench/test/browser/workbenchTestServices';
import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestFileService, TestFileDialogService, TestPathService, TestEncodingOracle, TestProductService } from 'vs/workbench/test/browser/workbenchTestServices';
import { Event } from 'vs/base/common/event';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { NativeTextFileService, } from 'vs/workbench/services/textfile/electron-browser/nativeTextFileService';
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
import { FileOperationError, IFileService } from 'vs/platform/files/common/files';
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { INativeWorkbenchConfiguration, INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
import { IDialogService, IFileDialogService, INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
@@ -40,8 +39,8 @@ import { TestContextService } from 'vs/workbench/test/common/workbenchTestServic
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IOSProperties } from 'vs/platform/electron/common/electron';
import { ColorScheme } from 'vs/platform/theme/common/theme';
import { IOSProperties, IOSStatistics } from 'vs/platform/native/common/native';
import { homedir, release } from 'os';
export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
windowId: 0,
@@ -54,11 +53,12 @@ export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
userEnv: {},
execPath: process.execPath,
perfEntries: [],
colorScheme: ColorScheme.DARK,
colorScheme: { dark: true, highContrast: false },
os: { release: release() },
...parseArgs(process.argv, OPTIONS)
};
export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(TestWorkbenchConfiguration);
export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(TestWorkbenchConfiguration, TestProductService);
export class TestTextFileService extends NativeTextFileService {
private resolveTextContentError!: FileOperationError | null;
@@ -69,7 +69,7 @@ export class TestTextFileService extends NativeTextFileService {
@ILifecycleService lifecycleService: ILifecycleService,
@IInstantiationService instantiationService: IInstantiationService,
@IModelService modelService: IModelService,
@IWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
@INativeWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
@IDialogService dialogService: IDialogService,
@IFileDialogService fileDialogService: IFileDialogService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService,
@@ -77,11 +77,12 @@ export class TestTextFileService extends NativeTextFileService {
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@ITextModelService textModelService: ITextModelService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@IPathService athService: IPathService,
@IPathService pathService: IPathService,
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService,
@ILogService logService: ILogService,
@IUriIdentityService uriIdentityService: IUriIdentityService,
@IModeService modeService: IModeService
@IModeService modeService: IModeService,
@INativeHostService nativeHostService: INativeHostService
) {
super(
fileService,
@@ -93,15 +94,15 @@ export class TestTextFileService extends NativeTextFileService {
dialogService,
fileDialogService,
textResourceConfigurationService,
productService,
filesConfigurationService,
textModelService,
codeEditorService,
athService,
pathService,
workingCopyFileService,
logService,
uriIdentityService,
modeService
modeService,
nativeHostService,
logService
);
}
@@ -155,19 +156,20 @@ export class TestSharedProcessService implements ISharedProcessService {
async whenSharedProcessReady(): Promise<void> { }
}
export class TestElectronService implements IElectronService {
export class TestNativeHostService implements INativeHostService {
declare readonly _serviceBrand: undefined;
readonly windowId = -1;
onWindowOpen: Event<number> = Event.None;
onWindowMaximize: Event<number> = Event.None;
onWindowUnmaximize: Event<number> = Event.None;
onWindowFocus: Event<number> = Event.None;
onWindowBlur: Event<number> = Event.None;
onOSResume: Event<unknown> = Event.None;
onColorSchemeChange = Event.None;
onDidOpenWindow: Event<number> = Event.None;
onDidMaximizeWindow: Event<number> = Event.None;
onDidUnmaximizeWindow: Event<number> = Event.None;
onDidFocusWindow: Event<number> = Event.None;
onDidBlurWindow: Event<number> = Event.None;
onDidResumeOS: Event<unknown> = Event.None;
onDidChangeColorScheme = Event.None;
onDidChangePassword = Event.None;
windowCount = Promise.resolve(1);
getWindowCount(): Promise<number> { return this.windowCount; }
@@ -187,6 +189,7 @@ export class TestElectronService implements IElectronService {
async maximizeWindow(): Promise<void> { }
async unmaximizeWindow(): Promise<void> { }
async minimizeWindow(): Promise<void> { }
async setMinimumSize(width: number | undefined, height: number | undefined): 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.'); }
@@ -198,8 +201,10 @@ export class TestElectronService implements IElectronService {
async showItemInFolder(path: string): Promise<void> { }
async setRepresentedFilename(path: string): Promise<void> { }
async isAdmin(): Promise<boolean> { return false; }
async getTotalMem(): Promise<number> { return 0; }
async getOS(): Promise<IOSProperties> { return Object.create(null); }
async writeElevated(source: URI, target: URI, options?: { overwriteReadonly?: boolean | undefined; }): Promise<void> { }
async getOSProperties(): Promise<IOSProperties> { return Object.create(null); }
async getOSStatistics(): Promise<IOSStatistics> { return Object.create(null); }
async getOSVirtualMachineHint(): Promise<number> { return 0; }
async killProcess(): Promise<void> { }
async setDocumentEdited(edited: boolean): Promise<void> { }
async openExternal(url: string): Promise<boolean> { return false; }
@@ -230,6 +235,12 @@ export class TestElectronService implements IElectronService {
async readClipboardBuffer(format: string): Promise<Uint8Array> { return Uint8Array.from([]); }
async hasClipboard(format: string, type?: 'selection' | 'clipboard' | undefined): Promise<boolean> { return false; }
async sendInputEvent(event: MouseInputEvent): Promise<void> { }
async windowsGetStringRegKey(hive: 'HKEY_CURRENT_USER' | 'HKEY_LOCAL_MACHINE' | 'HKEY_CLASSES_ROOT' | 'HKEY_USERS' | 'HKEY_CURRENT_CONFIG', path: string, name: string): Promise<string | undefined> { return undefined; }
async getPassword(service: string, account: string): Promise<string | null> { return null; }
async setPassword(service: string, account: string, password: string): Promise<void> { }
async deletePassword(service: string, account: string): Promise<boolean> { return false; }
async findPassword(service: string): Promise<string | null> { return null; }
async findCredentials(service: string): Promise<{ account: string; password: string; }[]> { return []; }
}
export function workbenchInstantiationService(): ITestInstantiationService {
@@ -238,7 +249,8 @@ export function workbenchInstantiationService(): ITestInstantiationService {
pathService: insta => <IPathService>insta.createInstance(TestNativePathService)
});
instantiationService.stub(IElectronService, new TestElectronService());
instantiationService.stub(INativeHostService, new TestNativeHostService());
instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService);
return instantiationService;
}
@@ -251,7 +263,7 @@ export class TestServiceAccessor {
@IWorkspaceContextService public contextService: TestContextService,
@IModelService public modelService: ModelServiceImpl,
@IFileService public fileService: TestFileService,
@IElectronService public electronService: TestElectronService,
@INativeHostService public nativeHostService: TestNativeHostService,
@IFileDialogService public fileDialogService: TestFileDialogService,
@IBackupFileService public backupFileService: NodeTestBackupFileService,
@IWorkingCopyService public workingCopyService: IWorkingCopyService,
@@ -264,7 +276,7 @@ export class TestNativePathService extends TestPathService {
declare readonly _serviceBrand: undefined;
constructor(@IWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService) {
super(environmentService.userHome);
constructor() {
super(URI.file(homedir()));
}
}