Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -115,14 +115,14 @@ suite('Workbench base editor', () => {
});
test('EditorDescriptor', () => {
let d = new EditorDescriptor(MyEditor, 'id', 'name');
let d = EditorDescriptor.create(MyEditor, 'id', 'name');
assert.strictEqual(d.getId(), 'id');
assert.strictEqual(d.getName(), 'name');
});
test('Editor Registration', function () {
let d1 = new EditorDescriptor(MyEditor, 'id1', 'name');
let d2 = new EditorDescriptor(MyOtherEditor, 'id2', 'name');
let d1 = EditorDescriptor.create(MyEditor, 'id1', 'name');
let d2 = EditorDescriptor.create(MyOtherEditor, 'id2', 'name');
let oldEditorsCnt = EditorRegistry.getEditors().length;
let oldInputCnt = (<any>EditorRegistry).getEditorInputs().length;
@@ -142,8 +142,8 @@ suite('Workbench base editor', () => {
});
test('Editor Lookup favors specific class over superclass (match on specific class)', function () {
let d1 = new EditorDescriptor(MyEditor, 'id1', 'name');
let d2 = new EditorDescriptor(MyOtherEditor, 'id2', 'name');
let d1 = EditorDescriptor.create(MyEditor, 'id1', 'name');
let d2 = EditorDescriptor.create(MyOtherEditor, 'id2', 'name');
let oldEditors = EditorRegistry.getEditors();
(<any>EditorRegistry).setEditors([]);
@@ -163,7 +163,7 @@ suite('Workbench base editor', () => {
});
test('Editor Lookup favors specific class over superclass (match on super class)', function () {
let d1 = new EditorDescriptor(MyOtherEditor, 'id1', 'name');
let d1 = EditorDescriptor.create(MyOtherEditor, 'id1', 'name');
let oldEditors = EditorRegistry.getEditors();
(<any>EditorRegistry).setEditors([]);

View File

@@ -29,7 +29,7 @@ suite('Breadcrumb Model', function () {
test('only uri, inside workspace', function () {
let model = new EditorBreadcrumbsModel(URI.parse('foo:/bar/baz/ws/some/path/file.ts'), undefined, configService, workspaceService);
let model = new EditorBreadcrumbsModel(URI.parse('foo:/bar/baz/ws/some/path/file.ts'), undefined, configService, configService, workspaceService);
let elements = model.getElements();
assert.equal(elements.length, 3);
@@ -44,7 +44,7 @@ suite('Breadcrumb Model', function () {
test('only uri, outside workspace', function () {
let model = new EditorBreadcrumbsModel(URI.parse('foo:/outside/file.ts'), undefined, configService, workspaceService);
let model = new EditorBreadcrumbsModel(URI.parse('foo:/outside/file.ts'), undefined, configService, configService, workspaceService);
let elements = model.getElements();
assert.equal(elements.length, 2);

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ContributableViewsModel, ViewsService } from 'vs/workbench/browser/parts/views/views';
import { ContributableViewsModel, ViewsService, IViewState } from 'vs/workbench/browser/parts/views/views';
import { IViewsRegistry, IViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, IViewsService } from 'vs/workbench/common/views';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { move } from 'vs/base/common/arrays';
@@ -13,6 +13,7 @@ import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestSe
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService';
import sinon = require('sinon');
const container = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer('test');
const ViewsRegistry = Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry);
@@ -244,4 +245,130 @@ suite('ContributableViewsModel', () => {
assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3], 'view2 should go to the middle');
assert.deepEqual(seq.elements, [view1, view2, view3]);
});
test('view states', async function () {
const viewStates = new Map<string, IViewState>();
viewStates.set('view1', { visibleGlobal: false, collapsed: false, visibleWorkspace: undefined });
const model = new ContributableViewsModel(container, viewsService, viewStates);
const seq = new ViewDescriptorSequence(model);
assert.equal(model.visibleViewDescriptors.length, 0);
assert.equal(seq.elements.length, 0);
const viewDescriptor: IViewDescriptor = {
id: 'view1',
ctorDescriptor: null!,
name: 'Test View 1'
};
ViewsRegistry.registerViews([viewDescriptor], container);
assert.equal(model.visibleViewDescriptors.length, 0, 'view should not appear since it was set not visible in view state');
assert.equal(seq.elements.length, 0);
});
test('view states and when contexts', async function () {
const viewStates = new Map<string, IViewState>();
viewStates.set('view1', { visibleGlobal: false, collapsed: false, visibleWorkspace: undefined });
const model = new ContributableViewsModel(container, viewsService, viewStates);
const seq = new ViewDescriptorSequence(model);
assert.equal(model.visibleViewDescriptors.length, 0);
assert.equal(seq.elements.length, 0);
const viewDescriptor: IViewDescriptor = {
id: 'view1',
ctorDescriptor: null!,
name: 'Test View 1',
when: ContextKeyExpr.equals('showview1', true)
};
ViewsRegistry.registerViews([viewDescriptor], container);
assert.equal(model.visibleViewDescriptors.length, 0, 'view should not appear since context isnt in');
assert.equal(seq.elements.length, 0);
const key = contextKeyService.createKey('showview1', false);
assert.equal(model.visibleViewDescriptors.length, 0, 'view should still not appear since showview1 isnt true');
assert.equal(seq.elements.length, 0);
key.set(true);
await new Promise(c => setTimeout(c, 30));
assert.equal(model.visibleViewDescriptors.length, 0, 'view should still not appear since it was set not visible in view state');
assert.equal(seq.elements.length, 0);
});
test('view states and when contexts multiple views', async function () {
const viewStates = new Map<string, IViewState>();
viewStates.set('view1', { visibleGlobal: false, collapsed: false, visibleWorkspace: undefined });
const model = new ContributableViewsModel(container, viewsService, viewStates);
const seq = new ViewDescriptorSequence(model);
assert.equal(model.visibleViewDescriptors.length, 0);
assert.equal(seq.elements.length, 0);
const view1: IViewDescriptor = {
id: 'view1',
ctorDescriptor: null!,
name: 'Test View 1',
when: ContextKeyExpr.equals('showview', true)
};
const view2: IViewDescriptor = {
id: 'view2',
ctorDescriptor: null!,
name: 'Test View 2',
};
const view3: IViewDescriptor = {
id: 'view3',
ctorDescriptor: null!,
name: 'Test View 3',
when: ContextKeyExpr.equals('showview', true)
};
ViewsRegistry.registerViews([view1, view2, view3], container);
assert.deepEqual(model.visibleViewDescriptors, [view2], 'Only view2 should be visible');
assert.deepEqual(seq.elements, [view2]);
const key = contextKeyService.createKey('showview', false);
assert.deepEqual(model.visibleViewDescriptors, [view2], 'Only view2 should be visible');
assert.deepEqual(seq.elements, [view2]);
key.set(true);
await new Promise(c => setTimeout(c, 30));
assert.deepEqual(model.visibleViewDescriptors, [view2, view3], 'view3 should be visible');
assert.deepEqual(seq.elements, [view2, view3]);
key.set(false);
await new Promise(c => setTimeout(c, 30));
assert.deepEqual(model.visibleViewDescriptors, [view2], 'Only view2 should be visible');
assert.deepEqual(seq.elements, [view2]);
});
test('remove event is not triggered if view was hidden and removed', async function () {
const model = new ContributableViewsModel(container, viewsService);
const seq = new ViewDescriptorSequence(model);
const viewDescriptor: IViewDescriptor = {
id: 'view1',
ctorDescriptor: null!,
name: 'Test View 1',
when: ContextKeyExpr.equals('showview1', true),
canToggleVisibility: true
};
ViewsRegistry.registerViews([viewDescriptor], container);
const key = contextKeyService.createKey('showview1', true);
await new Promise(c => setTimeout(c, 30));
assert.equal(model.visibleViewDescriptors.length, 1, 'view should appear after context is set');
assert.equal(seq.elements.length, 1);
model.setVisible('view1', false);
assert.equal(model.visibleViewDescriptors.length, 0, 'view should disappear after setting visibility to false');
assert.equal(seq.elements.length, 0);
const target = sinon.spy(model.onDidRemove);
key.set(false);
await new Promise(c => setTimeout(c, 30));
assert.ok(!target.called, 'remove event should not be called since it is already hidden');
});
});

View File

@@ -54,7 +54,7 @@ suite('QuickOpen', () => {
test('QuickOpen Handler and Registry', () => {
let registry = (Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen));
let handler = new QuickOpenHandlerDescriptor(
let handler = QuickOpenHandlerDescriptor.create(
TestHandler,
'testhandler',
',',
@@ -77,4 +77,4 @@ suite('QuickOpen', () => {
defaultAction.run();
prefixAction.run();
});
});
});

View File

@@ -22,7 +22,7 @@ suite('Viewlets', () => {
}
test('ViewletDescriptor API', function () {
let d = new ViewletDescriptor(TestViewlet, 'id', 'name', 'class', 5);
let d = ViewletDescriptor.create(TestViewlet, 'id', 'name', 'class', 5);
assert.strictEqual(d.id, 'id');
assert.strictEqual(d.name, 'name');
assert.strictEqual(d.cssClass, 'class');
@@ -30,11 +30,11 @@ suite('Viewlets', () => {
});
test('Editor Aware ViewletDescriptor API', function () {
let d = new ViewletDescriptor(TestViewlet, 'id', 'name', 'class', 5);
let d = ViewletDescriptor.create(TestViewlet, 'id', 'name', 'class', 5);
assert.strictEqual(d.id, 'id');
assert.strictEqual(d.name, 'name');
d = new ViewletDescriptor(TestViewlet, 'id', 'name', 'class', 5);
d = ViewletDescriptor.create(TestViewlet, 'id', 'name', 'class', 5);
assert.strictEqual(d.id, 'id');
assert.strictEqual(d.name, 'name');
});
@@ -45,7 +45,7 @@ suite('Viewlets', () => {
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets));
let oldCount = Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length;
let d = new ViewletDescriptor(TestViewlet, 'reg-test-id', 'name');
let d = ViewletDescriptor.create(TestViewlet, 'reg-test-id', 'name');
Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet(d);
assert(d === Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet('reg-test-id'));

View File

@@ -1,34 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInput';
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
suite('DataUriEditorInput', () => {
let instantiationService: IInstantiationService;
setup(() => {
instantiationService = workbenchInstantiationService();
});
test('simple', () => {
const resource = URI.parse('data:image/png;label:SomeLabel;description:SomeDescription;size:1024;base64,77+9UE5');
const input: DataUriEditorInput = instantiationService.createInstance(DataUriEditorInput, undefined, undefined, resource);
assert.equal(input.getName(), 'SomeLabel');
assert.equal(input.getDescription(), 'SomeDescription');
return input.resolve().then((model: BinaryEditorModel) => {
assert.ok(model);
assert.equal(model.getSize(), 1024);
assert.equal(model.getMime(), 'image/png');
});
});
});

View File

@@ -8,13 +8,13 @@ import { EditorInput, toResource, SideBySideEditor } from 'vs/workbench/common/e
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { IEditorModel } from 'vs/platform/editor/common/editor';
import { URI } from 'vs/base/common/uri';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
import { Schemas } from 'vs/base/common/network';
class ServiceAccessor {
constructor(@IUntitledEditorService public untitledEditorService: UntitledEditorService) {
constructor(@IUntitledTextEditorService public untitledTextEditorService: UntitledTextEditorService) {
}
}
@@ -48,12 +48,12 @@ suite('Workbench editor', () => {
});
teardown(() => {
accessor.untitledEditorService.revertAll();
accessor.untitledEditorService.dispose();
accessor.untitledTextEditorService.revertAll();
accessor.untitledTextEditorService.dispose();
});
test('toResource', () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
assert.ok(!toResource(null!));
@@ -82,4 +82,4 @@ suite('Workbench editor', () => {
assert.equal(toResource(file, { supportSideBySide: SideBySideEditor.MASTER, filterByScheme: Schemas.file })!.toString(), file.getResource().toString());
assert.equal(toResource(file, { supportSideBySide: SideBySideEditor.MASTER, filterByScheme: [Schemas.file, Schemas.untitled] })!.toString(), file.getResource().toString());
});
});
});

View File

@@ -187,19 +187,79 @@ suite('Workbench editor groups', () => {
assert.equal(clone.isActive(input3), true);
});
test('contains() with diff editor support', function () {
test('contains()', function () {
const group = createGroup();
const input1 = input();
const input2 = input();
const diffInput = new DiffEditorInput('name', 'description', input1, input2);
const diffInput1 = new DiffEditorInput('name', 'description', input1, input2);
const diffInput2 = new DiffEditorInput('name', 'description', input2, input1);
group.openEditor(input1, { pinned: true, active: true });
assert.equal(group.contains(input1), true);
assert.equal(group.contains(input1, true), true);
assert.equal(group.contains(input2), false);
assert.equal(group.contains(input2, true), false);
assert.equal(group.contains(diffInput1), false);
assert.equal(group.contains(diffInput2), false);
group.openEditor(input2, { pinned: true, active: true });
assert.equal(group.contains(input1), true);
assert.equal(group.contains(input2), true);
assert.equal(group.contains(diffInput), false);
assert.equal(group.contains(diffInput, true), true);
assert.equal(group.contains(diffInput1), false);
assert.equal(group.contains(diffInput2), false);
group.openEditor(diffInput1, { pinned: true, active: true });
assert.equal(group.contains(input1), true);
assert.equal(group.contains(input2), true);
assert.equal(group.contains(diffInput1), true);
assert.equal(group.contains(diffInput2), false);
group.openEditor(diffInput2, { pinned: true, active: true });
assert.equal(group.contains(input1), true);
assert.equal(group.contains(input2), true);
assert.equal(group.contains(diffInput1), true);
assert.equal(group.contains(diffInput2), true);
group.closeEditor(input1);
assert.equal(group.contains(input1), false);
assert.equal(group.contains(input1, true), true);
assert.equal(group.contains(input2), true);
assert.equal(group.contains(diffInput1), true);
assert.equal(group.contains(diffInput2), true);
group.closeEditor(input2);
assert.equal(group.contains(input1), false);
assert.equal(group.contains(input1, true), true);
assert.equal(group.contains(input2), false);
assert.equal(group.contains(input2, true), true);
assert.equal(group.contains(diffInput1), true);
assert.equal(group.contains(diffInput2), true);
group.closeEditor(diffInput1);
assert.equal(group.contains(input1), false);
assert.equal(group.contains(input1, true), true);
assert.equal(group.contains(input2), false);
assert.equal(group.contains(input2, true), true);
assert.equal(group.contains(diffInput1), false);
assert.equal(group.contains(diffInput2), true);
group.closeEditor(diffInput2);
assert.equal(group.contains(input1), false);
assert.equal(group.contains(input1, true), false);
assert.equal(group.contains(input2), false);
assert.equal(group.contains(input2, true), false);
assert.equal(group.contains(diffInput1), false);
assert.equal(group.contains(diffInput2), false);
});
test('group serialization', function () {
@@ -1162,47 +1222,6 @@ suite('Workbench editor groups', () => {
assert.equal(group1.getEditors()[1].matches(serializableInput2), true);
});
test('Multiple Editors - Resources', function () {
const group1 = createGroup();
const group2 = createGroup();
const input1Resource = URI.file('/hello/world.txt');
const input1ResourceUpper = URI.file('/hello/WORLD.txt');
const input1 = input(undefined, false, input1Resource);
group1.openEditor(input1);
assert.ok(group1.contains(input1Resource));
assert.equal(group1.getEditor(input1Resource), input1);
assert.ok(!group1.getEditor(input1ResourceUpper));
assert.ok(!group1.contains(input1ResourceUpper));
group2.openEditor(input1);
group1.closeEditor(input1);
assert.ok(!group1.contains(input1Resource));
assert.ok(!group1.getEditor(input1Resource));
assert.ok(!group1.getEditor(input1ResourceUpper));
assert.ok(group2.contains(input1Resource));
assert.equal(group2.getEditor(input1Resource), input1);
const input1ResourceClone = URI.file('/hello/world.txt');
const input1Clone = input(undefined, false, input1ResourceClone);
group1.openEditor(input1Clone);
assert.ok(group1.contains(input1Resource));
group2.closeEditor(input1);
assert.ok(group1.contains(input1Resource));
assert.equal(group1.getEditor(input1Resource), input1Clone);
assert.ok(!group2.contains(input1Resource));
group1.closeEditor(input1Clone);
assert.ok(!group1.contains(input1Resource));
});
test('Multiple Editors - Editor Dispose', function () {
const group1 = createGroup();
const group2 = createGroup();

View File

@@ -22,7 +22,7 @@ suite('Workbench editor input', () => {
assert(input.matches(input));
assert(!input.matches(otherInput));
assert(!input.matches(null));
assert(!input.getName());
assert(input.getName());
input.onDispose(() => {
assert(true);
@@ -84,4 +84,4 @@ suite('Workbench editor input', () => {
otherInput.dispose();
assert.equal(counter, 2);
});
});
});

View File

@@ -6,32 +6,34 @@ import { URI } from 'vs/base/common/uri';
import * as assert from 'assert';
import { join } from 'vs/base/common/path';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
import { UntitledTextEditorModel } from 'vs/workbench/common/editor/untitledTextEditorModel';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
import { UntitledTextEditorInput } from 'vs/workbench/common/editor/untitledTextEditorInput';
import { timeout } from 'vs/base/common/async';
import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService';
export class TestUntitledEditorService extends UntitledEditorService {
export class TestUntitledTextEditorService extends UntitledTextEditorService {
get(resource: URI) { return super.get(resource); }
getAll(resources?: URI[]): UntitledEditorInput[] { return super.getAll(resources); }
getAll(resources?: URI[]): UntitledTextEditorInput[] { return super.getAll(resources); }
}
class ServiceAccessor {
constructor(
@IUntitledEditorService public untitledEditorService: TestUntitledEditorService,
@IModeService public modeService: ModeServiceImpl,
@IConfigurationService public testConfigurationService: TestConfigurationService) {
@IUntitledTextEditorService public readonly untitledTextEditorService: TestUntitledTextEditorService,
@IWorkingCopyService public readonly workingCopyService: IWorkingCopyService,
@IModeService public readonly modeService: ModeServiceImpl,
@IConfigurationService public readonly testConfigurationService: TestConfigurationService) {
}
}
suite('Workbench untitled editors', () => {
suite('Workbench untitled text editors', () => {
let instantiationService: IInstantiationService;
let accessor: ServiceAccessor;
@@ -42,12 +44,14 @@ suite('Workbench untitled editors', () => {
});
teardown(() => {
accessor.untitledEditorService.revertAll();
accessor.untitledEditorService.dispose();
accessor.untitledTextEditorService.revertAll();
accessor.untitledTextEditorService.dispose();
});
test('Untitled Editor Service', async (done) => {
const service = accessor.untitledEditorService;
test('Untitled Text Editor Service', async (done) => {
const service = accessor.untitledTextEditorService;
const workingCopyService = accessor.workingCopyService;
assert.equal(service.getAll().length, 0);
const input1 = service.createOrGet();
@@ -83,14 +87,24 @@ suite('Workbench untitled editors', () => {
assert.equal(service.getDirty([input2.getResource()])[0].toString(), input2.getResource().toString());
assert.equal(service.getDirty([input1.getResource()]).length, 0);
assert.ok(workingCopyService.isDirty(input2.getResource()));
assert.equal(workingCopyService.dirtyCount, 1);
service.revertAll();
assert.equal(service.getAll().length, 0);
assert.ok(!input2.isDirty());
assert.ok(!model.isDirty());
input2.dispose();
assert.ok(!workingCopyService.isDirty(input2.getResource()));
assert.equal(workingCopyService.dirtyCount, 0);
assert.ok(input1.revert());
assert.ok(input1.isDisposed());
assert.ok(!service.exists(input1.getResource()));
input2.dispose();
assert.ok(!service.exists(input2.getResource()));
done();
});
@@ -98,7 +112,7 @@ suite('Workbench untitled editors', () => {
});
test('Untitled with associated resource', () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const file = URI.file(join('C:\\', '/foo/file.txt'));
const untitled = service.createOrGet(file);
@@ -108,20 +122,23 @@ suite('Workbench untitled editors', () => {
});
test('Untitled no longer dirty when content gets empty', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const workingCopyService = accessor.workingCopyService;
const input = service.createOrGet();
// dirty
const model = await input.resolve();
model.textEditorModel.setValue('foo bar');
assert.ok(model.isDirty());
assert.ok(workingCopyService.isDirty(model.resource));
model.textEditorModel.setValue('');
assert.ok(!model.isDirty());
assert.ok(!workingCopyService.isDirty(model.resource));
input.dispose();
});
test('Untitled via loadOrCreate', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const model1 = await service.loadOrCreate();
@@ -138,11 +155,11 @@ suite('Workbench untitled editors', () => {
const model3 = await service.loadOrCreate({ resource: input.getResource() });
assert.equal(model3.getResource().toString(), input.getResource().toString());
assert.equal(model3.resource.toString(), input.getResource().toString());
const file = URI.file(join('C:\\', '/foo/file44.txt'));
const model4 = await service.loadOrCreate({ resource: file });
assert.ok(service.hasAssociatedFilePath(model4.getResource()));
assert.ok(service.hasAssociatedFilePath(model4.resource));
assert.ok(model4.isDirty());
model1.dispose();
@@ -153,14 +170,14 @@ suite('Workbench untitled editors', () => {
});
test('Untitled suggest name', function () {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet();
assert.ok(service.suggestFileName(input.getResource()));
});
test('Untitled with associated path remains dirty when content gets empty', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const file = URI.file(join('C:\\', '/foo/file.txt'));
const input = service.createOrGet(file);
@@ -174,13 +191,23 @@ suite('Workbench untitled editors', () => {
});
test('Untitled with initial content is dirty', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet(undefined, undefined, 'Hello World');
const workingCopyService = accessor.workingCopyService;
let onDidChangeDirty: IWorkingCopy | undefined = undefined;
const listener = workingCopyService.onDidChangeDirty(copy => {
onDidChangeDirty = copy;
});
// dirty
const model = await input.resolve();
assert.ok(model.isDirty());
assert.equal(workingCopyService.dirtyCount, 1);
assert.equal(onDidChangeDirty, model);
input.dispose();
listener.dispose();
});
test('Untitled created with files.defaultLanguage setting', () => {
@@ -188,7 +215,7 @@ suite('Workbench untitled editors', () => {
const config = accessor.testConfigurationService;
config.setUserConfiguration('files', { 'defaultLanguage': defaultLanguage });
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet();
assert.equal(input.getMode(), defaultLanguage);
@@ -204,7 +231,7 @@ suite('Workbench untitled editors', () => {
const config = accessor.testConfigurationService;
config.setUserConfiguration('files', { 'defaultLanguage': defaultLanguage });
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet(null!, mode);
assert.equal(input.getMode(), mode);
@@ -221,7 +248,7 @@ suite('Workbench untitled editors', () => {
id: mode,
});
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet(null!, mode);
assert.equal(input.getMode(), mode);
@@ -237,7 +264,7 @@ suite('Workbench untitled editors', () => {
});
test('encoding change event', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet();
let counter = 0;
@@ -255,10 +282,10 @@ suite('Workbench untitled editors', () => {
});
test('onDidChangeContent event', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet();
UntitledEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = 0;
UntitledTextEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = 0;
let counter = 0;
@@ -293,7 +320,7 @@ suite('Workbench untitled editors', () => {
});
test('onDidDisposeModel event', async () => {
const service = accessor.untitledEditorService;
const service = accessor.untitledTextEditorService;
const input = service.createOrGet();
let counter = 0;
@@ -308,4 +335,4 @@ suite('Workbench untitled editors', () => {
input.dispose();
assert.equal(counter, 1);
});
});
});

View File

@@ -8,42 +8,69 @@ import * as assert from 'assert';
import { isURLDomainTrusted } from 'vs/workbench/contrib/url/common/trustedDomainsValidator';
import { URI } from 'vs/base/common/uri';
function linkAllowedByRules(link: string, rules: string[]) {
assert.ok(isURLDomainTrusted(URI.parse(link), rules), `Link\n${link}\n should be protected by rules\n${JSON.stringify(rules)}`);
}
function linkNotAllowedByRules(link: string, rules: string[]) {
assert.ok(!isURLDomainTrusted(URI.parse(link), rules), `Link\n${link}\n should NOT be protected by rules\n${JSON.stringify(rules)}`);
}
suite('Link protection domain matching', () => {
test('simple', () => {
assert.ok(!isURLDomainTrusted(URI.parse('https://x.org'), []));
assert.ok(isURLDomainTrusted(URI.parse('https://x.org'), ['https://x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://x.org/foo'), ['https://x.org']));
linkNotAllowedByRules('https://x.org', []);
assert.ok(!isURLDomainTrusted(URI.parse('https://x.org'), ['http://x.org']));
assert.ok(!isURLDomainTrusted(URI.parse('http://x.org'), ['https://x.org']));
linkAllowedByRules('https://x.org', ['https://x.org']);
linkAllowedByRules('https://x.org/foo', ['https://x.org']);
assert.ok(!isURLDomainTrusted(URI.parse('https://www.x.org'), ['https://x.org']));
linkNotAllowedByRules('https://x.org', ['http://x.org']);
linkNotAllowedByRules('http://x.org', ['https://x.org']);
assert.ok(isURLDomainTrusted(URI.parse('https://www.x.org'), ['https://www.x.org', 'https://y.org']));
linkNotAllowedByRules('https://www.x.org', ['https://x.org']);
linkAllowedByRules('https://www.x.org', ['https://www.x.org', 'https://y.org']);
});
test('localhost', () => {
assert.ok(isURLDomainTrusted(URI.parse('https://127.0.0.1'), []));
assert.ok(isURLDomainTrusted(URI.parse('https://127.0.0.1:3000'), []));
assert.ok(isURLDomainTrusted(URI.parse('https://localhost'), []));
assert.ok(isURLDomainTrusted(URI.parse('https://localhost:3000'), []));
linkAllowedByRules('https://127.0.0.1', []);
linkAllowedByRules('https://127.0.0.1:3000', []);
linkAllowedByRules('https://localhost', []);
linkAllowedByRules('https://localhost:3000', []);
});
test('* star', () => {
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['https://*.x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.b.x.org'), ['https://*.x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['https://a.x.*']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['https://a.*.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['https://*.*.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.b.x.org'), ['https://*.b.*.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.a.b.x.org'), ['https://*.b.*.org']));
linkAllowedByRules('https://a.x.org', ['https://*.x.org']);
linkAllowedByRules('https://a.b.x.org', ['https://*.x.org']);
linkAllowedByRules('https://a.x.org', ['https://a.x.*']);
linkAllowedByRules('https://a.x.org', ['https://a.*.org']);
linkAllowedByRules('https://a.x.org', ['https://*.*.org']);
linkAllowedByRules('https://a.b.x.org', ['https://*.b.*.org']);
linkAllowedByRules('https://a.a.b.x.org', ['https://*.b.*.org']);
});
test('no scheme', () => {
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['a.x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.x.org'), ['*.x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://a.b.x.org'), ['*.x.org']));
assert.ok(isURLDomainTrusted(URI.parse('https://x.org'), ['*.x.org']));
linkAllowedByRules('https://a.x.org', ['a.x.org']);
linkAllowedByRules('https://a.x.org', ['*.x.org']);
linkAllowedByRules('https://a.b.x.org', ['*.x.org']);
linkAllowedByRules('https://x.org', ['*.x.org']);
});
test('sub paths', () => {
linkAllowedByRules('https://x.org/foo', ['https://x.org/foo']);
linkAllowedByRules('https://x.org/foo', ['x.org/foo']);
linkAllowedByRules('https://x.org/foo', ['*.org/foo']);
linkNotAllowedByRules('https://x.org/bar', ['https://x.org/foo']);
linkNotAllowedByRules('https://x.org/bar', ['x.org/foo']);
linkNotAllowedByRules('https://x.org/bar', ['*.org/foo']);
linkAllowedByRules('https://x.org/foo/bar', ['https://x.org/foo']);
linkNotAllowedByRules('https://x.org/foo2', ['https://x.org/foo']);
linkNotAllowedByRules('https://www.x.org/foo', ['https://x.org/foo']);
linkNotAllowedByRules('https://a.x.org/bar', ['https://*.x.org/foo']);
linkNotAllowedByRules('https://a.b.x.org/bar', ['https://*.x.org/foo']);
linkAllowedByRules('https://github.com', ['https://github.com/foo/bar', 'https://github.com']);
});
});

View File

@@ -67,13 +67,13 @@ suite('ExtHostLanguageFeatureCommands', function () {
rpcProtocol = new TestRPCProtocol();
instantiationService.stub(ICommandService, {
_serviceBrand: undefined,
executeCommand(id: string, args: any): any {
executeCommand(id: string, ...args: any): any {
const command = CommandsRegistry.getCommands().get(id);
if (!command) {
return Promise.reject(new Error(id + ' NOT known'));
}
const { handler } = command;
return Promise.resolve(instantiationService.invokeFunction(handler, args));
return Promise.resolve(instantiationService.invokeFunction(handler, ...args));
}
});
instantiationService.stub(IMarkerService, new MarkerService());
@@ -112,7 +112,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol));
ExtHostApiCommands.register(commands);
const diagnostics = new ExtHostDiagnostics(rpcProtocol);
const diagnostics = new ExtHostDiagnostics(rpcProtocol, new NullLogService());
rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics);
extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, diagnostics, new NullLogService());
@@ -412,11 +412,8 @@ suite('ExtHostLanguageFeatureCommands', function () {
assert.equal(values.length, 4);
let [first, second, third, fourth] = values;
assert.equal(first.label, 'item1');
assert.equal(first.textEdit!.newText, 'item1');
assert.equal(first.textEdit!.range.start.line, 0);
assert.equal(first.textEdit!.range.start.character, 0);
assert.equal(first.textEdit!.range.end.line, 0);
assert.equal(first.textEdit!.range.end.character, 4);
assert.equal(first.textEdit, undefined);// no text edit, default ranges
assert.ok(!types.Range.isRange(first.range));
assert.equal(second.label, 'item2');
assert.equal(second.textEdit!.newText, 'foo');
@@ -434,10 +431,13 @@ suite('ExtHostLanguageFeatureCommands', function () {
assert.equal(fourth.label, 'item4');
assert.equal(fourth.textEdit, undefined);
assert.equal(fourth.range!.start.line, 0);
assert.equal(fourth.range!.start.character, 1);
assert.equal(fourth.range!.end.line, 0);
assert.equal(fourth.range!.end.character, 4);
const range: any = fourth.range!;
assert.ok(types.Range.isRange(range));
assert.equal(range.start.line, 0);
assert.equal(range.start.character, 1);
assert.equal(range.end.line, 0);
assert.equal(range.end.character, 4);
assert.ok(fourth.insertText instanceof types.SnippetString);
assert.equal((<types.SnippetString>fourth.insertText).value, 'foo$0bar');
});
@@ -859,31 +859,44 @@ suite('ExtHostLanguageFeatureCommands', function () {
// --- call hierarcht
test('Call Hierarchy, back and forth', async function () {
test('CallHierarchy, back and forth', async function () {
disposables.push(extHost.registerCallHierarchyProvider(nullExtensionDescription, defaultSelector, new class implements vscode.CallHierarchyItemProvider {
provideCallHierarchyIncomingCalls(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CallHierarchyIncomingCall[]> {
return [
new types.CallHierarchyIncomingCall(new types.CallHierarchyItem(types.SymbolKind.Array, 'IN', '', document.uri, new types.Range(0, 0, 2, 0), new types.Range(0, 0, 2, 0)), [new types.Range(0, 0, 0, 0)]),
];
disposables.push(extHost.registerCallHierarchyProvider(nullExtensionDescription, defaultSelector, new class implements vscode.CallHierarchyProvider {
prepareCallHierarchy(document: vscode.TextDocument, position: vscode.Position, ): vscode.ProviderResult<vscode.CallHierarchyItem> {
return new types.CallHierarchyItem(types.SymbolKind.Constant, 'ROOT', 'ROOT', document.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0));
}
provideCallHierarchyOutgoingCalls(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CallHierarchyOutgoingCall[]> {
return [
new types.CallHierarchyOutgoingCall(new types.CallHierarchyItem(types.SymbolKind.Array, 'OUT', '', document.uri, new types.Range(0, 0, 2, 0), new types.Range(0, 0, 2, 0)), [new types.Range(0, 0, 0, 0)]),
];
provideCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CallHierarchyIncomingCall[]> {
return [new types.CallHierarchyIncomingCall(
new types.CallHierarchyItem(types.SymbolKind.Constant, 'INCOMING', 'INCOMING', item.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0)),
[new types.Range(0, 0, 0, 0)]
)];
}
provideCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CallHierarchyOutgoingCall[]> {
return [new types.CallHierarchyOutgoingCall(
new types.CallHierarchyItem(types.SymbolKind.Constant, 'OUTGOING', 'OUTGOING', item.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0)),
[new types.Range(0, 0, 0, 0)]
)];
}
}));
await rpcProtocol.sync();
let incoming = await commands.executeCommand<vscode.CallHierarchyIncomingCall[]>('vscode.executeCallHierarchyProviderIncomingCalls', model.uri, new types.Position(0, 10));
assert.equal(incoming.length, 1);
assert.ok(incoming[0].from instanceof types.CallHierarchyItem);
assert.equal(incoming[0].from.name, 'IN');
const root = await commands.executeCommand<vscode.CallHierarchyItem[]>('vscode.prepareCallHierarchy', model.uri, new types.Position(0, 0));
let outgoing = await commands.executeCommand<vscode.CallHierarchyOutgoingCall[]>('vscode.executeCallHierarchyProviderOutgoingCalls', model.uri, new types.Position(0, 10));
assert.ok(Array.isArray(root));
assert.equal(root.length, 1);
assert.equal(root[0].name, 'ROOT');
const incoming = await commands.executeCommand<vscode.CallHierarchyIncomingCall[]>('vscode.provideIncomingCalls', root[0]);
assert.equal(incoming.length, 1);
assert.equal(incoming[0].from.name, 'INCOMING');
const outgoing = await commands.executeCommand<vscode.CallHierarchyOutgoingCall[]>('vscode.provideOutgoingCalls', root[0]);
assert.equal(outgoing.length, 1);
assert.ok(outgoing[0].to instanceof types.CallHierarchyItem);
assert.equal(outgoing[0].to.name, 'OUT');
assert.equal(outgoing[0].to.name, 'OUTGOING');
});
});

View File

@@ -35,7 +35,7 @@ suite('ExtHostConfiguration', function () {
if (!shape) {
shape = new class extends mock<MainThreadConfigurationShape>() { };
}
return new ExtHostConfigProvider(shape, createExtHostWorkspace(), createConfigurationData(contents));
return new ExtHostConfigProvider(shape, createExtHostWorkspace(), createConfigurationData(contents), new NullLogService());
}
function createConfigurationData(contents: any): IConfigurationInitData {
@@ -283,7 +283,8 @@ suite('ExtHostConfiguration', function () {
workspace: new ConfigurationModel({}, []),
folders: [],
configurationScopes: []
}
},
new NullLogService()
);
let actual = testObject.getConfiguration().inspect('editor.wordWrap')!;
@@ -331,7 +332,8 @@ suite('ExtHostConfiguration', function () {
workspace,
folders,
configurationScopes: []
}
},
new NullLogService()
);
let actual1 = testObject.getConfiguration().inspect('editor.wordWrap')!;
@@ -407,7 +409,8 @@ suite('ExtHostConfiguration', function () {
workspace,
folders,
configurationScopes: []
}
},
new NullLogService()
);
let actual1 = testObject.getConfiguration().inspect('editor.wordWrap')!;
@@ -607,7 +610,8 @@ suite('ExtHostConfiguration', function () {
'config': false,
'updatedconfig': false
}
})
}),
new NullLogService()
);
const newConfigData = createConfigurationData({

View File

@@ -11,6 +11,7 @@ import { MainThreadDiagnosticsShape, IMainContext } from 'vs/workbench/api/commo
import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { Emitter, Event } from 'vs/base/common/event';
import { NullLogService } from 'vs/platform/log/common/log';
suite('ExtHostDiagnostics', () => {
@@ -96,10 +97,10 @@ suite('ExtHostDiagnostics', () => {
assert.throws(() => array.pop());
assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil'));
collection.forEach((uri, array: Diagnostic[]) => {
assert.throws(() => array.length = 0);
assert.throws(() => array.pop());
assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil'));
collection.forEach((uri, array: readonly Diagnostic[]) => {
assert.throws(() => (array as Diagnostic[]).length = 0);
assert.throws(() => (array as Diagnostic[]).pop());
assert.throws(() => (array as Diagnostic[])[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil'));
});
array = collection.get(URI.parse('foo:bar')) as Diagnostic[];
@@ -387,7 +388,7 @@ suite('ExtHostDiagnostics', () => {
assertRegistered(): void {
}
});
}, new NullLogService());
let collection1 = diags.createDiagnosticCollection('foo');
let collection2 = diags.createDiagnosticCollection('foo'); // warns, uses a different owner
@@ -436,7 +437,7 @@ suite('ExtHostDiagnostics', () => {
assertRegistered(): void {
}
});
}, new NullLogService());
//

View File

@@ -251,11 +251,7 @@ suite('ExtHostDocumentData', () => {
assert.equal(range.end.character, 4);
// ignore bad regular expresson /.*/
range = data.document.getWordRangeAtPosition(new Position(0, 2), /.*/)!;
assert.equal(range.start.line, 0);
assert.equal(range.start.character, 0);
assert.equal(range.end.line, 0);
assert.equal(range.end.character, 4);
assert.throws(() => data.document.getWordRangeAtPosition(new Position(0, 2), /.*/)!);
range = data.document.getWordRangeAtPosition(new Position(0, 5), /[a-z+]+/)!;
assert.equal(range.start.line, 0);

View File

@@ -10,7 +10,7 @@ import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbe
import { MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant';
import { SingleProxyRPCProtocol } from './testRPCProtocol';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/common/editor';
import * as vscode from 'vscode';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { NullLogService } from 'vs/platform/log/common/log';

View File

@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService';
import { IMainContext } from 'vs/workbench/api/common/extHost.protocol';
import { NullLogService } from 'vs/platform/log/common/log';
suite('ExtHostFileSystemEventService', () => {
@@ -17,12 +18,12 @@ suite('ExtHostFileSystemEventService', () => {
assertRegistered: undefined!
};
const watcher1 = new ExtHostFileSystemEventService(protocol, undefined!).createFileSystemWatcher('**/somethingInteresting', false, false, false);
const watcher1 = new ExtHostFileSystemEventService(protocol, new NullLogService(), undefined!).createFileSystemWatcher('**/somethingInteresting', false, false, false);
assert.equal(watcher1.ignoreChangeEvents, false);
assert.equal(watcher1.ignoreCreateEvents, false);
assert.equal(watcher1.ignoreDeleteEvents, false);
const watcher2 = new ExtHostFileSystemEventService(protocol, undefined!).createFileSystemWatcher('**/somethingBoring', true, true, true);
const watcher2 = new ExtHostFileSystemEventService(protocol, new NullLogService(), undefined!).createFileSystemWatcher('**/somethingBoring', true, true, true);
assert.equal(watcher2.ignoreChangeEvents, true);
assert.equal(watcher2.ignoreCreateEvents, true);
assert.equal(watcher2.ignoreDeleteEvents, true);

View File

@@ -23,10 +23,9 @@ import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocum
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/quickOpen';
import * as modes from 'vs/editor/common/modes';
import { getCodeLensData } from 'vs/editor/contrib/codelens/codelens';
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition } from 'vs/editor/contrib/goToDefinition/goToDefinition';
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition, getReferencesAtPosition } from 'vs/editor/contrib/gotoSymbol/goToSymbol';
import { getHover } from 'vs/editor/contrib/hover/getHover';
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/wordHighlighter';
import { provideReferences } from 'vs/editor/contrib/referenceSearch/referenceSearch';
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
import { getWorkspaceSymbols } from 'vs/workbench/contrib/search/common/search';
import { rename } from 'vs/editor/contrib/rename/rename';
@@ -103,7 +102,7 @@ suite('ExtHostLanguageFeatures', function () {
rpcProtocol.set(ExtHostContext.ExtHostCommands, commands);
rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol));
const diagnostics = new ExtHostDiagnostics(rpcProtocol);
const diagnostics = new ExtHostDiagnostics(rpcProtocol, new NullLogService());
rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics);
extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, diagnostics, new NullLogService());
@@ -535,7 +534,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
let value = await provideReferences(model, new EditorPosition(1, 2), CancellationToken.None);
let value = await getReferencesAtPosition(model, new EditorPosition(1, 2), false, CancellationToken.None);
assert.equal(value.length, 2);
let [first, second] = value;
assert.equal(first.uri.path, '/second');
@@ -551,7 +550,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
let value = await provideReferences(model, new EditorPosition(1, 2), CancellationToken.None);
let value = await getReferencesAtPosition(model, new EditorPosition(1, 2), false, CancellationToken.None);
assert.equal(value.length, 1);
let [item] = value;
assert.deepEqual(item.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
@@ -572,7 +571,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const value = await provideReferences(model, new EditorPosition(1, 2), CancellationToken.None);
const value = await getReferencesAtPosition(model, new EditorPosition(1, 2), false, CancellationToken.None);
assert.equal(value.length, 1);
});
@@ -590,7 +589,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
assert.equal(actions.length, 2);
const [first, second] = actions;
assert.equal(first.title, 'Testing1');
@@ -614,7 +613,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
assert.equal(actions.length, 1);
const [first] = actions;
assert.equal(first.title, 'Testing1');
@@ -637,7 +636,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
assert.equal(actions.length, 1);
});
@@ -655,7 +654,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
const { actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
const { validActions: actions } = await getCodeActions(model, model.getFullModelRange(), { type: 'manual' }, CancellationToken.None);
assert.equal(actions.length, 1);
});

View File

@@ -12,7 +12,7 @@ import { joinPath } from 'vs/base/common/resources';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { MainContext, MainThreadSearchShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { Range } from 'vs/workbench/api/common/extHostTypes';
import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteStats, ISearchQuery, ITextQuery, QueryType, resultIsMatch } from 'vs/workbench/services/search/common/search';
import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol';
@@ -21,9 +21,11 @@ import { NullLogService } from 'vs/platform/log/common/log';
import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
let rpcProtocol: TestRPCProtocol;
let extHostSearch: ExtHostSearch;
let extHostSearch: NativeExtHostSearch;
const disposables = new DisposableStore();
let mockMainThreadSearch: MockMainThreadSearch;
@@ -138,7 +140,7 @@ suite('ExtHostSearch', () => {
rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch);
mockPFS = {};
extHostSearch = new class extends ExtHostSearch {
extHostSearch = new class extends NativeExtHostSearch {
constructor() {
super(
rpcProtocol,
@@ -148,6 +150,10 @@ suite('ExtHostSearch', () => {
);
this._pfs = mockPFS as any;
}
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
return new NativeTextSearchManager(query, provider, this._pfs);
}
};
});

View File

@@ -22,13 +22,11 @@ suite('ExtHostTypeConverter', function () {
data = MarkdownString.from('Hello [link](foo)');
assert.equal(data.value, 'Hello [link](foo)');
assert.equal(size(data.uris!), 1);
assert.ok(!!data.uris!['foo']);
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri
data = MarkdownString.from('Hello [link](www.noscheme.bad)');
assert.equal(data.value, 'Hello [link](www.noscheme.bad)');
assert.equal(size(data.uris!), 1);
assert.ok(!!data.uris!['www.noscheme.bad']);
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri
data = MarkdownString.from('Hello [link](foo:path)');
assert.equal(data.value, 'Hello [link](foo:path)');

View File

@@ -527,6 +527,25 @@ suite('ExtHostTypes', function () {
string.appendVariable('BAR', b => { });
assert.equal(string.value, '${BAR}');
string = new types.SnippetString();
string.appendChoice(['b', 'a', 'r']);
assert.equal(string.value, '${1|b,a,r|}');
string = new types.SnippetString();
string.appendChoice(['b', 'a', 'r'], 0);
assert.equal(string.value, '${0|b,a,r|}');
string = new types.SnippetString();
string.appendText('foo').appendChoice(['far', 'boo']).appendText('bar');
assert.equal(string.value, 'foo${1|far,boo|}bar');
string = new types.SnippetString();
string.appendText('foo').appendChoice(['far', '$boo']).appendText('bar');
assert.equal(string.value, 'foo${1|far,\\$boo|}bar');
string = new types.SnippetString();
string.appendText('foo').appendPlaceholder('farboo').appendChoice(['far', 'boo']).appendText('bar');
assert.equal(string.value, 'foo${1:farboo}${2|far,boo|}bar');
});
test('instanceof doesn\'t work for FileSystemError #49386', function () {

View File

@@ -4,14 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { NullLogService } from 'vs/platform/log/common/log';
import { MainThreadWebviews } from 'vs/workbench/api/browser/mainThreadWebview';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import * as vscode from 'vscode';
import { SingleProxyRPCProtocol } from './testRPCProtocol';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { URI } from 'vs/base/common/uri';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
suite('ExtHostWebview', () => {
@@ -23,7 +24,7 @@ suite('ExtHostWebview', () => {
webviewCspSource: '',
webviewResourceRoot: '',
isExtensionDevelopmentDebug: false,
}, undefined);
}, undefined, new NullLogService());
let lastInvokedDeserializer: vscode.WebviewPanelSerializer | undefined = undefined;
@@ -61,7 +62,7 @@ suite('ExtHostWebview', () => {
webviewCspSource: '',
webviewResourceRoot: 'vscode-resource://{{resource}}',
isExtensionDevelopmentDebug: false,
}, undefined);
}, undefined, new NullLogService());
const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {});
assert.strictEqual(
@@ -102,7 +103,7 @@ suite('ExtHostWebview', () => {
webviewCspSource: '',
webviewResourceRoot: `https://{{uuid}}.webview.contoso.com/commit/{{resource}}`,
isExtensionDevelopmentDebug: false,
}, undefined);
}, undefined, new NullLogService());
const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {});
function stripEndpointUuid(input: string) {

View File

@@ -11,13 +11,15 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace';
import { MainThreadWorkspace } from 'vs/workbench/api/browser/mainThreadWorkspace';
import { IMainContext, IWorkspaceData, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { IMainContext, IWorkspaceData, MainContext, ITextSearchComplete } from 'vs/workbench/api/common/extHost.protocol';
import { RelativePattern } from 'vs/workbench/api/common/extHostTypes';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { TestRPCProtocol } from './testRPCProtocol';
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';
function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace {
const result = new ExtHostWorkspace(
@@ -674,4 +676,106 @@ suite('ExtHostWorkspace', function () {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
test('findTextInFiles - no include', async () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
async $startTextSearch(query: IPatternInfo, folder: UriComponents | null, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete | null> {
mainThreadCalled = true;
assert.equal(query.pattern, 'foo');
assert.equal(folder, null);
assert.equal(options.includePattern, null);
assert.equal(options.excludePattern, null);
return null;
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
await ws.findTextInFiles({ pattern: 'foo' }, {}, () => { }, new ExtensionIdentifier('test'));
assert(mainThreadCalled, 'mainThreadCalled');
});
test('findTextInFiles - string include', async () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
async $startTextSearch(query: IPatternInfo, folder: UriComponents | null, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete | null> {
mainThreadCalled = true;
assert.equal(query.pattern, 'foo');
assert.equal(folder, null);
assert.equal(options.includePattern, '**/files');
assert.equal(options.excludePattern, null);
return null;
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
await ws.findTextInFiles({ pattern: 'foo' }, { include: '**/files' }, () => { }, new ExtensionIdentifier('test'));
assert(mainThreadCalled, 'mainThreadCalled');
});
test('findTextInFiles - RelativePattern include', async () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
async $startTextSearch(query: IPatternInfo, folder: UriComponents | null, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete | null> {
mainThreadCalled = true;
assert.equal(query.pattern, 'foo');
assert.deepEqual(folder, URI.file('/other/folder').toJSON());
assert.equal(options.includePattern, 'glob/**');
assert.equal(options.excludePattern, null);
return null;
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
await ws.findTextInFiles({ pattern: 'foo' }, { include: new RelativePattern('/other/folder', 'glob/**') }, () => { }, new ExtensionIdentifier('test'));
assert(mainThreadCalled, 'mainThreadCalled');
});
test('findTextInFiles - with cancelled token', async () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
async $startTextSearch(query: IPatternInfo, folder: UriComponents | null, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete | null> {
mainThreadCalled = true;
return null;
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
const token = CancellationToken.Cancelled;
await ws.findTextInFiles({ pattern: 'foo' }, {}, () => { }, new ExtensionIdentifier('test'), token);
assert(!mainThreadCalled, '!mainThreadCalled');
});
test('findTextInFiles - RelativePattern exclude', async () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
async $startTextSearch(query: IPatternInfo, folder: UriComponents | null, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<ITextSearchComplete | null> {
mainThreadCalled = true;
assert.equal(query.pattern, 'foo');
assert.deepEqual(folder, null);
assert.equal(options.includePattern, null);
assert.equal(options.excludePattern, 'glob/**'); // exclude folder is ignored...
return null;
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
await ws.findTextInFiles({ pattern: 'foo' }, { exclude: new RelativePattern('/other/folder', 'glob/**') }, () => { }, new ExtensionIdentifier('test'));
assert(mainThreadCalled, 'mainThreadCalled');
});
});

View File

@@ -20,6 +20,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { IFileService } from 'vs/platform/files/common/files';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
suite('MainThreadDocumentsAndEditors', () => {
@@ -42,7 +43,7 @@ suite('MainThreadDocumentsAndEditors', () => {
deltas.length = 0;
const configService = new TestConfigurationService();
configService.setUserConfiguration('editor', { 'detectIndentation': false });
modelService = new ModelServiceImpl(configService, new TestTextResourcePropertiesService(configService));
modelService = new ModelServiceImpl(configService, new TestTextResourcePropertiesService(configService), new TestThemeService());
codeEditorService = new TestCodeEditorService();
textFileService = new class extends mock<ITextFileService>() {
isDirty() { return false; }

View File

@@ -27,6 +27,7 @@ import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/se
import { IReference, ImmortalReference } from 'vs/base/common/lifecycle';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
suite('MainThreadEditors', () => {
@@ -36,15 +37,17 @@ suite('MainThreadEditors', () => {
let editors: MainThreadTextEditors;
const movedResources = new Map<URI, URI>();
const copiedResources = new Map<URI, URI>();
const createdResources = new Set<URI>();
const deletedResources = new Set<URI>();
setup(() => {
const configService = new TestConfigurationService();
modelService = new ModelServiceImpl(configService, new TestTextResourcePropertiesService(configService));
modelService = new ModelServiceImpl(configService, new TestTextResourcePropertiesService(configService), new TestThemeService());
const codeEditorService = new TestCodeEditorService();
movedResources.clear();
copiedResources.clear();
createdResources.clear();
deletedResources.clear();
@@ -64,6 +67,10 @@ suite('MainThreadEditors', () => {
movedResources.set(source, target);
return Promise.resolve(Object.create(null));
}
copy(source: URI, target: URI) {
copiedResources.set(source, target);
return Promise.resolve(Object.create(null));
}
models = <any>{
onModelSaved: Event.None,
onModelReverted: Event.None,

View File

@@ -13,7 +13,8 @@ import { IModelService } from 'vs/editor/common/services/modelService';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ITextFileService, SaveReason, IResolvedTextFileEditorModel, snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, IResolvedTextFileEditorModel, snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/common/editor';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
class ServiceAccessor {

View File

@@ -27,9 +27,10 @@ import 'vs/workbench/contrib/search/browser/search.contribution'; // load contri
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { LocalSearchService } from 'vs/workbench/services/search/node/searchService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { TestContextService, TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
namespace Timer {
export interface ITimerEvent {
@@ -73,12 +74,12 @@ suite.skip('QuickOpen performance (integration)', () => {
[ITelemetryService, telemetryService],
[IConfigurationService, configurationService],
[ITextResourcePropertiesService, textResourcePropertiesService],
[IModelService, new ModelServiceImpl(configurationService, textResourcePropertiesService)],
[IModelService, new ModelServiceImpl(configurationService, textResourcePropertiesService, new TestThemeService())],
[IWorkspaceContextService, new TestContextService(testWorkspace(URI.file(testWorkspacePath)))],
[IEditorService, new TestEditorService()],
[IEditorGroupsService, new TestEditorGroupsService()],
[IEnvironmentService, TestEnvironmentService],
[IUntitledEditorService, createSyncDescriptor(UntitledEditorService)],
[IUntitledTextEditorService, createSyncDescriptor(UntitledTextEditorService)],
[ISearchService, createSyncDescriptor(LocalSearchService)]
));

View File

@@ -11,7 +11,7 @@ import { createSyncDescriptor } from 'vs/platform/instantiation/common/descripto
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ISearchService } from 'vs/workbench/services/search/common/search';
import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import * as minimist from 'vscode-minimist';
import * as path from 'vs/base/common/path';
@@ -34,6 +34,7 @@ import { testWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { NullLogService, ILogService } from 'vs/platform/log/common/log';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
declare var __dirname: string;
@@ -63,12 +64,12 @@ suite.skip('TextSearch performance (integration)', () => {
[ITelemetryService, telemetryService],
[IConfigurationService, configurationService],
[ITextResourcePropertiesService, textResourcePropertiesService],
[IModelService, new ModelServiceImpl(configurationService, textResourcePropertiesService)],
[IModelService, new ModelServiceImpl(configurationService, textResourcePropertiesService, new TestThemeService())],
[IWorkspaceContextService, new TestContextService(testWorkspace(URI.file(testWorkspacePath)))],
[IEditorService, new TestEditorService()],
[IEditorGroupsService, new TestEditorGroupsService()],
[IEnvironmentService, TestEnvironmentService],
[IUntitledEditorService, createSyncDescriptor(UntitledEditorService)],
[IUntitledTextEditorService, createSyncDescriptor(UntitledTextEditorService)],
[ISearchService, createSyncDescriptor(LocalSearchService)],
[ILogService, new NullLogService()]
));

View File

@@ -8,10 +8,10 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileE
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { join } from 'vs/base/common/path';
import * as resources from 'vs/base/common/resources';
import { URI, UriComponents } from 'vs/base/common/uri';
import { URI } from 'vs/base/common/uri';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { ConfirmResult, IEditorInputWithOptions, CloseDirection, IEditorIdentifier, IUntitledResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInput, IEditor, IEditorCloseEvent, IEditorPartOptions } from 'vs/workbench/common/editor';
import { IEditorInputWithOptions, CloseDirection, IEditorIdentifier, IUntitledTextResourceInput, IResourceDiffInput, IResourceSideBySideInput, IEditorInput, IEditor, IEditorCloseEvent, IEditorPartOptions, IRevertOptions } from 'vs/workbench/common/editor';
import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor';
import { Event, Emitter } from 'vs/base/common/event';
import Severity from 'vs/base/common/severity';
@@ -21,7 +21,7 @@ import { IWorkbenchLayoutService, Parts, Position as PartPosition } from 'vs/wor
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { IEditorOptions, IResourceInput } from 'vs/platform/editor/common/editor';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace } from 'vs/platform/workspace/common/workspace';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
@@ -49,7 +49,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { ITextBufferFactory, DefaultEndOfLine, EndOfLinePreference, IModelDecorationOptions, ITextModel, ITextSnapshot } from 'vs/editor/common/model';
import { Range } from 'vs/editor/common/core/range';
import { IConfirmation, IConfirmationResult, IDialogService, IDialogOptions, IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService, IShowResult } from 'vs/platform/dialogs/common/dialogs';
import { IConfirmation, IConfirmationResult, IDialogService, IDialogOptions, IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService, IShowResult, ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { IExtensionService, NullExtensionService } from 'vs/workbench/services/extensions/common/extensions';
@@ -57,7 +57,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/browser/decorations';
import { IDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IMoveEditorOptions, ICopyEditorOptions, IEditorReplacement, IGroupChangeEvent, EditorsOrder, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService, IOpenEditorOverrideHandler, IVisibleEditor } from 'vs/workbench/services/editor/common/editorService';
import { IEditorService, IOpenEditorOverrideHandler, IVisibleEditor, ISaveEditorsOptions, IRevertAllEditorsOptions } from 'vs/workbench/services/editor/common/editorService';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
@@ -70,7 +70,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage';
import { isLinux, isMacintosh, IProcessEnvironment } from 'vs/base/common/platform';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { IDimension } from 'vs/platform/layout/browser/layoutService';
import { Part } from 'vs/workbench/browser/part';
@@ -79,7 +79,7 @@ import { IPanel } from 'vs/workbench/common/panel';
import { IBadge } from 'vs/workbench/services/activity/common/activity';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService';
import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
import { NativeTextFileService } from 'vs/workbench/services/textfile/electron-browser/nativeTextFileService';
import { Schemas } from 'vs/base/common/network';
@@ -92,12 +92,14 @@ import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/ele
import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
import { find } from 'vs/base/common/arrays';
import { WorkingCopyService, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined);
}
export const TestEnvironmentService = new WorkbenchEnvironmentService(parseArgs(process.argv, OPTIONS) as IWindowConfiguration, process.execPath, 0);
export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(parseArgs(process.argv, OPTIONS) as IWindowConfiguration, process.execPath, 0);
export class TestContextService implements IWorkspaceContextService {
public _serviceBrand: undefined;
@@ -190,48 +192,47 @@ export class TestTextFileService extends NativeTextFileService {
public cleanupBackupsBeforeShutdownCalled!: boolean;
private promptPath!: URI;
private confirmResult!: ConfirmResult;
private resolveTextContentError!: FileOperationError | null;
constructor(
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IFileService protected fileService: IFileService,
@IUntitledEditorService untitledEditorService: IUntitledEditorService,
@IUntitledTextEditorService untitledTextEditorService: IUntitledTextEditorService,
@ILifecycleService lifecycleService: ILifecycleService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@INotificationService notificationService: INotificationService,
@IBackupFileService backupFileService: IBackupFileService,
@IHistoryService historyService: IHistoryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IDialogService dialogService: IDialogService,
@IFileDialogService fileDialogService: IFileDialogService,
@IEditorService editorService: IEditorService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService,
@IElectronService electronService: IElectronService
@IElectronService electronService: IElectronService,
@IProductService productService: IProductService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
) {
super(
contextService,
fileService,
untitledEditorService,
untitledTextEditorService,
lifecycleService,
instantiationService,
configurationService,
modeService,
modelService,
environmentService,
notificationService,
backupFileService,
historyService,
contextKeyService,
dialogService,
fileDialogService,
editorService,
textResourceConfigurationService,
electronService
electronService,
productService,
filesConfigurationService
);
}
@@ -239,10 +240,6 @@ export class TestTextFileService extends NativeTextFileService {
this.promptPath = path;
}
public setConfirmResult(result: ConfirmResult): void {
this.confirmResult = result;
}
public setResolveTextContentErrorOnce(error: FileOperationError): void {
this.resolveTextContentError = error;
}
@@ -260,6 +257,7 @@ export class TestTextFileService extends NativeTextFileService {
resource: content.resource,
name: content.name,
mtime: content.mtime,
ctime: content.ctime,
etag: content.etag,
encoding: 'utf8',
value: await createTextBufferFactoryFromStream(content.value),
@@ -272,18 +270,6 @@ export class TestTextFileService extends NativeTextFileService {
return Promise.resolve(this.promptPath);
}
public confirmSave(_resources?: URI[]): Promise<ConfirmResult> {
return Promise.resolve(this.confirmResult);
}
public confirmOverwrite(_resource: URI): Promise<boolean> {
return Promise.resolve(true);
}
public onFilesConfigurationChange(configuration: any): void {
super.onFilesConfigurationChange(configuration);
}
protected cleanupBackupsBeforeShutdown(): Promise<void> {
this.cleanupBackupsBeforeShutdownCalled = true;
return Promise.resolve();
@@ -293,15 +279,19 @@ export class TestTextFileService extends NativeTextFileService {
export function workbenchInstantiationService(): IInstantiationService {
let instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()]));
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
instantiationService.stub(IContextKeyService, <IContextKeyService>instantiationService.createInstance(MockContextKeyService));
const contextKeyService = <IContextKeyService>instantiationService.createInstance(MockContextKeyService);
instantiationService.stub(IContextKeyService, contextKeyService);
const workspaceContextService = new TestContextService(TestWorkspace);
instantiationService.stub(IWorkspaceContextService, workspaceContextService);
const configService = new TestConfigurationService();
instantiationService.stub(IConfigurationService, configService);
instantiationService.stub(IFilesConfigurationService, new TestFilesConfigurationService(contextKeyService, configService, TestEnvironmentService));
instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService));
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService));
instantiationService.stub(IStorageService, new TestStorageService());
instantiationService.stub(IWorkbenchLayoutService, new TestLayoutService());
instantiationService.stub(IDialogService, new TestDialogService());
instantiationService.stub(IFileDialogService, new TestFileDialogService());
instantiationService.stub(IElectronService, new TestElectronService());
instantiationService.stub(IModeService, instantiationService.createInstance(ModeServiceImpl));
instantiationService.stub(IHistoryService, new TestHistoryService());
@@ -311,7 +301,7 @@ export function workbenchInstantiationService(): IInstantiationService {
instantiationService.stub(IBackupFileService, new TestBackupFileService());
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(INotificationService, new TestNotificationService());
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService));
instantiationService.stub(IMenuService, new TestMenuService());
instantiationService.stub(IKeybindingService, new MockKeybindingService());
instantiationService.stub(IDecorationsService, new TestDecorationsService());
@@ -327,6 +317,7 @@ export function workbenchInstantiationService(): IInstantiationService {
instantiationService.stub(IEditorService, editorService);
instantiationService.stub(ICodeEditorService, new TestCodeEditorService());
instantiationService.stub(IViewletService, new TestViewletService());
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
return instantiationService;
}
@@ -418,6 +409,8 @@ export class TestFileDialogService implements IFileDialogService {
public _serviceBrand: undefined;
private confirmResult!: ConfirmResult;
public defaultFilePath(_schemeFilter?: string): URI | undefined {
return undefined;
}
@@ -448,6 +441,12 @@ export class TestFileDialogService implements IFileDialogService {
public showOpenDialog(_options: IOpenDialogOptions): Promise<URI[] | undefined> {
return Promise.resolve(undefined);
}
public setConfirmResult(result: ConfirmResult): void {
this.confirmResult = result;
}
public showSaveConfirm(fileNamesOrResources: (string | URI)[]): Promise<ConfirmResult> {
return Promise.resolve(this.confirmResult);
}
}
export class TestLayoutService implements IWorkbenchLayoutService {
@@ -461,6 +460,7 @@ export class TestLayoutService implements IWorkbenchLayoutService {
onZenModeChange: Event<boolean> = Event.None;
onCenteredLayoutChange: Event<boolean> = Event.None;
onFullscreenChange: Event<boolean> = Event.None;
onMaximizeChange: Event<boolean> = Event.None;
onPanelPositionChange: Event<string> = Event.None;
onPartVisibilityChange: Event<void> = Event.None;
onLayout = Event.None;
@@ -479,6 +479,14 @@ export class TestLayoutService implements IWorkbenchLayoutService {
return false;
}
public hasWindowBorder(): boolean {
return false;
}
public getWindowBorderRadius(): string | undefined {
return undefined;
}
public isVisible(_part: Parts): boolean {
return true;
}
@@ -562,6 +570,12 @@ export class TestLayoutService implements IWorkbenchLayoutService {
public resizePart(_part: Parts, _sizeChange: number): void { }
public registerPart(part: Part): void { }
isWindowMaximized() {
return false;
}
public updateWindowMaximizedState(maximized: boolean): void { }
}
let activeViewlet: Viewlet = {} as any;
@@ -795,7 +809,7 @@ export class TestEditorGroup implements IEditorGroupView {
return [];
}
getEditor(_index: number): IEditorInput {
getEditorByIndex(_index: number): IEditorInput {
throw new Error('not implemented');
}
@@ -888,11 +902,11 @@ export class TestEditorService implements EditorServiceImpl {
throw new Error('not implemented');
}
isOpen(_editor: IEditorInput | IResourceInput | IUntitledResourceInput): boolean {
isOpen(_editor: IEditorInput | IResourceInput | IUntitledTextResourceInput): boolean {
return false;
}
getOpened(_editor: IEditorInput | IResourceInput | IUntitledResourceInput): IEditorInput {
getOpened(_editor: IEditorInput | IResourceInput | IUntitledTextResourceInput): IEditorInput {
throw new Error('not implemented');
}
@@ -904,9 +918,25 @@ export class TestEditorService implements EditorServiceImpl {
throw new Error('not implemented');
}
createInput(_input: IResourceInput | IUntitledResourceInput | IResourceDiffInput | IResourceSideBySideInput): IEditorInput {
createInput(_input: IResourceInput | IUntitledTextResourceInput | IResourceDiffInput | IResourceSideBySideInput): IEditorInput {
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.');
}
revert(editors: IEditorIdentifier[], options?: IRevertOptions): Promise<boolean> {
throw new Error('Method not implemented.');
}
revertAll(options?: IRevertAllEditorsOptions): Promise<boolean> {
throw new Error('Method not implemented.');
}
}
export class TestFileService implements IFileService {
@@ -964,7 +994,9 @@ export class TestFileService implements IFileService {
encoding: 'utf8',
mtime: Date.now(),
size: 42,
isFile: true,
isDirectory: false,
isSymbolicLink: false,
name: resources.basename(resource)
});
}
@@ -986,6 +1018,7 @@ export class TestFileService implements IFileService {
etag: 'index.txt',
encoding: 'utf8',
mtime: Date.now(),
ctime: Date.now(),
name: resources.basename(resource),
size: 1
});
@@ -1012,6 +1045,7 @@ export class TestFileService implements IFileService {
etag: 'index.txt',
encoding: 'utf8',
mtime: Date.now(),
ctime: Date.now(),
size: 1,
name: resources.basename(resource)
});
@@ -1023,8 +1057,11 @@ export class TestFileService implements IFileService {
etag: 'index.txt',
encoding: 'utf8',
mtime: Date.now(),
ctime: Date.now(),
size: 42,
isFile: true,
isDirectory: false,
isSymbolicLink: false,
name: resources.basename(resource)
}));
}
@@ -1354,7 +1391,7 @@ export class TestElectronService implements IElectronService {
async setRepresentedFilename(path: string): Promise<void> { }
async setDocumentEdited(edited: boolean): Promise<void> { }
async openExternal(url: string): Promise<boolean> { return false; }
async updateTouchBar(items: { id: string; title: string | { value: string; original: string; }; category?: string | { value: string; original: string; } | undefined; iconLocation?: { dark: UriComponents; light?: { readonly scheme: string; readonly authority: string; readonly path: string; readonly query: string; readonly fragment: string; readonly fsPath: string; with: {}; toString: {}; toJSON: {}; } | undefined; } | undefined; precondition?: { getType: {}; equals: {}; evaluate: {}; serialize: {}; keys: {}; map: {}; negate: {}; } | undefined; toggled?: { getType: {}; equals: {}; evaluate: {}; serialize: {}; keys: {}; map: {}; negate: {}; } | undefined; }[][]): Promise<void> { }
async updateTouchBar(): Promise<void> { }
async newWindowTab(): Promise<void> { }
async showPreviousWindowTab(): Promise<void> { }
async showNextWindowTab(): Promise<void> { }
@@ -1369,7 +1406,6 @@ export class TestElectronService implements IElectronService {
async toggleDevTools(): Promise<void> { }
async startCrashReporter(options: Electron.CrashReporterStartOptions): Promise<void> { }
async resolveProxy(url: string): Promise<string | undefined> { return undefined; }
async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment): Promise<void> { }
}
export class TestBackupMainService implements IBackupMainService {
@@ -1447,3 +1483,12 @@ export class TestDialogMainService implements IDialogMainService {
throw new Error('Method not implemented.');
}
}
export class TestWorkingCopyService extends WorkingCopyService { }
export class TestFilesConfigurationService extends FilesConfigurationService {
onFilesConfigurationChange(configuration: any): void {
super.onFilesConfigurationChange(configuration);
}
}